X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffunctional_tests.rs;h=d1dbad4720b814db3fb89476e0e8e8b7cee22193;hb=f84ce03cab66d63c4a5590a93364077d87fd6acf;hp=d1a68a90823b2783e660788effb938c29e795e93;hpb=531d6c8663abf4f3d673b78ca4c2db68411f979e;p=rust-lightning diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index d1a68a90..d1dbad47 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -1281,23 +1281,41 @@ fn test_duplicate_htlc_different_direction_onchain() { check_closed_event!(nodes[0], 1, ClosureReason::CommitmentTxConfirmed); connect_blocks(&nodes[0], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires - // Check we only broadcast 1 timeout tx let claim_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); assert_eq!(claim_txn.len(), 8); - assert_eq!(claim_txn[1], claim_txn[4]); - assert_eq!(claim_txn[2], claim_txn[5]); - check_spends!(claim_txn[1], chan_1.3); - check_spends!(claim_txn[2], claim_txn[1]); - check_spends!(claim_txn[7], claim_txn[1]); + + check_spends!(claim_txn[0], remote_txn[0]); // Immediate HTLC claim with preimage + + check_spends!(claim_txn[1], chan_1.3); // Alternative commitment tx + check_spends!(claim_txn[2], claim_txn[1]); // HTLC spend in alternative commitment tx + + let bump_tx = if claim_txn[1] == claim_txn[4] { + assert_eq!(claim_txn[1], claim_txn[4]); + assert_eq!(claim_txn[2], claim_txn[5]); + + check_spends!(claim_txn[7], claim_txn[1]); // HTLC timeout on alternative commitment tx + + check_spends!(claim_txn[3], remote_txn[0]); // HTLC timeout on broadcasted commitment tx + &claim_txn[3] + } else { + assert_eq!(claim_txn[1], claim_txn[3]); + assert_eq!(claim_txn[2], claim_txn[4]); + + check_spends!(claim_txn[5], claim_txn[1]); // HTLC timeout on alternative commitment tx + + check_spends!(claim_txn[7], remote_txn[0]); // HTLC timeout on broadcasted commitment tx + + &claim_txn[7] + }; assert_eq!(claim_txn[0].input.len(), 1); - assert_eq!(claim_txn[3].input.len(), 1); - assert_eq!(claim_txn[0].input[0].previous_output, claim_txn[3].input[0].previous_output); + assert_eq!(bump_tx.input.len(), 1); + assert_eq!(claim_txn[0].input[0].previous_output, bump_tx.input[0].previous_output); assert_eq!(claim_txn[0].input.len(), 1); assert_eq!(claim_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); // HTLC 1 <--> 0, preimage tx - check_spends!(claim_txn[0], remote_txn[0]); assert_eq!(remote_txn[0].output[claim_txn[0].input[0].previous_output.vout as usize].value, 800); + assert_eq!(claim_txn[6].input.len(), 1); assert_eq!(claim_txn[6].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); // HTLC 0 <--> 1, timeout tx check_spends!(claim_txn[6], remote_txn[0]); @@ -2356,7 +2374,8 @@ fn test_justice_tx() { chanmon_cfgs[1].keys_manager.disable_revocation_policy_check = true; let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &user_cfgs); - let nodes = create_network(2, &node_cfgs, &node_chanmgrs); + let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); + *nodes[0].connect_style.borrow_mut() = ConnectStyle::FullBlockViaListen; // Create some new channels: let chan_5 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); @@ -2588,11 +2607,7 @@ fn claim_htlc_outputs_single_tx() { expect_payment_failed!(nodes[1], payment_hash_2, true); let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 9); - // ChannelMonitor: justice tx revoked offered htlc, justice tx revoked received htlc, justice tx revoked to_local (3) - // ChannelManager: local commmitment + local HTLC-timeout (2) - // ChannelMonitor: bumped justice tx, after one increase, bumps on HTLC aren't generated not being substantial anymore, bump on revoked to_local isn't generated due to more room for expiration (2) - // ChannelMonitor: local commitment + local HTLC-timeout (2) + assert!(node_txn.len() == 9 || node_txn.len() == 10); // Check the pair local commitment and HTLC-timeout broadcast due to HTLC expiration assert_eq!(node_txn[0].input.len(), 1); @@ -3609,11 +3624,11 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs); - let mut as_funding_locked = None; + let mut as_channel_ready = None; if messages_delivered == 0 { - let (funding_locked, _, _) = create_chan_between_nodes_with_value_a(&nodes[0], &nodes[1], 100000, 10001, InitFeatures::known(), InitFeatures::known()); - as_funding_locked = Some(funding_locked); - // nodes[1] doesn't receive the funding_locked message (it'll be re-sent on reconnect) + let (channel_ready, _, _) = create_chan_between_nodes_with_value_a(&nodes[0], &nodes[1], 100000, 10001, InitFeatures::known(), InitFeatures::known()); + as_channel_ready = Some(channel_ready); + // nodes[1] doesn't receive the channel_ready message (it'll be re-sent on reconnect) // Note that we store it so that if we're running with `simulate_broken_lnd` we can deliver // it before the channel_reestablish message. } else { @@ -3666,17 +3681,17 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false); if messages_delivered < 3 { if simulate_broken_lnd { - // lnd has a long-standing bug where they send a funding_locked prior to a - // channel_reestablish if you reconnect prior to funding_locked time. + // lnd has a long-standing bug where they send a channel_ready prior to a + // channel_reestablish if you reconnect prior to channel_ready time. // - // Here we simulate that behavior, delivering a funding_locked immediately on - // reconnect. Note that we don't bother skipping the now-duplicate funding_locked sent + // Here we simulate that behavior, delivering a channel_ready immediately on + // reconnect. Note that we don't bother skipping the now-duplicate channel_ready sent // in `reconnect_nodes` but we currently don't fail based on that. // // See-also - nodes[1].node.handle_funding_locked(&nodes[0].node.get_our_node_id(), &as_funding_locked.as_ref().unwrap().0); + nodes[1].node.handle_channel_ready(&nodes[0].node.get_our_node_id(), &as_channel_ready.as_ref().unwrap().0); } - // Even if the funding_locked messages get exchanged, as long as nothing further was + // Even if the channel_ready messages get exchanged, as long as nothing further was // received on either side, both sides will need to resend them. reconnect_nodes(&nodes[0], &nodes[1], (true, true), (0, 1), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); } else if messages_delivered == 3 { @@ -3871,26 +3886,26 @@ fn test_funding_peer_disconnect() { nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None }); 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] hasn't yet received a channel_ready, 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 } => { + let as_channel_ready = match events_3[0] { + MessageSendEvent::SendChannelReady { 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 + // nodes[1] received nodes[0]'s channel_ready 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 } => { + let bs_channel_ready = match events_4[0] { + MessageSendEvent::SendChannelReady { ref node_id, ref msg } => { assert_eq!(*node_id, nodes[0].node.get_our_node_id()); chan_id = msg.channel_id; msg.clone() @@ -3911,9 +3926,9 @@ fn test_funding_peer_disconnect() { _ => panic!("Unexpected event {:?}", events_4[2]), } - // Re-deliver nodes[0]'s funding_locked, which nodes[1] can safely ignore. It currently + // Re-deliver nodes[0]'s channel_ready, 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); + nodes[1].node.handle_channel_ready(&nodes[0].node.get_our_node_id(), &as_channel_ready); let events_5 = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(events_5.len(), 1); match events_5[0] { @@ -3923,9 +3938,9 @@ fn test_funding_peer_disconnect() { _ => panic!("Unexpected event {:?}", events_5[0]), }; - // When we deliver nodes[1]'s funding_locked, however, nodes[0] will generate its + // When we deliver nodes[1]'s channel_ready, however, nodes[0] will generate its // announcement_signatures. - nodes[0].node.handle_funding_locked(&nodes[1].node.get_our_node_id(), &bs_funding_locked); + nodes[0].node.handle_channel_ready(&nodes[1].node.get_our_node_id(), &bs_channel_ready); 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] { @@ -4028,11 +4043,11 @@ fn test_funding_peer_disconnect() { } #[test] -fn test_funding_locked_without_best_block_updated() { +fn test_channel_ready_without_best_block_updated() { // Previously, if we were offline when a funding transaction was locked in, and then we came // back online, calling best_block_updated once followed by transactions_confirmed, we'd not - // generate a funding_locked until a later best_block_updated. This tests that we generate the - // funding_locked immediately instead. + // generate a channel_ready until a later best_block_updated. This tests that we generate the + // channel_ready immediately instead. 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]); @@ -4048,9 +4063,9 @@ fn test_funding_locked_without_best_block_updated() { let conf_block_header = nodes[0].get_block_header(conf_height); nodes[0].node.transactions_confirmed(&conf_block_header, &conf_txn[..], conf_height); - // Ensure nodes[0] generates a funding_locked after the transactions_confirmed - let as_funding_locked = get_event_msg!(nodes[0], MessageSendEvent::SendFundingLocked, nodes[1].node.get_our_node_id()); - nodes[1].node.handle_funding_locked(&nodes[0].node.get_our_node_id(), &as_funding_locked); + // Ensure nodes[0] generates a channel_ready after the transactions_confirmed + let as_channel_ready = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReady, nodes[1].node.get_our_node_id()); + nodes[1].node.handle_channel_ready(&nodes[0].node.get_our_node_id(), &as_channel_ready); } #[test] @@ -4403,8 +4418,8 @@ fn test_no_txn_manager_serialize_deserialize() { nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); - let (funding_locked, _) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx); - let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_locked); + let (channel_ready, _) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx); + let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &channel_ready); for node in nodes.iter() { assert!(node.net_graph_msg_handler.handle_channel_announcement(&announcement).unwrap()); node.net_graph_msg_handler.handle_channel_update(&as_update).unwrap(); @@ -4523,8 +4538,8 @@ fn test_manager_serialize_deserialize_events() { nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]); assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty()); - let (funding_locked, _) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx); - let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_locked); + let (channel_ready, _) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx); + let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &channel_ready); for node in nodes.iter() { assert!(node.net_graph_msg_handler.handle_channel_announcement(&announcement).unwrap()); node.net_graph_msg_handler.handle_channel_update(&as_update).unwrap(); @@ -5298,21 +5313,30 @@ fn test_duplicate_payment_hash_one_failure_one_success() { let htlc_timeout_tx; { // Extract one of the two HTLC-Timeout transaction let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - // ChannelMonitor: timeout tx * 3, ChannelManager: local commitment tx - assert_eq!(node_txn.len(), 4); + // ChannelMonitor: timeout tx * 2-or-3, ChannelManager: local commitment tx + assert!(node_txn.len() == 4 || node_txn.len() == 3); check_spends!(node_txn[0], chan_2.3); check_spends!(node_txn[1], commitment_txn[0]); assert_eq!(node_txn[1].input.len(), 1); - check_spends!(node_txn[2], commitment_txn[0]); - assert_eq!(node_txn[2].input.len(), 1); - assert_eq!(node_txn[1].input[0].previous_output, node_txn[2].input[0].previous_output); - check_spends!(node_txn[3], commitment_txn[0]); - assert_ne!(node_txn[1].input[0].previous_output, node_txn[3].input[0].previous_output); + + if node_txn.len() > 3 { + check_spends!(node_txn[2], commitment_txn[0]); + assert_eq!(node_txn[2].input.len(), 1); + assert_eq!(node_txn[1].input[0].previous_output, node_txn[2].input[0].previous_output); + + check_spends!(node_txn[3], commitment_txn[0]); + assert_ne!(node_txn[1].input[0].previous_output, node_txn[3].input[0].previous_output); + } else { + check_spends!(node_txn[2], commitment_txn[0]); + assert_ne!(node_txn[1].input[0].previous_output, node_txn[2].input[0].previous_output); + } assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); assert_eq!(node_txn[2].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - assert_eq!(node_txn[3].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + if node_txn.len() > 3 { + assert_eq!(node_txn[3].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + } htlc_timeout_tx = node_txn[1].clone(); } @@ -7982,13 +8006,24 @@ fn test_bump_penalty_txn_on_remote_commitment() { assert_eq!(node_txn[6].input.len(), 1); check_spends!(node_txn[0], remote_txn[0]); check_spends!(node_txn[6], remote_txn[0]); - assert_eq!(node_txn[0].input[0].previous_output, node_txn[3].input[0].previous_output); - preimage_bump = node_txn[3].clone(); check_spends!(node_txn[1], chan.3); check_spends!(node_txn[2], node_txn[1]); - assert_eq!(node_txn[1], node_txn[4]); - assert_eq!(node_txn[2], node_txn[5]); + + if node_txn[0].input[0].previous_output == node_txn[3].input[0].previous_output { + preimage_bump = node_txn[3].clone(); + check_spends!(node_txn[3], remote_txn[0]); + + assert_eq!(node_txn[1], node_txn[4]); + assert_eq!(node_txn[2], node_txn[5]); + } else { + preimage_bump = node_txn[7].clone(); + check_spends!(node_txn[7], remote_txn[0]); + assert_eq!(node_txn[0].input[0].previous_output, node_txn[7].input[0].previous_output); + + assert_eq!(node_txn[1], node_txn[3]); + assert_eq!(node_txn[2], node_txn[4]); + } timeout = node_txn[6].txid(); let index = node_txn[6].input[0].previous_output.vout; @@ -8737,10 +8772,11 @@ 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 }; + let block = Block { header, txdata: vec![] }; // Make the tx_broadcaster aware of enough blocks that it doesn't think we're violating // transaction lock time requirements here. - chanmon_cfgs[0].tx_broadcaster.blocks.lock().unwrap().resize(200, (header, 0)); - watchtower.chain_monitor.block_connected(&Block { header, txdata: vec![] }, 200); + chanmon_cfgs[0].tx_broadcaster.blocks.lock().unwrap().resize(200, (block.clone(), 0)); + watchtower.chain_monitor.block_connected(&block, 200); // Try to update ChannelMonitor nodes[1].node.claim_funds(preimage); @@ -8800,10 +8836,11 @@ 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 }; + let block = Block { header, txdata: vec![] }; // Make the tx_broadcaster aware of enough blocks that it doesn't think we're violating // transaction lock time requirements here. - chanmon_cfgs[0].tx_broadcaster.blocks.lock().unwrap().resize((CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS) as usize, (header, 0)); - watchtower_alice.chain_monitor.block_connected(&Block { header, txdata: vec![] }, CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS); + chanmon_cfgs[0].tx_broadcaster.blocks.lock().unwrap().resize((CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS) as usize, (block.clone(), 0)); + watchtower_alice.chain_monitor.block_connected(&block, CHAN_CONFIRM_DEPTH + 1 + TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS); // Watchtower Alice should have broadcast a commitment/HTLC-timeout { @@ -9249,7 +9286,11 @@ fn test_duplicate_chan_id() { let funding_created = { let mut a_channel_lock = nodes[0].node.channel_state.lock().unwrap(); - let mut as_chan = a_channel_lock.by_id.get_mut(&open_chan_2_msg.temporary_channel_id).unwrap(); + // Once we call `get_outbound_funding_created` the channel has a duplicate channel_id as + // another channel in the ChannelManager - an invalid state. Thus, we'd panic later when we + // try to create another channel. Instead, we drop the channel entirely here (leaving the + // channelmanager in a possibly nonsense state instead). + let mut as_chan = a_channel_lock.by_id.remove(&open_chan_2_msg.temporary_channel_id).unwrap(); let logger = test_utils::TestLogger::new(); as_chan.get_outbound_funding_created(tx.clone(), funding_outpoint, &&logger).unwrap() }; @@ -9287,10 +9328,10 @@ fn test_duplicate_chan_id() { let events_4 = nodes[0].node.get_and_clear_pending_events(); assert_eq!(events_4.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].txid(), funding_output.txid); + assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0], tx); - let (funding_locked, _) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx); - let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_locked); + let (channel_ready, _) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx); + let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &channel_ready); update_nodes_with_chan_announce(&nodes, 0, 1, &announcement, &as_update, &bs_update); send_payment(&nodes[0], &[&nodes[1]], 8000000); } @@ -9590,7 +9631,7 @@ fn test_forwardable_regen() { check_added_monitors!(nodes[1], 2); reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); - // Note that nodes[1] and nodes[2] resend their funding_locked here since they haven't updated + // Note that nodes[1] and nodes[2] resend their channel_ready here since they haven't updated // the commitment state. reconnect_nodes(&nodes[1], &nodes[2], (true, true), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false)); @@ -10172,8 +10213,8 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e 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 (funding_locked, channel_id) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx); - let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_locked); + let (channel_ready, channel_id) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx); + let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &channel_ready); update_nodes_with_chan_announce(&nodes, 0, 1, &announcement, &as_update, &bs_update); let dust_buffer_feerate = {