Merge pull request #1268 from TheBlueMatt/2022-01-balance-underflow
[rust-lightning] / lightning / src / ln / functional_tests.rs
index ce6a84c952403c8fc104f576360e80b2b6c1fb1c..35ecd66cc713701420940e177a093092761d059f 100644 (file)
@@ -483,10 +483,54 @@ fn do_test_1_conf_open(connect_style: ConnectStyle) {
        let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001, InitFeatures::known(), InitFeatures::known());
        mine_transaction(&nodes[1], &tx);
        nodes[0].node.handle_funding_locked(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendFundingLocked, nodes[0].node.get_our_node_id()));
+       assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
 
        mine_transaction(&nodes[0], &tx);
-       let (funding_locked, _) = create_chan_between_nodes_with_value_confirm_second(&nodes[1], &nodes[0]);
-       let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_locked);
+       let as_msg_events = nodes[0].node.get_and_clear_pending_msg_events();
+       assert_eq!(as_msg_events.len(), 2);
+       let as_funding_locked = if let MessageSendEvent::SendFundingLocked { ref node_id, ref msg } = as_msg_events[0] {
+               assert_eq!(*node_id, nodes[1].node.get_our_node_id());
+               msg.clone()
+       } else { panic!("Unexpected event"); };
+       if let MessageSendEvent::SendChannelUpdate { ref node_id, msg: _ } = as_msg_events[1] {
+               assert_eq!(*node_id, nodes[1].node.get_our_node_id());
+       } else { panic!("Unexpected event"); }
+
+       nodes[1].node.handle_funding_locked(&nodes[0].node.get_our_node_id(), &as_funding_locked);
+       let bs_msg_events = nodes[1].node.get_and_clear_pending_msg_events();
+       assert_eq!(bs_msg_events.len(), 1);
+       if let MessageSendEvent::SendChannelUpdate { ref node_id, msg: _ } = bs_msg_events[0] {
+               assert_eq!(*node_id, nodes[0].node.get_our_node_id());
+       } else { panic!("Unexpected event"); }
+
+       send_payment(&nodes[0], &[&nodes[1]], 100_000);
+
+       // After 6 confirmations, as required by the spec, we'll send announcement_signatures and
+       // broadcast the channel_announcement (but not before exactly 6 confirmations).
+       connect_blocks(&nodes[0], 4);
+       assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
+       connect_blocks(&nodes[0], 1);
+       nodes[1].node.handle_announcement_signatures(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendAnnouncementSignatures, nodes[1].node.get_our_node_id()));
+       assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
+
+       connect_blocks(&nodes[1], 5);
+       let bs_announce_events = nodes[1].node.get_and_clear_pending_msg_events();
+       assert_eq!(bs_announce_events.len(), 2);
+       let bs_announcement_sigs = if let MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } = bs_announce_events[0] {
+               assert_eq!(*node_id, nodes[0].node.get_our_node_id());
+               msg.clone()
+       } else { panic!("Unexpected event"); };
+       let (bs_announcement, bs_update) = if let MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } = bs_announce_events[1] {
+               (msg.clone(), update_msg.clone())
+       } else { panic!("Unexpected event"); };
+
+       nodes[0].node.handle_announcement_signatures(&nodes[1].node.get_our_node_id(), &bs_announcement_sigs);
+       let as_announce_events = nodes[0].node.get_and_clear_pending_msg_events();
+       assert_eq!(as_announce_events.len(), 1);
+       let (announcement, as_update) = if let MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } = as_announce_events[0] {
+               (msg.clone(), update_msg.clone())
+       } else { panic!("Unexpected event"); };
+       assert_eq!(announcement, bs_announcement);
 
        for node in nodes {
                assert!(node.net_graph_msg_handler.handle_channel_announcement(&announcement).unwrap());
@@ -730,7 +774,7 @@ fn test_update_fee_that_funder_cannot_afford() {
                        &mut htlcs,
                        &local_chan.channel_transaction_parameters.as_counterparty_broadcastable()
                );
-               local_chan_signer.sign_counterparty_commitment(&commitment_tx, &secp_ctx).unwrap()
+               local_chan_signer.sign_counterparty_commitment(&commitment_tx, Vec::new(), &secp_ctx).unwrap()
        };
 
        let commit_signed_msg = msgs::CommitmentSigned {
@@ -1466,7 +1510,7 @@ fn test_fee_spike_violation_fails_htlc() {
                        &mut vec![(accepted_htlc_info, ())],
                        &local_chan.channel_transaction_parameters.as_counterparty_broadcastable()
                );
-               local_chan_signer.sign_counterparty_commitment(&commitment_tx, &secp_ctx).unwrap()
+               local_chan_signer.sign_counterparty_commitment(&commitment_tx, Vec::new(), &secp_ctx).unwrap()
        };
 
        let commit_signed_msg = msgs::CommitmentSigned {
@@ -3807,15 +3851,7 @@ fn test_funding_peer_disconnect() {
 
        confirm_transaction(&nodes[0], &tx);
        let events_1 = nodes[0].node.get_and_clear_pending_msg_events();
-       let chan_id;
-       assert_eq!(events_1.len(), 1);
-       match events_1[0] {
-               MessageSendEvent::SendFundingLocked { ref node_id, ref msg } => {
-                       assert_eq!(*node_id, nodes[1].node.get_our_node_id());
-                       chan_id = msg.channel_id;
-               },
-               _ => panic!("Unexpected event"),
-       }
+       assert!(events_1.is_empty());
 
        reconnect_nodes(&nodes[0], &nodes[1], (false, true), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
 
@@ -3824,53 +3860,106 @@ fn test_funding_peer_disconnect() {
 
        confirm_transaction(&nodes[1], &tx);
        let events_2 = nodes[1].node.get_and_clear_pending_msg_events();
-       assert_eq!(events_2.len(), 2);
-       let funding_locked = match events_2[0] {
+       assert!(events_2.is_empty());
+
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       let as_reestablish = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id());
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       let bs_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
+
+       // nodes[0] hasn't yet received a funding_locked, so it only sends that on reconnect.
+       nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish);
+       let events_3 = nodes[0].node.get_and_clear_pending_msg_events();
+       assert_eq!(events_3.len(), 1);
+       let as_funding_locked = match events_3[0] {
+               MessageSendEvent::SendFundingLocked { ref node_id, ref msg } => {
+                       assert_eq!(*node_id, nodes[1].node.get_our_node_id());
+                       msg.clone()
+               },
+               _ => panic!("Unexpected event {:?}", events_3[0]),
+       };
+
+       // nodes[1] received nodes[0]'s funding_locked on the first reconnect above, so it should send
+       // announcement_signatures as well as channel_update.
+       nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &as_reestablish);
+       let events_4 = nodes[1].node.get_and_clear_pending_msg_events();
+       assert_eq!(events_4.len(), 3);
+       let chan_id;
+       let bs_funding_locked = match events_4[0] {
                MessageSendEvent::SendFundingLocked { ref node_id, ref msg } => {
                        assert_eq!(*node_id, nodes[0].node.get_our_node_id());
+                       chan_id = msg.channel_id;
                        msg.clone()
                },
-               _ => panic!("Unexpected event"),
+               _ => panic!("Unexpected event {:?}", events_4[0]),
        };
-       let bs_announcement_sigs = match events_2[1] {
+       let bs_announcement_sigs = match events_4[1] {
                MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => {
                        assert_eq!(*node_id, nodes[0].node.get_our_node_id());
                        msg.clone()
                },
-               _ => panic!("Unexpected event"),
+               _ => panic!("Unexpected event {:?}", events_4[1]),
        };
+       match events_4[2] {
+               MessageSendEvent::SendChannelUpdate { ref node_id, msg: _ } => {
+                       assert_eq!(*node_id, nodes[0].node.get_our_node_id());
+               },
+               _ => panic!("Unexpected event {:?}", events_4[2]),
+       }
 
-       reconnect_nodes(&nodes[0], &nodes[1], (true, true), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
+       // Re-deliver nodes[0]'s funding_locked, which nodes[1] can safely ignore. It currently
+       // generates a duplicative private channel_update
+       nodes[1].node.handle_funding_locked(&nodes[0].node.get_our_node_id(), &as_funding_locked);
+       let events_5 = nodes[1].node.get_and_clear_pending_msg_events();
+       assert_eq!(events_5.len(), 1);
+       match events_5[0] {
+               MessageSendEvent::SendChannelUpdate { ref node_id, msg: _ } => {
+                       assert_eq!(*node_id, nodes[0].node.get_our_node_id());
+               },
+               _ => panic!("Unexpected event {:?}", events_5[0]),
+       };
 
-       nodes[0].node.handle_funding_locked(&nodes[1].node.get_our_node_id(), &funding_locked);
-       nodes[0].node.handle_announcement_signatures(&nodes[1].node.get_our_node_id(), &bs_announcement_sigs);
-       let events_3 = nodes[0].node.get_and_clear_pending_msg_events();
-       assert_eq!(events_3.len(), 2);
-       let as_announcement_sigs = match events_3[0] {
+       // When we deliver nodes[1]'s funding_locked, however, nodes[0] will generate its
+       // announcement_signatures.
+       nodes[0].node.handle_funding_locked(&nodes[1].node.get_our_node_id(), &bs_funding_locked);
+       let events_6 = nodes[0].node.get_and_clear_pending_msg_events();
+       assert_eq!(events_6.len(), 1);
+       let as_announcement_sigs = match events_6[0] {
                MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => {
                        assert_eq!(*node_id, nodes[1].node.get_our_node_id());
                        msg.clone()
                },
-               _ => panic!("Unexpected event"),
+               _ => panic!("Unexpected event {:?}", events_6[0]),
        };
-       let (as_announcement, as_update) = match events_3[1] {
+
+       // When we deliver nodes[1]'s announcement_signatures to nodes[0], nodes[0] should immediately
+       // broadcast the channel announcement globally, as well as re-send its (now-public)
+       // channel_update.
+       nodes[0].node.handle_announcement_signatures(&nodes[1].node.get_our_node_id(), &bs_announcement_sigs);
+       let events_7 = nodes[0].node.get_and_clear_pending_msg_events();
+       assert_eq!(events_7.len(), 1);
+       let (chan_announcement, as_update) = match events_7[0] {
                MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
                        (msg.clone(), update_msg.clone())
                },
-               _ => panic!("Unexpected event"),
+               _ => panic!("Unexpected event {:?}", events_7[0]),
        };
 
+       // Finally, deliver nodes[0]'s announcement_signatures to nodes[1] and make sure it creates the
+       // same channel_announcement.
        nodes[1].node.handle_announcement_signatures(&nodes[0].node.get_our_node_id(), &as_announcement_sigs);
-       let events_4 = nodes[1].node.get_and_clear_pending_msg_events();
-       assert_eq!(events_4.len(), 1);
-       let (_, bs_update) = match events_4[0] {
+       let events_8 = nodes[1].node.get_and_clear_pending_msg_events();
+       assert_eq!(events_8.len(), 1);
+       let bs_update = match events_8[0] {
                MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
-                       (msg.clone(), update_msg.clone())
+                       assert_eq!(*msg, chan_announcement);
+                       update_msg.clone()
                },
-               _ => panic!("Unexpected event"),
+               _ => panic!("Unexpected event {:?}", events_8[0]),
        };
 
-       nodes[0].net_graph_msg_handler.handle_channel_announcement(&as_announcement).unwrap();
+       // Provide the channel announcement and public updates to the network graph
+       nodes[0].net_graph_msg_handler.handle_channel_announcement(&chan_announcement).unwrap();
        nodes[0].net_graph_msg_handler.handle_channel_update(&bs_update).unwrap();
        nodes[0].net_graph_msg_handler.handle_channel_update(&as_update).unwrap();
 
@@ -3918,14 +4007,14 @@ fn test_funding_peer_disconnect() {
 
        reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
 
-       // as_announcement should be re-generated exactly by broadcast_node_announcement.
+       // The channel announcement should be re-generated exactly by broadcast_node_announcement.
        nodes[0].node.broadcast_node_announcement([0, 0, 0], [0; 32], Vec::new());
        let msgs = nodes[0].node.get_and_clear_pending_msg_events();
        let mut found_announcement = false;
        for event in msgs.iter() {
                match event {
                        MessageSendEvent::BroadcastChannelAnnouncement { ref msg, .. } => {
-                               if *msg == as_announcement { found_announcement = true; }
+                               if *msg == chan_announcement { found_announcement = true; }
                        },
                        MessageSendEvent::BroadcastNodeAnnouncement { .. } => {},
                        _ => panic!("Unexpected event"),
@@ -7350,7 +7439,7 @@ fn test_check_htlc_underpaying() {
        // Create some initial channels
        create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
 
-       let scorer = test_utils::TestScorer::with_fixed_penalty(0);
+       let scorer = test_utils::TestScorer::with_penalty(0);
        let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id()).with_features(InvoiceFeatures::known());
        let route = get_route(&nodes[0].node.get_our_node_id(), &payment_params, nodes[0].network_graph, None, 10_000, TEST_FINAL_CLTV, nodes[0].logger, &scorer).unwrap();
        let (_, our_payment_hash, _) = get_payment_preimage_hash!(nodes[0]);
@@ -7753,7 +7842,7 @@ fn test_bump_penalty_txn_on_revoked_htlcs() {
        let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 59000000, InitFeatures::known(), InitFeatures::known());
        // Lock HTLC in both directions (using a slightly lower CLTV delay to provide timely RBF bumps)
        let payment_params = PaymentParameters::from_node_id(nodes[1].node.get_our_node_id()).with_features(InvoiceFeatures::known());
-       let scorer = test_utils::TestScorer::with_fixed_penalty(0);
+       let scorer = test_utils::TestScorer::with_penalty(0);
        let route = get_route(&nodes[0].node.get_our_node_id(), &payment_params, &nodes[0].network_graph, None,
                3_000_000, 50, nodes[0].logger, &scorer).unwrap();
        let payment_preimage = send_along_route(&nodes[0], route, &[&nodes[1]], 3_000_000).0;
@@ -9327,7 +9416,7 @@ fn test_keysend_payments_to_public_node() {
                final_value_msat: 10000,
                final_cltv_expiry_delta: 40,
        };
-       let scorer = test_utils::TestScorer::with_fixed_penalty(0);
+       let scorer = test_utils::TestScorer::with_penalty(0);
        let route = find_route(&payer_pubkey, &route_params, network_graph, None, nodes[0].logger, &scorer).unwrap();
 
        let test_preimage = PaymentPreimage([42; 32]);
@@ -9361,7 +9450,7 @@ fn test_keysend_payments_to_private_node() {
        };
        let network_graph = nodes[0].network_graph;
        let first_hops = nodes[0].node.list_usable_channels();
-       let scorer = test_utils::TestScorer::with_fixed_penalty(0);
+       let scorer = test_utils::TestScorer::with_penalty(0);
        let route = find_route(
                &payer_pubkey, &route_params, network_graph, Some(&first_hops.iter().collect::<Vec<_>>()),
                nodes[0].logger, &scorer