},
events::MessageSendEvent::SendFundingLocked { .. } => continue,
events::MessageSendEvent::SendAnnouncementSignatures { .. } => continue,
- events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => continue,
events::MessageSendEvent::SendChannelUpdate { ref node_id, ref msg } => {
assert_eq!(msg.contents.flags & 2, 0); // The disable bit must never be set!
if Some(*node_id) == expect_drop_id { panic!("peer_disconnected should drop msgs bound for the disconnected peer"); }
events::MessageSendEvent::SendAnnouncementSignatures { .. } => {
// Can be generated as a reestablish response
},
- events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {
- // Can be generated due to a payment forward being rejected due to a
- // channel having previously failed a monitor update
- },
events::MessageSendEvent::SendChannelUpdate { ref msg, .. } => {
// When we reconnect we will resend a channel_update to make sure our
// counterparty has the latest parameters for receiving payments
events::MessageSendEvent::SendChannelReestablish { .. } => {},
events::MessageSendEvent::SendFundingLocked { .. } => {},
events::MessageSendEvent::SendAnnouncementSignatures { .. } => {},
- events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {},
events::MessageSendEvent::SendChannelUpdate { ref msg, .. } => {
assert_eq!(msg.contents.flags & 2, 0); // The disable bit must never be set!
},
events::MessageSendEvent::SendChannelReestablish { .. } => {},
events::MessageSendEvent::SendFundingLocked { .. } => {},
events::MessageSendEvent::SendAnnouncementSignatures { .. } => {},
- events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {},
events::MessageSendEvent::SendChannelUpdate { ref msg, .. } => {
assert_eq!(msg.contents.flags & 2, 0); // The disable bit must never be set!
},
use lightning::ln::msgs::DecodeError;
use lightning::ln::script::ShutdownScript;
use lightning::routing::router::get_route;
-use lightning::routing::network_graph::NetGraphMsgHandler;
+use lightning::routing::network_graph::{NetGraphMsgHandler, NetworkGraph};
use lightning::util::config::UserConfig;
use lightning::util::errors::APIError;
use lightning::util::events::Event;
};
let channelmanager = Arc::new(ChannelManager::new(fee_est.clone(), monitor.clone(), broadcast.clone(), Arc::clone(&logger), keys_manager.clone(), config, params));
let our_id = PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret());
- let net_graph_msg_handler = Arc::new(NetGraphMsgHandler::new(genesis_block(network).block_hash(), None, Arc::clone(&logger)));
+ let network_graph = NetworkGraph::new(genesis_block(network).block_hash());
+ let net_graph_msg_handler = Arc::new(NetGraphMsgHandler::new(network_graph, None, Arc::clone(&logger)));
let peers = RefCell::new([false; 256]);
let mut loss_detector = MoneyLossDetector::new(&peers, channelmanager.clone(), monitor.clone(), PeerManager::new(MessageHandler {
},
4 => {
let value = slice_to_be24(get_slice!(3)) as u64;
- let route = match get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &get_pubkey!(), None, None, &Vec::new(), value, 42, Arc::clone(&logger)) {
+ let route = match get_route(&our_id, &net_graph_msg_handler.network_graph, &get_pubkey!(), None, None, &Vec::new(), value, 42, Arc::clone(&logger)) {
Ok(route) => route,
Err(_) => return,
};
},
15 => {
let value = slice_to_be24(get_slice!(3)) as u64;
- let mut route = match get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &get_pubkey!(), None, None, &Vec::new(), value, 42, Arc::clone(&logger)) {
+ let mut route = match get_route(&our_id, &net_graph_msg_handler.network_graph, &get_pubkey!(), None, None, &Vec::new(), value, 42, Arc::clone(&logger)) {
Ok(route) => route,
Err(_) => return,
};
let logger: Arc<dyn Logger> = Arc::new(test_logger::TestLogger::new("".to_owned(), out));
let our_pubkey = get_pubkey!();
- let mut net_graph = NetworkGraph::new(genesis_block(Network::Bitcoin).header.block_hash());
+ let net_graph = NetworkGraph::new(genesis_block(Network::Bitcoin).header.block_hash());
let mut node_pks = HashSet::new();
let mut scid = 42;
use lightning::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler};
use lightning::ln::peer_handler::{PeerManager, SocketDescriptor};
use lightning::ln::peer_handler::CustomMessageHandler;
-use lightning::util::events::{EventHandler, EventsProvider};
+use lightning::routing::network_graph::NetGraphMsgHandler;
+use lightning::util::events::{Event, EventHandler, EventsProvider};
use lightning::util::logger::Logger;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::{Duration, Instant};
use std::ops::Deref;
-/// BackgroundProcessor takes care of tasks that (1) need to happen periodically to keep
+/// `BackgroundProcessor` takes care of tasks that (1) need to happen periodically to keep
/// Rust-Lightning running properly, and (2) either can or should be run in the background. Its
/// responsibilities are:
-/// * Monitoring whether the ChannelManager needs to be re-persisted to disk, and if so,
+/// * Processing [`Event`]s with a user-provided [`EventHandler`].
+/// * Monitoring whether the [`ChannelManager`] needs to be re-persisted to disk, and if so,
/// writing it to disk/backups by invoking the callback given to it at startup.
-/// ChannelManager persistence should be done in the background.
-/// * Calling `ChannelManager::timer_tick_occurred()` and
-/// `PeerManager::timer_tick_occurred()` every minute (can be done in the
-/// background).
+/// [`ChannelManager`] persistence should be done in the background.
+/// * Calling [`ChannelManager::timer_tick_occurred`] and [`PeerManager::timer_tick_occurred`]
+/// at the appropriate intervals.
///
-/// Note that if ChannelManager persistence fails and the persisted manager becomes out-of-date,
-/// then there is a risk of channels force-closing on startup when the manager realizes it's
-/// outdated. However, as long as `ChannelMonitor` backups are sound, no funds besides those used
-/// for unilateral chain closure fees are at risk.
+/// It will also call [`PeerManager::process_events`] periodically though this shouldn't be relied
+/// upon as doing so may result in high latency.
+///
+/// # Note
+///
+/// If [`ChannelManager`] persistence fails and the persisted manager becomes out-of-date, then
+/// there is a risk of channels force-closing on startup when the manager realizes it's outdated.
+/// However, as long as [`ChannelMonitor`] backups are sound, no funds besides those used for
+/// unilateral chain closure fees are at risk.
+///
+/// [`ChannelMonitor`]: lightning::chain::channelmonitor::ChannelMonitor
+/// [`Event`]: lightning::util::events::Event
#[must_use = "BackgroundProcessor will immediately stop on drop. It should be stored until shutdown."]
pub struct BackgroundProcessor {
stop_thread: Arc<AtomicBool>,
}
}
+/// Decorates an [`EventHandler`] with common functionality provided by standard [`EventHandler`]s.
+struct DecoratingEventHandler<
+ E: EventHandler,
+ N: Deref<Target = NetGraphMsgHandler<A, L>>,
+ A: Deref,
+ L: Deref,
+>
+where A::Target: chain::Access, L::Target: Logger {
+ event_handler: E,
+ net_graph_msg_handler: Option<N>,
+}
+
+impl<
+ E: EventHandler,
+ N: Deref<Target = NetGraphMsgHandler<A, L>>,
+ A: Deref,
+ L: Deref,
+> EventHandler for DecoratingEventHandler<E, N, A, L>
+where A::Target: chain::Access, L::Target: Logger {
+ fn handle_event(&self, event: &Event) {
+ if let Some(event_handler) = &self.net_graph_msg_handler {
+ event_handler.handle_event(event);
+ }
+ self.event_handler.handle_event(event);
+ }
+}
+
impl BackgroundProcessor {
/// Start a background thread that takes care of responsibilities enumerated in the [top-level
/// documentation].
/// `persist_manager` returns an error. In case of an error, the error is retrieved by calling
/// either [`join`] or [`stop`].
///
- /// Typically, users should either implement [`ChannelManagerPersister`] to never return an
- /// error or call [`join`] and handle any error that may arise. For the latter case, the
- /// `BackgroundProcessor` must be restarted by calling `start` again after handling the error.
+ /// # Data Persistence
///
/// `persist_manager` is responsible for writing out the [`ChannelManager`] to disk, and/or
/// uploading to one or more backup services. See [`ChannelManager::write`] for writing out a
/// [`ChannelManager`]. See [`FilesystemPersister::persist_manager`] for Rust-Lightning's
/// provided implementation.
///
+ /// Typically, users should either implement [`ChannelManagerPersister`] to never return an
+ /// error or call [`join`] and handle any error that may arise. For the latter case,
+ /// `BackgroundProcessor` must be restarted by calling `start` again after handling the error.
+ ///
+ /// # Event Handling
+ ///
+ /// `event_handler` is responsible for handling events that users should be notified of (e.g.,
+ /// payment failed). [`BackgroundProcessor`] may decorate the given [`EventHandler`] with common
+ /// functionality implemented by other handlers.
+ /// * [`NetGraphMsgHandler`] if given will update the [`NetworkGraph`] based on payment failures.
+ ///
/// [top-level documentation]: Self
/// [`join`]: Self::join
/// [`stop`]: Self::stop
/// [`ChannelManager`]: lightning::ln::channelmanager::ChannelManager
/// [`ChannelManager::write`]: lightning::ln::channelmanager::ChannelManager#impl-Writeable
/// [`FilesystemPersister::persist_manager`]: lightning_persister::FilesystemPersister::persist_manager
+ /// [`NetworkGraph`]: lightning::routing::network_graph::NetworkGraph
pub fn start<
Signer: 'static + Sign,
+ CA: 'static + Deref + Send + Sync,
CF: 'static + Deref + Send + Sync,
CW: 'static + Deref + Send + Sync,
T: 'static + Deref + Send + Sync,
CMP: 'static + Send + ChannelManagerPersister<Signer, CW, T, K, F, L>,
M: 'static + Deref<Target = ChainMonitor<Signer, CF, T, F, L, P>> + Send + Sync,
CM: 'static + Deref<Target = ChannelManager<Signer, CW, T, K, F, L>> + Send + Sync,
+ NG: 'static + Deref<Target = NetGraphMsgHandler<CA, L>> + Send + Sync,
UMH: 'static + Deref + Send + Sync,
PM: 'static + Deref<Target = PeerManager<Descriptor, CMH, RMH, L, UMH>> + Send + Sync,
- >
- (persister: CMP, event_handler: EH, chain_monitor: M, channel_manager: CM, peer_manager: PM, logger: L) -> Self
+ >(
+ persister: CMP, event_handler: EH, chain_monitor: M, channel_manager: CM,
+ net_graph_msg_handler: Option<NG>, peer_manager: PM, logger: L
+ ) -> Self
where
+ CA::Target: 'static + chain::Access,
CF::Target: 'static + chain::Filter,
CW::Target: 'static + chain::Watch<Signer>,
T::Target: 'static + BroadcasterInterface,
let stop_thread = Arc::new(AtomicBool::new(false));
let stop_thread_clone = stop_thread.clone();
let handle = thread::spawn(move || -> Result<(), std::io::Error> {
+ let event_handler = DecoratingEventHandler { event_handler, net_graph_msg_handler };
+
log_trace!(logger, "Calling ChannelManager's timer_tick_occurred on startup");
channel_manager.timer_tick_occurred();
use lightning::ln::features::InitFeatures;
use lightning::ln::msgs::{ChannelMessageHandler, Init};
use lightning::ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor, IgnoringMessageHandler};
+ use lightning::routing::network_graph::{NetworkGraph, NetGraphMsgHandler};
use lightning::util::config::UserConfig;
use lightning::util::events::{Event, MessageSendEventsProvider, MessageSendEvent};
use lightning::util::ser::Writeable;
struct Node {
node: Arc<SimpleArcChannelManager<ChainMonitor, test_utils::TestBroadcaster, test_utils::TestFeeEstimator, test_utils::TestLogger>>,
+ net_graph_msg_handler: Option<Arc<NetGraphMsgHandler<Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>>>,
peer_manager: Arc<PeerManager<TestDescriptor, Arc<test_utils::TestChannelMessageHandler>, Arc<test_utils::TestRoutingMessageHandler>, Arc<test_utils::TestLogger>, IgnoringMessageHandler>>,
chain_monitor: Arc<ChainMonitor>,
persister: Arc<FilesystemPersister>,
let persister = Arc::new(FilesystemPersister::new(format!("{}_persister_{}", persist_dir, i)));
let seed = [i as u8; 32];
let network = Network::Testnet;
- let now = Duration::from_secs(genesis_block(network).header.time as u64);
+ let genesis_block = genesis_block(network);
+ let now = Duration::from_secs(genesis_block.header.time as u64);
let keys_manager = Arc::new(KeysManager::new(&seed, now.as_secs(), now.subsec_nanos()));
let chain_monitor = Arc::new(chainmonitor::ChainMonitor::new(Some(chain_source.clone()), tx_broadcaster.clone(), logger.clone(), fee_estimator.clone(), persister.clone()));
let best_block = BestBlock::from_genesis(network);
let params = ChainParameters { network, best_block };
let manager = Arc::new(ChannelManager::new(fee_estimator.clone(), chain_monitor.clone(), tx_broadcaster.clone(), logger.clone(), keys_manager.clone(), UserConfig::default(), params));
+ let network_graph = NetworkGraph::new(genesis_block.header.block_hash());
+ let net_graph_msg_handler = Some(Arc::new(NetGraphMsgHandler::new(network_graph, Some(chain_source.clone()), logger.clone())));
let msg_handler = MessageHandler { chan_handler: Arc::new(test_utils::TestChannelMessageHandler::new()), route_handler: Arc::new(test_utils::TestRoutingMessageHandler::new() )};
let peer_manager = Arc::new(PeerManager::new(msg_handler, keys_manager.get_node_secret(), &seed, logger.clone(), IgnoringMessageHandler{}));
- let node = Node { node: manager, peer_manager, chain_monitor, persister, tx_broadcaster, logger, best_block };
+ let node = Node { node: manager, net_graph_msg_handler, peer_manager, chain_monitor, persister, tx_broadcaster, logger, best_block };
nodes.push(node);
}
begin_open_channel!($node_a, $node_b, $channel_value);
let events = $node_a.node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
- let (temporary_channel_id, tx) = handle_funding_generation_ready!(events[0], $channel_value);
+ let (temporary_channel_id, tx) = handle_funding_generation_ready!(&events[0], $channel_value);
end_open_channel!($node_a, $node_b, temporary_channel_id, tx);
tx
}}
macro_rules! handle_funding_generation_ready {
($event: expr, $channel_value: expr) => {{
match $event {
- Event::FundingGenerationReady { ref temporary_channel_id, ref channel_value_satoshis, ref output_script, user_channel_id } => {
- assert_eq!(*channel_value_satoshis, $channel_value);
+ &Event::FundingGenerationReady { temporary_channel_id, channel_value_satoshis, ref output_script, user_channel_id } => {
+ assert_eq!(channel_value_satoshis, $channel_value);
assert_eq!(user_channel_id, 42);
let tx = Transaction { version: 1 as i32, lock_time: 0, input: Vec::new(), output: vec![TxOut {
- value: *channel_value_satoshis, script_pubkey: output_script.clone(),
+ value: channel_value_satoshis, script_pubkey: output_script.clone(),
}]};
- (*temporary_channel_id, tx)
+ (temporary_channel_id, tx)
},
_ => panic!("Unexpected event"),
}
// Initiate the background processors to watch each node.
let data_dir = nodes[0].persister.get_data_dir();
let persister = move |node: &ChannelManager<InMemorySigner, Arc<ChainMonitor>, Arc<test_utils::TestBroadcaster>, Arc<KeysManager>, Arc<test_utils::TestFeeEstimator>, Arc<test_utils::TestLogger>>| FilesystemPersister::persist_manager(data_dir.clone(), node);
- let event_handler = |_| {};
- let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
+ let event_handler = |_: &_| {};
+ let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
macro_rules! check_persisted_data {
($node: expr, $filepath: expr, $expected_bytes: expr) => {
let nodes = create_nodes(1, "test_timer_tick_called".to_string());
let data_dir = nodes[0].persister.get_data_dir();
let persister = move |node: &ChannelManager<InMemorySigner, Arc<ChainMonitor>, Arc<test_utils::TestBroadcaster>, Arc<KeysManager>, Arc<test_utils::TestFeeEstimator>, Arc<test_utils::TestLogger>>| FilesystemPersister::persist_manager(data_dir.clone(), node);
- let event_handler = |_| {};
- let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
+ let event_handler = |_: &_| {};
+ let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
loop {
let log_entries = nodes[0].logger.lines.lock().unwrap();
let desired_log = "Calling ChannelManager's timer_tick_occurred".to_string();
open_channel!(nodes[0], nodes[1], 100000);
let persister = |_: &_| Err(std::io::Error::new(std::io::ErrorKind::Other, "test"));
- let event_handler = |_| {};
- let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
+ let event_handler = |_: &_| {};
+ let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
match bg_processor.join() {
Ok(_) => panic!("Expected error persisting manager"),
Err(e) => {
// Set up a background event handler for FundingGenerationReady events.
let (sender, receiver) = std::sync::mpsc::sync_channel(1);
- let event_handler = move |event| {
+ let event_handler = move |event: &Event| {
sender.send(handle_funding_generation_ready!(event, channel_value)).unwrap();
};
- let bg_processor = BackgroundProcessor::start(persister.clone(), event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
+ let bg_processor = BackgroundProcessor::start(persister.clone(), event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
// Open a channel and check that the FundingGenerationReady event was handled.
begin_open_channel!(nodes[0], nodes[1], channel_value);
// Set up a background event handler for SpendableOutputs events.
let (sender, receiver) = std::sync::mpsc::sync_channel(1);
- let event_handler = move |event| sender.send(event).unwrap();
- let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
+ let event_handler = move |event: &Event| sender.send(event.clone()).unwrap();
+ let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone());
// Force close the channel and check that the SpendableOutputs event was handled.
nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id).unwrap();
let amt_msat = invoice.amount_pico_btc().unwrap() / 10;
let first_hops = nodes[0].node.list_usable_channels();
let last_hops = invoice.route_hints();
- let network_graph = nodes[0].net_graph_msg_handler.network_graph.read().unwrap();
+ let network_graph = &nodes[0].net_graph_msg_handler.network_graph;
let logger = test_utils::TestLogger::new();
let route = router::get_route(
&nodes[0].node.get_our_node_id(),
- &network_graph,
+ network_graph,
&invoice.recover_payee_pub_key(),
Some(invoice.features().unwrap().clone()),
Some(&first_hops.iter().collect::<Vec<_>>()),
//! async fn connect_to_node(peer_manager: PeerManager, chain_monitor: Arc<ChainMonitor>, channel_manager: ChannelManager, their_node_id: PublicKey, addr: SocketAddr) {
//! lightning_net_tokio::connect_outbound(peer_manager, their_node_id, addr).await;
//! loop {
-//! channel_manager.await_persistable_update();
-//! channel_manager.process_pending_events(&|event| {
-//! // Handle the event!
-//! });
-//! chain_monitor.process_pending_events(&|event| {
+//! let event_handler = |event: &Event| {
//! // Handle the event!
-//! });
+//! };
+//! channel_manager.await_persistable_update();
+//! channel_manager.process_pending_events(&event_handler);
+//! chain_monitor.process_pending_events(&event_handler);
//! }
//! }
//!
//! async fn accept_socket(peer_manager: PeerManager, chain_monitor: Arc<ChainMonitor>, channel_manager: ChannelManager, socket: TcpStream) {
//! lightning_net_tokio::setup_inbound(peer_manager, socket);
//! loop {
-//! channel_manager.await_persistable_update();
-//! channel_manager.process_pending_events(&|event| {
-//! // Handle the event!
-//! });
-//! chain_monitor.process_pending_events(&|event| {
+//! let event_handler = |event: &Event| {
//! // Handle the event!
-//! });
+//! };
+//! channel_manager.await_persistable_update();
+//! channel_manager.process_pending_events(&event_handler);
+//! chain_monitor.process_pending_events(&event_handler);
//! }
//! }
//! ```
fn handle_node_announcement(&self, _msg: &NodeAnnouncement) -> Result<bool, LightningError> { Ok(false) }
fn handle_channel_announcement(&self, _msg: &ChannelAnnouncement) -> Result<bool, LightningError> { Ok(false) }
fn handle_channel_update(&self, _msg: &ChannelUpdate) -> Result<bool, LightningError> { Ok(false) }
- fn handle_htlc_fail_channel_update(&self, _update: &HTLCFailChannelUpdate) { }
fn get_next_channel_announcements(&self, _starting_point: u64, _batch_amount: u8) -> Vec<(ChannelAnnouncement, Option<ChannelUpdate>, Option<ChannelUpdate>)> { Vec::new() }
fn get_next_node_announcements(&self, _starting_point: Option<&PublicKey>, _batch_amount: u8) -> Vec<NodeAnnouncement> { Vec::new() }
fn sync_routing_table(&self, _their_node_id: &PublicKey, _init_msg: &Init) { }
pub fn get_and_clear_pending_events(&self) -> Vec<events::Event> {
use util::events::EventsProvider;
let events = core::cell::RefCell::new(Vec::new());
- let event_handler = |event| events.borrow_mut().push(event);
+ let event_handler = |event: &events::Event| events.borrow_mut().push(event.clone());
self.process_pending_events(&event_handler);
events.into_inner()
}
pending_events.append(&mut monitor.get_and_clear_pending_events());
}
for event in pending_events.drain(..) {
- handler.handle_event(event);
+ handler.handle_event(&event);
}
}
}
false => *nodes[0].chain_monitor.update_ret.lock().unwrap() = Some(Err(ChannelMonitorUpdateErr::PermanentFailure))
}
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)), true, APIError::ChannelUnavailable {..}, {});
check_added_monitors!(nodes[0], 2);
{
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)), false, APIError::MonitorUpdateFailed, {});
check_added_monitors!(nodes[0], 1);
}
false => *nodes[0].chain_monitor.update_ret.lock().unwrap() = Some(Err(ChannelMonitorUpdateErr::TemporaryFailure))
}
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)), false, APIError::MonitorUpdateFailed, {});
check_added_monitors!(nodes[0], 1);
}
{
*nodes[0].chain_monitor.update_ret.lock().unwrap() = Some(Err(ChannelMonitorUpdateErr::TemporaryFailure));
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
unwrap_send_err!(nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)), false, APIError::MonitorUpdateFailed, {});
check_added_monitors!(nodes[0], 1);
}
let (payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
{
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
}
let (payment_preimage_1, our_payment_hash, payment_secret_1) = get_payment_preimage_hash!(nodes[1]);
{
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(payment_secret_1)).unwrap();
check_added_monitors!(nodes[0], 1);
}
let (payment_preimage_1, our_payment_hash_1, our_payment_secret_1) = get_payment_preimage_hash!(nodes[1]);
{
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash_1, &Some(our_payment_secret_1)).unwrap();
check_added_monitors!(nodes[0], 1);
}
let (payment_preimage_2, our_payment_hash_2, our_payment_secret_2) = get_payment_preimage_hash!(nodes[0]);
{
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
- let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[1].node.send_payment(&route, our_payment_hash_2, &Some(our_payment_secret_2)).unwrap();
check_added_monitors!(nodes[1], 1);
}
let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[2]);
{
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
check_added_monitors!(nodes[0], 1);
}
let (_, payment_hash_3, payment_secret_3) = get_payment_preimage_hash!(nodes[2]);
{
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3)).unwrap();
check_added_monitors!(nodes[0], 1);
}
// Try to route another payment backwards from 2 to make sure 1 holds off on responding
let (payment_preimage_4, payment_hash_4, payment_secret_4) = get_payment_preimage_hash!(nodes[0]);
let net_graph_msg_handler = &nodes[2].net_graph_msg_handler;
- let route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[2].node.send_payment(&route, payment_hash_4, &Some(payment_secret_4)).unwrap();
check_added_monitors!(nodes[2], 1);
// generation during RAA while in monitor-update-failed state.
{
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap();
check_added_monitors!(nodes[0], 1);
nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
// commitment transaction states) whereas here we can explicitly check for it.
{
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3)).unwrap();
check_added_monitors!(nodes[0], 0);
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]);
{
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
check_added_monitors!(nodes[0], 1);
}
let (payment_preimage_1, payment_hash_1, payment_secret_1) = get_payment_preimage_hash!(nodes[1]);
{
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap();
check_added_monitors!(nodes[0], 1);
}
let (payment_preimage_1, payment_hash_1, payment_secret_1) = get_payment_preimage_hash!(nodes[1]);
{
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap();
check_added_monitors!(nodes[0], 1);
}
let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]);
{
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
check_added_monitors!(nodes[0], 1);
}
let route;
{
let net_graph_msg_handler = &nodes[2].net_graph_msg_handler;
- route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1_000_000, TEST_FINAL_CLTV, &logger).unwrap();
+ route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1_000_000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[2].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
check_added_monitors!(nodes[2], 1);
}
let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[0]);
{
let net_graph_msg_handler = &nodes[2].net_graph_msg_handler;
- let route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[2].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[2].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
check_added_monitors!(nodes[2], 1);
}
let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]);
{
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
check_added_monitors!(nodes[0], 1);
}
let logger = test_utils::TestLogger::new();
let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[3]);
- let mut route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let mut route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph, &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
// Set us up to take multiple routes, one 0 -> 1 -> 3 and one 0 -> 2 -> 3:
let path = route.paths[0].clone();
send_payment(&nodes[0], &[&nodes[1]], 100_000_00);
let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[0]);
- let route = get_route(&nodes[1].node.get_our_node_id(), &nodes[1].net_graph_msg_handler.network_graph.read().unwrap(),
+ let route = get_route(&nodes[1].node.get_our_node_id(), &nodes[1].net_graph_msg_handler.network_graph,
&nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1_000_000, TEST_FINAL_CLTV, nodes[1].logger).unwrap();
nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap();
check_added_monitors!(nodes[1], 1);
let route = {
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 100000, TEST_FINAL_CLTV, nodes[0].logger).unwrap()
+ get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), None, None, &Vec::new(), 100000, TEST_FINAL_CLTV, nodes[0].logger).unwrap()
};
nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap();
// In order to get the HTLC claim into the holding cell at nodes[1], we need nodes[1] to be
// awaiting a remote revoke_and_ack from nodes[0].
let (_, second_payment_hash, second_payment_secret) = get_payment_preimage_hash!(nodes[1]);
- let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(),
+ let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph,
&nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100_000, TEST_FINAL_CLTV, nodes[1].logger).unwrap();
nodes[0].node.send_payment(&route, second_payment_hash, &Some(second_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
// We can't accept HTLCs sent after we've sent a shutdown.
let local_sent_shutdown = (self.channel_state & (ChannelState::ChannelFunded as u32 | ChannelState::LocalShutdownSent as u32)) != (ChannelState::ChannelFunded as u32);
if local_sent_shutdown {
- pending_forward_status = create_pending_htlc_status(self, pending_forward_status, 0x1000|20);
+ pending_forward_status = create_pending_htlc_status(self, pending_forward_status, 0x4000|8);
}
// If the remote has sent a shutdown prior to adding this HTLC, then they are in violation of the spec.
let remote_sent_shutdown = (self.channel_state & (ChannelState::ChannelFunded as u32 | ChannelState::RemoteShutdownSent as u32)) != (ChannelState::ChannelFunded as u32);
events::Event::PaymentFailed {
payment_hash,
rejected_by_dest: false,
+ network_update: None,
#[cfg(test)]
error_code: None,
#[cfg(test)]
match &onion_error {
&HTLCFailReason::LightningError { ref err } => {
#[cfg(test)]
- let (channel_update, payment_retryable, onion_error_code, onion_error_data) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone());
+ let (network_update, payment_retryable, onion_error_code, onion_error_data) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone());
#[cfg(not(test))]
- let (channel_update, payment_retryable, _, _) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone());
+ let (network_update, payment_retryable, _, _) = onion_utils::process_onion_failure(&self.secp_ctx, &self.logger, &source, err.data.clone());
// TODO: If we decided to blame ourselves (or one of our channels) in
// process_onion_failure we should close that channel as it implies our
// next-hop is needlessly blaming us!
- if let Some(update) = channel_update {
- self.channel_state.lock().unwrap().pending_msg_events.push(
- events::MessageSendEvent::PaymentFailureNetworkUpdate {
- update,
- }
- );
- }
self.pending_events.lock().unwrap().push(
events::Event::PaymentFailed {
payment_hash: payment_hash.clone(),
rejected_by_dest: !payment_retryable,
+ network_update,
#[cfg(test)]
error_code: onion_error_code,
#[cfg(test)]
ref data,
.. } => {
// we get a fail_malformed_htlc from the first hop
- // TODO: We'd like to generate a PaymentFailureNetworkUpdate for temporary
+ // TODO: We'd like to generate a NetworkUpdate for temporary
// failures here, but that would be insufficient as get_route
// generally ignores its view of our own channels as we provide them via
// ChannelDetails.
events::Event::PaymentFailed {
payment_hash: payment_hash.clone(),
rejected_by_dest: path.len() == 1,
+ network_update: None,
#[cfg(test)]
error_code: Some(*failure_code),
#[cfg(test)]
}
let create_pending_htlc_status = |chan: &Channel<Signer>, pending_forward_info: PendingHTLCStatus, error_code: u16| {
- // Ensure error_code has the UPDATE flag set, since by default we send a
- // channel update along as part of failing the HTLC.
- assert!((error_code & 0x1000) != 0);
// If the update_add is completely bogus, the call will Err and we will close,
// but if we've sent a shutdown and they haven't acknowledged it yet, we just
// want to reject the new HTLC and fail it backwards instead of forwarding.
match pending_forward_info {
PendingHTLCStatus::Forward(PendingHTLCInfo { ref incoming_shared_secret, .. }) => {
- let reason = if let Ok(upd) = self.get_channel_update_for_unicast(chan) {
- onion_utils::build_first_hop_failure_packet(incoming_shared_secret, error_code, &{
- let mut res = Vec::with_capacity(8 + 128);
- // TODO: underspecified, follow https://github.com/lightningnetwork/lightning-rfc/issues/791
- res.extend_from_slice(&byte_utils::be16_to_array(0));
- res.extend_from_slice(&upd.encode_with_len()[..]);
- res
- }[..])
+ let reason = if (error_code & 0x1000) != 0 {
+ if let Ok(upd) = self.get_channel_update_for_unicast(chan) {
+ onion_utils::build_first_hop_failure_packet(incoming_shared_secret, error_code, &{
+ let mut res = Vec::with_capacity(8 + 128);
+ // TODO: underspecified, follow https://github.com/lightningnetwork/lightning-rfc/issues/791
+ res.extend_from_slice(&byte_utils::be16_to_array(0));
+ res.extend_from_slice(&upd.encode_with_len()[..]);
+ res
+ }[..])
+ } else {
+ // The only case where we'd be unable to
+ // successfully get a channel update is if the
+ // channel isn't in the fully-funded state yet,
+ // implying our counterparty is trying to route
+ // payments over the channel back to themselves
+ // (because no one else should know the short_id
+ // is a lightning channel yet). We should have
+ // no problem just calling this
+ // unknown_next_peer (0x4000|10).
+ onion_utils::build_first_hop_failure_packet(incoming_shared_secret, 0x4000|10, &[])
+ }
} else {
- // The only case where we'd be unable to
- // successfully get a channel update is if the
- // channel isn't in the fully-funded state yet,
- // implying our counterparty is trying to route
- // payments over the channel back to themselves
- // (cause no one else should know the short_id
- // is a lightning channel yet). We should have
- // no problem just calling this
- // unknown_next_peer (0x4000|10).
- onion_utils::build_first_hop_failure_packet(incoming_shared_secret, 0x4000|10, &[])
+ onion_utils::build_first_hop_failure_packet(incoming_shared_secret, error_code, &[])
};
let msg = msgs::UpdateFailHTLC {
channel_id: msg.channel_id,
#[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))]
pub fn get_and_clear_pending_events(&self) -> Vec<events::Event> {
let events = core::cell::RefCell::new(Vec::new());
- let event_handler = |event| events.borrow_mut().push(event);
+ let event_handler = |event: &events::Event| events.borrow_mut().push(event.clone());
self.process_pending_events(&event_handler);
events.into_inner()
}
}
for event in pending_events.drain(..) {
- handler.handle_event(event);
+ handler.handle_event(&event);
}
result
&events::MessageSendEvent::BroadcastChannelUpdate { .. } => true,
&events::MessageSendEvent::SendChannelUpdate { ref node_id, .. } => node_id != counterparty_node_id,
&events::MessageSendEvent::HandleError { ref node_id, .. } => node_id != counterparty_node_id,
- &events::MessageSendEvent::PaymentFailureNetworkUpdate { .. } => true,
&events::MessageSendEvent::SendChannelRangeQuery { .. } => false,
&events::MessageSendEvent::SendShortIdsQuery { .. } => false,
&events::MessageSendEvent::SendReplyChannelRange { .. } => false,
// First, send a partial MPP payment.
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100_000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100_000, TEST_FINAL_CLTV, &logger).unwrap();
let (payment_preimage, our_payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[1]);
// Use the utility function send_payment_along_path to send the payment with MPP data which
// indicates there are more HTLCs coming.
let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &expected_route, 100_000);
// Next, attempt a keysend payment and make sure it fails.
- let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100_000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph, &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100_000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_spontaneous_payment(&route, Some(payment_preimage)).unwrap();
check_added_monitors!(nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
// To start (2), send a keysend payment but don't claim it.
let payment_preimage = PaymentPreimage([42; 32]);
- let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100_000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph, &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100_000, TEST_FINAL_CLTV, &logger).unwrap();
let payment_hash = nodes[0].node.send_spontaneous_payment(&route, Some(payment_preimage)).unwrap();
check_added_monitors!(nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() });
let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known());
- let network_graph = nodes[0].net_graph_msg_handler.network_graph.read().unwrap();
+ let network_graph = &nodes[0].net_graph_msg_handler.network_graph;
let first_hops = nodes[0].node.list_usable_channels();
- let route = get_keysend_route(&payer_pubkey, &network_graph, &payee_pubkey,
+ let route = get_keysend_route(&payer_pubkey, network_graph, &payee_pubkey,
Some(&first_hops.iter().collect::<Vec<_>>()), &vec![], 10000, 40,
nodes[0].logger).unwrap();
nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() });
let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known());
- let network_graph = nodes[0].net_graph_msg_handler.network_graph.read().unwrap();
+ let network_graph = &nodes[0].net_graph_msg_handler.network_graph;
let first_hops = nodes[0].node.list_usable_channels();
- let route = get_keysend_route(&payer_pubkey, &network_graph, &payee_pubkey,
+ let route = get_keysend_route(&payer_pubkey, network_graph, &payee_pubkey,
Some(&first_hops.iter().collect::<Vec<_>>()), &vec![], 10000, 40,
nodes[0].logger).unwrap();
// Marshall an MPP route.
let (_, payment_hash, _) = get_payment_preimage_hash!(&nodes[3]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
let path = route.paths[0].clone();
route.paths.push(path);
route.paths[0][0].pubkey = nodes[1].node.get_our_node_id();
// Check that if we serialize the Router, we can deserialize it again.
{
let mut w = test_utils::TestVecWriter(Vec::new());
- let network_graph_ser = self.net_graph_msg_handler.network_graph.read().unwrap();
+ let network_graph_ser = &self.net_graph_msg_handler.network_graph;
network_graph_ser.write(&mut w).unwrap();
let network_graph_deser = <NetworkGraph>::read(&mut io::Cursor::new(&w.0)).unwrap();
- assert!(network_graph_deser == *self.net_graph_msg_handler.network_graph.read().unwrap());
- let net_graph_msg_handler = NetGraphMsgHandler::from_net_graph(
- Some(self.chain_source), self.logger, network_graph_deser
+ assert!(network_graph_deser == self.net_graph_msg_handler.network_graph);
+ let net_graph_msg_handler = NetGraphMsgHandler::new(
+ network_graph_deser, Some(self.chain_source), self.logger
);
let mut chan_progress = 0;
loop {
let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!($recv_node);
let net_graph_msg_handler = &$send_node.net_graph_msg_handler;
let route = get_route(&$send_node.node.get_our_node_id(),
- &net_graph_msg_handler.network_graph.read().unwrap(),
+ &net_graph_msg_handler.network_graph,
&$recv_node.node.get_our_node_id(), None, None, &Vec::new(), $recv_value, TEST_FINAL_CLTV, $send_node.logger).unwrap();
(route, payment_hash, payment_preimage, payment_secret)
}}
}
#[cfg(test)]
-macro_rules! expect_payment_failure_chan_update {
- ($node: expr, $scid: expr, $chan_closed: expr) => {
- let events = $node.node.get_and_clear_pending_msg_events();
+macro_rules! expect_payment_failed_with_update {
+ ($node: expr, $expected_payment_hash: expr, $rejected_by_dest: expr, $scid: expr, $chan_closed: expr) => {
+ let events = $node.node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
- MessageSendEvent::PaymentFailureNetworkUpdate { ref update } => {
- match update {
- &HTLCFailChannelUpdate::ChannelUpdateMessage { ref msg } if !$chan_closed => {
+ Event::PaymentFailed { ref payment_hash, rejected_by_dest, ref network_update, ref error_code, ref error_data } => {
+ assert_eq!(*payment_hash, $expected_payment_hash, "unexpected payment_hash");
+ assert_eq!(rejected_by_dest, $rejected_by_dest, "unexpected rejected_by_dest value");
+ assert!(error_code.is_some(), "expected error_code.is_some() = true");
+ assert!(error_data.is_some(), "expected error_data.is_some() = true");
+ match network_update {
+ &Some(NetworkUpdate::ChannelUpdateMessage { ref msg }) if !$chan_closed => {
assert_eq!(msg.contents.short_channel_id, $scid);
assert_eq!(msg.contents.flags & 2, 0);
},
- &HTLCFailChannelUpdate::ChannelClosed { short_channel_id, is_permanent } if $chan_closed => {
+ &Some(NetworkUpdate::ChannelClosed { short_channel_id, is_permanent }) if $chan_closed => {
assert_eq!(short_channel_id, $scid);
assert!(is_permanent);
},
- _ => panic!("Unexpected update type"),
+ Some(_) => panic!("Unexpected update type"),
+ None => panic!("Expected update"),
}
},
_ => panic!("Unexpected event"),
let events = $node.node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
- Event::PaymentFailed { ref payment_hash, rejected_by_dest, ref error_code, ref error_data } => {
+ Event::PaymentFailed { ref payment_hash, rejected_by_dest, network_update: _, ref error_code, ref error_data } => {
assert_eq!(*payment_hash, $expected_payment_hash, "unexpected payment_hash");
assert_eq!(rejected_by_dest, $rejected_by_dest, "unexpected rejected_by_dest value");
assert!(error_code.is_some(), "expected error_code.is_some() = true");
pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) -> (PaymentPreimage, PaymentHash, PaymentSecret) {
let net_graph_msg_handler = &origin_node.net_graph_msg_handler;
- let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(),
+ let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph,
&expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()),
Some(&origin_node.node.list_usable_channels().iter().collect::<Vec<_>>()), &[],
recv_value, TEST_FINAL_CLTV, origin_node.logger).unwrap();
pub fn route_over_limit<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64) {
let net_graph_msg_handler = &origin_node.net_graph_msg_handler;
- let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), recv_value, TEST_FINAL_CLTV, origin_node.logger).unwrap();
+ let route = get_route(&origin_node.node.get_our_node_id(), &net_graph_msg_handler.network_graph, &expected_route.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), recv_value, TEST_FINAL_CLTV, origin_node.logger).unwrap();
assert_eq!(route.paths.len(), 1);
assert_eq!(route.paths[0].len(), expected_route.len());
for (node, hop) in expected_route.iter().zip(route.paths[0].iter()) {
let connect_style = Rc::new(RefCell::new(ConnectStyle::FullBlockViaListen));
for i in 0..node_count {
- let net_graph_msg_handler = NetGraphMsgHandler::new(cfgs[i].chain_source.genesis_hash, None, cfgs[i].logger);
+ let network_graph = NetworkGraph::new(cfgs[i].chain_source.genesis_hash);
+ let net_graph_msg_handler = NetGraphMsgHandler::new(network_graph, None, cfgs[i].logger);
nodes.push(Node{ chain_source: cfgs[i].chain_source,
tx_broadcaster: cfgs[i].tx_broadcaster, chain_monitor: &cfgs[i].chain_monitor,
keys_manager: &cfgs[i].keys_manager, node: &chan_mgrs[i], net_graph_msg_handler,
use chain::channelmonitor;
use chain::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY};
use chain::transaction::OutPoint;
-use chain::keysinterface::{KeysInterface, BaseSign};
+use chain::keysinterface::BaseSign;
use ln::{PaymentPreimage, PaymentSecret, PaymentHash};
use ln::channel::{COMMITMENT_TX_BASE_WEIGHT, COMMITMENT_TX_WEIGHT_PER_HTLC};
use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA};
use ln::{chan_utils, onion_utils};
use ln::chan_utils::HTLC_SUCCESS_TX_WEIGHT;
use routing::router::{Route, RouteHop, RouteHint, RouteHintHop, get_route, get_keysend_route};
-use routing::network_graph::RoutingFees;
+use routing::network_graph::{NetworkUpdate, RoutingFees};
use ln::features::{ChannelFeatures, InitFeatures, InvoiceFeatures, NodeFeatures};
use ln::msgs;
-use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler,HTLCFailChannelUpdate, ErrorAction};
+use ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, ErrorAction};
use util::enforcing_trait_impls::EnforcingSigner;
use util::{byte_utils, test_utils};
use util::events::{Event, MessageSendEvent, MessageSendEventsProvider, PaymentPurpose};
use util::ser::{Writeable, ReadableArgs};
use util::config::UserConfig;
-use bitcoin::hashes::sha256d::Hash as Sha256dHash;
use bitcoin::hash_types::{Txid, BlockHash};
use bitcoin::blockdata::block::{Block, BlockHeader};
use bitcoin::blockdata::script::Builder;
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::Hash;
-use bitcoin::secp256k1::{Secp256k1, Message};
+use bitcoin::secp256k1::Secp256k1;
use bitcoin::secp256k1::key::{PublicKey,SecretKey};
use regex;
// ...but before it's delivered, nodes[1] starts to send a payment back to nodes[0]...
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[0]);
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
- nodes[1].node.send_payment(&get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40000, TEST_FINAL_CLTV, &logger).unwrap(), our_payment_hash, &Some(our_payment_secret)).unwrap();
+ nodes[1].node.send_payment(&get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40000, TEST_FINAL_CLTV, &logger).unwrap(), our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[1], 1);
let payment_event = {
// ...but before it's delivered, nodes[1] starts to send a payment back to nodes[0]...
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[0]);
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
- nodes[1].node.send_payment(&get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40000, TEST_FINAL_CLTV, &logger).unwrap(), our_payment_hash, &Some(our_payment_secret)).unwrap();
+ nodes[1].node.send_payment(&get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40000, TEST_FINAL_CLTV, &logger).unwrap(), our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[1], 1);
let payment_event = {
let (our_payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[0]);
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
- let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 800000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 800000, TEST_FINAL_CLTV, &logger).unwrap();
// nothing happens since node[1] is in AwaitingRemoteRevoke
nodes[1].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
for _ in 0..::ln::channel::OUR_MAX_HTLCS {
let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]);
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
- let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap();
payments.push((payment_preimage, payment_hash));
}
let (_, payment_hash_1, payment_secret_1) = get_payment_preimage_hash!(nodes[2]);
{
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
- let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
unwrap_send_err!(nodes[1].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)), true, APIError::ChannelUnavailable { ref err },
assert!(regex::Regex::new(r"Cannot push more than their max accepted HTLCs \(\d+\)").unwrap().is_match(err)));
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
let (_, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[2]);
{
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
check_added_monitors!(nodes[0], 1);
}
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &bs_fail_updates.update_fail_htlcs[0]);
commitment_signed_dance!(nodes[0], nodes[1], bs_fail_updates.commitment_signed, false, true);
- expect_payment_failure_chan_update!(nodes[0], chan_2.0.contents.short_channel_id, false);
- expect_payment_failed!(nodes[0], payment_hash_2, false);
+ expect_payment_failed_with_update!(nodes[0], payment_hash_2, false, chan_2.0.contents.short_channel_id, false);
// Now forward all the pending HTLCs and claim them back
nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &initial_payment_event.msgs[0]);
let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &vec!(&nodes[1])[..], 900_000);
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
- let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 800_000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 800_000, TEST_FINAL_CLTV, &logger).unwrap();
let node_a_payment_secret = nodes[0].node.create_inbound_payment_for_hash(payment_hash, None, 7200, 0).unwrap();
send_along_route_with_secret(&nodes[1], route, &[&[&nodes[0]]], 800_000, payment_hash, node_a_payment_secret);
let commit_tx_fee = 2 * commit_tx_fee_msat(get_feerate!(nodes[0], chan.2), 1 + 1);
let max_can_send = 5000000 - channel_reserve - commit_tx_fee;
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), max_can_send + 1, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes.last().unwrap().node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), max_can_send + 1, TEST_FINAL_CLTV, &logger).unwrap();
let err = nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).err().unwrap();
match err {
PaymentSendFailure::AllFailedRetrySafe(ref fails) => {
let (payment_preimage_3, payment_hash_3, payment_secret_3) = get_payment_preimage_hash!(nodes[1]);
let send_1 = {
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash_3, &Some(payment_secret_3)).unwrap();
check_added_monitors!(nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
let (payment_preimage_4, payment_hash_4, payment_secret_4) = get_payment_preimage_hash!(nodes[0]);
let send_2 = {
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
- let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 10000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 10000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[1].node.send_payment(&route, payment_hash_4, &Some(payment_secret_4)).unwrap();
check_added_monitors!(nodes[1], 1);
let mut events = nodes[1].node.get_and_clear_pending_msg_events();
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &update_fail_htlcs[0]);
commitment_signed_dance!(nodes[0], nodes[1], commitment_signed, false, true);
- expect_payment_failure_chan_update!(nodes[0], chan_2.0.contents.short_channel_id, true);
- expect_payment_failed!(nodes[0], payment_hash, false);
+ expect_payment_failed_with_update!(nodes[0], payment_hash, false, chan_2.0.contents.short_channel_id, true);
},
_ => panic!("Unexpected event"),
}
let (_, fourth_payment_hash, fourth_payment_secret) = get_payment_preimage_hash!(nodes[2]);
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
let logger = test_utils::TestLogger::new();
- let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[1].node.send_payment(&route, fourth_payment_hash, &Some(fourth_payment_secret)).unwrap();
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
commitment_signed_dance!(nodes[0], nodes[1], commitment_signed, false, true);
- let events = nodes[0].node.get_and_clear_pending_msg_events();
- // If we delivered B's RAA we got an unknown preimage error, not something
- // that we should update our routing table for.
- assert_eq!(events.len(), if deliver_bs_raa { 2 } else { 3 });
- for event in events {
- match event {
- MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {},
- _ => panic!("Unexpected event"),
- }
- }
let events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events.len(), 3);
match events[0] {
- Event::PaymentFailed { ref payment_hash, .. } => {
+ Event::PaymentFailed { ref payment_hash, rejected_by_dest: _, ref network_update, .. } => {
assert!(failed_htlcs.insert(payment_hash.0));
+ // If we delivered B's RAA we got an unknown preimage error, not something
+ // that we should update our routing table for.
+ if !deliver_bs_raa {
+ assert!(network_update.is_some());
+ }
},
_ => panic!("Unexpected event"),
}
match events[1] {
- Event::PaymentFailed { ref payment_hash, .. } => {
+ Event::PaymentFailed { ref payment_hash, rejected_by_dest: _, ref network_update, .. } => {
assert!(failed_htlcs.insert(payment_hash.0));
+ assert!(network_update.is_some());
},
_ => panic!("Unexpected event"),
}
match events[2] {
- Event::PaymentFailed { ref payment_hash, .. } => {
+ Event::PaymentFailed { ref payment_hash, rejected_by_dest: _, ref network_update, .. } => {
assert!(failed_htlcs.insert(payment_hash.0));
+ assert!(network_update.is_some());
},
_ => panic!("Unexpected event"),
}
{
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let (_, failed_payment_hash, failed_payment_secret) = get_payment_preimage_hash!(nodes[1]);
{
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, failed_payment_hash, &Some(failed_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 0);
let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
let current_height = nodes[1].node.best_block.read().unwrap().height() + 1;
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
- let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, TEST_FINAL_CLTV, &logger).unwrap();
let (onion_payloads, _amount_msat, cltv_expiry) = onion_utils::build_onion_payloads(&route.paths[0], 50_000, &Some(payment_secret), current_height, &None).unwrap();
let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv).unwrap();
let onion_routing_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash);
let mut payment_event = {
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, 42, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, 42, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let logger = test_utils::TestLogger::new();
let payment_event = {
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(),
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph,
&nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), Some(&nodes[0].node.list_usable_channels().iter().collect::<Vec<_>>()),
&Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash_1, &Some(payment_secret_1)).unwrap();
// Channel should still work fine...
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(),
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph,
&nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), Some(&nodes[0].node.list_usable_channels().iter().collect::<Vec<_>>()),
&Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
let payment_preimage_2 = send_along_route(&nodes[0], route, &[&nodes[1]], 1000000).0;
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
let logger = test_utils::TestLogger::new();
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
let (payment_preimage, _, _) = send_along_route(&nodes[0], route, &[&nodes[1]], 1000000);
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage);
// Now try to send a second payment which will fail to send
let (payment_preimage_2, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash_2, &Some(payment_secret_2)).unwrap();
check_added_monitors!(nodes[0], 1);
let our_payment_hash = if send_partial_mpp {
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
let (_, our_payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[1]);
// Use the utility function send_payment_along_path to send the payment with MPP data which
// indicates there are more HTLCs coming.
let (_, first_payment_hash, first_payment_secret) = get_payment_preimage_hash!(nodes[2]);
{
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
- let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[1].node.send_payment(&route, first_payment_hash, &Some(first_payment_secret)).unwrap();
}
assert_eq!(nodes[1].node.get_and_clear_pending_msg_events().len(), 1);
let (_, second_payment_hash, second_payment_secret) = get_payment_preimage_hash!(nodes[2]);
if forwarded_htlc {
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, second_payment_hash, &Some(first_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let payment_event = SendEvent::from_event(nodes[0].node.get_and_clear_pending_msg_events().remove(0));
check_added_monitors!(nodes[1], 0);
} else {
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
- let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[1].node.send_payment(&route, second_payment_hash, &Some(second_payment_secret)).unwrap();
check_added_monitors!(nodes[1], 0);
}
},
_ => unreachable!(),
}
- expect_payment_failed!(nodes[0], second_payment_hash, false);
- expect_payment_failure_chan_update!(nodes[0], chan_2.0.contents.short_channel_id, false);
+ expect_payment_failed_with_update!(nodes[0], second_payment_hash, false, chan_2.0.contents.short_channel_id, false);
} else {
expect_payment_failed!(nodes[1], second_payment_hash, true);
}
do_test_holding_cell_htlc_add_timeouts(true);
}
-#[test]
-fn test_invalid_channel_announcement() {
- //Test BOLT 7 channel_announcement msg requirement for final node, gather data to build customed channel_announcement msgs
- let secp_ctx = Secp256k1::new();
- let chanmon_cfgs = create_chanmon_cfgs(2);
- let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
- let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
- let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-
- let chan_announcement = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known());
-
- let a_channel_lock = nodes[0].node.channel_state.lock().unwrap();
- let b_channel_lock = nodes[1].node.channel_state.lock().unwrap();
- let as_chan = a_channel_lock.by_id.get(&chan_announcement.3).unwrap();
- let bs_chan = b_channel_lock.by_id.get(&chan_announcement.3).unwrap();
-
- nodes[0].net_graph_msg_handler.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id : as_chan.get_short_channel_id().unwrap(), is_permanent: false } );
-
- let as_bitcoin_key = as_chan.get_signer().inner.holder_channel_pubkeys.funding_pubkey;
- let bs_bitcoin_key = bs_chan.get_signer().inner.holder_channel_pubkeys.funding_pubkey;
-
- let as_network_key = nodes[0].node.get_our_node_id();
- let bs_network_key = nodes[1].node.get_our_node_id();
-
- let were_node_one = as_bitcoin_key.serialize()[..] < bs_bitcoin_key.serialize()[..];
-
- let mut chan_announcement;
-
- macro_rules! dummy_unsigned_msg {
- () => {
- msgs::UnsignedChannelAnnouncement {
- features: ChannelFeatures::known(),
- chain_hash: genesis_block(Network::Testnet).header.block_hash(),
- short_channel_id: as_chan.get_short_channel_id().unwrap(),
- node_id_1: if were_node_one { as_network_key } else { bs_network_key },
- node_id_2: if were_node_one { bs_network_key } else { as_network_key },
- bitcoin_key_1: if were_node_one { as_bitcoin_key } else { bs_bitcoin_key },
- bitcoin_key_2: if were_node_one { bs_bitcoin_key } else { as_bitcoin_key },
- excess_data: Vec::new(),
- }
- }
- }
-
- macro_rules! sign_msg {
- ($unsigned_msg: expr) => {
- let msghash = Message::from_slice(&Sha256dHash::hash(&$unsigned_msg.encode()[..])[..]).unwrap();
- let as_bitcoin_sig = secp_ctx.sign(&msghash, &as_chan.get_signer().inner.funding_key);
- let bs_bitcoin_sig = secp_ctx.sign(&msghash, &bs_chan.get_signer().inner.funding_key);
- let as_node_sig = secp_ctx.sign(&msghash, &nodes[0].keys_manager.get_node_secret());
- let bs_node_sig = secp_ctx.sign(&msghash, &nodes[1].keys_manager.get_node_secret());
- chan_announcement = msgs::ChannelAnnouncement {
- node_signature_1 : if were_node_one { as_node_sig } else { bs_node_sig},
- node_signature_2 : if were_node_one { bs_node_sig } else { as_node_sig},
- bitcoin_signature_1: if were_node_one { as_bitcoin_sig } else { bs_bitcoin_sig },
- bitcoin_signature_2 : if were_node_one { bs_bitcoin_sig } else { as_bitcoin_sig },
- contents: $unsigned_msg
- }
- }
- }
-
- let unsigned_msg = dummy_unsigned_msg!();
- sign_msg!(unsigned_msg);
- assert_eq!(nodes[0].net_graph_msg_handler.handle_channel_announcement(&chan_announcement).unwrap(), true);
- let _ = nodes[0].net_graph_msg_handler.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id : as_chan.get_short_channel_id().unwrap(), is_permanent: false } );
-
- // Configured with Network::Testnet
- let mut unsigned_msg = dummy_unsigned_msg!();
- unsigned_msg.chain_hash = genesis_block(Network::Bitcoin).header.block_hash();
- sign_msg!(unsigned_msg);
- assert!(nodes[0].net_graph_msg_handler.handle_channel_announcement(&chan_announcement).is_err());
-
- let mut unsigned_msg = dummy_unsigned_msg!();
- unsigned_msg.chain_hash = BlockHash::hash(&[1,2,3,4,5,6,7,8,9]);
- sign_msg!(unsigned_msg);
- assert!(nodes[0].net_graph_msg_handler.handle_channel_announcement(&chan_announcement).is_err());
-}
-
#[test]
fn test_no_txn_manager_serialize_deserialize() {
let chanmon_cfgs = create_chanmon_cfgs(2);
// We reduce the final CLTV here by a somewhat arbitrary constant to keep it under the one-byte
// script push size limit so that the below script length checks match
// ACCEPTED_HTLC_SCRIPT_WEIGHT.
- let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(),
+ let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph,
&nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 900000, TEST_FINAL_CLTV - 40, nodes[0].logger).unwrap();
send_along_route_with_secret(&nodes[0], route, &[&[&nodes[1], &nodes[2], &nodes[3]]], 900000, duplicate_payment_hash, payment_secret);
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
{
commitment_signed_dance!(nodes[0], nodes[1], &htlc_updates.commitment_signed, false, true);
- expect_payment_failure_chan_update!(nodes[0], chan_2.0.contents.short_channel_id, true);
}
- expect_payment_failed!(nodes[0], duplicate_payment_hash, false);
+ expect_payment_failed_with_update!(nodes[0], duplicate_payment_hash, false, chan_2.0.contents.short_channel_id, true);
// Solve 2nd HTLC by broadcasting on B's chain HTLC-Success Tx from C
// Note that the fee paid is effectively double as the HTLC value (including the nodes[1] fee
let (_, payment_hash_2, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], ds_dust_limit*1000); // not added < dust limit + HTLC tx fee
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
let our_node_id = &nodes[1].node.get_our_node_id();
- let route = get_route(our_node_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), ds_dust_limit*1000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(our_node_id, &net_graph_msg_handler.network_graph, &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), ds_dust_limit*1000, TEST_FINAL_CLTV, &logger).unwrap();
// 2nd HTLC:
send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_1, nodes[5].node.create_inbound_payment_for_hash(payment_hash_1, None, 7200, 0).unwrap()); // not added < dust limit + HTLC tx fee
// 3rd HTLC:
let (_, payment_hash_3, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 1000000);
// 5th HTLC:
let (_, payment_hash_4, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 1000000);
- let route = get_route(our_node_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(our_node_id, &net_graph_msg_handler.network_graph, &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
// 6th HTLC:
send_along_route_with_secret(&nodes[1], route.clone(), &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_3, nodes[5].node.create_inbound_payment_for_hash(payment_hash_3, None, 7200, 0).unwrap());
// 7th HTLC:
// 8th HTLC:
let (_, payment_hash_5, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], 1000000);
// 9th HTLC:
- let route = get_route(our_node_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), ds_dust_limit*1000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(our_node_id, &net_graph_msg_handler.network_graph, &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), ds_dust_limit*1000, TEST_FINAL_CLTV, &logger).unwrap();
send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], ds_dust_limit*1000, payment_hash_5, nodes[5].node.create_inbound_payment_for_hash(payment_hash_5, None, 7200, 0).unwrap()); // not added < dust limit + HTLC tx fee
// 10th HTLC:
let (_, payment_hash_6, _) = route_payment(&nodes[0], &[&nodes[2], &nodes[3], &nodes[4]], ds_dust_limit*1000); // not added < dust limit + HTLC tx fee
// 11th HTLC:
- let route = get_route(our_node_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(our_node_id, &net_graph_msg_handler.network_graph, &nodes[5].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 1000000, TEST_FINAL_CLTV, &logger).unwrap();
send_along_route_with_secret(&nodes[1], route, &[&[&nodes[2], &nodes[3], &nodes[5]]], 1000000, payment_hash_6, nodes[5].node.create_inbound_payment_for_hash(payment_hash_6, None, 7200, 0).unwrap());
// Double-check that six of the new HTLC were added
let as_events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(as_events.len(), if announce_latest { 5 } else { 3 });
let mut as_failds = HashSet::new();
+ let mut as_updates = 0;
for event in as_events.iter() {
- if let &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, .. } = event {
+ if let &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update, .. } = event {
assert!(as_failds.insert(*payment_hash));
if *payment_hash != payment_hash_2 {
assert_eq!(*rejected_by_dest, deliver_last_raa);
} else {
assert!(!rejected_by_dest);
}
+ if network_update.is_some() {
+ as_updates += 1;
+ }
} else { panic!("Unexpected event"); }
}
assert!(as_failds.contains(&payment_hash_1));
let bs_events = nodes[1].node.get_and_clear_pending_events();
assert_eq!(bs_events.len(), if announce_latest { 4 } else { 3 });
let mut bs_failds = HashSet::new();
+ let mut bs_updates = 0;
for event in bs_events.iter() {
- if let &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, .. } = event {
+ if let &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update, .. } = event {
assert!(bs_failds.insert(*payment_hash));
if *payment_hash != payment_hash_1 && *payment_hash != payment_hash_5 {
assert_eq!(*rejected_by_dest, deliver_last_raa);
} else {
assert!(!rejected_by_dest);
}
+ if network_update.is_some() {
+ bs_updates += 1;
+ }
} else { panic!("Unexpected event"); }
}
assert!(bs_failds.contains(&payment_hash_1));
assert!(bs_failds.contains(&payment_hash_5));
// For each HTLC which was not failed-back by normal process (ie deliver_last_raa), we should
- // get a PaymentFailureNetworkUpdate. A should have gotten 4 HTLCs which were failed-back due
- // to unknown-preimage-etc, B should have gotten 2. Thus, in the
- // announce_latest && deliver_last_raa case, we should have 5-4=1 and 4-2=2
- // PaymentFailureNetworkUpdates.
- let as_msg_events = nodes[0].node.get_and_clear_pending_msg_events();
- assert_eq!(as_msg_events.len(), if deliver_last_raa { 1 } else if !announce_latest { 3 } else { 5 });
- let bs_msg_events = nodes[1].node.get_and_clear_pending_msg_events();
- assert_eq!(bs_msg_events.len(), if deliver_last_raa { 2 } else if !announce_latest { 3 } else { 4 });
- for event in as_msg_events.iter().chain(bs_msg_events.iter()) {
- match event {
- &MessageSendEvent::PaymentFailureNetworkUpdate { .. } => {},
- _ => panic!("Unexpected event"),
- }
- }
+ // get a NetworkUpdate. A should have gotten 4 HTLCs which were failed-back due to
+ // unknown-preimage-etc, B should have gotten 2. Thus, in the
+ // announce_latest && deliver_last_raa case, we should have 5-4=1 and 4-2=2 NetworkUpdates.
+ assert_eq!(as_updates, if deliver_last_raa { 1 } else if !announce_latest { 3 } else { 5 });
+ assert_eq!(bs_updates, if deliver_last_raa { 2 } else if !announce_latest { 3 } else { 4 });
}
#[test]
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), if use_dust { 50000 } else { 3000000 }, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), if use_dust { 50000 } else { 3000000 }, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
let max_can_send = 5000000 - channel_reserve - 2*commit_tx_fee_msat(feerate, 1 + 1);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], max_can_send, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], max_can_send, TEST_FINAL_CLTV, &logger).unwrap();
// Send a payment which passes reserve checks but gets stuck in the holding cell.
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
let events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match &events[0] {
- &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref error_code, ref error_data } => {
+ &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update, ref error_code, ref error_data } => {
assert_eq!(our_payment_hash.clone(), *payment_hash);
assert_eq!(*rejected_by_dest, false);
+ assert_eq!(*network_update, None);
assert_eq!(*error_code, None);
assert_eq!(*error_data, None);
},
let (_, payment_hash_2, payment_secret_2) = get_payment_preimage_hash!(nodes[1]);
let amt_2 = 5000000 - channel_reserve - 2*commit_tx_fee_msat(feerate, 2 + 1) - amt_1;
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route_1 = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], amt_1, TEST_FINAL_CLTV, &logger).unwrap();
- let route_2 = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], amt_2, TEST_FINAL_CLTV, &logger).unwrap();
+ let route_1 = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], amt_1, TEST_FINAL_CLTV, &logger).unwrap();
+ let route_2 = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], amt_2, TEST_FINAL_CLTV, &logger).unwrap();
// Send 2 payments which pass reserve checks but get stuck in the holding cell.
nodes[0].node.send_payment(&route_1, payment_hash_1, &Some(payment_secret_1)).unwrap();
let events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match &events[0] {
- &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref error_code, ref error_data } => {
+ &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update, ref error_code, ref error_data } => {
assert_eq!(payment_hash_2.clone(), *payment_hash);
assert_eq!(*rejected_by_dest, false);
+ assert_eq!(*network_update, None);
assert_eq!(*error_code, None);
assert_eq!(*error_data, None);
},
let max_can_send = 5000000 - channel_reserve - 2*commit_tx_fee_msat(feerate, 1 + 1) - total_routing_fee_msat;
let payment_event = {
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], max_can_send, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], max_can_send, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
_ => panic!("Unexpected event"),
};
nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &raa);
- expect_payment_failure_chan_update!(nodes[0], chan_1_2.0.contents.short_channel_id, false);
- expect_payment_failed!(nodes[0], our_payment_hash, false);
+ expect_payment_failed_with_update!(nodes[0], our_payment_hash, false, chan_1_2.0.contents.short_channel_id, false);
check_added_monitors!(nodes[0], 1);
}
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
let logger = test_utils::TestLogger::new();
- let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
route.paths[0][0].fee_msat = 100;
unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::ChannelUnavailable { ref err },
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
let logger = test_utils::TestLogger::new();
- let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
route.paths[0][0].fee_msat = 0;
unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::ChannelUnavailable { ref err },
assert_eq!(err, "Cannot send 0-msat HTLC"));
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
let logger = test_utils::TestLogger::new();
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000000, 500000001, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000000, 500000001, &logger).unwrap();
unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::RouteError { ref err },
assert_eq!(err, &"Channel CLTV overflowed?"));
}
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
let payment_event = {
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
}
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)), true, APIError::ChannelUnavailable { ref err },
assert!(regex::Regex::new(r"Cannot push more than their max accepted HTLCs \(\d+\)").unwrap().is_match(err)));
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
let logger = test_utils::TestLogger::new();
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], htlc_minimum_msat, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], htlc_minimum_msat, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
let max_can_send = 5000000 - channel_reserve - commit_tx_fee_outbound;
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], max_can_send, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], max_can_send, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 3999999, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 3999999, TEST_FINAL_CLTV, &logger).unwrap();
let cur_height = nodes[0].node.best_block.read().unwrap().height() + 1;
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::signing_only(), &route.paths[0], &session_priv).unwrap();
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, InitFeatures::known(), InitFeatures::known());
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let mut updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
let (our_payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[1]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1000000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
//First hop
let mut payment_event = {
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
// Create some initial channels
create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
- let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 10_000, TEST_FINAL_CLTV, nodes[0].logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 10_000, TEST_FINAL_CLTV, nodes[0].logger).unwrap();
let (_, our_payment_hash, _) = get_payment_preimage_hash!(nodes[0]);
let our_payment_secret = nodes[1].node.create_inbound_payment_for_hash(our_payment_hash, Some(100_000), 7200, 0).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
// to nodes[2], which should be rejected:
let (our_payment_preimage, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[2]);
let route = get_route(&nodes[0].node.get_our_node_id(),
- &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(),
+ &nodes[0].net_graph_msg_handler.network_graph,
&nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None,
&[&RouteHint(vec![RouteHintHop {
src_node_id: nodes[1].node.get_our_node_id(),
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &htlc_fail_updates.update_fail_htlcs[0]);
commitment_signed_dance!(nodes[0], nodes[1], htlc_fail_updates.commitment_signed, true, true);
- expect_payment_failed!(nodes[0], our_payment_hash, false);
- expect_payment_failure_chan_update!(nodes[0], nodes[2].node.list_channels()[0].short_channel_id.unwrap(), true);
+ expect_payment_failed_with_update!(nodes[0], our_payment_hash, false, nodes[2].node.list_channels()[0].short_channel_id.unwrap(), true);
// Now disconnect nodes[1] from its peers and restart with accept_forwards_to_priv_channels set
// to true. Sadly there is currently no way to change it at runtime.
let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 3000000).0;
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
- let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 3000000, 30, &logger).unwrap();
+ let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 3000000, 30, &logger).unwrap();
send_along_route(&nodes[1], route, &vec!(&nodes[0])[..], 3000000);
let revoked_txn = get_local_commitment_txn!(nodes[0], chan.2);
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 59000000, InitFeatures::known(), InitFeatures::known());
// Lock HTLC in both directions (using a slightly lower CLTV delay to provide timely RBF bumps)
- let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(),
+ let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph,
&nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 3_000_000, 50, nodes[0].logger).unwrap();
let payment_preimage = send_along_route(&nodes[0], route, &[&nodes[1]], 3_000_000).0;
- let route = get_route(&nodes[1].node.get_our_node_id(), &nodes[1].net_graph_msg_handler.network_graph.read().unwrap(),
+ let route = get_route(&nodes[1].node.get_our_node_id(), &nodes[1].net_graph_msg_handler.network_graph,
&nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 3_000_000, 50, nodes[0].logger).unwrap();
send_along_route(&nodes[1], route, &[&nodes[0]], 3_000_000);
let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[3]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
let path = route.paths[0].clone();
route.paths.push(path);
route.paths[0][0].pubkey = nodes[1].node.get_our_node_id();
let logger = test_utils::TestLogger::new();
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100_000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100_000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
{
let logger = test_utils::TestLogger::new();
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100_000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100_000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
let logger = test_utils::TestLogger::new();
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100_000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100_000, TEST_FINAL_CLTV, &logger).unwrap();
// All the below cases should end up being handled exactly identically, so we macro the
// resulting events.
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[0]);
{
let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
- let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 3000000 , TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 3000000 , TEST_FINAL_CLTV, &logger).unwrap();
nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap();
}
check_added_monitors!(nodes[1], 1);
assert!(updates.update_fee.is_none());
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fail_htlcs[0]);
commitment_signed_dance!(nodes[0], nodes[1], updates.commitment_signed, true, true);
- expect_payment_failed!(nodes[0], payment_hash, false);
- expect_payment_failure_chan_update!(nodes[0], chan_announce.contents.short_channel_id, true);
+ expect_payment_failed_with_update!(nodes[0], payment_hash, false, chan_announce.contents.short_channel_id, true);
}
}
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 10001, InitFeatures::known(), InitFeatures::known());
- let network_graph = nodes[0].net_graph_msg_handler.network_graph.read().unwrap();
+ let network_graph = &nodes[0].net_graph_msg_handler.network_graph;
let payer_pubkey = nodes[0].node.get_our_node_id();
let payee_pubkey = nodes[1].node.get_our_node_id();
- let route = get_route(&payer_pubkey, &network_graph, &payee_pubkey, None,
+ let route = get_route(&payer_pubkey, network_graph, &payee_pubkey, None,
None, &vec![], 10000, 40,
nodes[0].logger).unwrap();
nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() });
let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known());
- let network_graph = nodes[0].net_graph_msg_handler.network_graph.read().unwrap();
+ let network_graph = &nodes[0].net_graph_msg_handler.network_graph;
let first_hops = nodes[0].node.list_usable_channels();
let route = get_keysend_route(&payer_pubkey, &network_graph, &payee_pubkey,
Some(&first_hops.iter().collect::<Vec<_>>()), &vec![], 10000, 40,
use chain::channelmonitor::ANTI_REORG_DELAY;
use ln::{PaymentPreimage, PaymentHash};
use ln::features::InitFeatures;
-use ln::msgs::{ChannelMessageHandler, HTLCFailChannelUpdate, ErrorAction};
+use ln::msgs::{ChannelMessageHandler, ErrorAction};
use util::events::{Event, MessageSendEvent, MessageSendEventsProvider};
+use routing::network_graph::NetworkUpdate;
use routing::router::get_route;
use bitcoin::hashes::sha256::Hash as Sha256;
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_updates.update_fail_htlcs[0]);
commitment_signed_dance!(nodes[0], nodes[1], fail_updates.commitment_signed, true, true);
- expect_payment_failed!(nodes[0], payment_hash, false);
- expect_payment_failure_chan_update!(nodes[0], update_a.contents.short_channel_id, true);
+ expect_payment_failed_with_update!(nodes[0], payment_hash, false, update_a.contents.short_channel_id, true);
}
pub commitment_signed: CommitmentSigned,
}
-/// The information we received from a peer along the route of a payment we originated. This is
-/// returned by ChannelMessageHandler::handle_update_fail_htlc to be passed into
-/// RoutingMessageHandler::handle_htlc_fail_channel_update to update our network map.
-#[derive(Clone, Debug, PartialEq)]
-pub enum HTLCFailChannelUpdate {
- /// We received an error which included a full ChannelUpdate message.
- ChannelUpdateMessage {
- /// The unwrapped message we received
- msg: ChannelUpdate,
- },
- /// We received an error which indicated only that a channel has been closed
- ChannelClosed {
- /// The short_channel_id which has now closed.
- short_channel_id: u64,
- /// when this true, this channel should be permanently removed from the
- /// consideration. Otherwise, this channel can be restored as new channel_update is received
- is_permanent: bool,
- },
- /// We received an error which indicated only that a node has failed
- NodeFailure {
- /// The node_id that has failed.
- node_id: PublicKey,
- /// when this true, node should be permanently removed from the
- /// consideration. Otherwise, the channels connected to this node can be
- /// restored as new channel_update is received
- is_permanent: bool,
- }
-}
-
/// Messages could have optional fields to use with extended features
/// As we wish to serialize these differently from Option<T>s (Options get a tag byte, but
/// OptionalFeild simply gets Present if there are enough bytes to read into it), we have a
/// Handle an incoming channel_update message, returning true if it should be forwarded on,
/// false or returning an Err otherwise.
fn handle_channel_update(&self, msg: &ChannelUpdate) -> Result<bool, LightningError>;
- /// Handle some updates to the route graph that we learned due to an outbound failed payment.
- fn handle_htlc_fail_channel_update(&self, update: &HTLCFailChannelUpdate);
/// Gets a subset of the channel announcements and updates required to dump our routing table
/// to a remote node, starting at the short_channel_id indicated by starting_point and
/// including the batch_amount entries immediately higher in numerical value than starting_point.
use ln::channelmanager::{HTLCForwardInfo, CLTV_FAR_FAR_AWAY};
use ln::onion_utils;
use routing::router::{Route, get_route};
+use routing::network_graph::NetworkUpdate;
use ln::features::{InitFeatures, InvoiceFeatures};
use ln::msgs;
-use ln::msgs::{ChannelMessageHandler, ChannelUpdate, HTLCFailChannelUpdate, OptionalField};
+use ln::msgs::{ChannelMessageHandler, ChannelUpdate, OptionalField};
use util::test_utils;
use util::events::{Event, MessageSendEvent, MessageSendEventsProvider};
use util::ser::{Writeable, Writer};
use ln::functional_test_utils::*;
-fn run_onion_failure_test<F1,F2>(_name: &str, test_case: u8, nodes: &Vec<Node>, route: &Route, payment_hash: &PaymentHash, payment_secret: &PaymentSecret, callback_msg: F1, callback_node: F2, expected_retryable: bool, expected_error_code: Option<u16>, expected_channel_update: Option<HTLCFailChannelUpdate>)
+fn run_onion_failure_test<F1,F2>(_name: &str, test_case: u8, nodes: &Vec<Node>, route: &Route, payment_hash: &PaymentHash, payment_secret: &PaymentSecret, callback_msg: F1, callback_node: F2, expected_retryable: bool, expected_error_code: Option<u16>, expected_channel_update: Option<NetworkUpdate>)
where F1: for <'a> FnMut(&'a mut msgs::UpdateAddHTLC),
F2: FnMut(),
{
// 3: final node fails backward (but tamper onion payloads from node0)
// 100: trigger error in the intermediate node and tamper returning fail_htlc
// 200: trigger error in the final node and tamper returning fail_htlc
-fn run_onion_failure_test_with_fail_intercept<F1,F2,F3>(_name: &str, test_case: u8, nodes: &Vec<Node>, route: &Route, payment_hash: &PaymentHash, payment_secret: &PaymentSecret, mut callback_msg: F1, mut callback_fail: F2, mut callback_node: F3, expected_retryable: bool, expected_error_code: Option<u16>, expected_channel_update: Option<HTLCFailChannelUpdate>)
+fn run_onion_failure_test_with_fail_intercept<F1,F2,F3>(_name: &str, test_case: u8, nodes: &Vec<Node>, route: &Route, payment_hash: &PaymentHash, payment_secret: &PaymentSecret, mut callback_msg: F1, mut callback_fail: F2, mut callback_node: F3, expected_retryable: bool, expected_error_code: Option<u16>, expected_channel_update: Option<NetworkUpdate>)
where F1: for <'a> FnMut(&'a mut msgs::UpdateAddHTLC),
F2: for <'a> FnMut(&'a mut msgs::UpdateFailHTLC),
F3: FnMut(),
let events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
- if let &Event::PaymentFailed { payment_hash:_, ref rejected_by_dest, ref error_code, error_data: _ } = &events[0] {
+ if let &Event::PaymentFailed { payment_hash:_, ref rejected_by_dest, ref network_update, ref error_code, error_data: _ } = &events[0] {
assert_eq!(*rejected_by_dest, !expected_retryable);
assert_eq!(*error_code, expected_error_code);
- } else {
- panic!("Uexpected event");
- }
-
- let events = nodes[0].node.get_and_clear_pending_msg_events();
- if expected_channel_update.is_some() {
- assert_eq!(events.len(), 1);
- match events[0] {
- MessageSendEvent::PaymentFailureNetworkUpdate { ref update } => {
- match update {
- &HTLCFailChannelUpdate::ChannelUpdateMessage { .. } => {
- if let HTLCFailChannelUpdate::ChannelUpdateMessage { .. } = expected_channel_update.unwrap() {} else {
+ if expected_channel_update.is_some() {
+ match network_update {
+ Some(update) => match update {
+ &NetworkUpdate::ChannelUpdateMessage { .. } => {
+ if let NetworkUpdate::ChannelUpdateMessage { .. } = expected_channel_update.unwrap() {} else {
panic!("channel_update not found!");
}
},
- &HTLCFailChannelUpdate::ChannelClosed { ref short_channel_id, ref is_permanent } => {
- if let HTLCFailChannelUpdate::ChannelClosed { short_channel_id: ref expected_short_channel_id, is_permanent: ref expected_is_permanent } = expected_channel_update.unwrap() {
+ &NetworkUpdate::ChannelClosed { ref short_channel_id, ref is_permanent } => {
+ if let NetworkUpdate::ChannelClosed { short_channel_id: ref expected_short_channel_id, is_permanent: ref expected_is_permanent } = expected_channel_update.unwrap() {
assert!(*short_channel_id == *expected_short_channel_id);
assert!(*is_permanent == *expected_is_permanent);
} else {
panic!("Unexpected message event");
}
},
- &HTLCFailChannelUpdate::NodeFailure { ref node_id, ref is_permanent } => {
- if let HTLCFailChannelUpdate::NodeFailure { node_id: ref expected_node_id, is_permanent: ref expected_is_permanent } = expected_channel_update.unwrap() {
+ &NetworkUpdate::NodeFailure { ref node_id, ref is_permanent } => {
+ if let NetworkUpdate::NodeFailure { node_id: ref expected_node_id, is_permanent: ref expected_is_permanent } = expected_channel_update.unwrap() {
assert!(*node_id == *expected_node_id);
assert!(*is_permanent == *expected_is_permanent);
} else {
}
},
}
- },
- _ => panic!("Unexpected message event"),
+ None => panic!("Expected channel update"),
+ }
+ } else {
+ assert!(network_update.is_none());
}
} else {
- assert_eq!(events.len(), 0);
+ panic!("Unexpected event");
}
}
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
let channels = [create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()), create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known())];
let logger = test_utils::TestLogger::new();
- let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40_000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40_000, TEST_FINAL_CLTV, &logger).unwrap();
// positive case
let (payment_preimage_success, payment_hash_success, payment_secret_success) = get_payment_preimage_hash!(nodes[2]);
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]);
run_onion_failure_test("fee_insufficient", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| {
msg.amount_msat -= 1;
- }, || {}, true, Some(UPDATE|12), Some(msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true}));
+ }, || {}, true, Some(UPDATE|12), Some(NetworkUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true}));
// In an earlier version, we spuriously failed to forward payments if the expected feerate
// changed between the channel open and the payment.
let channels = [create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()), create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known())];
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]);
let logger = test_utils::TestLogger::new();
- let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &nodes[0].net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 40000, TEST_FINAL_CLTV, &logger).unwrap();
// positve case
send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 40000);
// describing a length-1 TLV payload, which is obviously bogus.
new_payloads[0].data[0] = 1;
msg.onion_routing_packet = onion_utils::construct_onion_packet_bogus_hopdata(new_payloads, onion_keys, [0; 32], &payment_hash);
- }, ||{}, true, Some(PERM|22), Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true}));//XXX incremented channels idx here
+ }, ||{}, true, Some(PERM|22), Some(NetworkUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true}));
// final node failure
run_onion_failure_test("invalid_realm", 3, &nodes, &route, &payment_hash, &payment_secret, |msg| {
// length-1 TLV payload, which is obviously bogus.
new_payloads[1].data[0] = 1;
msg.onion_routing_packet = onion_utils::construct_onion_packet_bogus_hopdata(new_payloads, onion_keys, [0; 32], &payment_hash);
- }, ||{}, false, Some(PERM|22), Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true}));
+ }, ||{}, false, Some(PERM|22), Some(NetworkUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true}));
// the following three with run_onion_failure_test_with_fail_intercept() test only the origin node
// receiving simulated fail messages
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], NODE|2, &[0;0]);
- }, ||{}, true, Some(NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: false}));
+ }, ||{}, true, Some(NODE|2), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: false}));
// final node failure
run_onion_failure_test_with_fail_intercept("temporary_node_failure", 200, &nodes, &route, &payment_hash, &payment_secret, |_msg| {}, |msg| {
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], NODE|2, &[0;0]);
}, ||{
nodes[2].node.fail_htlc_backwards(&payment_hash);
- }, true, Some(NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: false}));
+ }, true, Some(NODE|2), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: false}));
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]);
// intermediate node failure
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|NODE|2, &[0;0]);
- }, ||{}, true, Some(PERM|NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: true}));
+ }, ||{}, true, Some(PERM|NODE|2), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: true}));
// final node failure
run_onion_failure_test_with_fail_intercept("permanent_node_failure", 200, &nodes, &route, &payment_hash, &payment_secret, |_msg| {}, |msg| {
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|2, &[0;0]);
}, ||{
nodes[2].node.fail_htlc_backwards(&payment_hash);
- }, false, Some(PERM|NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: true}));
+ }, false, Some(PERM|NODE|2), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: true}));
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]);
// intermediate node failure
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|NODE|3, &[0;0]);
}, ||{
nodes[2].node.fail_htlc_backwards(&payment_hash);
- }, true, Some(PERM|NODE|3), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: true}));
+ }, true, Some(PERM|NODE|3), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][0].pubkey, is_permanent: true}));
// final node failure
run_onion_failure_test_with_fail_intercept("required_node_feature_missing", 200, &nodes, &route, &payment_hash, &payment_secret, |_msg| {}, |msg| {
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|3, &[0;0]);
}, ||{
nodes[2].node.fail_htlc_backwards(&payment_hash);
- }, false, Some(PERM|NODE|3), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: true}));
+ }, false, Some(PERM|NODE|3), Some(NetworkUpdate::NodeFailure{node_id: route.paths[0][1].pubkey, is_permanent: true}));
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]);
run_onion_failure_test("invalid_onion_version", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { msg.onion_routing_packet.version = 1; }, ||{}, true,
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], UPDATE|7, &ChannelUpdate::dummy().encode_with_len()[..]);
- }, ||{}, true, Some(UPDATE|7), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
+ }, ||{}, true, Some(UPDATE|7), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
run_onion_failure_test_with_fail_intercept("permanent_channel_failure", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| {
msg.amount_msat -= 1;
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|8, &[0;0]);
// short_channel_id from the processing node
- }, ||{}, true, Some(PERM|8), Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true}));
+ }, ||{}, true, Some(PERM|8), Some(NetworkUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true}));
run_onion_failure_test_with_fail_intercept("required_channel_feature_missing", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| {
msg.amount_msat -= 1;
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|9, &[0;0]);
// short_channel_id from the processing node
- }, ||{}, true, Some(PERM|9), Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true}));
+ }, ||{}, true, Some(PERM|9), Some(NetworkUpdate::ChannelClosed{short_channel_id: channels[1].0.contents.short_channel_id, is_permanent: true}));
let mut bogus_route = route.clone();
bogus_route.paths[0][1].short_channel_id -= 1;
run_onion_failure_test("unknown_next_peer", 0, &nodes, &bogus_route, &payment_hash, &payment_secret, |_| {}, ||{}, true, Some(PERM|10),
- Some(msgs::HTLCFailChannelUpdate::ChannelClosed{short_channel_id: bogus_route.paths[0][1].short_channel_id, is_permanent:true}));
+ Some(NetworkUpdate::ChannelClosed{short_channel_id: bogus_route.paths[0][1].short_channel_id, is_permanent:true}));
let amt_to_forward = nodes[1].node.channel_state.lock().unwrap().by_id.get(&channels[1].2).unwrap().get_counterparty_htlc_minimum_msat() - 1;
let mut bogus_route = route.clone();
let route_len = bogus_route.paths[0].len();
bogus_route.paths[0][route_len-1].fee_msat = amt_to_forward;
- run_onion_failure_test("amount_below_minimum", 0, &nodes, &bogus_route, &payment_hash, &payment_secret, |_| {}, ||{}, true, Some(UPDATE|11), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
+ run_onion_failure_test("amount_below_minimum", 0, &nodes, &bogus_route, &payment_hash, &payment_secret, |_| {}, ||{}, true, Some(UPDATE|11), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
// Test a positive test-case with one extra msat, meeting the minimum.
bogus_route.paths[0][route_len-1].fee_msat = amt_to_forward + 1;
//invalid channel_update cases.
run_onion_failure_test("fee_insufficient", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| {
msg.amount_msat -= 1;
- }, || {}, true, Some(UPDATE|12), Some(msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true}));
+ }, || {}, true, Some(UPDATE|12), Some(NetworkUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true}));
run_onion_failure_test("incorrect_cltv_expiry", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| {
// need to violate: cltv_expiry - cltv_expiry_delta >= outgoing_cltv_value
msg.cltv_expiry -= 1;
- }, || {}, true, Some(UPDATE|13), Some(msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true}));
+ }, || {}, true, Some(UPDATE|13), Some(NetworkUpdate::ChannelClosed { short_channel_id: channels[0].0.contents.short_channel_id, is_permanent: true}));
run_onion_failure_test("expiry_too_soon", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| {
let height = msg.cltv_expiry - CLTV_CLAIM_BUFFER - LATENCY_GRACE_PERIOD_BLOCKS + 1;
connect_blocks(&nodes[0], height - nodes[0].best_block_info().1);
connect_blocks(&nodes[1], height - nodes[1].best_block_info().1);
connect_blocks(&nodes[2], height - nodes[2].best_block_info().1);
- }, ||{}, true, Some(UPDATE|14), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
+ }, ||{}, true, Some(UPDATE|14), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
run_onion_failure_test("unknown_payment_hash", 2, &nodes, &route, &payment_hash, &payment_secret, |_| {}, || {
nodes[2].node.fail_htlc_backwards(&payment_hash);
// disconnect event to the channel between nodes[1] ~ nodes[2]
nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), false);
nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
- }, true, Some(UPDATE|20), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
+ }, true, Some(UPDATE|20), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
reconnect_nodes(&nodes[1], &nodes[2], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
run_onion_failure_test("expiry_too_far", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| {
use ln::{PaymentHash, PaymentPreimage, PaymentSecret};
use ln::channelmanager::HTLCSource;
use ln::msgs;
+use routing::network_graph::NetworkUpdate;
use routing::router::RouteHop;
use util::chacha20::ChaCha20;
use util::errors::{self, APIError};
/// OutboundRoute).
/// Returns update, a boolean indicating that the payment itself failed, and the error code.
#[inline]
-pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &Secp256k1<T>, logger: &L, htlc_source: &HTLCSource, mut packet_decrypted: Vec<u8>) -> (Option<msgs::HTLCFailChannelUpdate>, bool, Option<u16>, Option<Vec<u8>>) where L::Target: Logger {
+pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &Secp256k1<T>, logger: &L, htlc_source: &HTLCSource, mut packet_decrypted: Vec<u8>) -> (Option<NetworkUpdate>, bool, Option<u16>, Option<Vec<u8>>) where L::Target: Logger {
if let &HTLCSource::OutboundRoute { ref path, ref session_priv, ref first_hop_htlc_msat } = htlc_source {
let mut res = None;
let mut htlc_msat = *first_hop_htlc_msat;
} && is_from_final_node) // PERM bit observed below even this error is from the intermediate nodes
|| error_code == 21; // Special case error 21 as the Route object is bogus, TODO: Maybe fail the node if the CLTV was reasonable?
- let mut fail_channel_update = None;
+ let mut network_update = None;
if error_code & NODE == NODE {
- fail_channel_update = Some(msgs::HTLCFailChannelUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent: error_code & PERM == PERM });
+ network_update = Some(NetworkUpdate::NodeFailure { node_id: route_hop.pubkey, is_permanent: error_code & PERM == PERM });
}
else if error_code & PERM == PERM {
- fail_channel_update = if payment_failed {None} else {Some(msgs::HTLCFailChannelUpdate::ChannelClosed {
+ network_update = if payment_failed { None } else { Some(NetworkUpdate::ChannelClosed {
short_channel_id: path[next_route_hop_ix - if next_route_hop_ix == path.len() { 1 } else { 0 }].short_channel_id,
is_permanent: true,
})};
20 => chan_update.contents.flags & 2 == 0,
_ => false, // unknown error code; take channel_update as valid
};
- fail_channel_update = if is_chan_update_invalid {
+ network_update = if is_chan_update_invalid {
// This probably indicates the node which forwarded
// to the node in question corrupted something.
- Some(msgs::HTLCFailChannelUpdate::ChannelClosed {
+ Some(NetworkUpdate::ChannelClosed {
short_channel_id: route_hop.short_channel_id,
is_permanent: true,
})
} else {
- Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage {
+ Some(NetworkUpdate::ChannelUpdateMessage {
msg: chan_update,
})
};
}
}
}
- if fail_channel_update.is_none() {
+ if network_update.is_none() {
// They provided an UPDATE which was obviously bogus, not worth
// trying to relay through them anymore.
- fail_channel_update = Some(msgs::HTLCFailChannelUpdate::NodeFailure {
+ network_update = Some(NetworkUpdate::NodeFailure {
node_id: route_hop.pubkey,
is_permanent: true,
});
// We can't understand their error messages and they failed to
// forward...they probably can't understand our forwards so its
// really not worth trying any further.
- fail_channel_update = Some(msgs::HTLCFailChannelUpdate::NodeFailure {
+ network_update = Some(NetworkUpdate::NodeFailure {
node_id: route_hop.pubkey,
is_permanent: true,
});
// TODO: Here (and a few other places) we assume that BADONION errors
// are always "sourced" from the node previous to the one which failed
// to decode the onion.
- res = Some((fail_channel_update, !(error_code & PERM == PERM && is_from_final_node)));
+ res = Some((network_update, !(error_code & PERM == PERM && is_from_final_node)));
let (description, title) = errors::get_onion_error_description(error_code);
if debug_field_size > 0 && err_packet.failuremsg.len() >= 4 + debug_field_size {
} else {
// Useless packet that we can't use but it passed HMAC, so it
// definitely came from the peer in question
- res = Some((Some(msgs::HTLCFailChannelUpdate::NodeFailure {
+ res = Some((Some(NetworkUpdate::NodeFailure {
node_id: route_hop.pubkey,
is_permanent: true,
}), !is_from_final_node));
fn handle_node_announcement(&self, _msg: &msgs::NodeAnnouncement) -> Result<bool, LightningError> { Ok(false) }
fn handle_channel_announcement(&self, _msg: &msgs::ChannelAnnouncement) -> Result<bool, LightningError> { Ok(false) }
fn handle_channel_update(&self, _msg: &msgs::ChannelUpdate) -> Result<bool, LightningError> { Ok(false) }
- fn handle_htlc_fail_channel_update(&self, _update: &msgs::HTLCFailChannelUpdate) {}
fn get_next_channel_announcements(&self, _starting_point: u64, _batch_amount: u8) ->
Vec<(msgs::ChannelAnnouncement, Option<msgs::ChannelUpdate>, Option<msgs::ChannelUpdate>)> { Vec::new() }
fn get_next_node_announcements(&self, _starting_point: Option<&PublicKey>, _batch_amount: u8) -> Vec<msgs::NodeAnnouncement> { Vec::new() }
let peer = get_peer_for_forwarding!(node_id);
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg)));
},
- MessageSendEvent::PaymentFailureNetworkUpdate { ref update } => {
- self.message_handler.route_handler.handle_htlc_fail_channel_update(update);
- },
MessageSendEvent::HandleError { ref node_id, ref action } => {
match *action {
msgs::ErrorAction::DisconnectPeer { ref msg } => {
use chain::{Confirm, Watch};
use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs};
use ln::features::InitFeatures;
-use ln::msgs::{ChannelMessageHandler, ErrorAction, HTLCFailChannelUpdate};
+use ln::msgs::{ChannelMessageHandler, ErrorAction};
+use routing::network_graph::NetworkUpdate;
use util::enforcing_trait_impls::EnforcingSigner;
use util::events::{Event, MessageSendEvent, MessageSendEventsProvider};
use util::test_utils;
if claim {
expect_payment_sent!(nodes[0], our_payment_preimage);
} else {
- let events = nodes[0].node.get_and_clear_pending_msg_events();
- assert_eq!(events.len(), 1);
- if let MessageSendEvent::PaymentFailureNetworkUpdate { update: HTLCFailChannelUpdate::ChannelClosed { ref is_permanent, .. } } = events[0] {
- assert!(is_permanent);
- } else { panic!("Unexpected event!"); }
- expect_payment_failed!(nodes[0], our_payment_hash, false);
+ expect_payment_failed_with_update!(nodes[0], our_payment_hash, false, chan_2.0.contents.short_channel_id, true);
}
}
use chain::transaction::OutPoint;
use ln::{PaymentPreimage, PaymentHash};
use ln::channelmanager::PaymentSendFailure;
+use routing::network_graph::NetworkUpdate;
use routing::router::get_route;
use ln::features::{InitFeatures, InvoiceFeatures};
use ln::msgs;
let net_graph_msg_handler0 = &nodes[0].net_graph_msg_handler;
let net_graph_msg_handler1 = &nodes[1].net_graph_msg_handler;
- let route_1 = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler0.network_graph.read().unwrap(), &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
- let route_2 = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler1.network_graph.read().unwrap(), &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route_1 = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler0.network_graph, &nodes[1].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route_2 = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler1.network_graph, &nodes[0].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
unwrap_send_err!(nodes[0].node.send_payment(&route_1, payment_hash, &Some(payment_secret)), true, APIError::ChannelUnavailable {..}, {});
unwrap_send_err!(nodes[1].node.send_payment(&route_2, payment_hash, &Some(payment_secret)), true, APIError::ChannelUnavailable {..}, {});
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[2]);
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
- let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
+ let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 100000, TEST_FINAL_CLTV, &logger).unwrap();
nodes[0].node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
check_added_monitors!(nodes[0], 1);
let updates = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &updates_2.update_fail_htlcs[0]);
commitment_signed_dance!(nodes[0], nodes[1], updates_2.commitment_signed, false, true);
- expect_payment_failed!(nodes[0], our_payment_hash, false);
+ expect_payment_failed_with_update!(nodes[0], our_payment_hash, false, chan_2.0.contents.short_channel_id, true);
let msg_events = nodes[0].node.get_and_clear_pending_msg_events();
- assert_eq!(msg_events.len(), 2);
- match msg_events[0] {
- MessageSendEvent::PaymentFailureNetworkUpdate { update: msgs::HTLCFailChannelUpdate::ChannelUpdateMessage { ref msg }} => {
- assert_eq!(msg.contents.short_channel_id, chan_1.0.contents.short_channel_id);
- },
- _ => panic!("Unexpected event"),
- }
- let node_0_closing_signed = match msg_events[1] {
+ assert_eq!(msg_events.len(), 1);
+ let node_0_closing_signed = match msg_events[0] {
MessageSendEvent::SendClosingSigned { ref node_id, ref msg } => {
assert_eq!(*node_id, nodes[1].node.get_our_node_id());
(*msg).clone()
use ln::msgs;
use util::ser::{Writeable, Readable, Writer};
use util::logger::{Logger, Level};
-use util::events::{MessageSendEvent, MessageSendEventsProvider};
+use util::events::{Event, EventHandler, MessageSendEvent, MessageSendEventsProvider};
use util::scid_utils::{block_from_scid, scid_from_parts, MAX_SCID_BLOCK};
use io;
const MAX_SCIDS_PER_REPLY: usize = 8000;
/// Represents the network as nodes and channels between them
-#[derive(Clone, PartialEq)]
pub struct NetworkGraph {
genesis_hash: BlockHash,
- channels: BTreeMap<u64, ChannelInfo>,
- nodes: BTreeMap<PublicKey, NodeInfo>,
+ // Lock order: channels -> nodes
+ channels: RwLock<BTreeMap<u64, ChannelInfo>>,
+ nodes: RwLock<BTreeMap<PublicKey, NodeInfo>>,
}
-/// A simple newtype for RwLockReadGuard<'a, NetworkGraph>.
-/// This exists only to make accessing a RwLock<NetworkGraph> possible from
-/// the C bindings, as it can be done directly in Rust code.
-pub struct LockedNetworkGraph<'a>(pub RwLockReadGuard<'a, NetworkGraph>);
+/// A read-only view of [`NetworkGraph`].
+pub struct ReadOnlyNetworkGraph<'a> {
+ channels: RwLockReadGuard<'a, BTreeMap<u64, ChannelInfo>>,
+ nodes: RwLockReadGuard<'a, BTreeMap<PublicKey, NodeInfo>>,
+}
+
+/// Update to the [`NetworkGraph`] based on payment failure information conveyed via the Onion
+/// return packet by a node along the route. See [BOLT #4] for details.
+///
+/// [BOLT #4]: https://github.com/lightningnetwork/lightning-rfc/blob/master/04-onion-routing.md
+#[derive(Clone, Debug, PartialEq)]
+pub enum NetworkUpdate {
+ /// An error indicating a `channel_update` messages should be applied via
+ /// [`NetworkGraph::update_channel`].
+ ChannelUpdateMessage {
+ /// The update to apply via [`NetworkGraph::update_channel`].
+ msg: ChannelUpdate,
+ },
+ /// An error indicating only that a channel has been closed, which should be applied via
+ /// [`NetworkGraph::close_channel_from_update`].
+ ChannelClosed {
+ /// The short channel id of the closed channel.
+ short_channel_id: u64,
+ /// Whether the channel should be permanently removed or temporarily disabled until a new
+ /// `channel_update` message is received.
+ is_permanent: bool,
+ },
+ /// An error indicating only that a node has failed, which should be applied via
+ /// [`NetworkGraph::fail_node`].
+ NodeFailure {
+ /// The node id of the failed node.
+ node_id: PublicKey,
+ /// Whether the node should be permanently removed from consideration or can be restored
+ /// when a new `channel_update` message is received.
+ is_permanent: bool,
+ }
+}
+
+impl_writeable_tlv_based_enum_upgradable!(NetworkUpdate,
+ (0, ChannelUpdateMessage) => {
+ (0, msg, required),
+ },
+ (2, ChannelClosed) => {
+ (0, short_channel_id, required),
+ (2, is_permanent, required),
+ },
+ (4, NodeFailure) => {
+ (0, node_id, required),
+ (2, is_permanent, required),
+ },
+);
+
+impl<C: Deref, L: Deref> EventHandler for NetGraphMsgHandler<C, L>
+where C::Target: chain::Access, L::Target: Logger {
+ fn handle_event(&self, event: &Event) {
+ if let Event::PaymentFailed { payment_hash: _, rejected_by_dest: _, network_update, .. } = event {
+ if let Some(network_update) = network_update {
+ self.handle_network_update(network_update);
+ }
+ }
+ }
+}
/// Receives and validates network updates from peers,
/// stores authentic and relevant data as a network graph.
/// This network graph is then used for routing payments.
/// Provides interface to help with initial routing sync by
/// serving historical announcements.
-pub struct NetGraphMsgHandler<C: Deref, L: Deref> where C::Target: chain::Access, L::Target: Logger {
+///
+/// Serves as an [`EventHandler`] for applying updates from [`Event::PaymentFailed`] to the
+/// [`NetworkGraph`].
+pub struct NetGraphMsgHandler<C: Deref, L: Deref>
+where C::Target: chain::Access, L::Target: Logger
+{
secp_ctx: Secp256k1<secp256k1::VerifyOnly>,
/// Representation of the payment channel network
- pub network_graph: RwLock<NetworkGraph>,
+ pub network_graph: NetworkGraph,
chain_access: Option<C>,
full_syncs_requested: AtomicUsize,
pending_events: Mutex<Vec<MessageSendEvent>>,
logger: L,
}
-impl<C: Deref, L: Deref> NetGraphMsgHandler<C, L> where C::Target: chain::Access, L::Target: Logger {
+impl<C: Deref, L: Deref> NetGraphMsgHandler<C, L>
+where C::Target: chain::Access, L::Target: Logger
+{
/// Creates a new tracker of the actual state of the network of channels and nodes,
- /// assuming a fresh network graph.
+ /// assuming an existing Network Graph.
/// Chain monitor is used to make sure announced channels exist on-chain,
/// channel data is correct, and that the announcement is signed with
/// channel owners' keys.
- pub fn new(genesis_hash: BlockHash, chain_access: Option<C>, logger: L) -> Self {
- NetGraphMsgHandler {
- secp_ctx: Secp256k1::verification_only(),
- network_graph: RwLock::new(NetworkGraph::new(genesis_hash)),
- full_syncs_requested: AtomicUsize::new(0),
- chain_access,
- pending_events: Mutex::new(vec![]),
- logger,
- }
- }
-
- /// Creates a new tracker of the actual state of the network of channels and nodes,
- /// assuming an existing Network Graph.
- pub fn from_net_graph(chain_access: Option<C>, logger: L, network_graph: NetworkGraph) -> Self {
+ pub fn new(network_graph: NetworkGraph, chain_access: Option<C>, logger: L) -> Self {
NetGraphMsgHandler {
secp_ctx: Secp256k1::verification_only(),
- network_graph: RwLock::new(network_graph),
+ network_graph,
full_syncs_requested: AtomicUsize::new(0),
chain_access,
pending_events: Mutex::new(vec![]),
self.chain_access = chain_access;
}
- /// Take a read lock on the network_graph and return it in the C-bindings
- /// newtype helper. This is likely only useful when called via the C
- /// bindings as you can call `self.network_graph.read().unwrap()` in Rust
- /// yourself.
- pub fn read_locked_graph<'a>(&'a self) -> LockedNetworkGraph<'a> {
- LockedNetworkGraph(self.network_graph.read().unwrap())
- }
-
/// Returns true when a full routing table sync should be performed with a peer.
fn should_request_full_sync(&self, _node_id: &PublicKey) -> bool {
//TODO: Determine whether to request a full sync based on the network map.
false
}
}
-}
-impl<'a> LockedNetworkGraph<'a> {
- /// Get a reference to the NetworkGraph which this read-lock contains.
- pub fn graph(&self) -> &NetworkGraph {
- &*self.0
+ /// Applies changes to the [`NetworkGraph`] from the given update.
+ fn handle_network_update(&self, update: &NetworkUpdate) {
+ match *update {
+ NetworkUpdate::ChannelUpdateMessage { ref msg } => {
+ let short_channel_id = msg.contents.short_channel_id;
+ let is_enabled = msg.contents.flags & (1 << 1) != (1 << 1);
+ let status = if is_enabled { "enabled" } else { "disabled" };
+ log_debug!(self.logger, "Updating channel with channel_update from a payment failure. Channel {} is {}.", short_channel_id, status);
+ let _ = self.network_graph.update_channel(msg, &self.secp_ctx);
+ },
+ NetworkUpdate::ChannelClosed { short_channel_id, is_permanent } => {
+ let action = if is_permanent { "Removing" } else { "Disabling" };
+ log_debug!(self.logger, "{} channel graph entry for {} due to a payment failure.", action, short_channel_id);
+ self.network_graph.close_channel_from_update(short_channel_id, is_permanent);
+ },
+ NetworkUpdate::NodeFailure { ref node_id, is_permanent } => {
+ let action = if is_permanent { "Removing" } else { "Disabling" };
+ log_debug!(self.logger, "{} node graph entry for {} due to a payment failure.", action, node_id);
+ self.network_graph.fail_node(node_id, is_permanent);
+ },
+ }
}
}
-
macro_rules! secp_verify_sig {
( $secp_ctx: expr, $msg: expr, $sig: expr, $pubkey: expr ) => {
match $secp_ctx.verify($msg, $sig, $pubkey) {
};
}
-impl<C: Deref , L: Deref > RoutingMessageHandler for NetGraphMsgHandler<C, L> where C::Target: chain::Access, L::Target: Logger {
+impl<C: Deref, L: Deref> RoutingMessageHandler for NetGraphMsgHandler<C, L>
+where C::Target: chain::Access, L::Target: Logger
+{
fn handle_node_announcement(&self, msg: &msgs::NodeAnnouncement) -> Result<bool, LightningError> {
- self.network_graph.write().unwrap().update_node_from_announcement(msg, &self.secp_ctx)?;
+ self.network_graph.update_node_from_announcement(msg, &self.secp_ctx)?;
Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY &&
msg.contents.excess_address_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY &&
msg.contents.excess_data.len() + msg.contents.excess_address_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY)
}
fn handle_channel_announcement(&self, msg: &msgs::ChannelAnnouncement) -> Result<bool, LightningError> {
- self.network_graph.write().unwrap().update_channel_from_announcement(msg, &self.chain_access, &self.secp_ctx)?;
+ self.network_graph.update_channel_from_announcement(msg, &self.chain_access, &self.secp_ctx)?;
log_trace!(self.logger, "Added channel_announcement for {}{}", msg.contents.short_channel_id, if !msg.contents.excess_data.is_empty() { " with excess uninterpreted data!" } else { "" });
Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY)
}
- fn handle_htlc_fail_channel_update(&self, update: &msgs::HTLCFailChannelUpdate) {
- match update {
- &msgs::HTLCFailChannelUpdate::ChannelUpdateMessage { ref msg } => {
- let chan_enabled = msg.contents.flags & (1 << 1) != (1 << 1);
- log_debug!(self.logger, "Updating channel with channel_update from a payment failure. Channel {} is {}abled.", msg.contents.short_channel_id, if chan_enabled { "en" } else { "dis" });
- let _ = self.network_graph.write().unwrap().update_channel(msg, &self.secp_ctx);
- },
- &msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id, is_permanent } => {
- log_debug!(self.logger, "{} channel graph entry for {} due to a payment failure.", if is_permanent { "Removing" } else { "Disabling" }, short_channel_id);
- self.network_graph.write().unwrap().close_channel_from_update(short_channel_id, is_permanent);
- },
- &msgs::HTLCFailChannelUpdate::NodeFailure { ref node_id, is_permanent } => {
- log_debug!(self.logger, "{} node graph entry for {} due to a payment failure.", if is_permanent { "Removing" } else { "Disabling" }, node_id);
- self.network_graph.write().unwrap().fail_node(node_id, is_permanent);
- },
- }
- }
-
fn handle_channel_update(&self, msg: &msgs::ChannelUpdate) -> Result<bool, LightningError> {
- self.network_graph.write().unwrap().update_channel(msg, &self.secp_ctx)?;
+ self.network_graph.update_channel(msg, &self.secp_ctx)?;
Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY)
}
fn get_next_channel_announcements(&self, starting_point: u64, batch_amount: u8) -> Vec<(ChannelAnnouncement, Option<ChannelUpdate>, Option<ChannelUpdate>)> {
- let network_graph = self.network_graph.read().unwrap();
let mut result = Vec::with_capacity(batch_amount as usize);
- let mut iter = network_graph.get_channels().range(starting_point..);
+ let channels = self.network_graph.channels.read().unwrap();
+ let mut iter = channels.range(starting_point..);
while result.len() < batch_amount as usize {
if let Some((_, ref chan)) = iter.next() {
if chan.announcement_message.is_some() {
}
fn get_next_node_announcements(&self, starting_point: Option<&PublicKey>, batch_amount: u8) -> Vec<NodeAnnouncement> {
- let network_graph = self.network_graph.read().unwrap();
let mut result = Vec::with_capacity(batch_amount as usize);
+ let nodes = self.network_graph.nodes.read().unwrap();
let mut iter = if let Some(pubkey) = starting_point {
- let mut iter = network_graph.get_nodes().range((*pubkey)..);
+ let mut iter = nodes.range((*pubkey)..);
iter.next();
iter
} else {
- network_graph.get_nodes().range(..)
+ nodes.range(..)
};
while result.len() < batch_amount as usize {
if let Some((_, ref node)) = iter.next() {
pending_events.push(MessageSendEvent::SendChannelRangeQuery {
node_id: their_node_id.clone(),
msg: QueryChannelRange {
- chain_hash: self.network_graph.read().unwrap().genesis_hash,
+ chain_hash: self.network_graph.genesis_hash,
first_blocknum,
number_of_blocks,
},
fn handle_query_channel_range(&self, their_node_id: &PublicKey, msg: QueryChannelRange) -> Result<(), LightningError> {
log_debug!(self.logger, "Handling query_channel_range peer={}, first_blocknum={}, number_of_blocks={}", log_pubkey!(their_node_id), msg.first_blocknum, msg.number_of_blocks);
- let network_graph = self.network_graph.read().unwrap();
-
let inclusive_start_scid = scid_from_parts(msg.first_blocknum as u64, 0, 0);
// We might receive valid queries with end_blocknum that would overflow SCID conversion.
let exclusive_end_scid = scid_from_parts(cmp::min(msg.end_blocknum() as u64, MAX_SCID_BLOCK), 0, 0);
// Per spec, we must reply to a query. Send an empty message when things are invalid.
- if msg.chain_hash != network_graph.genesis_hash || inclusive_start_scid.is_err() || exclusive_end_scid.is_err() || msg.number_of_blocks == 0 {
+ if msg.chain_hash != self.network_graph.genesis_hash || inclusive_start_scid.is_err() || exclusive_end_scid.is_err() || msg.number_of_blocks == 0 {
let mut pending_events = self.pending_events.lock().unwrap();
pending_events.push(MessageSendEvent::SendReplyChannelRange {
node_id: their_node_id.clone(),
// (has at least one update). A peer may still want to know the channel
// exists even if its not yet routable.
let mut batches: Vec<Vec<u64>> = vec![Vec::with_capacity(MAX_SCIDS_PER_REPLY)];
- for (_, ref chan) in network_graph.get_channels().range(inclusive_start_scid.unwrap()..exclusive_end_scid.unwrap()) {
+ let channels = self.network_graph.channels.read().unwrap();
+ for (_, ref chan) in channels.range(inclusive_start_scid.unwrap()..exclusive_end_scid.unwrap()) {
if let Some(chan_announcement) = &chan.announcement_message {
// Construct a new batch if last one is full
if batches.last().unwrap().len() == batches.last().unwrap().capacity() {
batch.push(chan_announcement.contents.short_channel_id);
}
}
- drop(network_graph);
+ drop(channels);
let mut pending_events = self.pending_events.lock().unwrap();
let batch_count = batches.len();
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
self.genesis_hash.write(writer)?;
- (self.channels.len() as u64).write(writer)?;
- for (ref chan_id, ref chan_info) in self.channels.iter() {
+ let channels = self.channels.read().unwrap();
+ (channels.len() as u64).write(writer)?;
+ for (ref chan_id, ref chan_info) in channels.iter() {
(*chan_id).write(writer)?;
chan_info.write(writer)?;
}
- (self.nodes.len() as u64).write(writer)?;
- for (ref node_id, ref node_info) in self.nodes.iter() {
+ let nodes = self.nodes.read().unwrap();
+ (nodes.len() as u64).write(writer)?;
+ for (ref node_id, ref node_info) in nodes.iter() {
node_id.write(writer)?;
node_info.write(writer)?;
}
Ok(NetworkGraph {
genesis_hash,
- channels,
- nodes,
+ channels: RwLock::new(channels),
+ nodes: RwLock::new(nodes),
})
}
}
impl fmt::Display for NetworkGraph {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
writeln!(f, "Network map\n[Channels]")?;
- for (key, val) in self.channels.iter() {
+ for (key, val) in self.channels.read().unwrap().iter() {
writeln!(f, " {}: {}", key, val)?;
}
writeln!(f, "[Nodes]")?;
- for (key, val) in self.nodes.iter() {
+ for (key, val) in self.nodes.read().unwrap().iter() {
writeln!(f, " {}: {}", log_pubkey!(key), val)?;
}
Ok(())
}
}
-impl NetworkGraph {
- /// Returns all known valid channels' short ids along with announced channel info.
- ///
- /// (C-not exported) because we have no mapping for `BTreeMap`s
- pub fn get_channels<'a>(&'a self) -> &'a BTreeMap<u64, ChannelInfo> { &self.channels }
- /// Returns all known nodes' public keys along with announced node info.
- ///
- /// (C-not exported) because we have no mapping for `BTreeMap`s
- pub fn get_nodes<'a>(&'a self) -> &'a BTreeMap<PublicKey, NodeInfo> { &self.nodes }
-
- /// Get network addresses by node id.
- /// Returns None if the requested node is completely unknown,
- /// or if node announcement for the node was never received.
- ///
- /// (C-not exported) as there is no practical way to track lifetimes of returned values.
- pub fn get_addresses<'a>(&'a self, pubkey: &PublicKey) -> Option<&'a Vec<NetAddress>> {
- if let Some(node) = self.nodes.get(pubkey) {
- if let Some(node_info) = node.announcement_info.as_ref() {
- return Some(&node_info.addresses)
- }
- }
- None
+impl PartialEq for NetworkGraph {
+ fn eq(&self, other: &Self) -> bool {
+ self.genesis_hash == other.genesis_hash &&
+ *self.channels.read().unwrap() == *other.channels.read().unwrap() &&
+ *self.nodes.read().unwrap() == *other.nodes.read().unwrap()
}
+}
+impl NetworkGraph {
/// Creates a new, empty, network graph.
pub fn new(genesis_hash: BlockHash) -> NetworkGraph {
Self {
genesis_hash,
- channels: BTreeMap::new(),
- nodes: BTreeMap::new(),
+ channels: RwLock::new(BTreeMap::new()),
+ nodes: RwLock::new(BTreeMap::new()),
+ }
+ }
+
+ /// Returns a read-only view of the network graph.
+ pub fn read_only(&'_ self) -> ReadOnlyNetworkGraph<'_> {
+ let channels = self.channels.read().unwrap();
+ let nodes = self.nodes.read().unwrap();
+ ReadOnlyNetworkGraph {
+ channels,
+ nodes,
}
}
/// You probably don't want to call this directly, instead relying on a NetGraphMsgHandler's
/// RoutingMessageHandler implementation to call it indirectly. This may be useful to accept
/// routing messages from a source using a protocol other than the lightning P2P protocol.
- pub fn update_node_from_announcement<T: secp256k1::Verification>(&mut self, msg: &msgs::NodeAnnouncement, secp_ctx: &Secp256k1<T>) -> Result<(), LightningError> {
+ pub fn update_node_from_announcement<T: secp256k1::Verification>(&self, msg: &msgs::NodeAnnouncement, secp_ctx: &Secp256k1<T>) -> Result<(), LightningError> {
let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
secp_verify_sig!(secp_ctx, &msg_hash, &msg.signature, &msg.contents.node_id);
self.update_node_from_announcement_intern(&msg.contents, Some(&msg))
/// given node announcement without verifying the associated signatures. Because we aren't
/// given the associated signatures here we cannot relay the node announcement to any of our
/// peers.
- pub fn update_node_from_unsigned_announcement(&mut self, msg: &msgs::UnsignedNodeAnnouncement) -> Result<(), LightningError> {
+ pub fn update_node_from_unsigned_announcement(&self, msg: &msgs::UnsignedNodeAnnouncement) -> Result<(), LightningError> {
self.update_node_from_announcement_intern(msg, None)
}
- fn update_node_from_announcement_intern(&mut self, msg: &msgs::UnsignedNodeAnnouncement, full_msg: Option<&msgs::NodeAnnouncement>) -> Result<(), LightningError> {
- match self.nodes.get_mut(&msg.node_id) {
+ fn update_node_from_announcement_intern(&self, msg: &msgs::UnsignedNodeAnnouncement, full_msg: Option<&msgs::NodeAnnouncement>) -> Result<(), LightningError> {
+ match self.nodes.write().unwrap().get_mut(&msg.node_id) {
None => Err(LightningError{err: "No existing channels for node_announcement".to_owned(), action: ErrorAction::IgnoreError}),
Some(node) => {
if let Some(node_info) = node.announcement_info.as_ref() {
///
/// If a `chain::Access` object is provided via `chain_access`, it will be called to verify
/// the corresponding UTXO exists on chain and is correctly-formatted.
- pub fn update_channel_from_announcement<T: secp256k1::Verification, C: Deref>
- (&mut self, msg: &msgs::ChannelAnnouncement, chain_access: &Option<C>, secp_ctx: &Secp256k1<T>)
- -> Result<(), LightningError>
- where C::Target: chain::Access {
+ pub fn update_channel_from_announcement<T: secp256k1::Verification, C: Deref>(
+ &self, msg: &msgs::ChannelAnnouncement, chain_access: &Option<C>, secp_ctx: &Secp256k1<T>
+ ) -> Result<(), LightningError>
+ where
+ C::Target: chain::Access,
+ {
let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.contents.encode()[..])[..]);
secp_verify_sig!(secp_ctx, &msg_hash, &msg.node_signature_1, &msg.contents.node_id_1);
secp_verify_sig!(secp_ctx, &msg_hash, &msg.node_signature_2, &msg.contents.node_id_2);
///
/// If a `chain::Access` object is provided via `chain_access`, it will be called to verify
/// the corresponding UTXO exists on chain and is correctly-formatted.
- pub fn update_channel_from_unsigned_announcement<C: Deref>
- (&mut self, msg: &msgs::UnsignedChannelAnnouncement, chain_access: &Option<C>)
- -> Result<(), LightningError>
- where C::Target: chain::Access {
+ pub fn update_channel_from_unsigned_announcement<C: Deref>(
+ &self, msg: &msgs::UnsignedChannelAnnouncement, chain_access: &Option<C>
+ ) -> Result<(), LightningError>
+ where
+ C::Target: chain::Access,
+ {
self.update_channel_from_unsigned_announcement_intern(msg, None, chain_access)
}
- fn update_channel_from_unsigned_announcement_intern<C: Deref>
- (&mut self, msg: &msgs::UnsignedChannelAnnouncement, full_msg: Option<&msgs::ChannelAnnouncement>, chain_access: &Option<C>)
- -> Result<(), LightningError>
- where C::Target: chain::Access {
+ fn update_channel_from_unsigned_announcement_intern<C: Deref>(
+ &self, msg: &msgs::UnsignedChannelAnnouncement, full_msg: Option<&msgs::ChannelAnnouncement>, chain_access: &Option<C>
+ ) -> Result<(), LightningError>
+ where
+ C::Target: chain::Access,
+ {
if msg.node_id_1 == msg.node_id_2 || msg.bitcoin_key_1 == msg.bitcoin_key_2 {
return Err(LightningError{err: "Channel announcement node had a channel with itself".to_owned(), action: ErrorAction::IgnoreError});
}
{ full_msg.cloned() } else { None },
};
- match self.channels.entry(msg.short_channel_id) {
+ let mut channels = self.channels.write().unwrap();
+ let mut nodes = self.nodes.write().unwrap();
+ match channels.entry(msg.short_channel_id) {
BtreeEntry::Occupied(mut entry) => {
//TODO: because asking the blockchain if short_channel_id is valid is only optional
//in the blockchain API, we need to handle it smartly here, though it's unclear
// b) we don't track UTXOs of channels we know about and remove them if they
// get reorg'd out.
// c) it's unclear how to do so without exposing ourselves to massive DoS risk.
- Self::remove_channel_in_nodes(&mut self.nodes, &entry.get(), msg.short_channel_id);
+ Self::remove_channel_in_nodes(&mut nodes, &entry.get(), msg.short_channel_id);
*entry.get_mut() = chan_info;
} else {
return Err(LightningError{err: "Already have knowledge of channel".to_owned(), action: ErrorAction::IgnoreAndLog(Level::Trace)})
macro_rules! add_channel_to_node {
( $node_id: expr ) => {
- match self.nodes.entry($node_id) {
+ match nodes.entry($node_id) {
BtreeEntry::Occupied(node_entry) => {
node_entry.into_mut().channels.push(msg.short_channel_id);
},
/// If permanent, removes a channel from the local storage.
/// May cause the removal of nodes too, if this was their last channel.
/// If not permanent, makes channels unavailable for routing.
- pub fn close_channel_from_update(&mut self, short_channel_id: u64, is_permanent: bool) {
+ pub fn close_channel_from_update(&self, short_channel_id: u64, is_permanent: bool) {
+ let mut channels = self.channels.write().unwrap();
if is_permanent {
- if let Some(chan) = self.channels.remove(&short_channel_id) {
- Self::remove_channel_in_nodes(&mut self.nodes, &chan, short_channel_id);
+ if let Some(chan) = channels.remove(&short_channel_id) {
+ let mut nodes = self.nodes.write().unwrap();
+ Self::remove_channel_in_nodes(&mut nodes, &chan, short_channel_id);
}
} else {
- if let Some(chan) = self.channels.get_mut(&short_channel_id) {
+ if let Some(chan) = channels.get_mut(&short_channel_id) {
if let Some(one_to_two) = chan.one_to_two.as_mut() {
one_to_two.enabled = false;
}
}
}
- fn fail_node(&mut self, _node_id: &PublicKey, is_permanent: bool) {
+ /// Marks a node in the graph as failed.
+ pub fn fail_node(&self, _node_id: &PublicKey, is_permanent: bool) {
if is_permanent {
// TODO: Wholly remove the node
} else {
/// You probably don't want to call this directly, instead relying on a NetGraphMsgHandler's
/// RoutingMessageHandler implementation to call it indirectly. This may be useful to accept
/// routing messages from a source using a protocol other than the lightning P2P protocol.
- pub fn update_channel<T: secp256k1::Verification>(&mut self, msg: &msgs::ChannelUpdate, secp_ctx: &Secp256k1<T>) -> Result<(), LightningError> {
+ pub fn update_channel<T: secp256k1::Verification>(&self, msg: &msgs::ChannelUpdate, secp_ctx: &Secp256k1<T>) -> Result<(), LightningError> {
self.update_channel_intern(&msg.contents, Some(&msg), Some((&msg.signature, secp_ctx)))
}
/// For an already known (from announcement) channel, update info about one of the directions
/// of the channel without verifying the associated signatures. Because we aren't given the
/// associated signatures here we cannot relay the channel update to any of our peers.
- pub fn update_channel_unsigned(&mut self, msg: &msgs::UnsignedChannelUpdate) -> Result<(), LightningError> {
+ pub fn update_channel_unsigned(&self, msg: &msgs::UnsignedChannelUpdate) -> Result<(), LightningError> {
self.update_channel_intern(msg, None, None::<(&secp256k1::Signature, &Secp256k1<secp256k1::VerifyOnly>)>)
}
- fn update_channel_intern<T: secp256k1::Verification>(&mut self, msg: &msgs::UnsignedChannelUpdate, full_msg: Option<&msgs::ChannelUpdate>, sig_info: Option<(&secp256k1::Signature, &Secp256k1<T>)>) -> Result<(), LightningError> {
+ fn update_channel_intern<T: secp256k1::Verification>(&self, msg: &msgs::UnsignedChannelUpdate, full_msg: Option<&msgs::ChannelUpdate>, sig_info: Option<(&secp256k1::Signature, &Secp256k1<T>)>) -> Result<(), LightningError> {
let dest_node_id;
let chan_enabled = msg.flags & (1 << 1) != (1 << 1);
let chan_was_enabled;
- match self.channels.get_mut(&msg.short_channel_id) {
+ let mut channels = self.channels.write().unwrap();
+ match channels.get_mut(&msg.short_channel_id) {
None => return Err(LightningError{err: "Couldn't find channel for update".to_owned(), action: ErrorAction::IgnoreError}),
Some(channel) => {
if let OptionalField::Present(htlc_maximum_msat) = msg.htlc_maximum_msat {
}
}
+ let mut nodes = self.nodes.write().unwrap();
if chan_enabled {
- let node = self.nodes.get_mut(&dest_node_id).unwrap();
+ let node = nodes.get_mut(&dest_node_id).unwrap();
let mut base_msat = msg.fee_base_msat;
let mut proportional_millionths = msg.fee_proportional_millionths;
if let Some(fees) = node.lowest_inbound_channel_fees {
proportional_millionths
});
} else if chan_was_enabled {
- let node = self.nodes.get_mut(&dest_node_id).unwrap();
+ let node = nodes.get_mut(&dest_node_id).unwrap();
let mut lowest_inbound_channel_fees = None;
for chan_id in node.channels.iter() {
- let chan = self.channels.get(chan_id).unwrap();
+ let chan = channels.get(chan_id).unwrap();
let chan_info_opt;
if chan.node_one == dest_node_id {
chan_info_opt = chan.two_to_one.as_ref();
}
}
+impl ReadOnlyNetworkGraph<'_> {
+ /// Returns all known valid channels' short ids along with announced channel info.
+ ///
+ /// (C-not exported) because we have no mapping for `BTreeMap`s
+ pub fn channels(&self) -> &BTreeMap<u64, ChannelInfo> {
+ &*self.channels
+ }
+
+ /// Returns all known nodes' public keys along with announced node info.
+ ///
+ /// (C-not exported) because we have no mapping for `BTreeMap`s
+ pub fn nodes(&self) -> &BTreeMap<PublicKey, NodeInfo> {
+ &*self.nodes
+ }
+
+ /// Get network addresses by node id.
+ /// Returns None if the requested node is completely unknown,
+ /// or if node announcement for the node was never received.
+ ///
+ /// (C-not exported) as there is no practical way to track lifetimes of returned values.
+ pub fn get_addresses(&self, pubkey: &PublicKey) -> Option<&Vec<NetAddress>> {
+ if let Some(node) = self.nodes.get(pubkey) {
+ if let Some(node_info) = node.announcement_info.as_ref() {
+ return Some(&node_info.addresses)
+ }
+ }
+ None
+ }
+}
+
#[cfg(test)]
mod tests {
use chain;
+ use ln::PaymentHash;
use ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
- use routing::network_graph::{NetGraphMsgHandler, NetworkGraph, MAX_EXCESS_BYTES_FOR_RELAY};
+ use routing::network_graph::{NetGraphMsgHandler, NetworkGraph, NetworkUpdate, MAX_EXCESS_BYTES_FOR_RELAY};
use ln::msgs::{Init, OptionalField, RoutingMessageHandler, UnsignedNodeAnnouncement, NodeAnnouncement,
- UnsignedChannelAnnouncement, ChannelAnnouncement, UnsignedChannelUpdate, ChannelUpdate, HTLCFailChannelUpdate,
+ UnsignedChannelAnnouncement, ChannelAnnouncement, UnsignedChannelUpdate, ChannelUpdate,
ReplyChannelRange, ReplyShortChannelIdsEnd, QueryChannelRange, QueryShortChannelIds, MAX_VALUE_MSAT};
use util::test_utils;
use util::logger::Logger;
use util::ser::{Readable, Writeable};
- use util::events::{MessageSendEvent, MessageSendEventsProvider};
+ use util::events::{Event, EventHandler, MessageSendEvent, MessageSendEventsProvider};
use util::scid_utils::scid_from_parts;
use bitcoin::hashes::sha256d::Hash as Sha256dHash;
let secp_ctx = Secp256k1::new();
let logger = Arc::new(test_utils::TestLogger::new());
let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
- let net_graph_msg_handler = NetGraphMsgHandler::new(genesis_hash, None, Arc::clone(&logger));
+ let network_graph = NetworkGraph::new(genesis_hash);
+ let net_graph_msg_handler = NetGraphMsgHandler::new(network_graph, None, Arc::clone(&logger));
(secp_ctx, net_graph_msg_handler)
}
};
// Test if the UTXO lookups were not supported
- let mut net_graph_msg_handler = NetGraphMsgHandler::new(genesis_block(Network::Testnet).header.block_hash(), None, Arc::clone(&logger));
+ let network_graph = NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash());
+ let mut net_graph_msg_handler = NetGraphMsgHandler::new(network_graph, None, Arc::clone(&logger));
match net_graph_msg_handler.handle_channel_announcement(&valid_announcement) {
Ok(res) => assert!(res),
_ => panic!()
};
{
- let network = net_graph_msg_handler.network_graph.read().unwrap();
- match network.get_channels().get(&unsigned_announcement.short_channel_id) {
+ let network = &net_graph_msg_handler.network_graph;
+ match network.read_only().channels().get(&unsigned_announcement.short_channel_id) {
None => panic!(),
Some(_) => ()
- }
+ };
}
// If we receive announcement for the same channel (with UTXO lookups disabled),
// Test if an associated transaction were not on-chain (or not confirmed).
let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Testnet));
*chain_source.utxo_ret.lock().unwrap() = Err(chain::AccessError::UnknownTx);
- net_graph_msg_handler = NetGraphMsgHandler::new(chain_source.clone().genesis_hash, Some(chain_source.clone()), Arc::clone(&logger));
+ let network_graph = NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash());
+ net_graph_msg_handler = NetGraphMsgHandler::new(network_graph, Some(chain_source.clone()), Arc::clone(&logger));
unsigned_announcement.short_channel_id += 1;
msghash = hash_to_message!(&Sha256dHash::hash(&unsigned_announcement.encode()[..])[..]);
};
{
- let network = net_graph_msg_handler.network_graph.read().unwrap();
- match network.get_channels().get(&unsigned_announcement.short_channel_id) {
+ let network = &net_graph_msg_handler.network_graph;
+ match network.read_only().channels().get(&unsigned_announcement.short_channel_id) {
None => panic!(),
Some(_) => ()
- }
+ };
}
// If we receive announcement for the same channel (but TX is not confirmed),
_ => panic!()
};
{
- let network = net_graph_msg_handler.network_graph.read().unwrap();
- match network.get_channels().get(&unsigned_announcement.short_channel_id) {
+ let network = &net_graph_msg_handler.network_graph;
+ match network.read_only().channels().get(&unsigned_announcement.short_channel_id) {
Some(channel_entry) => {
assert_eq!(channel_entry.features, ChannelFeatures::empty());
},
_ => panic!()
- }
+ };
}
// Don't relay valid channels with excess data
let secp_ctx = Secp256k1::new();
let logger: Arc<Logger> = Arc::new(test_utils::TestLogger::new());
let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Testnet));
- let net_graph_msg_handler = NetGraphMsgHandler::new(genesis_block(Network::Testnet).header.block_hash(), Some(chain_source.clone()), Arc::clone(&logger));
+ let network_graph = NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash());
+ let net_graph_msg_handler = NetGraphMsgHandler::new(network_graph, Some(chain_source.clone()), Arc::clone(&logger));
let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap();
let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap();
};
{
- let network = net_graph_msg_handler.network_graph.read().unwrap();
- match network.get_channels().get(&short_channel_id) {
+ let network = &net_graph_msg_handler.network_graph;
+ match network.read_only().channels().get(&short_channel_id) {
None => panic!(),
Some(channel_info) => {
assert_eq!(channel_info.one_to_two.as_ref().unwrap().cltv_expiry_delta, 144);
assert!(channel_info.two_to_one.is_none());
}
- }
+ };
}
unsigned_channel_update.timestamp += 100;
}
#[test]
- fn handling_htlc_fail_channel_update() {
- let (secp_ctx, net_graph_msg_handler) = create_net_graph_msg_handler();
+ fn handling_network_update() {
+ let logger = test_utils::TestLogger::new();
+ let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Testnet));
+ let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
+ let network_graph = NetworkGraph::new(genesis_hash);
+ let net_graph_msg_handler = NetGraphMsgHandler::new(network_graph, Some(chain_source.clone()), &logger);
+ let secp_ctx = Secp256k1::new();
+
let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap();
let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap();
let node_id_1 = PublicKey::from_secret_key(&secp_ctx, node_1_privkey);
let short_channel_id = 0;
let chain_hash = genesis_block(Network::Testnet).header.block_hash();
+ let network_graph = &net_graph_msg_handler.network_graph;
{
// There is no nodes in the table at the beginning.
- let network = net_graph_msg_handler.network_graph.read().unwrap();
- assert_eq!(network.get_nodes().len(), 0);
+ assert_eq!(network_graph.read_only().nodes().len(), 0);
}
{
bitcoin_signature_2: secp_ctx.sign(&msghash, node_2_btckey),
contents: unsigned_announcement.clone(),
};
- match net_graph_msg_handler.handle_channel_announcement(&valid_channel_announcement) {
- Ok(_) => (),
- Err(_) => panic!()
- };
+ let chain_source: Option<&test_utils::TestChainSource> = None;
+ assert!(network_graph.update_channel_from_announcement(&valid_channel_announcement, &chain_source, &secp_ctx).is_ok());
+ assert!(network_graph.read_only().channels().get(&short_channel_id).is_some());
let unsigned_channel_update = UnsignedChannelUpdate {
chain_hash,
contents: unsigned_channel_update.clone()
};
- match net_graph_msg_handler.handle_channel_update(&valid_channel_update) {
- Ok(res) => assert!(res),
- _ => panic!()
- };
+ assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_none());
+
+ net_graph_msg_handler.handle_event(&Event::PaymentFailed {
+ payment_hash: PaymentHash([0; 32]),
+ rejected_by_dest: false,
+ network_update: Some(NetworkUpdate::ChannelUpdateMessage {
+ msg: valid_channel_update,
+ }),
+ error_code: None,
+ error_data: None,
+ });
+
+ assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_some());
}
// Non-permanent closing just disables a channel
{
- let network = net_graph_msg_handler.network_graph.read().unwrap();
- match network.get_channels().get(&short_channel_id) {
+ match network_graph.read_only().channels().get(&short_channel_id) {
None => panic!(),
Some(channel_info) => {
- assert!(channel_info.one_to_two.is_some());
+ assert!(channel_info.one_to_two.as_ref().unwrap().enabled);
}
- }
- }
-
- let channel_close_msg = HTLCFailChannelUpdate::ChannelClosed {
- short_channel_id,
- is_permanent: false
- };
+ };
- net_graph_msg_handler.handle_htlc_fail_channel_update(&channel_close_msg);
+ net_graph_msg_handler.handle_event(&Event::PaymentFailed {
+ payment_hash: PaymentHash([0; 32]),
+ rejected_by_dest: false,
+ network_update: Some(NetworkUpdate::ChannelClosed {
+ short_channel_id,
+ is_permanent: false,
+ }),
+ error_code: None,
+ error_data: None,
+ });
- // Non-permanent closing just disables a channel
- {
- let network = net_graph_msg_handler.network_graph.read().unwrap();
- match network.get_channels().get(&short_channel_id) {
+ match network_graph.read_only().channels().get(&short_channel_id) {
None => panic!(),
Some(channel_info) => {
assert!(!channel_info.one_to_two.as_ref().unwrap().enabled);
}
- }
+ };
}
- let channel_close_msg = HTLCFailChannelUpdate::ChannelClosed {
- short_channel_id,
- is_permanent: true
- };
-
- net_graph_msg_handler.handle_htlc_fail_channel_update(&channel_close_msg);
-
// Permanent closing deletes a channel
{
- let network = net_graph_msg_handler.network_graph.read().unwrap();
- assert_eq!(network.get_channels().len(), 0);
+ net_graph_msg_handler.handle_event(&Event::PaymentFailed {
+ payment_hash: PaymentHash([0; 32]),
+ rejected_by_dest: false,
+ network_update: Some(NetworkUpdate::ChannelClosed {
+ short_channel_id,
+ is_permanent: true,
+ }),
+ error_code: None,
+ error_data: None,
+ });
+
+ assert_eq!(network_graph.read_only().channels().len(), 0);
// Nodes are also deleted because there are no associated channels anymore
- assert_eq!(network.get_nodes().len(), 0);
+ assert_eq!(network_graph.read_only().nodes().len(), 0);
}
- // TODO: Test HTLCFailChannelUpdate::NodeFailure, which is not implemented yet.
+ // TODO: Test NetworkUpdate::NodeFailure, which is not implemented yet.
}
#[test]
Err(_) => panic!()
};
- let network = net_graph_msg_handler.network_graph.write().unwrap();
+ let network = &net_graph_msg_handler.network_graph;
let mut w = test_utils::TestVecWriter(Vec::new());
- assert!(!network.get_nodes().is_empty());
- assert!(!network.get_channels().is_empty());
+ assert!(!network.read_only().nodes().is_empty());
+ assert!(!network.read_only().channels().is_empty());
network.write(&mut w).unwrap();
assert!(<NetworkGraph>::read(&mut io::Cursor::new(&w.0)).unwrap() == *network);
}
// to use as the A* heuristic beyond just the cost to get one node further than the current
// one.
+ let network_graph = network.read_only();
+ let network_channels = network_graph.channels();
+ let network_nodes = network_graph.nodes();
let dummy_directional_info = DummyDirectionalChannelInfo { // used for first_hops routes
cltv_expiry_delta: 0,
htlc_minimum_msat: 0,
// work reliably.
let allow_mpp = if let Some(features) = &payee_features {
features.supports_basic_mpp()
- } else if let Some(node) = network.get_nodes().get(&payee) {
+ } else if let Some(node) = network_nodes.get(&payee) {
if let Some(node_info) = node.announcement_info.as_ref() {
node_info.features.supports_basic_mpp()
} else { false }
// Map from node_id to information about the best current path to that node, including feerate
// information.
- let mut dist = HashMap::with_capacity(network.get_nodes().len());
+ let mut dist = HashMap::with_capacity(network_nodes.len());
// During routing, if we ignore a path due to an htlc_minimum_msat limit, we set this,
// indicating that we may wish to try again with a higher value, potentially paying to meet an
// This map allows paths to be aware of the channel use by other paths in the same call.
// This would help to make a better path finding decisions and not "overbook" channels.
// It is unaware of the directions (except for `outbound_capacity_msat` in `first_hops`).
- let mut bookkeeped_channels_liquidity_available_msat = HashMap::with_capacity(network.get_nodes().len());
+ let mut bookkeeped_channels_liquidity_available_msat = HashMap::with_capacity(network_nodes.len());
// Keeping track of how much value we already collected across other paths. Helps to decide:
// - how much a new path should be transferring (upper bound);
// as a way to reach the $dest_node_id.
let mut fee_base_msat = u32::max_value();
let mut fee_proportional_millionths = u32::max_value();
- if let Some(Some(fees)) = network.get_nodes().get(&$src_node_id).map(|node| node.lowest_inbound_channel_fees) {
+ if let Some(Some(fees)) = network_nodes.get(&$src_node_id).map(|node| node.lowest_inbound_channel_fees) {
fee_base_msat = fees.base_msat;
fee_proportional_millionths = fees.proportional_millionths;
}
if !features.requires_unknown_bits() {
for chan_id in $node.channels.iter() {
- let chan = network.get_channels().get(chan_id).unwrap();
+ let chan = network_channels.get(chan_id).unwrap();
if !chan.features.requires_unknown_bits() {
if chan.node_one == *$node_id {
// ie $node is one, ie next hop in A* is two, via the two_to_one channel
// Add the payee as a target, so that the payee-to-payer
// search algorithm knows what to start with.
- match network.get_nodes().get(payee) {
+ match network_nodes.get(payee) {
// The payee is not in our network graph, so nothing to add here.
// There is still a chance of reaching them via last_hops though,
// so don't yet fail the payment here.
// we have a direct channel to the first hop or the first hop is
// in the regular network graph.
first_hop_targets.get(&first_hop_in_route.src_node_id).is_some() ||
- network.get_nodes().get(&first_hop_in_route.src_node_id).is_some();
+ network_nodes.get(&first_hop_in_route.src_node_id).is_some();
if have_hop_src_in_graph {
// We start building the path from reverse, i.e., from payee
// to the first RouteHintHop in the path.
'path_walk: loop {
if let Some(&(_, _, _, ref features)) = first_hop_targets.get(&ordered_hops.last().unwrap().0.pubkey) {
ordered_hops.last_mut().unwrap().1 = features.clone();
- } else if let Some(node) = network.get_nodes().get(&ordered_hops.last().unwrap().0.pubkey) {
+ } else if let Some(node) = network_nodes.get(&ordered_hops.last().unwrap().0.pubkey) {
if let Some(node_info) = node.announcement_info.as_ref() {
ordered_hops.last_mut().unwrap().1 = node_info.features.clone();
} else {
// Otherwise, since the current target node is not us,
// keep "unrolling" the payment graph from payee to payer by
// finding a way to reach the current target from the payer side.
- match network.get_nodes().get(&pubkey) {
+ match network_nodes.get(&pubkey) {
None => {},
Some(node) => {
add_entries_to_cheapest_to_target_node!(node, &pubkey, lowest_fee_to_node, value_contribution_msat, path_htlc_minimum_msat);
}
// Using the same keys for LN and BTC ids
- fn add_channel(net_graph_msg_handler: &NetGraphMsgHandler<Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>, secp_ctx: &Secp256k1<All>, node_1_privkey: &SecretKey,
- node_2_privkey: &SecretKey, features: ChannelFeatures, short_channel_id: u64) {
+ fn add_channel(
+ net_graph_msg_handler: &NetGraphMsgHandler<Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
+ secp_ctx: &Secp256k1<All>, node_1_privkey: &SecretKey, node_2_privkey: &SecretKey, features: ChannelFeatures, short_channel_id: u64
+ ) {
let node_id_1 = PublicKey::from_secret_key(&secp_ctx, node_1_privkey);
let node_id_2 = PublicKey::from_secret_key(&secp_ctx, node_2_privkey);
};
}
- fn update_channel(net_graph_msg_handler: &NetGraphMsgHandler<Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>, secp_ctx: &Secp256k1<All>, node_privkey: &SecretKey, update: UnsignedChannelUpdate) {
+ fn update_channel(
+ net_graph_msg_handler: &NetGraphMsgHandler<Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
+ secp_ctx: &Secp256k1<All>, node_privkey: &SecretKey, update: UnsignedChannelUpdate
+ ) {
let msghash = hash_to_message!(&Sha256dHash::hash(&update.encode()[..])[..]);
let valid_channel_update = ChannelUpdate {
signature: secp_ctx.sign(&msghash, node_privkey),
};
}
- fn add_or_update_node(net_graph_msg_handler: &NetGraphMsgHandler<Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>, secp_ctx: &Secp256k1<All>, node_privkey: &SecretKey,
- features: NodeFeatures, timestamp: u32) {
+ fn add_or_update_node(
+ net_graph_msg_handler: &NetGraphMsgHandler<Arc<test_utils::TestChainSource>, Arc<test_utils::TestLogger>>,
+ secp_ctx: &Secp256k1<All>, node_privkey: &SecretKey, features: NodeFeatures, timestamp: u32
+ ) {
let node_id = PublicKey::from_secret_key(&secp_ctx, node_privkey);
let unsigned_announcement = UnsignedNodeAnnouncement {
features,
let secp_ctx = Secp256k1::new();
let logger = Arc::new(test_utils::TestLogger::new());
let chain_monitor = Arc::new(test_utils::TestChainSource::new(Network::Testnet));
- let net_graph_msg_handler = NetGraphMsgHandler::new(genesis_block(Network::Testnet).header.block_hash(), None, Arc::clone(&logger));
+ let network_graph = NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash());
+ let net_graph_msg_handler = NetGraphMsgHandler::new(network_graph, None, Arc::clone(&logger));
// Build network from our_id to node6:
//
// -1(1)2- node0 -1(3)2-
// Simple route to 2 via 1
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 0, 42, Arc::clone(&logger)) {
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 0, 42, Arc::clone(&logger)) {
assert_eq!(err, "Cannot send a payment of 0 msat");
} else { panic!(); }
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 2);
assert_eq!(route.paths[0][0].pubkey, nodes[1]);
let our_chans = vec![get_channel_details(Some(2), our_id, InitFeatures::from_le_bytes(vec![0b11]), 100000)];
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, Some(&our_chans.iter().collect::<Vec<_>>()), &Vec::new(), 100, 42, Arc::clone(&logger)) {
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, Some(&our_chans.iter().collect::<Vec<_>>()), &Vec::new(), 100, 42, Arc::clone(&logger)) {
assert_eq!(err, "First hop cannot have our_node_id as a destination.");
} else { panic!(); }
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 2);
}
});
// Not possible to send 199_999_999, because the minimum on channel=2 is 200_000_000.
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 199_999_999, 42, Arc::clone(&logger)) {
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 199_999_999, 42, Arc::clone(&logger)) {
assert_eq!(err, "Failed to find a path to the given destination");
} else { panic!(); }
});
// A payment above the minimum should pass
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 199_999_999, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 199_999_999, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 2);
}
excess_data: Vec::new()
});
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 60_000, 42, Arc::clone(&logger)).unwrap();
// Overpay fees to hit htlc_minimum_msat.
let overpaid_fees = route.paths[0][0].fee_msat + route.paths[1][0].fee_msat;
excess_data: Vec::new()
});
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 60_000, 42, Arc::clone(&logger)).unwrap();
// Fine to overpay for htlc_minimum_msat if it allows us to save fee.
assert_eq!(route.paths.len(), 1);
let fees = route.paths[0][0].fee_msat;
assert_eq!(fees, 5_000);
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, 42, Arc::clone(&logger)).unwrap();
// Not fine to overpay for htlc_minimum_msat if it requires paying more than fee on
// the other channel.
});
// If all the channels require some features we don't understand, route should fail
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)) {
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)) {
assert_eq!(err, "Failed to find a path to the given destination");
} else { panic!(); }
// If we specify a channel to node7, that overrides our local channel view and that gets used
let our_chans = vec![get_channel_details(Some(42), nodes[7].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)];
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, Some(&our_chans.iter().collect::<Vec<_>>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, Some(&our_chans.iter().collect::<Vec<_>>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 2);
assert_eq!(route.paths[0][0].pubkey, nodes[7]);
add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[7], unknown_features.clone(), 1);
// If all nodes require some features we don't understand, route should fail
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)) {
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)) {
assert_eq!(err, "Failed to find a path to the given destination");
} else { panic!(); }
// If we specify a channel to node7, that overrides our local channel view and that gets used
let our_chans = vec![get_channel_details(Some(42), nodes[7].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)];
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, Some(&our_chans.iter().collect::<Vec<_>>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, Some(&our_chans.iter().collect::<Vec<_>>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 2);
assert_eq!(route.paths[0][0].pubkey, nodes[7]);
let (_, our_id, _, nodes) = get_nodes(&secp_ctx);
// Route to 1 via 2 and 3 because our channel to 1 is disabled
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[0], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[0], None, None, &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 3);
assert_eq!(route.paths[0][0].pubkey, nodes[1]);
// If we specify a channel to node7, that overrides our local channel view and that gets used
let our_chans = vec![get_channel_details(Some(42), nodes[7].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)];
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, Some(&our_chans.iter().collect::<Vec<_>>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, Some(&our_chans.iter().collect::<Vec<_>>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 2);
assert_eq!(route.paths[0][0].pubkey, nodes[7]);
let mut invalid_last_hops = last_hops_multi_private_channels(&nodes);
invalid_last_hops.push(invalid_last_hop);
{
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, None, &invalid_last_hops.iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)) {
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &invalid_last_hops.iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)) {
assert_eq!(err, "Last hop cannot have a payee as a source.");
} else { panic!(); }
}
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, None, &last_hops_multi_private_channels(&nodes).iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &last_hops_multi_private_channels(&nodes).iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 5);
assert_eq!(route.paths[0][0].pubkey, nodes[1]);
// Test handling of an empty RouteHint passed in Invoice.
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, None, &empty_last_hop(&nodes).iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &empty_last_hop(&nodes).iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 5);
assert_eq!(route.paths[0][0].pubkey, nodes[1]);
excess_data: Vec::new()
});
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, None, &multi_hint_last_hops(&nodes).iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &multi_hint_last_hops(&nodes).iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 4);
assert_eq!(route.paths[0][0].pubkey, nodes[1]);
// This test shows that public routes can be present in the invoice
// which would be handled in the same manner.
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, None, &last_hops_with_public_channel(&nodes).iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &last_hops_with_public_channel(&nodes).iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 5);
assert_eq!(route.paths[0][0].pubkey, nodes[1]);
// Simple test with outbound channel to 4 to test that last_hops and first_hops connect
let our_chans = vec![get_channel_details(Some(42), nodes[3].clone(), InitFeatures::from_le_bytes(vec![0b11]), 250_000_000)];
let mut last_hops = last_hops(&nodes);
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, Some(&our_chans.iter().collect::<Vec<_>>()), &last_hops.iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, Some(&our_chans.iter().collect::<Vec<_>>()), &last_hops.iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 2);
assert_eq!(route.paths[0][0].pubkey, nodes[3]);
last_hops[0].0[0].fees.base_msat = 1000;
// Revert to via 6 as the fee on 8 goes up
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, None, &last_hops.iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &last_hops.iter().collect::<Vec<_>>(), 100, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 4);
assert_eq!(route.paths[0][0].pubkey, nodes[1]);
assert_eq!(route.paths[0][3].channel_features.le_flags(), &Vec::<u8>::new()); // We can't learn any flags from invoices, sadly
// ...but still use 8 for larger payments as 6 has a variable feerate
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, None, &last_hops.iter().collect::<Vec<_>>(), 2000, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &last_hops.iter().collect::<Vec<_>>(), 2000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths[0].len(), 5);
assert_eq!(route.paths[0][0].pubkey, nodes[1]);
{
// Attempt to route more than available results in a failure.
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 250_000_001, 42, Arc::clone(&logger)) {
assert_eq!(err, "Failed to find a sufficient route to the given destination");
} else { panic!(); }
{
// Now, attempt to route an exact amount we have should be fine.
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 250_000_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 1);
let path = route.paths.last().unwrap();
{
// Attempt to route more than available results in a failure.
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), Some(&our_chans.iter().collect::<Vec<_>>()), &Vec::new(), 200_000_001, 42, Arc::clone(&logger)) {
assert_eq!(err, "Failed to find a sufficient route to the given destination");
} else { panic!(); }
{
// Now, attempt to route an exact amount we have should be fine.
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), Some(&our_chans.iter().collect::<Vec<_>>()), &Vec::new(), 200_000_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 1);
let path = route.paths.last().unwrap();
{
// Attempt to route more than available results in a failure.
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 15_001, 42, Arc::clone(&logger)) {
assert_eq!(err, "Failed to find a sufficient route to the given destination");
} else { panic!(); }
{
// Now, attempt to route an exact amount we have should be fine.
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 15_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 1);
let path = route.paths.last().unwrap();
{
// Attempt to route more than available results in a failure.
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 15_001, 42, Arc::clone(&logger)) {
assert_eq!(err, "Failed to find a sufficient route to the given destination");
} else { panic!(); }
{
// Now, attempt to route an exact amount we have should be fine.
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 15_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 1);
let path = route.paths.last().unwrap();
{
// Attempt to route more than available results in a failure.
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 10_001, 42, Arc::clone(&logger)) {
assert_eq!(err, "Failed to find a sufficient route to the given destination");
} else { panic!(); }
{
// Now, attempt to route an exact amount we have should be fine.
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 10_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 1);
let path = route.paths.last().unwrap();
});
{
// Attempt to route more than available results in a failure.
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3],
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3],
Some(InvoiceFeatures::known()), None, &Vec::new(), 60_000, 42, Arc::clone(&logger)) {
assert_eq!(err, "Failed to find a sufficient route to the given destination");
} else { panic!(); }
{
// Now, attempt to route 49 sats (just a bit below the capacity).
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3],
Some(InvoiceFeatures::known()), None, &Vec::new(), 49_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 1);
let mut total_amount_paid_msat = 0;
{
// Attempt to route an exact amount is also fine
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3],
Some(InvoiceFeatures::known()), None, &Vec::new(), 50_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 1);
let mut total_amount_paid_msat = 0;
});
{
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 50_000, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 50_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 1);
let mut total_amount_paid_msat = 0;
for path in &route.paths {
{
// Attempt to route more than available results in a failure.
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(),
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph,
&nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 300_000, 42, Arc::clone(&logger)) {
assert_eq!(err, "Failed to find a sufficient route to the given destination");
} else { panic!(); }
{
// Now, attempt to route 250 sats (just a bit below the capacity).
// Our algorithm should provide us with these 3 paths.
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 250_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 3);
let mut total_amount_paid_msat = 0;
{
// Attempt to route an exact amount is also fine
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 290_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 3);
let mut total_amount_paid_msat = 0;
{
// Attempt to route more than available results in a failure.
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3],
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3],
Some(InvoiceFeatures::known()), None, &Vec::new(), 350_000, 42, Arc::clone(&logger)) {
assert_eq!(err, "Failed to find a sufficient route to the given destination");
} else { panic!(); }
{
// Now, attempt to route 300 sats (exact amount we can route).
// Our algorithm should provide us with these 3 paths, 100 sats each.
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3],
Some(InvoiceFeatures::known()), None, &Vec::new(), 300_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 3);
{
// Now, attempt to route 180 sats.
// Our algorithm should provide us with these 2 paths.
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3],
Some(InvoiceFeatures::known()), None, &Vec::new(), 180_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 2);
{
// Attempt to route more than available results in a failure.
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3],
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3],
Some(InvoiceFeatures::known()), None, &Vec::new(), 210_000, 42, Arc::clone(&logger)) {
assert_eq!(err, "Failed to find a sufficient route to the given destination");
} else { panic!(); }
{
// Now, attempt to route 200 sats (exact amount we can route).
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[3],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[3],
Some(InvoiceFeatures::known()), None, &Vec::new(), 200_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 2);
{
// Attempt to route more than available results in a failure.
- if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ if let Err(LightningError{err, action: ErrorAction::IgnoreError}) = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 150_000, 42, Arc::clone(&logger)) {
assert_eq!(err, "Failed to find a sufficient route to the given destination");
} else { panic!(); }
{
// Now, attempt to route 125 sats (just a bit below the capacity of 3 channels).
// Our algorithm should provide us with these 3 paths.
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 125_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 3);
let mut total_amount_paid_msat = 0;
{
// Attempt to route without the last small cheap channel
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2],
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2],
Some(InvoiceFeatures::known()), None, &Vec::new(), 90_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 2);
let mut total_amount_paid_msat = 0;
// "previous hop" being set to node 3, creating a loop in the path.
let secp_ctx = Secp256k1::new();
let logger = Arc::new(test_utils::TestLogger::new());
- let net_graph_msg_handler = NetGraphMsgHandler::new(genesis_block(Network::Testnet).header.block_hash(), None, Arc::clone(&logger));
+ let network_graph = NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash());
+ let net_graph_msg_handler = NetGraphMsgHandler::new(network_graph, None, Arc::clone(&logger));
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
add_channel(&net_graph_msg_handler, &secp_ctx, &our_privkey, &privkeys[1], ChannelFeatures::from_le_bytes(id_to_feature_flags(6)), 6);
{
// Now ensure the route flows simply over nodes 1 and 4 to 6.
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[6], None, None, &Vec::new(), 10_000, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[6], None, None, &Vec::new(), 10_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 1);
assert_eq!(route.paths[0].len(), 3);
{
// Now, attempt to route 90 sats, which is exactly 90 sats at the last hop, plus the
// 200% fee charged channel 13 in the 1-to-2 direction.
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, None, &Vec::new(), 90_000, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], None, None, &Vec::new(), 90_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 1);
assert_eq!(route.paths[0].len(), 2);
// Now, attempt to route 90 sats, hitting the htlc_minimum on channel 4, but
// overshooting the htlc_maximum on channel 2. Thus, we should pick the (absurdly
// expensive) channels 12-13 path.
- let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 90_000, 42, Arc::clone(&logger)).unwrap();
+ let route = get_route(&our_id, &net_graph_msg_handler.network_graph, &nodes[2], Some(InvoiceFeatures::known()), None, &Vec::new(), 90_000, 42, Arc::clone(&logger)).unwrap();
assert_eq!(route.paths.len(), 1);
assert_eq!(route.paths[0].len(), 2);
// First, get 100 (source, destination) pairs for which route-getting actually succeeds...
let mut seed = random_init_seed() as usize;
+ let nodes = graph.read_only().nodes().clone();
'load_endpoints: for _ in 0..10 {
loop {
seed = seed.overflowing_mul(0xdeadbeef).0;
- let src = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap();
+ let src = nodes.keys().skip(seed % nodes.len()).next().unwrap();
seed = seed.overflowing_mul(0xdeadbeef).0;
- let dst = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap();
+ let dst = nodes.keys().skip(seed % nodes.len()).next().unwrap();
let amt = seed as u64 % 200_000_000;
if get_route(src, &graph, dst, None, None, &[], amt, 42, &test_utils::TestLogger::new()).is_ok() {
continue 'load_endpoints;
// First, get 100 (source, destination) pairs for which route-getting actually succeeds...
let mut seed = random_init_seed() as usize;
+ let nodes = graph.read_only().nodes().clone();
'load_endpoints: for _ in 0..10 {
loop {
seed = seed.overflowing_mul(0xdeadbeef).0;
- let src = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap();
+ let src = nodes.keys().skip(seed % nodes.len()).next().unwrap();
seed = seed.overflowing_mul(0xdeadbeef).0;
- let dst = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap();
+ let dst = nodes.keys().skip(seed % nodes.len()).next().unwrap();
let amt = seed as u64 % 200_000_000;
if get_route(src, &graph, dst, Some(InvoiceFeatures::known()), None, &[], amt, 42, &test_utils::TestLogger::new()).is_ok() {
continue 'load_endpoints;
fn generate_routes(bench: &mut Bencher) {
let mut d = test_utils::get_route_file().unwrap();
let graph = NetworkGraph::read(&mut d).unwrap();
+ let nodes = graph.read_only().nodes().clone();
// First, get 100 (source, destination) pairs for which route-getting actually succeeds...
let mut path_endpoints = Vec::new();
'load_endpoints: for _ in 0..100 {
loop {
seed *= 0xdeadbeef;
- let src = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap();
+ let src = nodes.keys().skip(seed % nodes.len()).next().unwrap();
seed *= 0xdeadbeef;
- let dst = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap();
+ let dst = nodes.keys().skip(seed % nodes.len()).next().unwrap();
let amt = seed as u64 % 1_000_000;
if get_route(src, &graph, dst, None, None, &[], amt, 42, &DummyLogger{}).is_ok() {
path_endpoints.push((src, dst, amt));
fn generate_mpp_routes(bench: &mut Bencher) {
let mut d = test_utils::get_route_file().unwrap();
let graph = NetworkGraph::read(&mut d).unwrap();
+ let nodes = graph.read_only().nodes().clone();
// First, get 100 (source, destination) pairs for which route-getting actually succeeds...
let mut path_endpoints = Vec::new();
'load_endpoints: for _ in 0..100 {
loop {
seed *= 0xdeadbeef;
- let src = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap();
+ let src = nodes.keys().skip(seed % nodes.len()).next().unwrap();
seed *= 0xdeadbeef;
- let dst = graph.get_nodes().keys().skip(seed % graph.get_nodes().len()).next().unwrap();
+ let dst = nodes.keys().skip(seed % nodes.len()).next().unwrap();
let amt = seed as u64 % 1_000_000;
if get_route(src, &graph, dst, Some(InvoiceFeatures::known()), None, &[], amt, 42, &DummyLogger{}).is_ok() {
path_endpoints.push((src, dst, amt));
//! future, as well as generate and broadcast funding transactions handle payment preimages and a
//! few other things.
+use chain::keysinterface::SpendableOutputDescriptor;
use ln::msgs;
use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
-use chain::keysinterface::SpendableOutputDescriptor;
+use routing::network_graph::NetworkUpdate;
use util::ser::{Writeable, Writer, MaybeReadable, Readable, VecReadWrapper, VecWriteWrapper};
use bitcoin::blockdata::script::Script;
/// the payment has failed, not just the route in question. If this is not set, you may
/// retry the payment via a different route.
rejected_by_dest: bool,
+ /// Any failure information conveyed via the Onion return packet by a node along the failed
+ /// payment route.
+ ///
+ /// Should be applied to the [`NetworkGraph`] so that routing decisions can take into
+ /// account the update. [`NetGraphMsgHandler`] is capable of doing this.
+ ///
+ /// [`NetworkGraph`]: crate::routing::network_graph::NetworkGraph
+ /// [`NetGraphMsgHandler`]: crate::routing::network_graph::NetGraphMsgHandler
+ network_update: Option<NetworkUpdate>,
#[cfg(test)]
error_code: Option<u16>,
#[cfg(test)]
(0, payment_preimage, required),
});
},
- &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest,
+ &Event::PaymentFailed { ref payment_hash, ref rejected_by_dest, ref network_update,
#[cfg(test)]
ref error_code,
#[cfg(test)]
error_data.write(writer)?;
write_tlv_fields!(writer, {
(0, payment_hash, required),
+ (1, network_update, option),
(2, rejected_by_dest, required),
});
},
let error_data = Readable::read(reader)?;
let mut payment_hash = PaymentHash([0; 32]);
let mut rejected_by_dest = false;
+ let mut network_update = None;
read_tlv_fields!(reader, {
(0, payment_hash, required),
+ (1, network_update, ignorable),
(2, rejected_by_dest, required),
});
Ok(Some(Event::PaymentFailed {
payment_hash,
rejected_by_dest,
+ network_update,
#[cfg(test)]
error_code,
#[cfg(test)]
/// The action which should be taken.
action: msgs::ErrorAction
},
- /// When a payment fails we may receive updates back from the hop where it failed. In such
- /// cases this event is generated so that we can inform the network graph of this information.
- PaymentFailureNetworkUpdate {
- /// The channel/node update which should be sent to NetGraphMsgHandler
- update: msgs::HTLCFailChannelUpdate,
- },
/// Query a peer for channels with funding transaction UTXOs in a block range.
SendChannelRangeQuery {
/// The node_id of this message recipient
/// Handles the given [`Event`].
///
/// See [`EventsProvider`] for details that must be considered when implementing this method.
- fn handle_event(&self, event: Event);
+ fn handle_event(&self, event: &Event);
}
-impl<F> EventHandler for F where F: Fn(Event) {
- fn handle_event(&self, event: Event) {
+impl<F> EventHandler for F where F: Fn(&Event) {
+ fn handle_event(&self, event: &Event) {
self(event)
}
}
self.chan_upds_recvd.fetch_add(1, Ordering::AcqRel);
Err(msgs::LightningError { err: "".to_owned(), action: msgs::ErrorAction::IgnoreError })
}
- fn handle_htlc_fail_channel_update(&self, _update: &msgs::HTLCFailChannelUpdate) {}
fn get_next_channel_announcements(&self, starting_point: u64, batch_amount: u8) -> Vec<(msgs::ChannelAnnouncement, Option<msgs::ChannelUpdate>, Option<msgs::ChannelUpdate>)> {
let mut chan_anns = Vec::new();
const TOTAL_UPDS: u64 = 100;