Add a test for shutdown negotiaion funder restart and timeout
[rust-lightning] / lightning / src / ln / functional_test_utils.rs
index feeb691b1ceb9b0029d82c42e1b994285c65002e..3b0a8452b7b16ec713f90c5640c8059469d94d59 100644 (file)
@@ -199,6 +199,7 @@ pub struct NodeCfg<'a> {
        pub keys_manager: &'a test_utils::TestKeysInterface,
        pub logger: &'a test_utils::TestLogger,
        pub node_seed: [u8; 32],
+       pub features: InitFeatures,
 }
 
 pub struct Node<'a, 'b: 'a, 'c: 'b> {
@@ -415,12 +416,22 @@ macro_rules! get_htlc_update_msgs {
        }
 }
 
+#[cfg(test)]
+macro_rules! get_channel_ref {
+       ($node: expr, $lock: ident, $channel_id: expr) => {
+               {
+                       $lock = $node.node.channel_state.lock().unwrap();
+                       $lock.by_id.get_mut(&$channel_id).unwrap()
+               }
+       }
+}
+
 #[cfg(test)]
 macro_rules! get_feerate {
        ($node: expr, $channel_id: expr) => {
                {
-                       let chan_lock = $node.node.channel_state.lock().unwrap();
-                       let chan = chan_lock.by_id.get(&$channel_id).unwrap();
+                       let mut lock;
+                       let chan = get_channel_ref!($node, lock, $channel_id);
                        chan.get_feerate()
                }
        }
@@ -754,7 +765,7 @@ macro_rules! check_closed_broadcast {
 
 pub fn close_channel<'a, 'b, 'c>(outbound_node: &Node<'a, 'b, 'c>, inbound_node: &Node<'a, 'b, 'c>, channel_id: &[u8; 32], 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) = if close_inbound_first { (&outbound_node.node, &outbound_node.tx_broadcaster) } else { (&inbound_node.node, &inbound_node.tx_broadcaster) };
+       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) };
        let (tx_a, tx_b);
 
        node_a.close_channel(channel_id).unwrap();
@@ -787,29 +798,33 @@ pub fn close_channel<'a, 'b, 'c>(outbound_node: &Node<'a, 'b, 'c>, inbound_node:
        let (as_update, bs_update) = if close_inbound_first {
                assert!(node_a.get_and_clear_pending_msg_events().is_empty());
                node_a.handle_closing_signed(&node_b.get_our_node_id(), &closing_signed_b.unwrap());
-               assert_eq!(broadcaster_a.txn_broadcasted.lock().unwrap().len(), 1);
-               tx_a = broadcaster_a.txn_broadcasted.lock().unwrap().remove(0);
-               let (as_update, closing_signed_a) = get_closing_signed_broadcast!(node_a, node_b.get_our_node_id());
 
-               node_b.handle_closing_signed(&node_a.get_our_node_id(), &closing_signed_a.unwrap());
-               let (bs_update, none_b) = get_closing_signed_broadcast!(node_b, node_a.get_our_node_id());
-               assert!(none_b.is_none());
+               node_b.handle_closing_signed(&node_a.get_our_node_id(), &get_event_msg!(struct_a, MessageSendEvent::SendClosingSigned, node_b.get_our_node_id()));
                assert_eq!(broadcaster_b.txn_broadcasted.lock().unwrap().len(), 1);
                tx_b = broadcaster_b.txn_broadcasted.lock().unwrap().remove(0);
+               let (bs_update, closing_signed_b) = get_closing_signed_broadcast!(node_b, node_a.get_our_node_id());
+
+               node_a.handle_closing_signed(&node_b.get_our_node_id(), &closing_signed_b.unwrap());
+               let (as_update, none_a) = get_closing_signed_broadcast!(node_a, node_b.get_our_node_id());
+               assert!(none_a.is_none());
+               assert_eq!(broadcaster_a.txn_broadcasted.lock().unwrap().len(), 1);
+               tx_a = broadcaster_a.txn_broadcasted.lock().unwrap().remove(0);
                (as_update, bs_update)
        } else {
                let closing_signed_a = get_event_msg!(struct_a, MessageSendEvent::SendClosingSigned, node_b.get_our_node_id());
 
                node_b.handle_closing_signed(&node_a.get_our_node_id(), &closing_signed_a);
-               assert_eq!(broadcaster_b.txn_broadcasted.lock().unwrap().len(), 1);
-               tx_b = broadcaster_b.txn_broadcasted.lock().unwrap().remove(0);
-               let (bs_update, closing_signed_b) = get_closing_signed_broadcast!(node_b, node_a.get_our_node_id());
+               node_a.handle_closing_signed(&node_b.get_our_node_id(), &get_event_msg!(struct_b, MessageSendEvent::SendClosingSigned, node_a.get_our_node_id()));
 
-               node_a.handle_closing_signed(&node_b.get_our_node_id(), &closing_signed_b.unwrap());
-               let (as_update, none_a) = get_closing_signed_broadcast!(node_a, node_b.get_our_node_id());
-               assert!(none_a.is_none());
                assert_eq!(broadcaster_a.txn_broadcasted.lock().unwrap().len(), 1);
                tx_a = broadcaster_a.txn_broadcasted.lock().unwrap().remove(0);
+               let (as_update, closing_signed_a) = get_closing_signed_broadcast!(node_a, node_b.get_our_node_id());
+
+               node_b.handle_closing_signed(&node_a.get_our_node_id(), &closing_signed_a.unwrap());
+               let (bs_update, none_b) = get_closing_signed_broadcast!(node_b, node_a.get_our_node_id());
+               assert!(none_b.is_none());
+               assert_eq!(broadcaster_b.txn_broadcasted.lock().unwrap().len(), 1);
+               tx_b = broadcaster_b.txn_broadcasted.lock().unwrap().remove(0);
                (as_update, bs_update)
        };
        assert_eq!(tx_a, tx_b);
@@ -1006,6 +1021,20 @@ macro_rules! expect_payment_sent {
        }
 }
 
+macro_rules! expect_payment_forwarded {
+       ($node: expr, $expected_fee: expr, $upstream_force_closed: expr) => {
+               let events = $node.node.get_and_clear_pending_events();
+               assert_eq!(events.len(), 1);
+               match events[0] {
+                       Event::PaymentForwarded { fee_earned_msat, claim_from_onchain_tx } => {
+                               assert_eq!(fee_earned_msat, $expected_fee);
+                               assert_eq!(claim_from_onchain_tx, $upstream_force_closed);
+                       },
+                       _ => panic!("Unexpected event"),
+               }
+       }
+}
+
 #[cfg(test)]
 macro_rules! expect_payment_failure_chan_update {
        ($node: expr, $scid: expr, $chan_closed: expr) => {
@@ -1170,6 +1199,8 @@ pub fn claim_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, exp
                        ($node: expr, $prev_node: expr, $new_msgs: expr) => {
                                {
                                        $node.node.handle_update_fulfill_htlc(&$prev_node.node.get_our_node_id(), &next_msgs.as_ref().unwrap().0);
+                                       let fee = $node.node.channel_state.lock().unwrap().by_id.get(&next_msgs.as_ref().unwrap().0.channel_id).unwrap().config.forwarding_fee_base_msat;
+                                       expect_payment_forwarded!($node, Some(fee as u64), false);
                                        check_added_monitors!($node, 1);
                                        let new_next_msgs = if $new_msgs {
                                                let events = $node.node.get_and_clear_pending_msg_events();
@@ -1352,7 +1383,16 @@ pub fn create_node_cfgs<'a>(node_count: usize, chanmon_cfgs: &'a Vec<TestChanMon
        for i in 0..node_count {
                let chain_monitor = test_utils::TestChainMonitor::new(Some(&chanmon_cfgs[i].chain_source), &chanmon_cfgs[i].tx_broadcaster, &chanmon_cfgs[i].logger, &chanmon_cfgs[i].fee_estimator, &chanmon_cfgs[i].persister, &chanmon_cfgs[i].keys_manager);
                let seed = [i as u8; 32];
-               nodes.push(NodeCfg { chain_source: &chanmon_cfgs[i].chain_source, logger: &chanmon_cfgs[i].logger, tx_broadcaster: &chanmon_cfgs[i].tx_broadcaster, fee_estimator: &chanmon_cfgs[i].fee_estimator, chain_monitor, keys_manager: &chanmon_cfgs[i].keys_manager, node_seed: seed });
+               nodes.push(NodeCfg {
+                       chain_source: &chanmon_cfgs[i].chain_source,
+                       logger: &chanmon_cfgs[i].logger,
+                       tx_broadcaster: &chanmon_cfgs[i].tx_broadcaster,
+                       fee_estimator: &chanmon_cfgs[i].fee_estimator,
+                       chain_monitor,
+                       keys_manager: &chanmon_cfgs[i].keys_manager,
+                       node_seed: seed,
+                       features: InitFeatures::known(),
+               });
        }
 
        nodes
@@ -1368,6 +1408,9 @@ pub fn test_default_channel_config() -> UserConfig {
        // When most of our tests were written, the default HTLC minimum was fixed at 1000.
        // It now defaults to 1, so we simply set it to the expected value here.
        default_config.own_channel_config.our_htlc_minimum_msat = 1000;
+       // When most of our tests were written, we didn't have the notion of a `max_dust_htlc_exposure_msat`,
+       // It now defaults to 5_000_000 msat; to avoid interfering with tests we bump it to 50_000_000 msat.
+       default_config.channel_options.max_dust_htlc_exposure_msat = 50_000_000;
        default_config
 }
 
@@ -1407,8 +1450,8 @@ 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: InitFeatures::known() });
-                       nodes[j].node.peer_connected(&nodes[i].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known() });
+                       nodes[i].node.peer_connected(&nodes[j].node.get_our_node_id(), &msgs::Init { features: cfgs[j].features.clone() });
+                       nodes[j].node.peer_connected(&nodes[i].node.get_our_node_id(), &msgs::Init { features: cfgs[i].features.clone() });
                }
        }