Expose `skimmed_fee_msat` in `PaymentForwarded`
[rust-lightning] / lightning / src / ln / functional_test_utils.rs
index 5a1a21e2999863b9f6af7b75da6c467b4228e7f3..e53fd6b0c1e61908ab7c8f758c34555852fe6ac6 100644 (file)
 //! nodes for functional tests.
 
 use crate::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen, Watch, chainmonitor::Persist};
-use crate::sign::EntropySource;
 use crate::chain::channelmonitor::ChannelMonitor;
 use crate::chain::transaction::OutPoint;
 use crate::events::{ClaimedHTLC, ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose, PaymentFailureReason};
-use crate::events::bump_transaction::{BumpTransactionEventHandler, Wallet, WalletSource};
+use crate::events::bump_transaction::{BumpTransactionEvent, BumpTransactionEventHandler, Wallet, WalletSource};
 use crate::ln::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret};
 use crate::ln::channelmanager::{AChannelManager, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, RecipientOnionFields, PaymentId, MIN_CLTV_EXPIRY_DELTA};
-use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
-use crate::routing::router::{self, PaymentParameters, Route, RouteParameters};
 use crate::ln::features::InitFeatures;
 use crate::ln::msgs;
-use crate::ln::msgs::{ChannelMessageHandler,RoutingMessageHandler};
-use crate::util::test_channel_signer::TestChannelSigner;
+use crate::ln::msgs::{ChannelMessageHandler, OnionMessageHandler, RoutingMessageHandler};
+use crate::ln::peer_handler::IgnoringMessageHandler;
+use crate::onion_message::messenger::OnionMessenger;
+use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
+use crate::routing::router::{self, PaymentParameters, Route, RouteParameters};
+use crate::sign::{EntropySource, RandomBytes};
+use crate::util::config::{UserConfig, MaxDustHTLCExposure};
+use crate::util::errors::APIError;
+#[cfg(test)]
+use crate::util::logger::Logger;
 use crate::util::scid_utils;
+use crate::util::test_channel_signer::TestChannelSigner;
 use crate::util::test_utils;
 use crate::util::test_utils::{panicking, TestChainMonitor, TestScorer, TestKeysInterface};
-use crate::util::errors::APIError;
-use crate::util::config::{UserConfig, MaxDustHTLCExposure};
 use crate::util::ser::{ReadableArgs, Writeable};
 
-use bitcoin::blockdata::block::{Block, BlockHeader};
-use bitcoin::blockdata::transaction::{Transaction, TxOut};
-use bitcoin::hash_types::BlockHash;
+use bitcoin::blockdata::block::{Block, Header, Version};
+use bitcoin::blockdata::locktime::absolute::LockTime;
+use bitcoin::blockdata::transaction::{Transaction, TxIn, TxOut};
+use bitcoin::hash_types::{BlockHash, TxMerkleNode};
 use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::hashes::Hash as _;
 use bitcoin::network::constants::Network;
+use bitcoin::pow::CompactTarget;
 use bitcoin::secp256k1::{PublicKey, SecretKey};
 
+use alloc::rc::Rc;
+use core::cell::RefCell;
+use core::iter::repeat;
+use core::mem;
+use core::ops::Deref;
 use crate::io;
 use crate::prelude::*;
-use core::cell::RefCell;
-use alloc::rc::Rc;
 use crate::sync::{Arc, Mutex, LockTestExt, RwLock};
-use core::mem;
-use core::iter::repeat;
-use bitcoin::{PackedLockTime, TxIn, TxMerkleNode};
 
 pub const CHAN_CONFIRM_DEPTH: u32 = 10;
 
@@ -78,11 +84,18 @@ pub fn mine_transactions<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, txn: &[&Tra
 pub fn mine_transaction_without_consistency_checks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction) {
        let height = node.best_block_info().1 + 1;
        let mut block = Block {
-               header: BlockHeader { version: 0x20000000, prev_blockhash: node.best_block_hash(), merkle_root: TxMerkleNode::all_zeros(), time: height, bits: 42, nonce: 42 },
+               header: Header {
+                       version: Version::NO_SOFT_FORK_SIGNALLING,
+                       prev_blockhash: node.best_block_hash(),
+                       merkle_root: TxMerkleNode::all_zeros(),
+                       time: height,
+                       bits: CompactTarget::from_consensus(42),
+                       nonce: 42,
+               },
                txdata: Vec::new(),
        };
        for _ in 0..*node.network_chan_count.borrow() { // Make sure we don't end up with channels at the same short id by offsetting by chan_count
-               block.txdata.push(Transaction { version: 0, lock_time: PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() });
+               block.txdata.push(Transaction { version: 0, lock_time: LockTime::ZERO, input: Vec::new(), output: Vec::new() });
        }
        block.txdata.push((*tx).clone());
        do_connect_block_without_consistency_checks(node, block, false);
@@ -100,7 +113,7 @@ pub fn confirm_transactions_at<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, txn:
        }
        let mut txdata = Vec::new();
        for _ in 0..*node.network_chan_count.borrow() { // Make sure we don't end up with channels at the same short id by offsetting by chan_count
-               txdata.push(Transaction { version: 0, lock_time: PackedLockTime::ZERO, input: Vec::new(), output: Vec::new() });
+               txdata.push(Transaction { version: 0, lock_time: LockTime::ZERO, input: Vec::new(), output: Vec::new() });
        }
        for tx in txn {
                txdata.push((*tx).clone());
@@ -202,13 +215,13 @@ impl ConnectStyle {
        }
 }
 
-pub fn create_dummy_header(prev_blockhash: BlockHash, time: u32) -> BlockHeader {
-       BlockHeader {
-               version: 0x2000_0000,
+pub fn create_dummy_header(prev_blockhash: BlockHash, time: u32) -> Header {
+       Header {
+               version: Version::NO_SOFT_FORK_SIGNALLING,
                prev_blockhash,
                merkle_root: TxMerkleNode::all_zeros(),
                time,
-               bits: 42,
+               bits: CompactTarget::from_consensus(42),
                nonce: 42,
        }
 }
@@ -239,7 +252,7 @@ pub fn connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block)
 
 fn call_claimable_balances<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>) {
        // Ensure `get_claimable_balances`' self-tests never panic
-       for funding_outpoint in node.chain_monitor.chain_monitor.list_monitors() {
+       for (funding_outpoint, _channel_id) in node.chain_monitor.chain_monitor.list_monitors() {
                node.chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances();
        }
 }
@@ -378,6 +391,7 @@ pub struct NodeCfg<'a> {
        pub tx_broadcaster: &'a test_utils::TestBroadcaster,
        pub fee_estimator: &'a test_utils::TestFeeEstimator,
        pub router: test_utils::TestRouter<'a>,
+       pub message_router: test_utils::TestMessageRouter<'a>,
        pub chain_monitor: test_utils::TestChainMonitor<'a>,
        pub keys_manager: &'a test_utils::TestKeysInterface,
        pub logger: &'a test_utils::TestLogger,
@@ -397,6 +411,26 @@ type TestChannelManager<'node_cfg, 'chan_mon_cfg> = ChannelManager<
        &'chan_mon_cfg test_utils::TestLogger,
 >;
 
+type TestOnionMessenger<'chan_man, 'node_cfg, 'chan_mon_cfg> = OnionMessenger<
+       DedicatedEntropy,
+       &'node_cfg test_utils::TestKeysInterface,
+       &'chan_mon_cfg test_utils::TestLogger,
+       &'node_cfg test_utils::TestMessageRouter<'chan_mon_cfg>,
+       &'chan_man TestChannelManager<'node_cfg, 'chan_mon_cfg>,
+       IgnoringMessageHandler,
+>;
+
+/// For use with [`OnionMessenger`] otherwise `test_restored_packages_retry` will fail. This is
+/// because that test uses older serialized data produced by calling [`EntropySource`] in a specific
+/// manner. Using the same [`EntropySource`] with [`OnionMessenger`] would introduce another call,
+/// causing the produced data to no longer match.
+pub struct DedicatedEntropy(RandomBytes);
+
+impl Deref for DedicatedEntropy {
+       type Target = RandomBytes;
+       fn deref(&self) -> &Self::Target { &self.0 }
+}
+
 pub struct Node<'chan_man, 'node_cfg: 'chan_man, 'chan_mon_cfg: 'node_cfg> {
        pub chain_source: &'chan_mon_cfg test_utils::TestChainSource,
        pub tx_broadcaster: &'chan_mon_cfg test_utils::TestBroadcaster,
@@ -405,6 +439,7 @@ pub struct Node<'chan_man, 'node_cfg: 'chan_man, 'chan_mon_cfg: 'node_cfg> {
        pub chain_monitor: &'node_cfg test_utils::TestChainMonitor<'chan_mon_cfg>,
        pub keys_manager: &'chan_mon_cfg test_utils::TestKeysInterface,
        pub node: &'chan_man TestChannelManager<'node_cfg, 'chan_mon_cfg>,
+       pub onion_messenger: TestOnionMessenger<'chan_man, 'node_cfg, 'chan_mon_cfg>,
        pub network_graph: &'node_cfg NetworkGraph<&'chan_mon_cfg test_utils::TestLogger>,
        pub gossip_sync: P2PGossipSync<&'node_cfg NetworkGraph<&'chan_mon_cfg test_utils::TestLogger>, &'chan_mon_cfg test_utils::TestChainSource, &'chan_mon_cfg test_utils::TestLogger>,
        pub node_seed: [u8; 32],
@@ -422,6 +457,14 @@ pub struct Node<'chan_man, 'node_cfg: 'chan_man, 'chan_mon_cfg: 'node_cfg> {
                &'chan_mon_cfg test_utils::TestLogger,
        >,
 }
+
+impl<'a, 'b, 'c> Node<'a, 'b, 'c> {
+       pub fn init_features(&self, peer_node_id: &PublicKey) -> InitFeatures {
+               self.override_init_features.borrow().clone()
+                       .unwrap_or_else(|| self.node.init_features() | self.onion_messenger.provided_init_features(peer_node_id))
+       }
+}
+
 #[cfg(feature = "std")]
 impl<'a, 'b, 'c> std::panic::UnwindSafe for Node<'a, 'b, 'c> {}
 #[cfg(feature = "std")]
@@ -433,9 +476,28 @@ impl<'a, 'b, 'c> Node<'a, 'b, 'c> {
        pub fn best_block_info(&self) -> (BlockHash, u32) {
                self.blocks.lock().unwrap().last().map(|(a, b)| (a.block_hash(), *b)).unwrap()
        }
-       pub fn get_block_header(&self, height: u32) -> BlockHeader {
+       pub fn get_block_header(&self, height: u32) -> Header {
                self.blocks.lock().unwrap()[height as usize].0.header
        }
+       /// Changes the channel signer's availability for the specified peer and channel.
+       ///
+       /// When `available` is set to `true`, the channel signer will behave normally. When set to
+       /// `false`, the channel signer will act like an off-line remote signer and will return `Err` for
+       /// several of the signing methods. Currently, only `get_per_commitment_point` and
+       /// `release_commitment_secret` are affected by this setting.
+       #[cfg(test)]
+       pub fn set_channel_signer_available(&self, peer_id: &PublicKey, chan_id: &ChannelId, available: bool) {
+               let per_peer_state = self.node.per_peer_state.read().unwrap();
+               let chan_lock = per_peer_state.get(peer_id).unwrap().lock().unwrap();
+               let signer = (|| {
+                       match chan_lock.channel_by_id.get(chan_id) {
+                               Some(phase) => phase.context().get_signer(),
+                               None => panic!("Couldn't find a channel with id {}", chan_id),
+                       }
+               })();
+               log_debug!(self.logger, "Setting channel signer for {} as available={}", chan_id, available);
+               signer.as_ecdsa().unwrap().set_available(available);
+       }
 }
 
 /// If we need an unsafe pointer to a `Node` (ie to reference it in a thread
@@ -539,7 +601,7 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
                        let feeest = test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) };
                        let mut deserialized_monitors = Vec::new();
                        {
-                               for outpoint in self.chain_monitor.chain_monitor.list_monitors() {
+                               for (outpoint, _channel_id) in self.chain_monitor.chain_monitor.list_monitors() {
                                        let mut w = test_utils::TestVecWriter(Vec::new());
                                        self.chain_monitor.chain_monitor.get_monitor(outpoint).unwrap().write(&mut w).unwrap();
                                        let (_, deserialized_monitor) = <(BlockHash, ChannelMonitor<TestChannelSigner>)>::read(
@@ -570,7 +632,7 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
                                        node_signer: self.keys_manager,
                                        signer_provider: self.keys_manager,
                                        fee_estimator: &test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) },
-                                       router: &test_utils::TestRouter::new(Arc::new(network_graph), &scorer),
+                                       router: &test_utils::TestRouter::new(Arc::new(network_graph), &self.logger, &scorer),
                                        chain_monitor: self.chain_monitor,
                                        tx_broadcaster: &broadcaster,
                                        logger: &self.logger,
@@ -582,7 +644,8 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
                        let chain_source = test_utils::TestChainSource::new(Network::Testnet);
                        let chain_monitor = test_utils::TestChainMonitor::new(Some(&chain_source), &broadcaster, &self.logger, &feeest, &persister, &self.keys_manager);
                        for deserialized_monitor in deserialized_monitors.drain(..) {
-                               if chain_monitor.watch_channel(deserialized_monitor.get_funding_txo().0, deserialized_monitor) != Ok(ChannelMonitorUpdateStatus::Completed) {
+                               let funding_outpoint = deserialized_monitor.get_funding_txo().0;
+                               if chain_monitor.watch_channel(funding_outpoint, deserialized_monitor) != Ok(ChannelMonitorUpdateStatus::Completed) {
                                        panic!();
                                }
                        }
@@ -665,6 +728,12 @@ pub fn get_err_msg(node: &Node, recipient: &PublicKey) -> msgs::ErrorMessage {
                        assert_eq!(node_id, recipient);
                        (*msg).clone()
                },
+               MessageSendEvent::HandleError {
+                       action: msgs::ErrorAction::DisconnectPeer { ref msg }, ref node_id
+               } => {
+                       assert_eq!(node_id, recipient);
+                       msg.as_ref().unwrap().clone()
+               },
                _ => panic!("Unexpected event"),
        }
 }
@@ -787,6 +856,18 @@ pub fn remove_first_msg_event_to_node(msg_node_id: &PublicKey, msg_events: &mut
                MessageSendEvent::SendOpenChannelV2 { node_id, .. } => {
                        node_id == msg_node_id
                },
+               MessageSendEvent::SendStfu { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendSplice { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendSpliceAck { node_id, .. } => {
+                       node_id == msg_node_id
+               },
+               MessageSendEvent::SendSpliceLocked { node_id, .. } => {
+                       node_id == msg_node_id
+               },
                MessageSendEvent::SendTxAddInput { node_id, .. } => {
                        node_id == msg_node_id
                },
@@ -909,7 +990,14 @@ macro_rules! unwrap_send_err {
                                        _ => panic!(),
                                }
                        },
-                       _ => panic!(),
+                       &Err(PaymentSendFailure::PathParameterError(ref result)) if !$all_failed => {
+                               assert_eq!(result.len(), 1);
+                               match result[0] {
+                                       Err($type) => { $check },
+                                       _ => panic!(),
+                               }
+                       },
+                       _ => {panic!()},
                }
        }
 }
@@ -918,7 +1006,8 @@ macro_rules! unwrap_send_err {
 pub fn check_added_monitors<CM: AChannelManager, H: NodeHolder<CM=CM>>(node: &H, count: usize) {
        if let Some(chain_monitor) = node.chain_monitor() {
                let mut added_monitors = chain_monitor.added_monitors.lock().unwrap();
-               assert_eq!(added_monitors.len(), count);
+               let n = added_monitors.len();
+               assert_eq!(n, count, "expected {} monitors to be added, not {}", count, n);
                added_monitors.clear();
        }
 }
@@ -980,7 +1069,8 @@ pub fn _reload_node<'a, 'b, 'c>(node: &'a Node<'a, 'b, 'c>, default_config: User
        assert!(node_read.is_empty());
 
        for monitor in monitors_read.drain(..) {
-               assert_eq!(node.chain_monitor.watch_channel(monitor.get_funding_txo().0, monitor),
+               let funding_outpoint = monitor.get_funding_txo().0;
+               assert_eq!(node.chain_monitor.watch_channel(funding_outpoint, monitor),
                        Ok(ChannelMonitorUpdateStatus::Completed));
                check_added_monitors!(node, 1);
        }
@@ -999,6 +1089,7 @@ macro_rules! reload_node {
 
                $new_channelmanager = _reload_node(&$node, $new_config, &chanman_encoded, $monitors_encoded);
                $node.node = &$new_channelmanager;
+               $node.onion_messenger.set_offers_handler(&$new_channelmanager);
        };
        ($node: expr, $chanman_encoded: expr, $monitors_encoded: expr, $persister: ident, $new_chain_monitor: ident, $new_channelmanager: ident) => {
                reload_node!($node, $crate::util::config::UserConfig::default(), $chanman_encoded, $monitors_encoded, $persister, $new_chain_monitor, $new_channelmanager);
@@ -1041,7 +1132,7 @@ fn internal_create_funding_transaction<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>,
                                Vec::new()
                        };
 
-                       let tx = Transaction { version: chan_id as i32, lock_time: PackedLockTime::ZERO, input, output: vec![TxOut {
+                       let tx = Transaction { version: chan_id as i32, lock_time: LockTime::ZERO, input, output: vec![TxOut {
                                value: *channel_value_satoshis, script_pubkey: output_script.clone(),
                        }]};
                        let funding_outpoint = OutPoint { txid: tx.txid(), index: 0 };
@@ -1098,7 +1189,7 @@ pub fn open_zero_conf_channel<'a, 'b, 'c, 'd>(initiator: &'a Node<'b, 'c, 'd>, r
        let initiator_channels = initiator.node.list_usable_channels().len();
        let receiver_channels = receiver.node.list_usable_channels().len();
 
-       initiator.node.create_channel(receiver.node.get_our_node_id(), 100_000, 10_001, 42, initiator_config).unwrap();
+       initiator.node.create_channel(receiver.node.get_our_node_id(), 100_000, 10_001, 42, None, initiator_config).unwrap();
        let open_channel = get_event_msg!(initiator, MessageSendEvent::SendOpenChannel, receiver.node.get_our_node_id());
 
        receiver.node.handle_open_channel(&initiator.node.get_our_node_id(), &open_channel);
@@ -1163,8 +1254,8 @@ pub fn open_zero_conf_channel<'a, 'b, 'c, 'd>(initiator: &'a Node<'b, 'c, 'd>, r
        (tx, as_channel_ready.channel_id)
 }
 
-pub fn create_chan_between_nodes_with_value_init<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, channel_value: u64, push_msat: u64) -> Transaction {
-       let create_chan_id = node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42, None).unwrap();
+pub fn exchange_open_accept_chan<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, channel_value: u64, push_msat: u64) -> ChannelId {
+       let create_chan_id = node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42, None, None).unwrap();
        let open_channel_msg = get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id());
        assert_eq!(open_channel_msg.temporary_channel_id, create_chan_id);
        assert_eq!(node_a.node.list_channels().iter().find(|channel| channel.channel_id == create_chan_id).unwrap().user_channel_id, 42);
@@ -1183,6 +1274,11 @@ pub fn create_chan_between_nodes_with_value_init<'a, 'b, 'c>(node_a: &Node<'a, '
        node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), &accept_channel_msg);
        assert_ne!(node_b.node.list_channels().iter().find(|channel| channel.channel_id == create_chan_id).unwrap().user_channel_id, 0);
 
+       create_chan_id
+}
+
+pub fn create_chan_between_nodes_with_value_init<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, channel_value: u64, push_msat: u64) -> Transaction {
+       let create_chan_id = exchange_open_accept_chan(node_a, node_b, channel_value, push_msat);
        sign_funding_transaction(node_a, node_b, channel_value, create_chan_id)
 }
 
@@ -1281,7 +1377,7 @@ pub fn create_announced_chan_between_nodes_with_value<'a, 'b, 'c: 'd, 'd>(nodes:
 pub fn create_unannounced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: &'a Vec<Node<'b, 'c, 'd>>, a: usize, b: usize, channel_value: u64, push_msat: u64) -> (msgs::ChannelReady, Transaction) {
        let mut no_announce_cfg = test_default_channel_config();
        no_announce_cfg.channel_handshake_config.announced_channel = false;
-       nodes[a].node.create_channel(nodes[b].node.get_our_node_id(), channel_value, push_msat, 42, Some(no_announce_cfg)).unwrap();
+       nodes[a].node.create_channel(nodes[b].node.get_our_node_id(), channel_value, push_msat, 42, None, Some(no_announce_cfg)).unwrap();
        let open_channel = get_event_msg!(nodes[a], MessageSendEvent::SendOpenChannel, nodes[b].node.get_our_node_id());
        nodes[b].node.handle_open_channel(&nodes[a].node.get_our_node_id(), &open_channel);
        let accept_channel = get_event_msg!(nodes[b], MessageSendEvent::SendAcceptChannel, nodes[a].node.get_our_node_id());
@@ -1367,7 +1463,7 @@ pub fn do_check_spends<F: Fn(&bitcoin::blockdata::transaction::OutPoint) -> Opti
        for output in tx.output.iter() {
                total_value_out += output.value;
        }
-       let min_fee = (tx.weight() as u64 + 3) / 4; // One sat per vbyte (ie per weight/4, rounded up)
+       let min_fee = (tx.weight().to_wu() as u64 + 3) / 4; // One sat per vbyte (ie per weight/4, rounded up)
        // Input amount - output amount = fee, so check that out + min_fee is smaller than input
        assert!(total_value_out + min_fee <= total_value_in);
        tx.verify(get_output).unwrap();
@@ -1446,10 +1542,15 @@ pub fn check_closed_broadcast(node: &Node, num_channels: usize, with_error_msg:
                                assert_eq!(msg.contents.flags & 2, 2);
                                None
                        },
-                       MessageSendEvent::HandleError { action: msgs::ErrorAction::SendErrorMessage { ref msg }, node_id: _ } => {
+                       MessageSendEvent::HandleError { action: msgs::ErrorAction::SendErrorMessage { msg }, node_id: _ } => {
                                assert!(with_error_msg);
                                // TODO: Check node_id
-                               Some(msg.clone())
+                               Some(msg)
+                       },
+                       MessageSendEvent::HandleError { action: msgs::ErrorAction::DisconnectPeer { msg }, node_id: _ } => {
+                               assert!(with_error_msg);
+                               // TODO: Check node_id
+                               Some(msg.unwrap())
                        },
                        _ => panic!("Unexpected event"),
                }
@@ -1467,27 +1568,87 @@ macro_rules! check_closed_broadcast {
        }
 }
 
+#[derive(Default)]
+pub struct ExpectedCloseEvent {
+       pub channel_capacity_sats: Option<u64>,
+       pub channel_id: Option<ChannelId>,
+       pub counterparty_node_id: Option<PublicKey>,
+       pub discard_funding: bool,
+       pub reason: Option<ClosureReason>,
+       pub channel_funding_txo: Option<OutPoint>,
+       pub user_channel_id: Option<u128>,
+}
+
+impl ExpectedCloseEvent {
+       pub fn from_id_reason(channel_id: ChannelId, discard_funding: bool, reason: ClosureReason) -> Self {
+               Self {
+                       channel_capacity_sats: None,
+                       channel_id: Some(channel_id),
+                       counterparty_node_id: None,
+                       discard_funding,
+                       reason: Some(reason),
+                       channel_funding_txo: None,
+                       user_channel_id: None,
+               }
+       }
+}
+
+/// Check that multiple channel closing events have been issued.
+pub fn check_closed_events(node: &Node, expected_close_events: &[ExpectedCloseEvent]) {
+       let closed_events_count = expected_close_events.len();
+       let discard_events_count = expected_close_events.iter().filter(|e| e.discard_funding).count();
+       let events = node.node.get_and_clear_pending_events();
+       assert_eq!(events.len(), closed_events_count + discard_events_count, "{:?}", events);
+       for expected_event in expected_close_events {
+               assert!(events.iter().any(|e| matches!(
+                       e,
+                       Event::ChannelClosed {
+                               channel_id,
+                               reason,
+                               counterparty_node_id,
+                               channel_capacity_sats,
+                               channel_funding_txo,
+                               user_channel_id,
+                               ..
+                       } if (
+                               expected_event.channel_id.map(|expected| *channel_id == expected).unwrap_or(true) &&
+                               expected_event.reason.as_ref().map(|expected| reason == expected).unwrap_or(true) &&
+                               expected_event.
+                                       counterparty_node_id.map(|expected| *counterparty_node_id == Some(expected)).unwrap_or(true) &&
+                               expected_event.channel_capacity_sats
+                                       .map(|expected| *channel_capacity_sats == Some(expected)).unwrap_or(true) &&
+                               expected_event.channel_funding_txo
+                                       .map(|expected| *channel_funding_txo == Some(expected)).unwrap_or(true) &&
+                               expected_event.user_channel_id
+                                       .map(|expected| *user_channel_id == expected).unwrap_or(true)
+                       )
+               )));
+       }
+       assert_eq!(events.iter().filter(|e| matches!(
+               e,
+               Event::DiscardFunding { .. },
+       )).count(), discard_events_count);
+}
+
 /// Check that a channel's closing channel events has been issued
 pub fn check_closed_event(node: &Node, events_count: usize, expected_reason: ClosureReason, is_check_discard_funding: bool,
        expected_counterparty_node_ids: &[PublicKey], expected_channel_capacity: u64) {
-       let events = node.node.get_and_clear_pending_events();
-       assert_eq!(events.len(), events_count, "{:?}", events);
-       let mut issues_discard_funding = false;
-       for (idx, event) in events.into_iter().enumerate() {
-               match event {
-                       Event::ChannelClosed { ref reason, counterparty_node_id, 
-                               channel_capacity_sats, .. } => {
-                               assert_eq!(*reason, expected_reason);
-                               assert_eq!(counterparty_node_id.unwrap(), expected_counterparty_node_ids[idx]);
-                               assert_eq!(channel_capacity_sats.unwrap(), expected_channel_capacity);
-                       },
-                       Event::DiscardFunding { .. } => {
-                               issues_discard_funding = true;
-                       }
-                       _ => panic!("Unexpected event"),
-               }
-       }
-       assert_eq!(is_check_discard_funding, issues_discard_funding);
+       let expected_events_count = if is_check_discard_funding {
+               2 * expected_counterparty_node_ids.len()
+       } else {
+               expected_counterparty_node_ids.len()
+       };
+       assert_eq!(events_count, expected_events_count);
+       let expected_close_events = expected_counterparty_node_ids.iter().map(|node_id| ExpectedCloseEvent {
+               channel_capacity_sats: Some(expected_channel_capacity),
+               channel_id: None,
+               counterparty_node_id: Some(*node_id),
+               discard_funding: is_check_discard_funding,
+               reason: Some(expected_reason.clone()),
+               channel_funding_txo: None,
+               user_channel_id: None,
+       }).collect::<Vec<_>>();
+       check_closed_events(node, expected_close_events.as_slice());
 }
 
 /// Check that a channel's closing channel events has been issued
@@ -1499,11 +1660,26 @@ macro_rules! check_closed_event {
                check_closed_event!($node, $events, $reason, false, $counterparty_node_ids, $channel_capacity);
        };
        ($node: expr, $events: expr, $reason: expr, $is_check_discard_funding: expr, $counterparty_node_ids: expr, $channel_capacity: expr) => {
-               $crate::ln::functional_test_utils::check_closed_event(&$node, $events, $reason, 
+               $crate::ln::functional_test_utils::check_closed_event(&$node, $events, $reason,
                        $is_check_discard_funding, &$counterparty_node_ids, $channel_capacity);
        }
 }
 
+pub fn handle_bump_htlc_event(node: &Node, count: usize) {
+       let events = node.chain_monitor.chain_monitor.get_and_clear_pending_events();
+       assert_eq!(events.len(), count);
+       for event in events {
+               match event {
+                       Event::BumpTransaction(bump_event) => {
+                               if let BumpTransactionEvent::HTLCResolution { .. } = &bump_event {}
+                               else { panic!(); }
+                               node.bump_tx_handler.handle_event(&bump_event);
+                       },
+                       _ => panic!(),
+               }
+       }
+}
+
 pub fn close_channel<'a, 'b, 'c>(outbound_node: &Node<'a, 'b, 'c>, inbound_node: &Node<'a, 'b, 'c>, channel_id: &ChannelId, funding_tx: Transaction, close_inbound_first: bool) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, Transaction) {
        let (node_a, broadcaster_a, struct_a) = if close_inbound_first { (&inbound_node.node, &inbound_node.tx_broadcaster, inbound_node) } else { (&outbound_node.node, &outbound_node.tx_broadcaster, outbound_node) };
        let (node_b, broadcaster_b, struct_b) = if close_inbound_first { (&outbound_node.node, &outbound_node.tx_broadcaster, outbound_node) } else { (&inbound_node.node, &inbound_node.tx_broadcaster, inbound_node) };
@@ -1829,7 +2005,7 @@ pub fn get_payment_preimage_hash(recipient: &Node, min_value_msat: Option<u64>,
        let mut payment_count = recipient.network_payment_count.borrow_mut();
        let payment_preimage = PaymentPreimage([*payment_count; 32]);
        *payment_count += 1;
-       let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner());
+       let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).to_byte_array());
        let payment_secret = recipient.node.create_inbound_payment_for_hash(payment_hash, min_value_msat, 7200, min_final_cltv_expiry_delta).unwrap();
        (payment_preimage, payment_hash, payment_secret)
 }
@@ -1858,7 +2034,19 @@ pub fn get_route(send_node: &Node, route_params: &RouteParameters) -> Result<Rou
        router::get_route(
                &send_node.node.get_our_node_id(), route_params, &send_node.network_graph.read_only(),
                Some(&send_node.node.list_usable_channels().iter().collect::<Vec<_>>()),
-               send_node.logger, &scorer, &(), &random_seed_bytes
+               send_node.logger, &scorer, &Default::default(), &random_seed_bytes
+       )
+}
+
+/// Like `get_route` above, but adds a random CLTV offset to the final hop.
+pub fn find_route(send_node: &Node, route_params: &RouteParameters) -> Result<Route, msgs::LightningError> {
+       let scorer = TestScorer::new();
+       let keys_manager = TestKeysInterface::new(&[0u8; 32], bitcoin::network::constants::Network::Testnet);
+       let random_seed_bytes = keys_manager.get_secure_random_bytes();
+       router::find_route(
+               &send_node.node.get_our_node_id(), route_params, &send_node.network_graph,
+               Some(&send_node.node.list_usable_channels().iter().collect::<Vec<_>>()),
+               send_node.logger, &scorer, &Default::default(), &random_seed_bytes
        )
 }
 
@@ -1878,11 +2066,15 @@ macro_rules! get_route {
 macro_rules! get_route_and_payment_hash {
        ($send_node: expr, $recv_node: expr, $recv_value: expr) => {{
                let payment_params = $crate::routing::router::PaymentParameters::from_node_id($recv_node.node.get_our_node_id(), TEST_FINAL_CLTV)
-                       .with_bolt11_features($recv_node.node.invoice_features()).unwrap();
+                       .with_bolt11_features($recv_node.node.bolt11_invoice_features()).unwrap();
                $crate::get_route_and_payment_hash!($send_node, $recv_node, payment_params, $recv_value)
        }};
        ($send_node: expr, $recv_node: expr, $payment_params: expr, $recv_value: expr) => {{
-               let route_params = $crate::routing::router::RouteParameters::from_payment_params_and_value($payment_params, $recv_value);
+               $crate::get_route_and_payment_hash!($send_node, $recv_node, $payment_params, $recv_value, None)
+       }};
+       ($send_node: expr, $recv_node: expr, $payment_params: expr, $recv_value: expr, $max_total_routing_fee_msat: expr) => {{
+               let mut route_params = $crate::routing::router::RouteParameters::from_payment_params_and_value($payment_params, $recv_value);
+               route_params.max_total_routing_fee_msat = $max_total_routing_fee_msat;
                let (payment_preimage, payment_hash, payment_secret) =
                        $crate::ln::functional_test_utils::get_payment_preimage_hash(&$recv_node, Some($recv_value), None);
                let route = $crate::ln::functional_test_utils::get_route(&$send_node, &route_params);
@@ -1947,7 +2139,7 @@ pub fn expect_payment_sent<CM: AChannelManager, H: NodeHolder<CM=CM>>(node: &H,
 ) {
        let events = node.node().get_and_clear_pending_events();
        let expected_payment_hash = PaymentHash(
-               bitcoin::hashes::sha256::Hash::hash(&expected_payment_preimage.0).into_inner());
+               bitcoin::hashes::sha256::Hash::hash(&expected_payment_preimage.0).to_byte_array());
        if expect_per_path_claims {
                assert!(events.len() > 1);
        } else {
@@ -2011,14 +2203,19 @@ macro_rules! expect_payment_path_successful {
 
 pub fn expect_payment_forwarded<CM: AChannelManager, H: NodeHolder<CM=CM>>(
        event: Event, node: &H, prev_node: &H, next_node: &H, expected_fee: Option<u64>,
-       upstream_force_closed: bool, downstream_force_closed: bool
+       expected_extra_fees_msat: Option<u64>, upstream_force_closed: bool,
+       downstream_force_closed: bool
 ) {
        match event {
                Event::PaymentForwarded {
-                       fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id,
-                       outbound_amount_forwarded_msat: _
+                       total_fee_earned_msat, prev_channel_id, claim_from_onchain_tx, next_channel_id,
+                       outbound_amount_forwarded_msat: _, skimmed_fee_msat
                } => {
-                       assert_eq!(fee_earned_msat, expected_fee);
+                       assert_eq!(total_fee_earned_msat, expected_fee);
+
+                       // Check that the (knowingly) withheld amount is always less or equal to the expected
+                       // overpaid amount.
+                       assert!(skimmed_fee_msat == expected_extra_fees_msat);
                        if !upstream_force_closed {
                                // Is the event prev_channel_id in one of the channels between the two nodes?
                                assert!(node.node().list_channels().iter().any(|x| x.counterparty.node_id == prev_node.node().get_our_node_id() && x.channel_id == prev_channel_id.unwrap()));
@@ -2034,13 +2231,15 @@ pub fn expect_payment_forwarded<CM: AChannelManager, H: NodeHolder<CM=CM>>(
        }
 }
 
+#[macro_export]
 macro_rules! expect_payment_forwarded {
        ($node: expr, $prev_node: expr, $next_node: expr, $expected_fee: expr, $upstream_force_closed: expr, $downstream_force_closed: expr) => {
                let mut events = $node.node.get_and_clear_pending_events();
                assert_eq!(events.len(), 1);
                $crate::ln::functional_test_utils::expect_payment_forwarded(
-                       events.pop().unwrap(), &$node, &$prev_node, &$next_node, $expected_fee,
-                       $upstream_force_closed, $downstream_force_closed);
+                       events.pop().unwrap(), &$node, &$prev_node, &$next_node, $expected_fee, None,
+                       $upstream_force_closed, $downstream_force_closed
+               );
        }
 }
 
@@ -2055,12 +2254,13 @@ macro_rules! expect_channel_shutdown_state {
 }
 
 #[cfg(any(test, ldk_bench, feature = "_test_utils"))]
-pub fn expect_channel_pending_event<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, expected_counterparty_node_id: &PublicKey) {
+pub fn expect_channel_pending_event<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, expected_counterparty_node_id: &PublicKey) -> ChannelId {
        let events = node.node.get_and_clear_pending_events();
        assert_eq!(events.len(), 1);
-       match events[0] {
-               crate::events::Event::ChannelPending { ref counterparty_node_id, .. } => {
+       match &events[0] {
+               crate::events::Event::ChannelPending { channel_id, counterparty_node_id, .. } => {
                        assert_eq!(*expected_counterparty_node_id, *counterparty_node_id);
+                       *channel_id
                },
                _ => panic!("Unexpected event"),
        }
@@ -2078,6 +2278,26 @@ pub fn expect_channel_ready_event<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, ex
        }
 }
 
+#[cfg(any(test, feature = "_test_utils"))]
+pub fn expect_probe_successful_events(node: &Node, mut probe_results: Vec<(PaymentHash, PaymentId)>) {
+       let mut events = node.node.get_and_clear_pending_events();
+
+       for event in events.drain(..) {
+               match event {
+                       Event::ProbeSuccessful { payment_hash: ev_ph, payment_id: ev_pid, ..} => {
+                               let result_idx = probe_results.iter().position(|(payment_hash, payment_id)| *payment_hash == ev_ph && *payment_id == ev_pid);
+                               assert!(result_idx.is_some());
+
+                               probe_results.remove(result_idx.unwrap());
+                       },
+                       _ => panic!(),
+               }
+       };
+
+       // Ensure that we received a ProbeSuccessful event for each probe result.
+       assert!(probe_results.is_empty());
+}
+
 pub struct PaymentFailedConditions<'a> {
        pub(crate) expected_htlc_error_data: Option<(u16, &'a [u8])>,
        pub(crate) expected_blamed_scid: Option<u64>,
@@ -2215,21 +2435,41 @@ pub fn send_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>,
        payment_id
 }
 
-pub fn do_pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<PaymentSecret>, ev: MessageSendEvent, payment_claimable_expected: bool, clear_recipient_events: bool, expected_preimage: Option<PaymentPreimage>) -> Option<Event> {
+fn fail_payment_along_path<'a, 'b, 'c>(expected_path: &[&Node<'a, 'b, 'c>]) {
+       let origin_node_id = expected_path[0].node.get_our_node_id();
+
+       // iterate from the receiving node to the origin node and handle update fail htlc.
+       for (&node, &prev_node) in expected_path.iter().rev().zip(expected_path.iter().rev().skip(1)) {
+               let updates = get_htlc_update_msgs!(node, prev_node.node.get_our_node_id());
+               prev_node.node.handle_update_fail_htlc(&node.node.get_our_node_id(), &updates.update_fail_htlcs[0]);
+               check_added_monitors!(prev_node, 0);
+
+               let is_first_hop = origin_node_id == prev_node.node.get_our_node_id();
+               // We do not want to fail backwards on the first hop. All other hops should fail backwards.
+               commitment_signed_dance!(prev_node, node, updates.commitment_signed, !is_first_hop);
+       }
+}
+
+pub fn do_pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<PaymentSecret>, ev: MessageSendEvent, payment_claimable_expected: bool, clear_recipient_events: bool, expected_preimage: Option<PaymentPreimage>, is_probe: bool) -> Option<Event> {
        let mut payment_event = SendEvent::from_event(ev);
        let mut prev_node = origin_node;
        let mut event = None;
 
        for (idx, &node) in expected_path.iter().enumerate() {
+               let is_last_hop = idx == expected_path.len() - 1;
                assert_eq!(node.node.get_our_node_id(), payment_event.node_id);
 
                node.node.handle_update_add_htlc(&prev_node.node.get_our_node_id(), &payment_event.msgs[0]);
                check_added_monitors!(node, 0);
-               commitment_signed_dance!(node, prev_node, payment_event.commitment_msg, false);
 
-               expect_pending_htlcs_forwardable!(node);
+               if is_last_hop && is_probe {
+                       commitment_signed_dance!(node, prev_node, payment_event.commitment_msg, true, true);
+               } else {
+                       commitment_signed_dance!(node, prev_node, payment_event.commitment_msg, false);
+                       expect_pending_htlcs_forwardable!(node);
+               }
 
-               if idx == expected_path.len() - 1 && clear_recipient_events {
+               if is_last_hop && clear_recipient_events {
                        let events_2 = node.node.get_and_clear_pending_events();
                        if payment_claimable_expected {
                                assert_eq!(events_2.len(), 1);
@@ -2263,7 +2503,7 @@ pub fn do_pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_p
                        } else {
                                assert!(events_2.is_empty());
                        }
-               } else if idx != expected_path.len() - 1 {
+               } else if !is_last_hop {
                        let mut events_2 = node.node.get_and_clear_pending_msg_events();
                        assert_eq!(events_2.len(), 1);
                        check_added_monitors!(node, 1);
@@ -2277,16 +2517,33 @@ pub fn do_pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_p
 }
 
 pub fn pass_along_path<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path: &[&Node<'a, 'b, 'c>], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: Option<PaymentSecret>, ev: MessageSendEvent, payment_claimable_expected: bool, expected_preimage: Option<PaymentPreimage>) -> Option<Event> {
-       do_pass_along_path(origin_node, expected_path, recv_value, our_payment_hash, our_payment_secret, ev, payment_claimable_expected, true, expected_preimage)
+       do_pass_along_path(origin_node, expected_path, recv_value, our_payment_hash, our_payment_secret, ev, payment_claimable_expected, true, expected_preimage, false)
+}
+
+pub fn send_probe_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&[&Node<'a, 'b, 'c>]]) {
+       let mut events = origin_node.node.get_and_clear_pending_msg_events();
+       assert_eq!(events.len(), expected_route.len());
+
+       check_added_monitors!(origin_node, expected_route.len());
+
+       for path in expected_route.iter() {
+               let ev = remove_first_msg_event_to_node(&path[0].node.get_our_node_id(), &mut events);
+
+               do_pass_along_path(origin_node, path, 0, PaymentHash([0_u8; 32]), None, ev, false, false, None, true);
+               let nodes_to_fail_payment: Vec<_> = vec![origin_node].into_iter().chain(path.iter().cloned()).collect();
+
+               fail_payment_along_path(nodes_to_fail_payment.as_slice());
+       }
 }
 
 pub fn pass_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: PaymentSecret) {
        let mut events = origin_node.node.get_and_clear_pending_msg_events();
        assert_eq!(events.len(), expected_route.len());
+
        for (path_idx, expected_path) in expected_route.iter().enumerate() {
                let ev = remove_first_msg_event_to_node(&expected_path[0].node.get_our_node_id(), &mut events);
                // Once we've gotten through all the HTLCs, the last one should result in a
-               // PaymentClaimable (but each previous one should not!).
+               // PaymentClaimable (but each previous one should not!).
                let expect_payment = path_idx == expected_route.len() - 1;
                pass_along_path(origin_node, expected_path, recv_value, our_payment_hash.clone(), Some(our_payment_secret), ev, expect_payment, None);
        }
@@ -2302,24 +2559,54 @@ pub fn do_claim_payment_along_route<'a, 'b, 'c>(
        origin_node: &Node<'a, 'b, 'c>, expected_paths: &[&[&Node<'a, 'b, 'c>]], skip_last: bool,
        our_payment_preimage: PaymentPreimage
 ) -> u64 {
-       let extra_fees = vec![0; expected_paths.len()];
-       do_claim_payment_along_route_with_extra_penultimate_hop_fees(origin_node, expected_paths,
-               &extra_fees[..], skip_last, our_payment_preimage)
-}
-
-pub fn do_claim_payment_along_route_with_extra_penultimate_hop_fees<'a, 'b, 'c>(
-       origin_node: &Node<'a, 'b, 'c>, expected_paths: &[&[&Node<'a, 'b, 'c>]], expected_extra_fees:
-       &[u32], skip_last: bool, our_payment_preimage: PaymentPreimage
-) -> u64 {
-       assert_eq!(expected_paths.len(), expected_extra_fees.len());
        for path in expected_paths.iter() {
                assert_eq!(path.last().unwrap().node.get_our_node_id(), expected_paths[0].last().unwrap().node.get_our_node_id());
        }
        expected_paths[0].last().unwrap().node.claim_funds(our_payment_preimage);
-       pass_claimed_payment_along_route(origin_node, expected_paths, expected_extra_fees, skip_last, our_payment_preimage)
+       pass_claimed_payment_along_route(
+               ClaimAlongRouteArgs::new(origin_node, expected_paths, our_payment_preimage)
+                       .skip_last(skip_last)
+       )
+}
+
+pub struct ClaimAlongRouteArgs<'a, 'b, 'c, 'd> {
+       pub origin_node: &'a Node<'b, 'c, 'd>,
+       pub expected_paths: &'a [&'a [&'a Node<'b, 'c, 'd>]],
+       pub expected_extra_fees: Vec<u32>,
+       pub expected_min_htlc_overpay: Vec<u32>,
+       pub skip_last: bool,
+       pub payment_preimage: PaymentPreimage,
 }
 
-pub fn pass_claimed_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths: &[&[&Node<'a, 'b, 'c>]], expected_extra_fees: &[u32], skip_last: bool, our_payment_preimage: PaymentPreimage) -> u64 {
+impl<'a, 'b, 'c, 'd> ClaimAlongRouteArgs<'a, 'b, 'c, 'd> {
+       pub fn new(
+               origin_node: &'a Node<'b, 'c, 'd>, expected_paths: &'a [&'a [&'a Node<'b, 'c, 'd>]],
+               payment_preimage: PaymentPreimage,
+       ) -> Self {
+               Self {
+                       origin_node, expected_paths, expected_extra_fees: vec![0; expected_paths.len()],
+                       expected_min_htlc_overpay: vec![0; expected_paths.len()], skip_last: false, payment_preimage,
+               }
+       }
+       pub fn skip_last(mut self, skip_last: bool) -> Self {
+               self.skip_last = skip_last;
+               self
+       }
+       pub fn with_expected_extra_fees(mut self, extra_fees: Vec<u32>) -> Self {
+               self.expected_extra_fees = extra_fees;
+               self
+       }
+       pub fn with_expected_min_htlc_overpay(mut self, extra_fees: Vec<u32>) -> Self {
+               self.expected_min_htlc_overpay = extra_fees;
+               self
+       }
+}
+
+pub fn pass_claimed_payment_along_route<'a, 'b, 'c, 'd>(args: ClaimAlongRouteArgs) -> u64 {
+       let ClaimAlongRouteArgs {
+               origin_node, expected_paths, expected_extra_fees, expected_min_htlc_overpay, skip_last,
+               payment_preimage: our_payment_preimage
+       } = args;
        let claim_event = expected_paths[0].last().unwrap().node.get_and_clear_pending_events();
        assert_eq!(claim_event.len(), 1);
        match claim_event[0] {
@@ -2416,8 +2703,17 @@ pub fn pass_claimed_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, '
                                                        channel.context().config().forwarding_fee_base_msat
                                                }
                                        };
-                                       if $idx == 1 { fee += expected_extra_fees[i]; }
-                                       expect_payment_forwarded!(*$node, $next_node, $prev_node, Some(fee as u64), false, false);
+
+                                       let mut expected_extra_fee = None;
+                                       if $idx == 1 {
+                                               fee += expected_extra_fees[i];
+                                               fee += expected_min_htlc_overpay[i];
+                                               expected_extra_fee = if expected_extra_fees[i] > 0 { Some(expected_extra_fees[i] as u64) } else { None };
+                                       }
+                                       let mut events = $node.node.get_and_clear_pending_events();
+                                       assert_eq!(events.len(), 1);
+                                       expect_payment_forwarded(events.pop().unwrap(), *$node, $next_node, $prev_node,
+                                               Some(fee as u64), expected_extra_fee, false, false);
                                        expected_total_fee_msat += fee as u64;
                                        check_added_monitors!($node, 1);
                                        let new_next_msgs = if $new_msgs {
@@ -2487,7 +2783,7 @@ pub const TEST_FINAL_CLTV: u32 = 70;
 
 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, PaymentId) {
        let payment_params = PaymentParameters::from_node_id(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV)
-               .with_bolt11_features(expected_route.last().unwrap().node.invoice_features()).unwrap();
+               .with_bolt11_features(expected_route.last().unwrap().node.bolt11_invoice_features()).unwrap();
        let route_params = RouteParameters::from_payment_params_and_value(payment_params, recv_value);
        let route = get_route(origin_node, &route_params).unwrap();
        assert_eq!(route.paths.len(), 1);
@@ -2502,7 +2798,7 @@ pub fn route_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route:
 
 pub fn route_over_limit<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_route: &[&Node<'a, 'b, 'c>], recv_value: u64)  {
        let payment_params = PaymentParameters::from_node_id(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV)
-               .with_bolt11_features(expected_route.last().unwrap().node.invoice_features()).unwrap();
+               .with_bolt11_features(expected_route.last().unwrap().node.bolt11_invoice_features()).unwrap();
        let route_params = RouteParameters::from_payment_params_and_value(payment_params, recv_value);
        let network_graph = origin_node.network_graph.read_only();
        let scorer = test_utils::TestScorer::new();
@@ -2510,7 +2806,7 @@ pub fn route_over_limit<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_rou
        let keys_manager = test_utils::TestKeysInterface::new(&seed, Network::Testnet);
        let random_seed_bytes = keys_manager.get_secure_random_bytes();
        let route = router::get_route(&origin_node.node.get_our_node_id(), &route_params, &network_graph,
-               None, origin_node.logger, &scorer, &(), &random_seed_bytes).unwrap();
+               None, origin_node.logger, &scorer, &Default::default(), &random_seed_bytes).unwrap();
        assert_eq!(route.paths.len(), 1);
        assert_eq!(route.paths[0].hops.len(), expected_route.len());
        for (node, hop) in expected_route.iter().zip(route.paths[0].hops.iter()) {
@@ -2683,7 +2979,8 @@ pub fn create_node_cfgs_with_persisters<'a>(node_count: usize, chanmon_cfgs: &'a
                        logger: &chanmon_cfgs[i].logger,
                        tx_broadcaster: &chanmon_cfgs[i].tx_broadcaster,
                        fee_estimator: &chanmon_cfgs[i].fee_estimator,
-                       router: test_utils::TestRouter::new(network_graph.clone(), &chanmon_cfgs[i].scorer),
+                       router: test_utils::TestRouter::new(network_graph.clone(), &chanmon_cfgs[i].logger, &chanmon_cfgs[i].scorer),
+                       message_router: test_utils::TestMessageRouter::new(network_graph.clone()),
                        chain_monitor,
                        keys_manager: &chanmon_cfgs[i].keys_manager,
                        node_seed: seed,
@@ -2737,6 +3034,11 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
        let connect_style = Rc::new(RefCell::new(ConnectStyle::random_style()));
 
        for i in 0..node_count {
+               let dedicated_entropy = DedicatedEntropy(RandomBytes::new([i as u8; 32]));
+               let onion_messenger = OnionMessenger::new(
+                       dedicated_entropy, cfgs[i].keys_manager, cfgs[i].logger, &cfgs[i].message_router,
+                       &chan_mgrs[i], IgnoringMessageHandler {},
+               );
                let gossip_sync = P2PGossipSync::new(cfgs[i].network_graph.as_ref(), None, cfgs[i].logger);
                let wallet_source = Arc::new(test_utils::TestWalletSource::new(SecretKey::from_slice(&[i as u8 + 1; 32]).unwrap()));
                nodes.push(Node{
@@ -2744,7 +3046,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
                        fee_estimator: cfgs[i].fee_estimator, router: &cfgs[i].router,
                        chain_monitor: &cfgs[i].chain_monitor, keys_manager: &cfgs[i].keys_manager,
                        node: &chan_mgrs[i], network_graph: cfgs[i].network_graph.as_ref(), gossip_sync,
-                       node_seed: cfgs[i].node_seed, network_chan_count: chan_count.clone(),
+                       node_seed: cfgs[i].node_seed, onion_messenger, network_chan_count: chan_count.clone(),
                        network_payment_count: payment_count.clone(), logger: cfgs[i].logger,
                        blocks: Arc::clone(&cfgs[i].tx_broadcaster.blocks),
                        connect_style: Rc::clone(&connect_style),
@@ -2759,16 +3061,24 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
 
        for i in 0..node_count {
                for j in (i+1)..node_count {
-                       nodes[i].node.peer_connected(&nodes[j].node.get_our_node_id(), &msgs::Init {
-                               features: nodes[j].override_init_features.borrow().clone().unwrap_or_else(|| nodes[j].node.init_features()),
+                       let node_id_i = nodes[i].node.get_our_node_id();
+                       let node_id_j = nodes[j].node.get_our_node_id();
+
+                       let init_i = msgs::Init {
+                               features: nodes[i].init_features(&node_id_j),
                                networks: None,
                                remote_network_address: None,
-                       }, true).unwrap();
-                       nodes[j].node.peer_connected(&nodes[i].node.get_our_node_id(), &msgs::Init {
-                               features: nodes[i].override_init_features.borrow().clone().unwrap_or_else(|| nodes[i].node.init_features()),
+                       };
+                       let init_j = msgs::Init {
+                               features: nodes[j].init_features(&node_id_i),
                                networks: None,
                                remote_network_address: None,
-                       }, false).unwrap();
+                       };
+
+                       nodes[i].node.peer_connected(&node_id_j, &init_j, true).unwrap();
+                       nodes[j].node.peer_connected(&node_id_i, &init_i, false).unwrap();
+                       nodes[i].onion_messenger.peer_connected(&node_id_j, &init_j, true).unwrap();
+                       nodes[j].onion_messenger.peer_connected(&node_id_i, &init_i, false).unwrap();
                }
        }
 
@@ -2776,7 +3086,8 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
 }
 
 // Note that the following only works for CLTV values up to 128
-pub const ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 137; //Here we have a diff due to HTLC CLTV expiry being < 2^15 in test
+pub const ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 137; // Here we have a diff due to HTLC CLTV expiry being < 2^15 in test
+pub const ACCEPTED_HTLC_SCRIPT_WEIGHT_ANCHORS: usize = 140; // Here we have a diff due to HTLC CLTV expiry being < 2^15 in test
 
 #[derive(PartialEq)]
 pub enum HTLCType { NONE, TIMEOUT, SUCCESS }
@@ -2818,9 +3129,9 @@ pub fn test_txn_broadcast<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, chan: &(msgs::Cha
                        if tx.input.len() == 1 && tx.input[0].previous_output.txid == res[0].txid() {
                                check_spends!(tx, res[0]);
                                if has_htlc_tx == HTLCType::TIMEOUT {
-                                       assert!(tx.lock_time.0 != 0);
+                                       assert_ne!(tx.lock_time, LockTime::ZERO);
                                } else {
-                                       assert!(tx.lock_time.0 == 0);
+                                       assert_eq!(tx.lock_time, LockTime::ZERO);
                                }
                                res.push(tx.clone());
                                false
@@ -2901,6 +3212,13 @@ pub fn handle_announce_close_broadcast_events<'a, 'b, 'c>(nodes: &Vec<Node<'a, '
                                nodes[b].node.handle_error(&nodes[a].node.get_our_node_id(), msg);
                        }
                },
+               MessageSendEvent::HandleError { node_id, action: msgs::ErrorAction::DisconnectPeer { ref msg } } => {
+                       assert_eq!(node_id, nodes[b].node.get_our_node_id());
+                       assert_eq!(msg.as_ref().unwrap().data, expected_error);
+                       if needs_err_handle {
+                               nodes[b].node.handle_error(&nodes[a].node.get_our_node_id(), msg.as_ref().unwrap());
+                       }
+               },
                _ => panic!("Unexpected event"),
        }
 
@@ -2918,6 +3236,10 @@ pub fn handle_announce_close_broadcast_events<'a, 'b, 'c>(nodes: &Vec<Node<'a, '
                                assert_eq!(node_id, nodes[a].node.get_our_node_id());
                                assert_eq!(msg.data, expected_error);
                        },
+                       MessageSendEvent::HandleError { node_id, action: msgs::ErrorAction::DisconnectPeer { ref msg } } => {
+                               assert_eq!(node_id, nodes[a].node.get_our_node_id());
+                               assert_eq!(msg.as_ref().unwrap().data, expected_error);
+                       },
                        _ => panic!("Unexpected event"),
                }
        }
@@ -3099,24 +3421,28 @@ pub fn reconnect_nodes<'a, 'b, 'c, 'd>(args: ReconnectArgs<'a, 'b, 'c, 'd>) {
                // If a expects a channel_ready, it better not think it has received a revoke_and_ack
                // from b
                for reestablish in reestablish_1.iter() {
-                       assert_eq!(reestablish.next_remote_commitment_number, 0);
+                       let n = reestablish.next_remote_commitment_number;
+                       assert_eq!(n, 0, "expected a->b next_remote_commitment_number to be 0, got {}", n);
                }
        }
        if send_channel_ready.1 {
                // If b expects a channel_ready, it better not think it has received a revoke_and_ack
                // from a
                for reestablish in reestablish_2.iter() {
-                       assert_eq!(reestablish.next_remote_commitment_number, 0);
+                       let n = reestablish.next_remote_commitment_number;
+                       assert_eq!(n, 0, "expected b->a next_remote_commitment_number to be 0, got {}", n);
                }
        }
        if send_channel_ready.0 || send_channel_ready.1 {
                // If we expect any channel_ready's, both sides better have set
                // next_holder_commitment_number to 1
                for reestablish in reestablish_1.iter() {
-                       assert_eq!(reestablish.next_local_commitment_number, 1);
+                       let n = reestablish.next_local_commitment_number;
+                       assert_eq!(n, 1, "expected a->b next_local_commitment_number to be 1, got {}", n);
                }
                for reestablish in reestablish_2.iter() {
-                       assert_eq!(reestablish.next_local_commitment_number, 1);
+                       let n = reestablish.next_local_commitment_number;
+                       assert_eq!(n, 1, "expected b->a next_local_commitment_number to be 1, got {}", n);
                }
        }
 
@@ -3262,3 +3588,77 @@ pub fn reconnect_nodes<'a, 'b, 'c, 'd>(args: ReconnectArgs<'a, 'b, 'c, 'd>) {
                }
        }
 }
+
+/// Initiates channel opening and creates a single batch funding transaction.
+/// This will go through the open_channel / accept_channel flow, and return the batch funding
+/// transaction with corresponding funding_created messages.
+pub fn create_batch_channel_funding<'a, 'b, 'c>(
+       funding_node: &Node<'a, 'b, 'c>,
+       params: &[(&Node<'a, 'b, 'c>, u64, u64, u128, Option<UserConfig>)],
+) -> (Transaction, Vec<msgs::FundingCreated>) {
+       let mut tx_outs = Vec::new();
+       let mut temp_chan_ids = Vec::new();
+       let mut funding_created_msgs = Vec::new();
+
+       for (other_node, channel_value_satoshis, push_msat, user_channel_id, override_config) in params {
+               // Initialize channel opening.
+               let temp_chan_id = funding_node.node.create_channel(
+                       other_node.node.get_our_node_id(), *channel_value_satoshis, *push_msat, *user_channel_id,
+                       None,
+                       *override_config,
+               ).unwrap();
+               let open_channel_msg = get_event_msg!(funding_node, MessageSendEvent::SendOpenChannel, other_node.node.get_our_node_id());
+               other_node.node.handle_open_channel(&funding_node.node.get_our_node_id(), &open_channel_msg);
+               let accept_channel_msg = get_event_msg!(other_node, MessageSendEvent::SendAcceptChannel, funding_node.node.get_our_node_id());
+               funding_node.node.handle_accept_channel(&other_node.node.get_our_node_id(), &accept_channel_msg);
+
+               // Create the corresponding funding output.
+               let events = funding_node.node.get_and_clear_pending_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       Event::FundingGenerationReady {
+                               ref temporary_channel_id,
+                               ref counterparty_node_id,
+                               channel_value_satoshis: ref event_channel_value_satoshis,
+                               ref output_script,
+                               user_channel_id: ref event_user_channel_id
+                       } => {
+                               assert_eq!(temporary_channel_id, &temp_chan_id);
+                               assert_eq!(counterparty_node_id, &other_node.node.get_our_node_id());
+                               assert_eq!(channel_value_satoshis, event_channel_value_satoshis);
+                               assert_eq!(user_channel_id, event_user_channel_id);
+                               tx_outs.push(TxOut {
+                                       value: *channel_value_satoshis, script_pubkey: output_script.clone(),
+                               });
+                       },
+                       _ => panic!("Unexpected event"),
+               };
+               temp_chan_ids.push((temp_chan_id, other_node.node.get_our_node_id()));
+       }
+
+       // Compose the batch funding transaction and give it to the ChannelManager.
+       let tx = Transaction {
+               version: 2,
+               lock_time: LockTime::ZERO,
+               input: Vec::new(),
+               output: tx_outs,
+       };
+       assert!(funding_node.node.batch_funding_transaction_generated(
+               temp_chan_ids.iter().map(|(a, b)| (a, b)).collect::<Vec<_>>().as_slice(),
+               tx.clone(),
+       ).is_ok());
+       check_added_monitors!(funding_node, 0);
+       let events = funding_node.node.get_and_clear_pending_msg_events();
+       assert_eq!(events.len(), params.len());
+       for (other_node, ..) in params {
+               let funding_created = events
+                       .iter()
+                       .find_map(|event| match event {
+                               MessageSendEvent::SendFundingCreated { node_id, msg } if node_id == &other_node.node.get_our_node_id() => Some(msg.clone()),
+                               _ => None,
+                       })
+                       .unwrap();
+               funding_created_msgs.push(funding_created);
+       }
+       return (tx, funding_created_msgs);
+}