DRY the get_route_and_payment_hash!() macro duplicated in tests
[rust-lightning] / lightning / src / ln / functional_tests.rs
index ca19ac8b4445062ce238e13e534a530b997d45ca..4ad777f5b6275cc957d5528cf62f4818db049f28 100644 (file)
@@ -12,6 +12,7 @@
 //! claim outputs on-chain.
 
 use chain;
+use chain::Listen;
 use chain::Watch;
 use chain::channelmonitor;
 use chain::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY};
@@ -1568,18 +1569,8 @@ fn test_fee_spike_violation_fails_htlc() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
        let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, InitFeatures::known(), InitFeatures::known());
-       let logger = test_utils::TestLogger::new();
-
-       macro_rules! get_route_and_payment_hash {
-               ($recv_value: expr) => {{
-                       let (payment_preimage, payment_hash) = get_payment_preimage_hash!(nodes[1]);
-                       let net_graph_msg_handler = &nodes[0].net_graph_msg_handler.network_graph.read().unwrap();
-                       let route = get_route(&nodes[0].node.get_our_node_id(), net_graph_msg_handler, &nodes.last().unwrap().node.get_our_node_id(), None, None, &Vec::new(), $recv_value, TEST_FINAL_CLTV, &logger).unwrap();
-                       (route, payment_hash, payment_preimage)
-               }}
-       }
 
-       let (route, payment_hash, _) = get_route_and_payment_hash!(3460001);
+       let (route, payment_hash, _) = get_route_and_payment_hash!(nodes[0], nodes[1], 3460001);
        // Need to manually create the update_add_htlc message to go around the channel reserve check in send_htlc()
        let secp_ctx = Secp256k1::new();
        let session_priv = SecretKey::from_slice(&[42; 32]).expect("RNG is bad!");
@@ -1708,18 +1699,8 @@ fn test_chan_reserve_violation_outbound_htlc_inbound_chan() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
        let _ = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, InitFeatures::known(), InitFeatures::known());
-       let logger = test_utils::TestLogger::new();
-
-       macro_rules! get_route_and_payment_hash {
-               ($recv_value: expr) => {{
-                       let (payment_preimage, payment_hash) = get_payment_preimage_hash!(nodes[1]);
-                       let net_graph_msg_handler = &nodes[1].net_graph_msg_handler;
-                       let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes.first().unwrap().node.get_our_node_id(), None, None, &Vec::new(), $recv_value, TEST_FINAL_CLTV, &logger).unwrap();
-                       (route, payment_hash, payment_preimage)
-               }}
-       }
 
-       let (route, our_payment_hash, _) = get_route_and_payment_hash!(4843000);
+       let (route, our_payment_hash, _) = get_route_and_payment_hash!(nodes[1], nodes[0], 4843000);
        unwrap_send_err!(nodes[1].node.send_payment(&route, our_payment_hash, &None), true, APIError::ChannelUnavailable { ref err },
                assert_eq!(err, "Cannot send value that would put counterparty balance under holder-announced channel reserve value"));
        assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
@@ -1740,18 +1721,8 @@ fn test_chan_reserve_violation_inbound_htlc_outbound_channel() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
        let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, InitFeatures::known(), InitFeatures::known());
-       let logger = test_utils::TestLogger::new();
 
-       macro_rules! get_route_and_payment_hash {
-               ($recv_value: expr) => {{
-                       let (payment_preimage, payment_hash) = get_payment_preimage_hash!(nodes[1]);
-                       let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
-                       let route = get_route(&nodes[1].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes.first().unwrap().node.get_our_node_id(), None, None, &Vec::new(), $recv_value, TEST_FINAL_CLTV, &logger).unwrap();
-                       (route, payment_hash, payment_preimage)
-               }}
-       }
-
-       let (route, payment_hash, _) = get_route_and_payment_hash!(1000);
+       let (route, payment_hash, _) = get_route_and_payment_hash!(nodes[1], nodes[0], 1000);
        // Need to manually create the update_add_htlc message to go around the channel reserve check in send_htlc()
        let secp_ctx = Secp256k1::new();
        let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
@@ -1836,16 +1807,6 @@ fn test_chan_reserve_violation_inbound_htlc_inbound_chan() {
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
        let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000, InitFeatures::known(), InitFeatures::known());
        let _ = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 100000, 95000000, InitFeatures::known(), InitFeatures::known());
-       let logger = test_utils::TestLogger::new();
-
-       macro_rules! get_route_and_payment_hash {
-               ($recv_value: expr) => {{
-                       let (payment_preimage, payment_hash) = get_payment_preimage_hash!(nodes[0]);
-                       let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
-                       let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes.last().unwrap().node.get_our_node_id(), None, None, &Vec::new(), $recv_value, TEST_FINAL_CLTV, &logger).unwrap();
-                       (route, payment_hash, payment_preimage)
-               }}
-       }
 
        let feemsat = 239;
        let total_routing_fee_msat = (nodes.len() - 2) as u64 * feemsat;
@@ -1858,7 +1819,7 @@ fn test_chan_reserve_violation_inbound_htlc_inbound_chan() {
        let amt_msat_1 = recv_value_1 + total_routing_fee_msat;
 
        // Add a pending HTLC.
-       let (route_1, our_payment_hash_1, _) = get_route_and_payment_hash!(amt_msat_1);
+       let (route_1, our_payment_hash_1, _) = get_route_and_payment_hash!(nodes[0], nodes[2], amt_msat_1);
        let payment_event_1 = {
                nodes[0].node.send_payment(&route_1, our_payment_hash_1, &None).unwrap();
                check_added_monitors!(nodes[0], 1);
@@ -1873,7 +1834,7 @@ fn test_chan_reserve_violation_inbound_htlc_inbound_chan() {
        let commit_tx_fee_2_htlcs = commit_tx_fee_msat(feerate, 2);
        let recv_value_2 = chan_stat.value_to_self_msat - amt_msat_1 - chan_stat.channel_reserve_msat - total_routing_fee_msat - commit_tx_fee_2_htlcs + 1;
        let amt_msat_2 = recv_value_2 + total_routing_fee_msat;
-       let (route_2, _, _) = get_route_and_payment_hash!(amt_msat_2);
+       let (route_2, _, _) = get_route_and_payment_hash!(nodes[0], nodes[2], amt_msat_2);
 
        // Need to manually create the update_add_htlc message to go around the channel reserve check in send_htlc()
        let secp_ctx = Secp256k1::new();
@@ -1931,7 +1892,6 @@ fn test_channel_reserve_holding_cell_htlcs() {
        let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
        let chan_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 190000, 1001, InitFeatures::known(), InitFeatures::known());
        let chan_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 190000, 1001, InitFeatures::known(), InitFeatures::known());
-       let logger = test_utils::TestLogger::new();
 
        let mut stat01 = get_channel_value_stat!(nodes[0], chan_1.2);
        let mut stat11 = get_channel_value_stat!(nodes[1], chan_1.2);
@@ -1939,15 +1899,6 @@ fn test_channel_reserve_holding_cell_htlcs() {
        let mut stat12 = get_channel_value_stat!(nodes[1], chan_2.2);
        let mut stat22 = get_channel_value_stat!(nodes[2], chan_2.2);
 
-       macro_rules! get_route_and_payment_hash {
-               ($recv_value: expr) => {{
-                       let (payment_preimage, payment_hash) = get_payment_preimage_hash!(nodes[0]);
-                       let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
-                       let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph.read().unwrap(), &nodes.last().unwrap().node.get_our_node_id(), None, None, &Vec::new(), $recv_value, TEST_FINAL_CLTV, &logger).unwrap();
-                       (route, payment_hash, payment_preimage)
-               }}
-       }
-
        macro_rules! expect_forward {
                ($node: expr) => {{
                        let mut events = $node.node.get_and_clear_pending_msg_events();
@@ -1966,7 +1917,7 @@ fn test_channel_reserve_holding_cell_htlcs() {
 
        // attempt to send amt_msat > their_max_htlc_value_in_flight_msat
        {
-               let (mut route, our_payment_hash, _) = get_route_and_payment_hash!(recv_value_0);
+               let (mut route, our_payment_hash, _) = get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_0);
                route.paths[0].last_mut().unwrap().fee_msat += 1;
                assert!(route.paths[0].iter().rev().skip(1).all(|h| h.fee_msat == feemsat));
                unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &None), true, APIError::ChannelUnavailable { ref err },
@@ -2018,7 +1969,7 @@ fn test_channel_reserve_holding_cell_htlcs() {
        let recv_value_1 = (stat01.value_to_self_msat - stat01.channel_reserve_msat - total_fee_msat - commit_tx_fee_2_htlcs)/2;
        let amt_msat_1 = recv_value_1 + total_fee_msat;
 
-       let (route_1, our_payment_hash_1, our_payment_preimage_1) = get_route_and_payment_hash!(recv_value_1);
+       let (route_1, our_payment_hash_1, our_payment_preimage_1) = get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_1);
        let payment_event_1 = {
                nodes[0].node.send_payment(&route_1, our_payment_hash_1, &None).unwrap();
                check_added_monitors!(nodes[0], 1);
@@ -2032,7 +1983,7 @@ fn test_channel_reserve_holding_cell_htlcs() {
        // channel reserve test with htlc pending output > 0
        let recv_value_2 = stat01.value_to_self_msat - amt_msat_1 - stat01.channel_reserve_msat - total_fee_msat - commit_tx_fee_2_htlcs;
        {
-               let (route, our_payment_hash, _) = get_route_and_payment_hash!(recv_value_2 + 1);
+               let (route, our_payment_hash, _) = get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_2 + 1);
                unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &None), true, APIError::ChannelUnavailable { ref err },
                        assert!(regex::Regex::new(r"Cannot send value that would put our balance under counterparty-announced channel reserve value \(\d+\)").unwrap().is_match(err)));
                assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
@@ -2049,7 +2000,7 @@ fn test_channel_reserve_holding_cell_htlcs() {
        }
 
        // now see if they go through on both sides
-       let (route_21, our_payment_hash_21, our_payment_preimage_21) = get_route_and_payment_hash!(recv_value_21);
+       let (route_21, our_payment_hash_21, our_payment_preimage_21) = get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_21);
        // but this will stuck in the holding cell
        nodes[0].node.send_payment(&route_21, our_payment_hash_21, &None).unwrap();
        check_added_monitors!(nodes[0], 0);
@@ -2058,14 +2009,14 @@ fn test_channel_reserve_holding_cell_htlcs() {
 
        // test with outbound holding cell amount > 0
        {
-               let (route, our_payment_hash, _) = get_route_and_payment_hash!(recv_value_22+1);
+               let (route, our_payment_hash, _) = get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_22+1);
                unwrap_send_err!(nodes[0].node.send_payment(&route, our_payment_hash, &None), true, APIError::ChannelUnavailable { ref err },
                        assert!(regex::Regex::new(r"Cannot send value that would put our balance under counterparty-announced channel reserve value \(\d+\)").unwrap().is_match(err)));
                assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
                nodes[0].logger.assert_log_contains("lightning::ln::channelmanager".to_string(), "Cannot send value that would put our balance under counterparty-announced channel reserve value".to_string(), 2);
        }
 
-       let (route_22, our_payment_hash_22, our_payment_preimage_22) = get_route_and_payment_hash!(recv_value_22);
+       let (route_22, our_payment_hash_22, our_payment_preimage_22) = get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_22);
        // this will also stuck in the holding cell
        nodes[0].node.send_payment(&route_22, our_payment_hash_22, &None).unwrap();
        check_added_monitors!(nodes[0], 0);
@@ -2940,8 +2891,7 @@ fn test_htlc_on_chain_success() {
        check_tx_local_broadcast!(nodes[0], true, commitment_tx[0], chan_1.3);
 }
 
-#[test]
-fn test_htlc_on_chain_timeout() {
+fn do_test_htlc_on_chain_timeout(connect_style: ConnectStyle) {
        // Test that in case of a unilateral close onchain, we detect the state of output and
        // timeout the HTLC backward accordingly. So here we test that ChannelManager is
        // broadcasting the right event to other nodes in payment path.
@@ -2953,7 +2903,10 @@ fn test_htlc_on_chain_timeout() {
        let chanmon_cfgs = create_chanmon_cfgs(3);
        let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
        let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
-       let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+       let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
+       *nodes[0].connect_style.borrow_mut() = connect_style;
+       *nodes[1].connect_style.borrow_mut() = connect_style;
+       *nodes[2].connect_style.borrow_mut() = connect_style;
 
        // Create some intial channels
        let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
@@ -3067,6 +3020,13 @@ fn test_htlc_on_chain_timeout() {
        assert_eq!(node_txn[2].clone().input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
 }
 
+#[test]
+fn test_htlc_on_chain_timeout() {
+       do_test_htlc_on_chain_timeout(ConnectStyle::BestBlockFirstSkippingBlocks);
+       do_test_htlc_on_chain_timeout(ConnectStyle::TransactionsFirstSkippingBlocks);
+       do_test_htlc_on_chain_timeout(ConnectStyle::FullBlockViaListen);
+}
+
 #[test]
 fn test_simple_commitment_revoked_fail_backward() {
        // Test that in case of a revoked commitment tx, we detect the resolution of output by justice tx
@@ -8216,7 +8176,7 @@ fn test_update_err_monitor_lockdown() {
                watchtower
        };
        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-       watchtower.chain_monitor.block_connected(&header, &[], 200);
+       watchtower.chain_monitor.block_connected(&Block { header, txdata: vec![] }, 200);
 
        // Try to update ChannelMonitor
        assert!(nodes[1].node.claim_funds(preimage, &None, 9_000_000));
@@ -8275,7 +8235,7 @@ fn test_concurrent_monitor_claim() {
                watchtower
        };
        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-       watchtower_alice.chain_monitor.block_connected(&header, &vec![], CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
+       watchtower_alice.chain_monitor.block_connected(&Block { header, txdata: vec![] }, CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
 
        // Watchtower Alice should have broadcast a commitment/HTLC-timeout
        {
@@ -8301,7 +8261,7 @@ fn test_concurrent_monitor_claim() {
                watchtower
        };
        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-       watchtower_bob.chain_monitor.block_connected(&header, &vec![], CHAN_CONFIRM_DEPTH + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
+       watchtower_bob.chain_monitor.block_connected(&Block { header, txdata: vec![] }, CHAN_CONFIRM_DEPTH + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
 
        // Route another payment to generate another update with still previous HTLC pending
        let (_, payment_hash) = get_payment_preimage_hash!(nodes[0]);
@@ -8327,7 +8287,8 @@ fn test_concurrent_monitor_claim() {
        check_added_monitors!(nodes[0], 1);
 
        //// Provide one more block to watchtower Bob, expect broadcast of commitment and HTLC-Timeout
-       watchtower_bob.chain_monitor.block_connected(&header, &vec![], CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
+       let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+       watchtower_bob.chain_monitor.block_connected(&Block { header, txdata: vec![] }, CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
 
        // Watchtower Bob should have broadcast a commitment/HTLC-timeout
        let bob_state_y;
@@ -8339,7 +8300,8 @@ fn test_concurrent_monitor_claim() {
        };
 
        // We confirm Bob's state Y on Alice, she should broadcast a HTLC-timeout
-       watchtower_alice.chain_monitor.block_connected(&header, &vec![(0, &bob_state_y)], CHAN_CONFIRM_DEPTH + 2 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
+       let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+       watchtower_alice.chain_monitor.block_connected(&Block { header, txdata: vec![bob_state_y.clone()] }, CHAN_CONFIRM_DEPTH + 2 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS);
        {
                let htlc_txn = chanmon_cfgs[0].tx_broadcaster.txn_broadcasted.lock().unwrap();
                // We broadcast twice the transaction, once due to the HTLC-timeout, once due
@@ -8816,3 +8778,53 @@ fn test_error_chans_closed() {
        assert_eq!(nodes[0].node.list_usable_channels().len(), 1);
        assert!(nodes[0].node.list_usable_channels()[0].channel_id == chan_3.2);
 }
+
+#[test]
+fn test_invalid_funding_tx() {
+       // Test that we properly handle invalid funding transactions sent to us from a peer.
+       //
+       // Previously, all other major lightning implementations had failed to properly sanitize
+       // funding transactions from their counterparties, leading to a multi-implementation critical
+       // security vulnerability (though we always sanitized properly, we've previously had
+       // un-released crashes in the sanitization process).
+       let chanmon_cfgs = create_chanmon_cfgs(2);
+       let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
+       let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
+
+       nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 10_000, 42, None).unwrap();
+       nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()));
+       nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
+
+       let (temporary_channel_id, mut tx, _) = create_funding_transaction(&nodes[0], 100_000, 42);
+       for output in tx.output.iter_mut() {
+               // Make the confirmed funding transaction have a bogus script_pubkey
+               output.script_pubkey = bitcoin::Script::new();
+       }
+
+       nodes[0].node.funding_transaction_generated_unchecked(&temporary_channel_id, tx.clone(), 0).unwrap();
+       nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id()));
+       check_added_monitors!(nodes[1], 1);
+
+       nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id()));
+       check_added_monitors!(nodes[0], 1);
+
+       let events_1 = nodes[0].node.get_and_clear_pending_events();
+       assert_eq!(events_1.len(), 0);
+
+       assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 1);
+       assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0], tx);
+       nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clear();
+
+       confirm_transaction_at(&nodes[1], &tx, 1);
+       check_added_monitors!(nodes[1], 1);
+       let events_2 = nodes[1].node.get_and_clear_pending_msg_events();
+       assert_eq!(events_2.len(), 1);
+       if let MessageSendEvent::HandleError { node_id, action } = &events_2[0] {
+               assert_eq!(*node_id, nodes[0].node.get_our_node_id());
+               if let msgs::ErrorAction::SendErrorMessage { msg } = action {
+                       assert_eq!(msg.data, "funding tx had wrong script/value or output index");
+               } else { panic!(); }
+       } else { panic!(); }
+       assert_eq!(nodes[1].node.list_channels().len(), 0);
+}