Merge pull request #1866 from TheBlueMatt/2022-11-noisy-no-graph
[rust-lightning] / lightning / src / ln / functional_test_utils.rs
index 43dfef5d188bc51d8d0aa65df6965ef9ccaf7b1a..6b247b28f097d30b9576b13c6fa435343ecf4fd1 100644 (file)
 //! A bunch of useful utilities for building networks of nodes and exchanging messages between
 //! nodes for functional tests.
 
-use chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen, Watch, keysinterface::KeysInterface};
-use chain::channelmonitor::ChannelMonitor;
-use chain::transaction::OutPoint;
-use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
-use ln::channelmanager::{self, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, PaymentId, MIN_CLTV_EXPIRY_DELTA};
-use routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
-use routing::router::{PaymentParameters, Route, get_route};
-use ln::features::InitFeatures;
-use ln::msgs;
-use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler};
-use util::enforcing_trait_impls::EnforcingSigner;
-use util::scid_utils;
-use util::test_utils;
-use util::test_utils::{panicking, TestChainMonitor};
-use util::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PaymentPurpose};
-use util::errors::APIError;
-use util::config::UserConfig;
-use util::ser::{ReadableArgs, Writeable};
+use crate::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen, Watch, keysinterface::KeysInterface};
+use crate::chain::channelmonitor::ChannelMonitor;
+use crate::chain::transaction::OutPoint;
+use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
+use crate::ln::channelmanager::{self, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, PaymentId, MIN_CLTV_EXPIRY_DELTA};
+use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
+use crate::routing::router::{PaymentParameters, Route, get_route};
+use crate::ln::features::InitFeatures;
+use crate::ln::msgs;
+use crate::ln::msgs::{ChannelMessageHandler,RoutingMessageHandler};
+use crate::util::enforcing_trait_impls::EnforcingSigner;
+use crate::util::scid_utils;
+use crate::util::test_utils;
+use crate::util::test_utils::{panicking, TestChainMonitor};
+use crate::util::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PaymentPurpose};
+use crate::util::errors::APIError;
+use crate::util::config::UserConfig;
+use crate::util::ser::{ReadableArgs, Writeable};
 
 use bitcoin::blockdata::block::{Block, BlockHeader};
 use bitcoin::blockdata::constants::genesis_block;
@@ -40,11 +40,11 @@ use bitcoin::hashes::Hash as _;
 
 use bitcoin::secp256k1::PublicKey;
 
-use io;
-use prelude::*;
+use crate::io;
+use crate::prelude::*;
 use core::cell::RefCell;
 use alloc::rc::Rc;
-use sync::{Arc, Mutex};
+use crate::sync::{Arc, Mutex};
 use core::mem;
 use core::iter::repeat;
 use bitcoin::{PackedLockTime, TxMerkleNode};
@@ -276,9 +276,10 @@ pub struct NodeCfg<'a> {
 pub struct Node<'a, 'b: 'a, 'c: 'b> {
        pub chain_source: &'c test_utils::TestChainSource,
        pub tx_broadcaster: &'c test_utils::TestBroadcaster,
+       pub fee_estimator: &'c test_utils::TestFeeEstimator,
        pub chain_monitor: &'b test_utils::TestChainMonitor<'c>,
        pub keys_manager: &'b test_utils::TestKeysInterface,
-       pub node: &'a ChannelManager<EnforcingSigner, &'b TestChainMonitor<'c>, &'c test_utils::TestBroadcaster, &'b test_utils::TestKeysInterface, &'c test_utils::TestFeeEstimator, &'c test_utils::TestLogger>,
+       pub node: &'a ChannelManager<&'b TestChainMonitor<'c>, &'c test_utils::TestBroadcaster, &'b test_utils::TestKeysInterface, &'c test_utils::TestFeeEstimator, &'c test_utils::TestLogger>,
        pub network_graph: &'b NetworkGraph<&'c test_utils::TestLogger>,
        pub gossip_sync: P2PGossipSync<&'b NetworkGraph<&'c test_utils::TestLogger>, &'c test_utils::TestChainSource, &'c test_utils::TestLogger>,
        pub node_seed: [u8; 32],
@@ -378,7 +379,7 @@ impl<'a, 'b, 'c> Drop for Node<'a, 'b, 'c> {
 
                                let mut w = test_utils::TestVecWriter(Vec::new());
                                self.node.write(&mut w).unwrap();
-                               <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut io::Cursor::new(w.0), ChannelManagerReadArgs {
+                               <(BlockHash, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut io::Cursor::new(w.0), ChannelManagerReadArgs {
                                        default_config: *self.node.get_current_default_configuration(),
                                        keys_manager: self.keys_manager,
                                        fee_estimator: &test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) },
@@ -587,7 +588,7 @@ macro_rules! get_local_commitment_txn {
 macro_rules! unwrap_send_err {
        ($res: expr, $all_failed: expr, $type: pat, $check: expr) => {
                match &$res {
-                       &Err(PaymentSendFailure::AllFailedRetrySafe(ref fails)) if $all_failed => {
+                       &Err(PaymentSendFailure::AllFailedResendSafe(ref fails)) if $all_failed => {
                                assert_eq!(fails.len(), 1);
                                match fails[0] {
                                        $type => { $check },
@@ -618,7 +619,61 @@ macro_rules! check_added_monitors {
        }
 }
 
-pub fn create_funding_transaction<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, expected_counterparty_node_id: &PublicKey, expected_chan_value: u64, expected_user_chan_id: u64) -> ([u8; 32], Transaction, OutPoint) {
+pub fn _reload_node<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, default_config: UserConfig, chanman_encoded: &[u8], monitors_encoded: &[&[u8]]) -> ChannelManager<&'b TestChainMonitor<'c>, &'c test_utils::TestBroadcaster, &'b test_utils::TestKeysInterface, &'c test_utils::TestFeeEstimator, &'c test_utils::TestLogger> {
+       let mut monitors_read = Vec::with_capacity(monitors_encoded.len());
+       for encoded in monitors_encoded {
+               let mut monitor_read = &encoded[..];
+               let (_, monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>
+                       ::read(&mut monitor_read, node.keys_manager).unwrap();
+               assert!(monitor_read.is_empty());
+               monitors_read.push(monitor);
+       }
+
+       let mut node_read = &chanman_encoded[..];
+       let (_, node_deserialized) = {
+               let mut channel_monitors = HashMap::new();
+               for monitor in monitors_read.iter_mut() {
+                       assert!(channel_monitors.insert(monitor.get_funding_txo().0, monitor).is_none());
+               }
+               <(BlockHash, ChannelManager<&test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut node_read, ChannelManagerReadArgs {
+                       default_config,
+                       keys_manager: node.keys_manager,
+                       fee_estimator: node.fee_estimator,
+                       chain_monitor: node.chain_monitor,
+                       tx_broadcaster: node.tx_broadcaster,
+                       logger: node.logger,
+                       channel_monitors,
+               }).unwrap()
+       };
+       assert!(node_read.is_empty());
+
+       for monitor in monitors_read.drain(..) {
+               assert_eq!(node.chain_monitor.watch_channel(monitor.get_funding_txo().0, monitor),
+                       ChannelMonitorUpdateStatus::Completed);
+               check_added_monitors!(node, 1);
+       }
+
+       node_deserialized
+}
+
+#[cfg(test)]
+macro_rules! reload_node {
+       ($node: expr, $new_config: expr, $chanman_encoded: expr, $monitors_encoded: expr, $persister: ident, $new_chain_monitor: ident, $new_channelmanager: ident) => {
+               let chanman_encoded = $chanman_encoded;
+
+               $persister = test_utils::TestPersister::new();
+               $new_chain_monitor = test_utils::TestChainMonitor::new(Some($node.chain_source), $node.tx_broadcaster.clone(), $node.logger, $node.fee_estimator, &$persister, &$node.keys_manager);
+               $node.chain_monitor = &$new_chain_monitor;
+
+               $new_channelmanager = _reload_node(&$node, $new_config, &chanman_encoded, $monitors_encoded);
+               $node.node = &$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);
+       };
+}
+
+pub fn create_funding_transaction<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, expected_counterparty_node_id: &PublicKey, expected_chan_value: u64, expected_user_chan_id: u128) -> ([u8; 32], Transaction, OutPoint) {
        let chan_id = *node.network_chan_count.borrow();
 
        let events = node.node.get_and_clear_pending_events();
@@ -741,6 +796,9 @@ pub fn open_zero_conf_channel<'a, 'b, 'c, 'd>(initiator: &'a Node<'b, 'c, 'd>, r
        assert_eq!(initiator.node.list_usable_channels().len(), initiator_channels + 1);
        assert_eq!(receiver.node.list_usable_channels().len(), receiver_channels + 1);
 
+       expect_channel_ready_event(&initiator, &receiver.node.get_our_node_id());
+       expect_channel_ready_event(&receiver, &initiator.node.get_our_node_id());
+
        (tx, as_channel_ready.channel_id)
 }
 
@@ -748,10 +806,12 @@ pub fn create_chan_between_nodes_with_value_init<'a, 'b, 'c>(node_a: &Node<'a, '
        let create_chan_id = node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42, 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);
        node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), a_flags, &open_channel_msg);
        let accept_channel_msg = get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a.node.get_our_node_id());
        assert_eq!(accept_channel_msg.temporary_channel_id, create_chan_id);
        node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), b_flags, &accept_channel_msg);
+       assert_ne!(node_b.node.list_channels().iter().find(|channel| channel.channel_id == create_chan_id).unwrap().user_channel_id, 0);
 
        sign_funding_transaction(node_a, node_b, channel_value, create_chan_id)
 }
@@ -794,6 +854,7 @@ pub fn create_chan_between_nodes_with_value_confirm<'a, 'b, 'c, 'd>(node_a: &'a
        create_chan_between_nodes_with_value_confirm_first(node_a, node_b, tx, conf_height);
        confirm_transaction_at(node_a, tx, conf_height);
        connect_blocks(node_a, CHAN_CONFIRM_DEPTH - 1);
+       expect_channel_ready_event(&node_a, &node_b.node.get_our_node_id());
        create_chan_between_nodes_with_value_confirm_second(node_b, node_a)
 }
 
@@ -832,6 +893,7 @@ pub fn create_chan_between_nodes_with_value_b<'a, 'b, 'c>(node_a: &Node<'a, 'b,
 
        *node_a.network_chan_count.borrow_mut() += 1;
 
+       expect_channel_ready_event(&node_b, &node_a.node.get_our_node_id());
        ((*announcement).clone(), (*as_update).clone(), (*bs_update).clone())
 }
 
@@ -870,8 +932,10 @@ pub fn create_unannounced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: &
        connect_blocks(&nodes[b], CHAN_CONFIRM_DEPTH - 1);
        let as_channel_ready = get_event_msg!(nodes[a], MessageSendEvent::SendChannelReady, nodes[b].node.get_our_node_id());
        nodes[a].node.handle_channel_ready(&nodes[b].node.get_our_node_id(), &get_event_msg!(nodes[b], MessageSendEvent::SendChannelReady, nodes[a].node.get_our_node_id()));
+       expect_channel_ready_event(&nodes[a], &nodes[b].node.get_our_node_id());
        let as_update = get_event_msg!(nodes[a], MessageSendEvent::SendChannelUpdate, nodes[b].node.get_our_node_id());
        nodes[b].node.handle_channel_ready(&nodes[a].node.get_our_node_id(), &as_channel_ready);
+       expect_channel_ready_event(&nodes[b], &nodes[a].node.get_our_node_id());
        let bs_update = get_event_msg!(nodes[b], MessageSendEvent::SendChannelUpdate, nodes[a].node.get_our_node_id());
 
        nodes[a].node.handle_channel_update(&nodes[b].node.get_our_node_id(), &bs_update);
@@ -1126,7 +1190,7 @@ impl SendEvent {
                assert!(updates.update_fail_htlcs.is_empty());
                assert!(updates.update_fail_malformed_htlcs.is_empty());
                assert!(updates.update_fee.is_none());
-               SendEvent { node_id: node_id, msgs: updates.update_add_htlcs, commitment_msg: updates.commitment_signed }
+               SendEvent { node_id, msgs: updates.update_add_htlcs, commitment_msg: updates.commitment_signed }
        }
 
        pub fn from_event(event: MessageSendEvent) -> SendEvent {
@@ -1503,6 +1567,19 @@ macro_rules! expect_payment_forwarded {
        }
 }
 
+#[cfg(any(test, feature = "_bench_unstable", feature = "_test_utils"))]
+pub fn expect_channel_ready_event<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, expected_counterparty_node_id: &PublicKey) {
+       let events = node.node.get_and_clear_pending_events();
+       assert_eq!(events.len(), 1);
+       match events[0] {
+               crate::util::events::Event::ChannelReady{ ref counterparty_node_id, .. } => {
+                       assert_eq!(*expected_counterparty_node_id, *counterparty_node_id);
+               },
+               _ => panic!("Unexpected event"),
+       }
+}
+
+
 pub struct PaymentFailedConditions<'a> {
        pub(crate) expected_htlc_error_data: Option<(u16, &'a [u8])>,
        pub(crate) expected_blamed_scid: Option<u64>,
@@ -1636,7 +1713,8 @@ pub fn expect_payment_failed_conditions<'a, 'b, 'c, 'd, 'e>(
 }
 
 pub fn send_along_route_with_secret<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, route: Route, expected_paths: &[&[&Node<'a, 'b, 'c>]], recv_value: u64, our_payment_hash: PaymentHash, our_payment_secret: PaymentSecret) -> PaymentId {
-       let payment_id = origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_secret)).unwrap();
+       let payment_id = PaymentId(origin_node.keys_manager.backing.get_secure_random_bytes());
+       origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_secret), payment_id).unwrap();
        check_added_monitors!(origin_node, expected_paths.len());
        pass_along_route(origin_node, expected_paths, recv_value, our_payment_hash, our_payment_secret);
        payment_id
@@ -1883,7 +1961,7 @@ pub fn route_over_limit<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_rou
        }
 
        let (_, our_payment_hash, our_payment_preimage) = get_payment_preimage_hash!(expected_route.last().unwrap());
-       unwrap_send_err!(origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_preimage)), true, APIError::ChannelUnavailable { ref err },
+       unwrap_send_err!(origin_node.node.send_payment(&route, our_payment_hash, &Some(our_payment_preimage), PaymentId(our_payment_hash.0)), true, APIError::ChannelUnavailable { ref err },
                assert!(err.contains("Cannot send value that would put us over the max HTLC value in flight our peer will accept")));
 }
 
@@ -1904,6 +1982,22 @@ pub fn fail_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expe
 }
 
 pub fn pass_failed_payment_back<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths_slice: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_hash: PaymentHash) {
+       let expected_payment_id = pass_failed_payment_back_no_abandon(origin_node, expected_paths_slice, skip_last, our_payment_hash);
+       if !skip_last {
+               origin_node.node.abandon_payment(expected_payment_id.unwrap());
+               let events = origin_node.node.get_and_clear_pending_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       Event::PaymentFailed { ref payment_hash, ref payment_id } => {
+                               assert_eq!(*payment_hash, our_payment_hash, "unexpected second payment_hash");
+                               assert_eq!(*payment_id, expected_payment_id.unwrap());
+                       }
+                       _ => panic!("Unexpected second event"),
+               }
+       }
+}
+
+pub fn pass_failed_payment_back_no_abandon<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths_slice: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_hash: PaymentHash) -> Option<PaymentId> {
        let mut expected_paths: Vec<_> = expected_paths_slice.iter().collect();
        check_added_monitors!(expected_paths[0].last().unwrap(), expected_paths.len());
 
@@ -1927,6 +2021,8 @@ pub fn pass_failed_payment_back<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expe
        per_path_msgs.sort_unstable_by(|(_, node_id_a), (_, node_id_b)| node_id_a.cmp(node_id_b));
        expected_paths.sort_unstable_by(|path_a, path_b| path_a[path_a.len() - 2].node.get_our_node_id().cmp(&path_b[path_b.len() - 2].node.get_our_node_id()));
 
+       let mut expected_payment_id = None;
+
        for (i, (expected_route, (path_msgs, next_hop))) in expected_paths.iter().zip(per_path_msgs.drain(..)).enumerate() {
                let mut next_msgs = Some(path_msgs);
                let mut expected_next_node = next_hop;
@@ -1975,7 +2071,7 @@ pub fn pass_failed_payment_back<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expe
                        commitment_signed_dance!(origin_node, prev_node, next_msgs.as_ref().unwrap().1, false);
                        let events = origin_node.node.get_and_clear_pending_events();
                        assert_eq!(events.len(), 1);
-                       let expected_payment_id = match events[0] {
+                       expected_payment_id = Some(match events[0] {
                                Event::PaymentPathFailed { payment_hash, payment_failed_permanently, all_paths_failed, ref path, ref payment_id, .. } => {
                                        assert_eq!(payment_hash, our_payment_hash);
                                        assert!(payment_failed_permanently);
@@ -1986,19 +2082,7 @@ pub fn pass_failed_payment_back<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expe
                                        payment_id.unwrap()
                                },
                                _ => panic!("Unexpected event"),
-                       };
-                       if i == expected_paths.len() - 1 {
-                               origin_node.node.abandon_payment(expected_payment_id);
-                               let events = origin_node.node.get_and_clear_pending_events();
-                               assert_eq!(events.len(), 1);
-                               match events[0] {
-                                       Event::PaymentFailed { ref payment_hash, ref payment_id } => {
-                                               assert_eq!(*payment_hash, our_payment_hash, "unexpected second payment_hash");
-                                               assert_eq!(*payment_id, expected_payment_id);
-                                       }
-                                       _ => panic!("Unexpected second event"),
-                               }
-                       }
+                       });
                }
        }
 
@@ -2007,6 +2091,8 @@ pub fn pass_failed_payment_back<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expe
        assert!(expected_paths[0].last().unwrap().node.get_and_clear_pending_events().is_empty());
        assert!(expected_paths[0].last().unwrap().node.get_and_clear_pending_msg_events().is_empty());
        check_added_monitors!(expected_paths[0].last().unwrap(), 0);
+
+       expected_payment_id
 }
 
 pub fn fail_payment<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_path: &[&Node<'a, 'b, 'c>], our_payment_hash: PaymentHash)  {
@@ -2071,7 +2157,7 @@ pub fn test_default_channel_config() -> UserConfig {
        default_config
 }
 
-pub fn create_node_chanmgrs<'a, 'b>(node_count: usize, cfgs: &'a Vec<NodeCfg<'b>>, node_config: &[Option<UserConfig>]) -> Vec<ChannelManager<EnforcingSigner, &'a TestChainMonitor<'b>, &'b test_utils::TestBroadcaster, &'a test_utils::TestKeysInterface, &'b test_utils::TestFeeEstimator, &'b test_utils::TestLogger>> {
+pub fn create_node_chanmgrs<'a, 'b>(node_count: usize, cfgs: &'a Vec<NodeCfg<'b>>, node_config: &[Option<UserConfig>]) -> Vec<ChannelManager<&'a TestChainMonitor<'b>, &'b test_utils::TestBroadcaster, &'a test_utils::TestKeysInterface, &'b test_utils::TestFeeEstimator, &'b test_utils::TestLogger>> {
        let mut chanmgrs = Vec::new();
        for i in 0..node_count {
                let network = Network::Testnet;
@@ -2087,7 +2173,7 @@ pub fn create_node_chanmgrs<'a, 'b>(node_count: usize, cfgs: &'a Vec<NodeCfg<'b>
        chanmgrs
 }
 
-pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeCfg<'c>>, chan_mgrs: &'a Vec<ChannelManager<EnforcingSigner, &'b TestChainMonitor<'c>, &'c test_utils::TestBroadcaster, &'b test_utils::TestKeysInterface, &'c test_utils::TestFeeEstimator, &'c test_utils::TestLogger>>) -> Vec<Node<'a, 'b, 'c>> {
+pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeCfg<'c>>, chan_mgrs: &'a Vec<ChannelManager<&'b TestChainMonitor<'c>, &'c test_utils::TestBroadcaster, &'b test_utils::TestKeysInterface, &'c test_utils::TestFeeEstimator, &'c test_utils::TestLogger>>) -> Vec<Node<'a, 'b, 'c>> {
        let mut nodes = Vec::new();
        let chan_count = Rc::new(RefCell::new(0));
        let payment_count = Rc::new(RefCell::new(0));
@@ -2097,6 +2183,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
                let gossip_sync = P2PGossipSync::new(&cfgs[i].network_graph, None, cfgs[i].logger);
                nodes.push(Node{
                        chain_source: cfgs[i].chain_source, tx_broadcaster: cfgs[i].tx_broadcaster,
+                       fee_estimator: cfgs[i].fee_estimator,
                        chain_monitor: &cfgs[i].chain_monitor, keys_manager: &cfgs[i].keys_manager,
                        node: &chan_mgrs[i], network_graph: &cfgs[i].network_graph, gossip_sync,
                        node_seed: cfgs[i].node_seed, network_chan_count: chan_count.clone(),
@@ -2326,6 +2413,14 @@ macro_rules! handle_chan_reestablish_msgs {
                                assert_eq!(*node_id, $dst_node.node.get_our_node_id());
                        }
 
+                       let mut had_channel_update = false; // ChannelUpdate may be now or later, but not both
+                       if let Some(&MessageSendEvent::SendChannelUpdate { ref node_id, ref msg }) = msg_events.get(idx) {
+                               assert_eq!(*node_id, $dst_node.node.get_our_node_id());
+                               idx += 1;
+                               assert_eq!(msg.contents.flags & 2, 0); // "disabled" flag must not be set as we just reconnected.
+                               had_channel_update = true;
+                       }
+
                        let mut revoke_and_ack = None;
                        let mut commitment_update = None;
                        let order = if let Some(ev) = msg_events.get(idx) {
@@ -2370,6 +2465,7 @@ macro_rules! handle_chan_reestablish_msgs {
                                assert_eq!(*node_id, $dst_node.node.get_our_node_id());
                                idx += 1;
                                assert_eq!(msg.contents.flags & 2, 0); // "disabled" flag must not be set as we just reconnected.
+                               assert!(!had_channel_update);
                        }
 
                        assert_eq!(msg_events.len(), idx);