X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffunctional_tests.rs;h=962e69d27c273b8e90b67a9c431f23b0827b2d7a;hb=29a780e9e07962b8687d0b1944f4c86411030d3b;hp=f6150a53645744d8c680077d448e1fe9455a1e42;hpb=79ffc5eac94cb618ff905894d480864384d0764f;p=rust-lightning diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index f6150a53..962e69d2 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -20,7 +20,7 @@ use chain::transaction::OutPoint; use chain::keysinterface::{KeysInterface, BaseSign}; use ln::{PaymentPreimage, PaymentSecret, PaymentHash}; use ln::channel::{COMMITMENT_TX_BASE_WEIGHT, COMMITMENT_TX_WEIGHT_PER_HTLC}; -use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, BREAKDOWN_TIMEOUT}; +use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA}; use ln::channel::{Channel, ChannelError}; use ln::{chan_utils, onion_utils}; use routing::router::{Route, RouteHop, get_route}; @@ -1496,20 +1496,30 @@ fn test_duplicate_htlc_different_direction_onchain() { mine_transaction(&nodes[0], &remote_txn[0]); check_added_monitors!(nodes[0], 1); + 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(), 5); - check_spends!(claim_txn[2], chan_1.3); - check_spends!(claim_txn[3], claim_txn[2]); - assert_eq!(claim_txn[1].input.len(), 1); - assert_eq!(claim_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); // HTLC 1 <--> 0, preimage tx - check_spends!(claim_txn[1], remote_txn[0]); - assert_eq!(remote_txn[0].output[claim_txn[1].input[0].previous_output.vout as usize].value, 800); + assert_eq!(claim_txn.len(), 9); + assert_eq!(claim_txn[1], claim_txn[5]); + assert_eq!(claim_txn[2], claim_txn[6]); + assert_eq!(claim_txn[3], claim_txn[8]); + check_spends!(claim_txn[1], chan_1.3); + check_spends!(claim_txn[2], claim_txn[1]); + check_spends!(claim_txn[3], claim_txn[1]); + + assert_eq!(claim_txn[0].input.len(), 1); + assert_eq!(claim_txn[4].input.len(), 1); + assert_eq!(claim_txn[0].input[0].previous_output, claim_txn[4].input[0].previous_output); + assert_eq!(claim_txn[0].input.len(), 1); - assert_eq!(claim_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); // HTLC 0 <--> 1, timeout tx + 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, 900); + assert_eq!(remote_txn[0].output[claim_txn[0].input[0].previous_output.vout as usize].value, 800); + assert_eq!(claim_txn[7].input.len(), 1); + assert_eq!(claim_txn[7].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); // HTLC 0 <--> 1, timeout tx + check_spends!(claim_txn[7], remote_txn[0]); + assert_eq!(remote_txn[0].output[claim_txn[7].input[0].previous_output.vout as usize].value, 900); let events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 3); @@ -2485,6 +2495,7 @@ fn test_justice_tx() { test_txn_broadcast(&nodes[1], &chan_5, None, HTLCType::NONE); mine_transaction(&nodes[0], &revoked_local_txn[0]); + connect_blocks(&nodes[0], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires // Verify broadcast of revoked HTLC-timeout let node_txn = test_txn_broadcast(&nodes[0], &chan_5, Some(revoked_local_txn[0].clone()), HTLCType::TIMEOUT); check_added_monitors!(nodes[0], 1); @@ -2738,6 +2749,12 @@ fn test_htlc_on_chain_success() { let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known()); + // Ensure all nodes are at the same height + let node_max_height = nodes.iter().map(|node| node.blocks.borrow().len()).max().unwrap() as u32; + connect_blocks(&nodes[0], node_max_height - nodes[0].best_block_info().1); + connect_blocks(&nodes[1], node_max_height - nodes[1].best_block_info().1); + connect_blocks(&nodes[2], node_max_height - nodes[2].best_block_info().1); + // Rebalance the network a bit by relaying one payment through all the channels... send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000); send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000); @@ -2779,6 +2796,7 @@ fn test_htlc_on_chain_success() { // Verify that B's ChannelManager is able to extract preimage from HTLC Success tx and pass it backward let header = BlockHeader { version: 0x20000000, prev_blockhash: nodes[1].best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42}; connect_block(&nodes[1], &Block { header, txdata: node_txn}); + connect_blocks(&nodes[1], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires { let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap(); assert_eq!(added_monitors.len(), 1); @@ -2819,31 +2837,31 @@ fn test_htlc_on_chain_success() { assert_eq!(node_txn.len(), 5); // Node[1]: ChannelManager: 3 (commitment tx, 2*HTLC-Timeout tx), ChannelMonitor: 2 (timeout tx) // Node[0]: ChannelManager: 3 (commtiemtn tx, 2*HTLC-Timeout tx), ChannelMonitor: 2 HTLC-timeout - check_spends!(node_txn[0], $commitment_tx); - check_spends!(node_txn[1], $commitment_tx); - assert_ne!(node_txn[0].lock_time, 0); - assert_ne!(node_txn[1].lock_time, 0); + check_spends!(node_txn[3], $commitment_tx); + check_spends!(node_txn[4], $commitment_tx); + assert_ne!(node_txn[3].lock_time, 0); + assert_ne!(node_txn[4].lock_time, 0); if $htlc_offered { - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output - assert!(node_txn[1].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output + assert_eq!(node_txn[3].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert_eq!(node_txn[4].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert!(node_txn[3].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output + assert!(node_txn[4].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output } else { - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment - assert!(node_txn[1].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment + assert_eq!(node_txn[3].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + assert_eq!(node_txn[4].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + assert!(node_txn[3].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment + assert!(node_txn[4].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment } - check_spends!(node_txn[2], $chan_tx); - check_spends!(node_txn[3], node_txn[2]); - check_spends!(node_txn[4], node_txn[2]); - assert_eq!(node_txn[2].input[0].witness.last().unwrap().len(), 71); - assert_eq!(node_txn[3].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert_eq!(node_txn[4].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert!(node_txn[3].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output - assert!(node_txn[4].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output - assert_ne!(node_txn[3].lock_time, 0); - assert_ne!(node_txn[4].lock_time, 0); + check_spends!(node_txn[0], $chan_tx); + check_spends!(node_txn[1], node_txn[0]); + check_spends!(node_txn[2], node_txn[0]); + assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), 71); + assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert_eq!(node_txn[2].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert!(node_txn[1].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output + assert!(node_txn[2].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output + assert_ne!(node_txn[1].lock_time, 0); + assert_ne!(node_txn[2].lock_time, 0); node_txn.clear(); } } } @@ -2854,29 +2872,43 @@ fn test_htlc_on_chain_success() { // Broadcast legit commitment tx from A on B's chain // Broadcast preimage tx by B on offered output from A commitment tx on A's chain - let commitment_tx = get_local_commitment_txn!(nodes[0], chan_1.2); - check_spends!(commitment_tx[0], chan_1.3); - mine_transaction(&nodes[1], &commitment_tx[0]); + let node_a_commitment_tx = get_local_commitment_txn!(nodes[0], chan_1.2); + check_spends!(node_a_commitment_tx[0], chan_1.3); + mine_transaction(&nodes[1], &node_a_commitment_tx[0]); check_closed_broadcast!(nodes[1], true); check_added_monitors!(nodes[1], 1); - let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 3 (commitment tx + HTLC-Sucess * 2), ChannelMonitor : 1 (HTLC-Success) - assert_eq!(node_txn.len(), 4); - check_spends!(node_txn[0], commitment_tx[0]); - assert_eq!(node_txn[0].input.len(), 2); - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert_eq!(node_txn[0].input[1].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert_eq!(node_txn[0].lock_time, 0); - assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment - check_spends!(node_txn[1], chan_1.3); - assert_eq!(node_txn[1].input[0].witness.clone().last().unwrap().len(), 71); - check_spends!(node_txn[2], node_txn[1]); - check_spends!(node_txn[3], node_txn[1]); + let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); + assert_eq!(node_txn.len(), 6); // ChannelManager : 3 (commitment tx + HTLC-Sucess * 2), ChannelMonitor : 3 (HTLC-Success, 2* RBF bumps of above HTLC txn) + let commitment_spend = + if node_txn[0].input[0].previous_output.txid == node_a_commitment_tx[0].txid() { + check_spends!(node_txn[1], commitment_tx[0]); + check_spends!(node_txn[2], commitment_tx[0]); + assert_ne!(node_txn[1].input[0].previous_output.vout, node_txn[2].input[0].previous_output.vout); + &node_txn[0] + } else { + check_spends!(node_txn[0], commitment_tx[0]); + check_spends!(node_txn[1], commitment_tx[0]); + assert_ne!(node_txn[0].input[0].previous_output.vout, node_txn[1].input[0].previous_output.vout); + &node_txn[2] + }; + + check_spends!(commitment_spend, node_a_commitment_tx[0]); + assert_eq!(commitment_spend.input.len(), 2); + assert_eq!(commitment_spend.input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert_eq!(commitment_spend.input[1].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert_eq!(commitment_spend.lock_time, 0); + assert!(commitment_spend.output[0].script_pubkey.is_v0_p2wpkh()); // direct payment + check_spends!(node_txn[3], chan_1.3); + assert_eq!(node_txn[3].input[0].witness.clone().last().unwrap().len(), 71); + check_spends!(node_txn[4], node_txn[3]); + check_spends!(node_txn[5], node_txn[3]); // We don't bother to check that B can claim the HTLC output on its commitment tx here as // we already checked the same situation with A. // Verify that A's ChannelManager is able to extract preimage from preimage tx and generate PaymentSent let mut header = BlockHeader { version: 0x20000000, prev_blockhash: nodes[0].best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42}; - connect_block(&nodes[0], &Block { header, txdata: vec![commitment_tx[0].clone(), node_txn[0].clone()] }); + connect_block(&nodes[0], &Block { header, txdata: vec![node_a_commitment_tx[0].clone(), commitment_spend.clone()] }); + connect_blocks(&nodes[0], TEST_FINAL_CLTV + MIN_CLTV_EXPIRY_DELTA as u32 - 1); // Confirm blocks until the HTLC expires check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); let events = nodes[0].node.get_and_clear_pending_events(); @@ -2895,7 +2927,7 @@ fn test_htlc_on_chain_success() { _ => panic!("Unexpected event"), } } - check_tx_local_broadcast!(nodes[0], true, commitment_tx[0], chan_1.3); + check_tx_local_broadcast!(nodes[0], true, node_a_commitment_tx[0], chan_1.3); } fn do_test_htlc_on_chain_timeout(connect_style: ConnectStyle) { @@ -3014,17 +3046,18 @@ fn do_test_htlc_on_chain_timeout(connect_style: ConnectStyle) { check_spends!(commitment_tx[0], chan_1.3); mine_transaction(&nodes[0], &commitment_tx[0]); + connect_blocks(&nodes[0], TEST_FINAL_CLTV + MIN_CLTV_EXPIRY_DELTA as u32 - 1); // Confirm blocks until the HTLC expires check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 2 (commitment tx, HTLC-Timeout tx), ChannelMonitor : 1 timeout tx assert_eq!(node_txn.len(), 3); - check_spends!(node_txn[0], commitment_tx[0]); - assert_eq!(node_txn[0].clone().input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[1], chan_1.3); - check_spends!(node_txn[2], node_txn[1]); - assert_eq!(node_txn[1].clone().input[0].witness.last().unwrap().len(), 71); - assert_eq!(node_txn[2].clone().input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + check_spends!(node_txn[0], chan_1.3); + check_spends!(node_txn[1], node_txn[0]); + assert_eq!(node_txn[0].clone().input[0].witness.last().unwrap().len(), 71); + assert_eq!(node_txn[1].clone().input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + check_spends!(node_txn[2], commitment_tx[0]); + assert_eq!(node_txn[2].clone().input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); } #[test] @@ -4990,24 +5023,25 @@ fn test_static_spendable_outputs_timeout_tx() { MessageSendEvent::BroadcastChannelUpdate { .. } => {}, _ => panic!("Unexpected event"), } + connect_blocks(&nodes[1], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires // Check B's monitor was able to send back output descriptor event for timeout tx on A's commitment tx - let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); + let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0); assert_eq!(node_txn.len(), 3); // ChannelManager : 2 (local commitent tx + HTLC-timeout), ChannelMonitor: timeout tx - check_spends!(node_txn[0], commitment_tx[0].clone()); - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[1], chan_1.3.clone()); - check_spends!(node_txn[2], node_txn[1]); + check_spends!(node_txn[0], chan_1.3.clone()); + check_spends!(node_txn[1], node_txn[0]); + check_spends!(node_txn[2], commitment_tx[0].clone()); + assert_eq!(node_txn[2].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - mine_transaction(&nodes[1], &node_txn[0]); + mine_transaction(&nodes[1], &node_txn[2]); connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1); expect_payment_failed!(nodes[1], our_payment_hash, true); let spend_txn = check_spendable_outputs!(nodes[1], 1, node_cfgs[1].keys_manager, 100000); assert_eq!(spend_txn.len(), 3); // SpendableOutput: remote_commitment_tx.to_remote, timeout_tx.output check_spends!(spend_txn[0], commitment_tx[0]); - check_spends!(spend_txn[1], node_txn[0]); - check_spends!(spend_txn[2], node_txn[0], commitment_tx[0]); // All outputs + check_spends!(spend_txn[1], node_txn[2]); + check_spends!(spend_txn[2], node_txn[2], commitment_tx[0]); // All outputs } #[test] @@ -5066,35 +5100,37 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() { mine_transaction(&nodes[0], &revoked_local_txn[0]); check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); + connect_blocks(&nodes[0], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires let revoked_htlc_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(revoked_htlc_txn.len(), 2); - assert_eq!(revoked_htlc_txn[0].input.len(), 1); - assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]); - check_spends!(revoked_htlc_txn[1], chan_1.3); + check_spends!(revoked_htlc_txn[0], chan_1.3); + assert_eq!(revoked_htlc_txn[1].input.len(), 1); + assert_eq!(revoked_htlc_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + check_spends!(revoked_htlc_txn[1], revoked_local_txn[0]); + assert_ne!(revoked_htlc_txn[1].lock_time, 0); // HTLC-Timeout // B will generate justice tx from A's revoked commitment/HTLC tx let header = BlockHeader { version: 0x20000000, prev_blockhash: nodes[1].best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - connect_block(&nodes[1], &Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }); + connect_block(&nodes[1], &Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[1].clone()] }); check_closed_broadcast!(nodes[1], true); check_added_monitors!(nodes[1], 1); let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 3); // ChannelMonitor: bogus justice tx, justice tx on revoked outputs, ChannelManager: local commitment tx // The first transaction generated is bogus - it spends both outputs of revoked_local_txn[0] - // including the one already spent by revoked_htlc_txn[0]. That's OK, we'll spend with valid + // including the one already spent by revoked_htlc_txn[1]. That's OK, we'll spend with valid // transactions next... assert_eq!(node_txn[0].input.len(), 3); - check_spends!(node_txn[0], revoked_local_txn[0], revoked_htlc_txn[0]); + check_spends!(node_txn[0], revoked_local_txn[0], revoked_htlc_txn[1]); assert_eq!(node_txn[1].input.len(), 2); - check_spends!(node_txn[1], revoked_local_txn[0], revoked_htlc_txn[0]); - if node_txn[1].input[1].previous_output.txid == revoked_htlc_txn[0].txid() { - assert_ne!(node_txn[1].input[0].previous_output, revoked_htlc_txn[0].input[0].previous_output); + check_spends!(node_txn[1], revoked_local_txn[0], revoked_htlc_txn[1]); + if node_txn[1].input[1].previous_output.txid == revoked_htlc_txn[1].txid() { + assert_ne!(node_txn[1].input[0].previous_output, revoked_htlc_txn[1].input[0].previous_output); } else { - assert_eq!(node_txn[1].input[0].previous_output.txid, revoked_htlc_txn[0].txid()); - assert_ne!(node_txn[1].input[1].previous_output, revoked_htlc_txn[0].input[0].previous_output); + assert_eq!(node_txn[1].input[0].previous_output.txid, revoked_htlc_txn[1].txid()); + assert_ne!(node_txn[1].input[1].previous_output, revoked_htlc_txn[1].input[0].previous_output); } assert_eq!(node_txn[2].input.len(), 1); @@ -5207,6 +5243,12 @@ fn test_onchain_to_onchain_claim() { let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known()); + // Ensure all nodes are at the same height + let node_max_height = nodes.iter().map(|node| node.blocks.borrow().len()).max().unwrap() as u32; + connect_blocks(&nodes[0], node_max_height - nodes[0].best_block_info().1); + connect_blocks(&nodes[1], node_max_height - nodes[1].best_block_info().1); + connect_blocks(&nodes[2], node_max_height - nodes[2].best_block_info().1); + // Rebalance the network a bit by relaying one payment through all the channels ... send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000); send_payment(&nodes[0], &vec!(&nodes[1], &nodes[2])[..], 8000000); @@ -5240,18 +5282,19 @@ fn test_onchain_to_onchain_claim() { // So we broadcast C's commitment tx and HTLC-Success on B's chain, we should successfully be able to extract preimage and update downstream monitor let header = BlockHeader { version: 0x20000000, prev_blockhash: nodes[1].best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42}; connect_block(&nodes[1], &Block { header, txdata: vec![c_txn[1].clone(), c_txn[2].clone()]}); + connect_blocks(&nodes[1], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires { let mut b_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); // ChannelMonitor: claim tx, ChannelManager: local commitment tx + HTLC-timeout tx assert_eq!(b_txn.len(), 3); - check_spends!(b_txn[1], chan_2.3); // B local commitment tx, issued by ChannelManager - check_spends!(b_txn[2], b_txn[1]); // HTLC-Timeout on B local commitment tx, issued by ChannelManager - assert_eq!(b_txn[2].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert!(b_txn[2].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output - assert_ne!(b_txn[2].lock_time, 0); // Timeout tx - check_spends!(b_txn[0], c_txn[1]); // timeout tx on C remote commitment tx, issued by ChannelMonitor - assert_eq!(b_txn[0].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - assert!(b_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment + check_spends!(b_txn[0], chan_2.3); // B local commitment tx, issued by ChannelManager + check_spends!(b_txn[1], b_txn[0]); // HTLC-Timeout on B local commitment tx, issued by ChannelManager + assert_eq!(b_txn[1].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert!(b_txn[1].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output + assert_ne!(b_txn[1].lock_time, 0); // Timeout tx + check_spends!(b_txn[2], c_txn[1]); // timeout tx on C remote commitment tx, issued by ChannelMonitor + assert_eq!(b_txn[2].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + assert!(b_txn[2].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment assert_ne!(b_txn[2].lock_time, 0); // Timeout tx b_txn.clear(); } @@ -5281,14 +5324,19 @@ fn test_onchain_to_onchain_claim() { let commitment_tx = get_local_commitment_txn!(nodes[0], chan_1.2); mine_transaction(&nodes[1], &commitment_tx[0]); let b_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - // ChannelMonitor: HTLC-Success tx, ChannelManager: local commitment tx + HTLC-Success tx - assert_eq!(b_txn.len(), 3); - check_spends!(b_txn[1], chan_1.3); - check_spends!(b_txn[2], b_txn[1]); - check_spends!(b_txn[0], commitment_tx[0]); - assert_eq!(b_txn[0].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert!(b_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment - assert_eq!(b_txn[0].lock_time, 0); // Success tx + // ChannelMonitor: HTLC-Success tx + HTLC-Timeout RBF Bump, ChannelManager: local commitment tx + HTLC-Success tx + assert_eq!(b_txn.len(), 4); + check_spends!(b_txn[2], chan_1.3); + check_spends!(b_txn[3], b_txn[2]); + let (htlc_success_claim, htlc_timeout_bumped) = + if b_txn[0].input[0].previous_output.txid == commitment_tx[0].txid() + { (&b_txn[0], &b_txn[1]) } else { (&b_txn[1], &b_txn[0]) }; + check_spends!(htlc_success_claim, commitment_tx[0]); + assert_eq!(htlc_success_claim.input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert!(htlc_success_claim.output[0].script_pubkey.is_v0_p2wpkh()); // direct payment + assert_eq!(htlc_success_claim.lock_time, 0); // Success tx + check_spends!(htlc_timeout_bumped, c_txn[1]); // timeout tx on C remote commitment tx, issued by ChannelMonitor + assert_ne!(htlc_timeout_bumped.lock_time, 0); // Success tx check_closed_broadcast!(nodes[1], true); check_added_monitors!(nodes[1], 1); @@ -5309,7 +5357,7 @@ fn test_duplicate_payment_hash_one_failure_one_success() { let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, InitFeatures::known(), InitFeatures::known()); create_announced_chan_between_nodes(&nodes, 2, 3, InitFeatures::known(), InitFeatures::known()); - let node_max_height = std::cmp::max(std::cmp::max(nodes[0].blocks.borrow().len(), nodes[1].blocks.borrow().len()), std::cmp::max(nodes[2].blocks.borrow().len(), nodes[3].blocks.borrow().len())) as u32; + let node_max_height = nodes.iter().map(|node| node.blocks.borrow().len()).max().unwrap() as u32; connect_blocks(&nodes[0], node_max_height - nodes[0].best_block_info().1); connect_blocks(&nodes[1], node_max_height - nodes[1].best_block_info().1); connect_blocks(&nodes[2], node_max_height - nodes[2].best_block_info().1); @@ -5332,23 +5380,29 @@ fn test_duplicate_payment_hash_one_failure_one_success() { mine_transaction(&nodes[1], &commitment_txn[0]); check_closed_broadcast!(nodes[1], true); check_added_monitors!(nodes[1], 1); + connect_blocks(&nodes[1], TEST_FINAL_CLTV - 40 + MIN_CLTV_EXPIRY_DELTA as u32 - 1); // Confirm blocks until the HTLC expires 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 * 2, ChannelManager: local commitment tx + HTLC-timeout * 2 - assert_eq!(node_txn.len(), 5); - check_spends!(node_txn[0], commitment_txn[0]); - assert_eq!(node_txn[0].input.len(), 1); - check_spends!(node_txn[1], commitment_txn[0]); - assert_eq!(node_txn[1].input.len(), 1); - assert_ne!(node_txn[0].input[0], node_txn[1].input[0]); - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[2], chan_2.3); - check_spends!(node_txn[3], node_txn[2]); - check_spends!(node_txn[4], node_txn[2]); - htlc_timeout_tx = node_txn[1].clone(); + // ChannelMonitor: timeout tx * 3, ChannelManager: local commitment tx + HTLC-timeout * 2 + assert_eq!(node_txn.len(), 6); + check_spends!(node_txn[0], chan_2.3); + check_spends!(node_txn[1], node_txn[0]); + check_spends!(node_txn[2], node_txn[0]); + + check_spends!(node_txn[3], commitment_txn[0]); + assert_eq!(node_txn[3].input.len(), 1); + check_spends!(node_txn[4], commitment_txn[0]); + assert_eq!(node_txn[4].input.len(), 1); + assert_eq!(node_txn[3].input[0].previous_output, node_txn[4].input[0].previous_output); + check_spends!(node_txn[5], commitment_txn[0]); + assert_ne!(node_txn[3].input[0].previous_output, node_txn[5].input[0].previous_output); + + assert_eq!(node_txn[3].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + assert_eq!(node_txn[4].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + assert_eq!(node_txn[5].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + htlc_timeout_tx = node_txn[3].clone(); } nodes[2].node.claim_funds(our_payment_preimage); @@ -5371,11 +5425,11 @@ fn test_duplicate_payment_hash_one_failure_one_success() { assert_eq!(htlc_success_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); assert_eq!(htlc_success_txn[1].input.len(), 1); assert_eq!(htlc_success_txn[1].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - assert_ne!(htlc_success_txn[0].input[0], htlc_success_txn[1].input[0]); + assert_ne!(htlc_success_txn[0].input[0].previous_output, htlc_success_txn[1].input[0].previous_output); assert_eq!(htlc_success_txn[2], commitment_txn[0]); assert_eq!(htlc_success_txn[3], htlc_success_txn[0]); assert_eq!(htlc_success_txn[4], htlc_success_txn[1]); - + assert_ne!(htlc_success_txn[0].input[0].previous_output, htlc_timeout_tx.input[0].previous_output); mine_transaction(&nodes[1], &htlc_timeout_tx); connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1); @@ -5748,13 +5802,17 @@ fn test_dynamic_spendable_outputs_local_htlc_timeout_tx() { mine_transaction(&nodes[0], &local_txn[0]); check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); + connect_blocks(&nodes[0], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires let htlc_timeout = { let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn[0].input.len(), 1); - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[0], local_txn[0]); - node_txn[0].clone() + assert_eq!(node_txn.len(), 3); + check_spends!(node_txn[0], chan_1.3); + assert_eq!(node_txn[1], node_txn[2]); + assert_eq!(node_txn[1].input.len(), 1); + assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + check_spends!(node_txn[1], local_txn[0]); + node_txn[1].clone() }; mine_transaction(&nodes[0], &htlc_timeout); @@ -5819,10 +5877,10 @@ fn test_key_derivation_params() { let htlc_timeout = { let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn[0].input.len(), 1); - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[0], local_txn_1[0]); - node_txn[0].clone() + assert_eq!(node_txn[1].input.len(), 1); + assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + check_spends!(node_txn[1], local_txn_1[0]); + node_txn[1].clone() }; mine_transaction(&nodes[0], &htlc_timeout); @@ -7258,7 +7316,7 @@ fn do_test_sweep_outbound_htlc_failure_update(revoked: bool, local: bool) { check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0); - timeout_tx.push(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0].clone()); + timeout_tx.push(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[1].clone()); connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1); expect_payment_failed!(nodes[0], dust_hash, true); assert_eq!(timeout_tx[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); @@ -7273,8 +7331,8 @@ fn do_test_sweep_outbound_htlc_failure_update(revoked: bool, local: bool) { check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); assert_eq!(nodes[0].node.get_and_clear_pending_events().len(), 0); - timeout_tx.push(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0].clone()); - connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1); + connect_blocks(&nodes[0], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires + timeout_tx.push(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[2].clone()); if !revoked { expect_payment_failed!(nodes[0], dust_hash, true); assert_eq!(timeout_tx[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); @@ -7981,31 +8039,28 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { connect_block(&nodes[1], &Block { header, txdata: vec![revoked_local_txn[0].clone()] }); check_closed_broadcast!(nodes[1], true); check_added_monitors!(nodes[1], 1); + connect_blocks(&nodes[1], 49); // Confirm blocks until the HTLC expires (note CLTV was explicitly 50 above) let revoked_htlc_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(revoked_htlc_txn.len(), 4); - if revoked_htlc_txn[0].input[0].witness.last().unwrap().len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { - assert_eq!(revoked_htlc_txn[0].input.len(), 1); - check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]); - assert_eq!(revoked_htlc_txn[1].input.len(), 1); - assert_eq!(revoked_htlc_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert_eq!(revoked_htlc_txn[1].output.len(), 1); - check_spends!(revoked_htlc_txn[1], revoked_local_txn[0]); - } else if revoked_htlc_txn[1].input[0].witness.last().unwrap().len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { - assert_eq!(revoked_htlc_txn[1].input.len(), 1); - check_spends!(revoked_htlc_txn[1], revoked_local_txn[0]); - assert_eq!(revoked_htlc_txn[0].input.len(), 1); - assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - assert_eq!(revoked_htlc_txn[0].output.len(), 1); - check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]); - } + check_spends!(revoked_htlc_txn[1], chan.3); + check_spends!(revoked_htlc_txn[2], revoked_htlc_txn[1]); + + assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + assert_eq!(revoked_htlc_txn[0].input.len(), 1); + check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]); + + assert_eq!(revoked_htlc_txn[3].input.len(), 1); + assert_eq!(revoked_htlc_txn[3].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + assert_eq!(revoked_htlc_txn[3].output.len(), 1); + check_spends!(revoked_htlc_txn[3], revoked_local_txn[0]); // Broadcast set of revoked txn on A let hash_128 = connect_blocks(&nodes[0], 40); let header_11 = BlockHeader { version: 0x20000000, prev_blockhash: hash_128, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; connect_block(&nodes[0], &Block { header: header_11, txdata: vec![revoked_local_txn[0].clone()] }); let header_129 = BlockHeader { version: 0x20000000, prev_blockhash: header_11.block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - connect_block(&nodes[0], &Block { header: header_129, txdata: vec![revoked_htlc_txn[0].clone(), revoked_htlc_txn[1].clone()] }); + connect_block(&nodes[0], &Block { header: header_129, txdata: vec![revoked_htlc_txn[0].clone(), revoked_htlc_txn[3].clone()] }); expect_pending_htlcs_forwardable_ignore!(nodes[0]); let first; let feerate_1; @@ -8034,7 +8089,7 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { assert_ne!(node_txn[1].input[0].previous_output, node_txn[2].input[0].previous_output); assert_eq!(node_txn[0].input[0].previous_output, revoked_htlc_txn[0].input[0].previous_output); - assert_eq!(node_txn[1].input[0].previous_output, revoked_htlc_txn[1].input[0].previous_output); + assert_eq!(node_txn[1].input[0].previous_output, revoked_htlc_txn[3].input[0].previous_output); // node_txn[3] is the local commitment tx broadcast just because (and somewhat in case of // reorgs, though its not clear its ever worth broadcasting conflicting txn like this when @@ -8045,11 +8100,11 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { // output, checked above). assert_eq!(node_txn[4].input.len(), 2); assert_eq!(node_txn[4].output.len(), 1); - check_spends!(node_txn[4], revoked_htlc_txn[0], revoked_htlc_txn[1]); + check_spends!(node_txn[4], revoked_htlc_txn[0], revoked_htlc_txn[3]); first = node_txn[4].txid(); // Store both feerates for later comparison - let fee_1 = revoked_htlc_txn[0].output[0].value + revoked_htlc_txn[1].output[0].value - node_txn[4].output[0].value; + let fee_1 = revoked_htlc_txn[0].output[0].value + revoked_htlc_txn[3].output[0].value - node_txn[4].output[0].value; feerate_1 = fee_1 * 1000 / node_txn[4].get_weight() as u64; penalty_txn = vec![node_txn[2].clone()]; node_txn.clear(); @@ -8068,9 +8123,9 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { check_spends!(node_txn[1], revoked_local_txn[0]); // Note that these are both bogus - they spend outputs already claimed in block 129: if node_txn[0].input[0].previous_output == revoked_htlc_txn[0].input[0].previous_output { - assert_eq!(node_txn[1].input[0].previous_output, revoked_htlc_txn[1].input[0].previous_output); + assert_eq!(node_txn[1].input[0].previous_output, revoked_htlc_txn[3].input[0].previous_output); } else { - assert_eq!(node_txn[0].input[0].previous_output, revoked_htlc_txn[1].input[0].previous_output); + assert_eq!(node_txn[0].input[0].previous_output, revoked_htlc_txn[3].input[0].previous_output); assert_eq!(node_txn[1].input[0].previous_output, revoked_htlc_txn[0].input[0].previous_output); } @@ -8086,10 +8141,10 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { assert_eq!(node_txn.len(), 1); assert_eq!(node_txn[0].input.len(), 2); - check_spends!(node_txn[0], revoked_htlc_txn[0], revoked_htlc_txn[1]); + check_spends!(node_txn[0], revoked_htlc_txn[0], revoked_htlc_txn[3]); // 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[1].output[0].value - node_txn[0].output[0].value; + let fee_2 = revoked_htlc_txn[0].output[0].value + revoked_htlc_txn[3].output[0].value - node_txn[0].output[0].value; let feerate_2 = fee_2 * 1000 / node_txn[0].get_weight() as u64; assert!(feerate_2 * 100 > feerate_1 * 125); let txn = vec![node_txn[0].clone()]; @@ -8143,43 +8198,45 @@ fn test_bump_penalty_txn_on_remote_commitment() { nodes[1].node.claim_funds(payment_preimage); mine_transaction(&nodes[1], &remote_txn[0]); check_added_monitors!(nodes[1], 2); + connect_blocks(&nodes[1], TEST_FINAL_CLTV - 1); // Confirm blocks until the HTLC expires // One or more claim tx should have been broadcast, check it let timeout; let preimage; + let preimage_bump; let feerate_timeout; let feerate_preimage; { let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 5); // 2 * claim tx (broadcasted from ChannelMonitor) + local commitment tx + local HTLC-timeout + local HTLC-success (broadcasted from ChannelManager) + // 9 transactions including: + // 2*3 ChannelManager local broadcasts of commitment + HTLC-Success + HTLC-Timeout + // 2 * HTLC-Success (one RBF bump we'll check later) + // 1 * HTLC-Timeout + assert_eq!(node_txn.len(), 9); assert_eq!(node_txn[0].input.len(), 1); - assert_eq!(node_txn[1].input.len(), 1); + assert_eq!(node_txn[7].input.len(), 1); check_spends!(node_txn[0], remote_txn[0]); - check_spends!(node_txn[1], remote_txn[0]); - check_spends!(node_txn[2], chan.3); - check_spends!(node_txn[3], node_txn[2]); - check_spends!(node_txn[4], node_txn[2]); - if node_txn[0].input[0].witness.last().unwrap().len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { - timeout = 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_timeout = fee * 1000 / node_txn[0].get_weight() as u64; - - preimage = node_txn[1].txid(); - let index = node_txn[1].input[0].previous_output.vout; - let fee = remote_txn[0].output[index as usize].value - node_txn[1].output[0].value; - feerate_preimage = fee * 1000 / node_txn[1].get_weight() as u64; - } else { - timeout = node_txn[1].txid(); - let index = node_txn[1].input[0].previous_output.vout; - let fee = remote_txn[0].output[index as usize].value - node_txn[1].output[0].value; - feerate_timeout = fee * 1000 / node_txn[1].get_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; - } + check_spends!(node_txn[7], remote_txn[0]); + assert_eq!(node_txn[0].input[0].previous_output, node_txn[4].input[0].previous_output); + preimage_bump = node_txn[4].clone(); + + check_spends!(node_txn[1], chan.3); + check_spends!(node_txn[2], node_txn[1]); + check_spends!(node_txn[3], node_txn[1]); + assert_eq!(node_txn[1], node_txn[5]); + assert_eq!(node_txn[2], node_txn[6]); + assert_eq!(node_txn[3], node_txn[8]); + + timeout = node_txn[7].txid(); + let index = node_txn[7].input[0].previous_output.vout; + let fee = remote_txn[0].output[index as usize].value - node_txn[7].output[0].value; + feerate_timeout = fee * 1000 / node_txn[7].get_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; + node_txn.clear(); }; assert_ne!(feerate_timeout, 0); @@ -8189,36 +8246,24 @@ fn test_bump_penalty_txn_on_remote_commitment() { connect_blocks(&nodes[1], 15); { let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 2); + assert_eq!(node_txn.len(), 1); assert_eq!(node_txn[0].input.len(), 1); - assert_eq!(node_txn[1].input.len(), 1); + assert_eq!(preimage_bump.input.len(), 1); check_spends!(node_txn[0], remote_txn[0]); - check_spends!(node_txn[1], remote_txn[0]); - if node_txn[0].input[0].witness.last().unwrap().len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { - 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; - assert!(new_feerate * 100 > feerate_timeout * 125); - assert_ne!(timeout, node_txn[0].txid()); - - let index = node_txn[1].input[0].previous_output.vout; - let fee = remote_txn[0].output[index as usize].value - node_txn[1].output[0].value; - let new_feerate = fee * 1000 / node_txn[1].get_weight() as u64; - assert!(new_feerate * 100 > feerate_preimage * 125); - assert_ne!(preimage, node_txn[1].txid()); - } else { - let index = node_txn[1].input[0].previous_output.vout; - let fee = remote_txn[0].output[index as usize].value - node_txn[1].output[0].value; - let new_feerate = fee * 1000 / node_txn[1].get_weight() as u64; - assert!(new_feerate * 100 > feerate_timeout * 125); - assert_ne!(timeout, node_txn[1].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; - assert!(new_feerate * 100 > feerate_preimage * 125); - assert_ne!(preimage, node_txn[0].txid()); - } + check_spends!(preimage_bump, remote_txn[0]); + + 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; + 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; + assert!(new_feerate * 100 > feerate_preimage * 125); + assert_ne!(preimage, node_txn[0].txid()); + node_txn.clear(); } @@ -8790,16 +8835,17 @@ fn test_htlc_no_detection() { chain::Listen::block_connected(&nodes[0].chain_monitor.chain_monitor, &Block { header, txdata: vec![local_txn[0].clone()] }, nodes[0].best_block_info().1 + 1); check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); + connect_blocks(&nodes[0], TEST_FINAL_CLTV - 1); let htlc_timeout = { let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn[0].input.len(), 1); - assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[0], local_txn[0]); - node_txn[0].clone() + assert_eq!(node_txn[1].input.len(), 1); + assert_eq!(node_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); + check_spends!(node_txn[1], local_txn[0]); + node_txn[1].clone() }; - let header_201 = BlockHeader { version: 0x20000000, prev_blockhash: header.block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + let header_201 = BlockHeader { version: 0x20000000, prev_blockhash: nodes[0].best_block_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; connect_block(&nodes[0], &Block { header: header_201, txdata: vec![htlc_timeout.clone()] }); connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1); expect_payment_failed!(nodes[0], our_payment_hash, true);