X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffunctional_tests.rs;h=49e06dab2d179acda19a5e07c164f186ba290d95;hb=7893ddc72184fb1495fd7e19880527fa425012b4;hp=1020b0fa43a8220f0f0ac6448df5a84fc5d809e2;hpb=d96a492b96df914cfd0ae389fd04fd7d8337f269;p=rust-lightning diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 1020b0fa..49e06dab 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -42,7 +42,7 @@ use bitcoin::blockdata::constants::genesis_block; use bitcoin::network::constants::Network; use bitcoin::secp256k1::Secp256k1; -use bitcoin::secp256k1::key::{PublicKey,SecretKey}; +use bitcoin::secp256k1::{PublicKey,SecretKey}; use regex; @@ -515,7 +515,7 @@ fn do_test_sanity_on_in_flight_opens(steps: u8) { if steps & 0x0f == 2 { return; } nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_channel); - let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], 100000, 42); + let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42); if steps & 0x0f == 3 { return; } nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); @@ -3489,6 +3489,47 @@ fn test_dup_events_on_peer_disconnect() { expect_payment_path_successful!(nodes[0]); } +#[test] +fn test_peer_disconnected_before_funding_broadcasted() { + // Test that channels are closed with `ClosureReason::DisconnectedPeer` if the peer disconnects + // before the funding transaction has been broadcasted. + 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); + + // Open a channel between `nodes[0]` and `nodes[1]`, for which the funding transaction is never + // broadcasted, even though it's created by `nodes[0]`. + let expected_temporary_channel_id = nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 1_000_000, 500_000_000, 42, None).unwrap(); + let open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()); + nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_channel); + let accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()); + nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_channel); + + let (temporary_channel_id, tx, _funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 1_000_000, 42); + assert_eq!(temporary_channel_id, expected_temporary_channel_id); + + assert!(nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).is_ok()); + + let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id()); + assert_eq!(funding_created_msg.temporary_channel_id, expected_temporary_channel_id); + + // Even though the funding transaction is created by `nodes[0]`, the `FundingCreated` msg is + // never sent to `nodes[1]`, and therefore the tx is never signed by either party nor + // broadcasted. + { + assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 0); + } + + // Ensure that the channel is closed with `ClosureReason::DisconnectedPeer` when the peers are + // disconnected before the funding transaction was broadcasted. + nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); + nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); + + check_closed_event!(nodes[0], 1, ClosureReason::DisconnectedPeer); + check_closed_event!(nodes[1], 1, ClosureReason::DisconnectedPeer); +} + #[test] fn test_simple_peer_disconnect() { // Test that we can reconnect when there are no lost messages @@ -4385,7 +4426,7 @@ fn test_manager_serialize_deserialize_events() { node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), a_flags, &get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id())); node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), b_flags, &get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a.node.get_our_node_id())); - let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&node_a, channel_value, 42); + let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&node_a, &node_b.node.get_our_node_id(), channel_value, 42); node_a.node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); check_added_monitors!(node_a, 0); @@ -5746,8 +5787,8 @@ fn test_key_derivation_params() { check_spends!(local_txn_1[0], chan_1.3); // We check funding pubkey are unique - let (from_0_funding_key_0, from_0_funding_key_1) = (PublicKey::from_slice(&local_txn_0[0].input[0].witness[3][2..35]), PublicKey::from_slice(&local_txn_0[0].input[0].witness[3][36..69])); - let (from_1_funding_key_0, from_1_funding_key_1) = (PublicKey::from_slice(&local_txn_1[0].input[0].witness[3][2..35]), PublicKey::from_slice(&local_txn_1[0].input[0].witness[3][36..69])); + let (from_0_funding_key_0, from_0_funding_key_1) = (PublicKey::from_slice(&local_txn_0[0].input[0].witness.to_vec()[3][2..35]), PublicKey::from_slice(&local_txn_0[0].input[0].witness.to_vec()[3][36..69])); + let (from_1_funding_key_0, from_1_funding_key_1) = (PublicKey::from_slice(&local_txn_1[0].input[0].witness.to_vec()[3][2..35]), PublicKey::from_slice(&local_txn_1[0].input[0].witness.to_vec()[3][36..69])); if from_0_funding_key_0 == from_1_funding_key_0 || from_0_funding_key_0 == from_1_funding_key_1 || from_0_funding_key_1 == from_1_funding_key_0 @@ -7641,7 +7682,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() { assert_eq!(node_txn[0].output.len(), 1); check_spends!(node_txn[0], revoked_txn[0]); let fee_1 = penalty_sum - node_txn[0].output[0].value; - feerate_1 = fee_1 * 1000 / node_txn[0].get_weight() as u64; + feerate_1 = fee_1 * 1000 / node_txn[0].weight() as u64; penalty_1 = node_txn[0].txid(); node_txn.clear(); }; @@ -7661,7 +7702,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() { // Verify new bumped tx is different from last claiming transaction, we don't want spurrious rebroadcast assert_ne!(penalty_2, penalty_1); let fee_2 = penalty_sum - node_txn[0].output[0].value; - feerate_2 = fee_2 * 1000 / node_txn[0].get_weight() as u64; + feerate_2 = fee_2 * 1000 / node_txn[0].weight() as u64; // Verify 25% bump heuristic assert!(feerate_2 * 100 >= feerate_1 * 125); node_txn.clear(); @@ -7684,7 +7725,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() { // Verify new bumped tx is different from last claiming transaction, we don't want spurrious rebroadcast assert_ne!(penalty_3, penalty_2); let fee_3 = penalty_sum - node_txn[0].output[0].value; - feerate_3 = fee_3 * 1000 / node_txn[0].get_weight() as u64; + feerate_3 = fee_3 * 1000 / node_txn[0].weight() as u64; // Verify 25% bump heuristic assert!(feerate_3 * 100 >= feerate_2 * 125); node_txn.clear(); @@ -7803,7 +7844,7 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { first = node_txn[4].txid(); // Store both feerates for later comparison let fee_1 = revoked_htlc_txn[0].output[0].value + revoked_htlc_txn[2].output[0].value - node_txn[4].output[0].value; - feerate_1 = fee_1 * 1000 / node_txn[4].get_weight() as u64; + feerate_1 = fee_1 * 1000 / node_txn[4].weight() as u64; penalty_txn = vec![node_txn[2].clone()]; node_txn.clear(); } @@ -7843,7 +7884,7 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { // Verify bumped tx is different and 25% bump heuristic assert_ne!(first, node_txn[0].txid()); let fee_2 = revoked_htlc_txn[0].output[0].value + revoked_htlc_txn[2].output[0].value - node_txn[0].output[0].value; - let feerate_2 = fee_2 * 1000 / node_txn[0].get_weight() as u64; + let feerate_2 = fee_2 * 1000 / node_txn[0].weight() as u64; assert!(feerate_2 * 100 > feerate_1 * 125); let txn = vec![node_txn[0].clone()]; node_txn.clear(); @@ -7927,12 +7968,12 @@ fn test_bump_penalty_txn_on_remote_commitment() { timeout = node_txn[6].txid(); let index = node_txn[6].input[0].previous_output.vout; let fee = remote_txn[0].output[index as usize].value - node_txn[6].output[0].value; - feerate_timeout = fee * 1000 / node_txn[6].get_weight() as u64; + feerate_timeout = fee * 1000 / node_txn[6].weight() as u64; preimage = node_txn[0].txid(); let index = node_txn[0].input[0].previous_output.vout; let fee = remote_txn[0].output[index as usize].value - node_txn[0].output[0].value; - feerate_preimage = fee * 1000 / node_txn[0].get_weight() as u64; + feerate_preimage = fee * 1000 / node_txn[0].weight() as u64; node_txn.clear(); }; @@ -7951,13 +7992,13 @@ fn test_bump_penalty_txn_on_remote_commitment() { let index = preimage_bump.input[0].previous_output.vout; let fee = remote_txn[0].output[index as usize].value - preimage_bump.output[0].value; - let new_feerate = fee * 1000 / preimage_bump.get_weight() as u64; + let new_feerate = fee * 1000 / preimage_bump.weight() as u64; assert!(new_feerate * 100 > feerate_timeout * 125); assert_ne!(timeout, preimage_bump.txid()); let index = node_txn[0].input[0].previous_output.vout; let fee = remote_txn[0].output[index as usize].value - node_txn[0].output[0].value; - let new_feerate = fee * 1000 / node_txn[0].get_weight() as u64; + let new_feerate = fee * 1000 / node_txn[0].weight() as u64; assert!(new_feerate * 100 > feerate_preimage * 125); assert_ne!(preimage, node_txn[0].txid()); @@ -8347,7 +8388,7 @@ fn test_reject_funding_before_inbound_channel_accepted() { nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_chan_msg); } - let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], 100000, 42); + let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42); nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id()); @@ -8834,7 +8875,7 @@ fn test_pre_lockin_no_chan_closed_update() { nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_chan_msg); // Move the first channel through the funding flow... - let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], 100000, 42); + let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42); nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); check_added_monitors!(nodes[0], 0); @@ -9123,7 +9164,7 @@ fn test_duplicate_chan_id() { } // Move the first channel through the funding flow... - let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], 100000, 42); + let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42); nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); check_added_monitors!(nodes[0], 0); @@ -9168,7 +9209,7 @@ fn test_duplicate_chan_id() { let open_chan_2_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()); nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_chan_2_msg); 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())); - create_funding_transaction(&nodes[0], 100000, 42); // Get and check the FundingGenerationReady event + create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42); // Get and check the FundingGenerationReady event let funding_created = { let mut a_channel_lock = nodes[0].node.channel_state.lock().unwrap(); @@ -9301,7 +9342,7 @@ fn test_invalid_funding_tx() { 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); + let (temporary_channel_id, mut tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 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(); @@ -9837,7 +9878,7 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e let opt_anchors = false; - let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], 1_000_000, 42); + let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 1_000_000, 42); if on_holder_tx { if let Some(mut chan) = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&temporary_channel_id) {