X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffunctional_tests.rs;h=a41ae11af2c2d19cb95060ef72d230b1e1cc4ca8;hb=78c48f76d429b21dc34bcf636946b3d5a30d9a1d;hp=089ac9ca71538bc763babb65cc62ce7149e0897a;hpb=53c894bcaa8c279f5ac8677b620833e590951cbf;p=rust-lightning diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 089ac9ca..a41ae11a 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -1499,10 +1499,10 @@ fn test_duplicate_htlc_different_direction_onchain() { check_spends!(claim_txn[3], claim_txn[2]); assert_eq!(htlc_pair.0.input.len(), 1); assert_eq!(htlc_pair.0.input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); // HTLC 1 <--> 0, preimage tx - check_spends!(htlc_pair.0, remote_txn[0].clone()); + check_spends!(htlc_pair.0, remote_txn[0]); assert_eq!(htlc_pair.1.input.len(), 1); assert_eq!(htlc_pair.1.input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); // HTLC 0 <--> 1, timeout tx - check_spends!(htlc_pair.1, remote_txn[0].clone()); + check_spends!(htlc_pair.1, remote_txn[0]); let events = nodes[0].node.get_and_clear_pending_msg_events(); assert_eq!(events.len(), 2); @@ -2120,7 +2120,7 @@ fn test_justice_tx() { assert_eq!(node_txn.len(), 2); // ChannelMonitor: penalty tx, ChannelManager: local commitment tx assert_eq!(node_txn[0].input.len(), 2); // We should claim the revoked output and the HTLC output - check_spends!(node_txn[0], revoked_local_txn[0].clone()); + check_spends!(node_txn[0], revoked_local_txn[0]); node_txn.swap_remove(0); node_txn.truncate(1); } @@ -2163,7 +2163,7 @@ fn test_justice_tx() { assert_eq!(node_txn.len(), 2); //ChannelMonitor: penalty tx, ChannelManager: local commitment tx assert_eq!(node_txn[0].input.len(), 1); // We claim the received HTLC output - check_spends!(node_txn[0], revoked_local_txn[0].clone()); + check_spends!(node_txn[0], revoked_local_txn[0]); node_txn.swap_remove(0); } test_txn_broadcast(&nodes[0], &chan_6, None, HTLCType::NONE); @@ -2202,8 +2202,8 @@ fn revoked_output_claim() { let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 2); // ChannelMonitor: justice tx against revoked to_local output, ChannelManager: local commitment tx - check_spends!(node_txn[0], revoked_local_txn[0].clone()); - check_spends!(node_txn[1], chan_1.3.clone()); + check_spends!(node_txn[0], revoked_local_txn[0]); + check_spends!(node_txn[1], chan_1.3); // Inform nodes[0] that a watchtower cheated on its behalf, so it will force-close the chan nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); @@ -2235,7 +2235,7 @@ fn claim_htlc_outputs_shared_tx() { assert_eq!(revoked_local_txn[1].input.len(), 1); assert_eq!(revoked_local_txn[1].input[0].previous_output.txid, revoked_local_txn[0].txid()); assert_eq!(revoked_local_txn[1].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); // HTLC-Timeout - check_spends!(revoked_local_txn[1], revoked_local_txn[0].clone()); + check_spends!(revoked_local_txn[1], revoked_local_txn[0]); //Revoke the old state claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage_1, 3_000_000); @@ -2259,7 +2259,7 @@ fn claim_htlc_outputs_shared_tx() { assert_eq!(node_txn.len(), 3); // ChannelMonitor: penalty tx, ChannelManager: local commitment + HTLC-timeout assert_eq!(node_txn[0].input.len(), 3); // Claim the revoked output + both revoked HTLC outputs - check_spends!(node_txn[0], revoked_local_txn[0].clone()); + check_spends!(node_txn[0], revoked_local_txn[0]); let mut witness_lens = BTreeSet::new(); witness_lens.insert(node_txn[0].input[0].witness.last().unwrap().len()); @@ -2325,62 +2325,53 @@ fn claim_htlc_outputs_single_tx() { } let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 26); + assert_eq!(node_txn.len(), 21); // 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 * 7 (7), after one increase, bumps on HTLC aren't generated not being substantial anymore - // ChannelMonitor: local commitment + local HTLC-timeout (14) - - - assert_eq!(node_txn[3], node_txn[5]); - assert_eq!(node_txn[3], node_txn[7]); - assert_eq!(node_txn[3], node_txn[9]); - assert_eq!(node_txn[3], node_txn[14]); - assert_eq!(node_txn[3], node_txn[17]); - assert_eq!(node_txn[3], node_txn[20]); - assert_eq!(node_txn[3], node_txn[23]); - - assert_eq!(node_txn[4], node_txn[6]); - assert_eq!(node_txn[4], node_txn[8]); - assert_eq!(node_txn[4], node_txn[10]); - assert_eq!(node_txn[4], node_txn[15]); - assert_eq!(node_txn[4], node_txn[18]); - assert_eq!(node_txn[4], node_txn[21]); - assert_eq!(node_txn[4], node_txn[24]); - + // ChannelMonitor: bumped justice tx (4), after one increase, bumps on HTLC aren't generated not being substantial anymore + // ChannelMonito r: local commitment + local HTLC-timeout (14) + + assert_eq!(node_txn[0], node_txn[5]); + assert_eq!(node_txn[0], node_txn[7]); + assert_eq!(node_txn[0], node_txn[9]); + assert_eq!(node_txn[0], node_txn[13]); + assert_eq!(node_txn[0], node_txn[15]); + assert_eq!(node_txn[0], node_txn[17]); + assert_eq!(node_txn[0], node_txn[19]); + + assert_eq!(node_txn[1], node_txn[6]); + assert_eq!(node_txn[1], node_txn[8]); + assert_eq!(node_txn[1], node_txn[10]); + assert_eq!(node_txn[1], node_txn[14]); + assert_eq!(node_txn[1], node_txn[16]); + assert_eq!(node_txn[1], node_txn[18]); + assert_eq!(node_txn[1], node_txn[20]); + + + // Check the pair local commitment and HTLC-timeout broadcast due to HTLC expiration and present 8 times (rebroadcast at every block from 200 to 206) assert_eq!(node_txn[0].input.len(), 1); + check_spends!(node_txn[0], chan_1.3); assert_eq!(node_txn[1].input.len(), 1); - assert_eq!(node_txn[2].input.len(), 1); + let witness_script = node_txn[1].input[0].witness.last().unwrap(); + assert_eq!(witness_script.len(), OFFERED_HTLC_SCRIPT_WEIGHT); //Spending an offered htlc output + check_spends!(node_txn[1], node_txn[0]); - fn get_txout(out_point: &BitcoinOutPoint, tx: &Transaction) -> Option { - if out_point.txid == tx.txid() { - tx.output.get(out_point.vout as usize).cloned() - } else { - None - } - } - node_txn[0].verify(|out|get_txout(out, &revoked_local_txn[0])).unwrap(); - node_txn[1].verify(|out|get_txout(out, &revoked_local_txn[0])).unwrap(); - node_txn[2].verify(|out|get_txout(out, &revoked_local_txn[0])).unwrap(); + // Justice transactions are indices 2-3-4 + assert_eq!(node_txn[2].input.len(), 1); + assert_eq!(node_txn[3].input.len(), 1); + assert_eq!(node_txn[4].input.len(), 1); + check_spends!(node_txn[2], revoked_local_txn[0]); + check_spends!(node_txn[3], revoked_local_txn[0]); + check_spends!(node_txn[4], revoked_local_txn[0]); let mut witness_lens = BTreeSet::new(); - witness_lens.insert(node_txn[0].input[0].witness.last().unwrap().len()); - witness_lens.insert(node_txn[1].input[0].witness.last().unwrap().len()); witness_lens.insert(node_txn[2].input[0].witness.last().unwrap().len()); + witness_lens.insert(node_txn[3].input[0].witness.last().unwrap().len()); + witness_lens.insert(node_txn[4].input[0].witness.last().unwrap().len()); assert_eq!(witness_lens.len(), 3); assert_eq!(*witness_lens.iter().skip(0).next().unwrap(), 77); // revoked to_local assert_eq!(*witness_lens.iter().skip(1).next().unwrap(), OFFERED_HTLC_SCRIPT_WEIGHT); // revoked offered HTLC assert_eq!(*witness_lens.iter().skip(2).next().unwrap(), ACCEPTED_HTLC_SCRIPT_WEIGHT); // revoked received HTLC - - assert_eq!(node_txn[3].input.len(), 1); - check_spends!(node_txn[3], chan_1.3.clone()); - - assert_eq!(node_txn[4].input.len(), 1); - let witness_script = node_txn[4].input[0].witness.last().unwrap(); - assert_eq!(witness_script.len(), OFFERED_HTLC_SCRIPT_WEIGHT); //Spending an offered htlc output - assert_eq!(node_txn[4].input[0].previous_output.txid, node_txn[3].txid()); - assert_ne!(node_txn[4].input[0].previous_output.txid, node_txn[0].input[0].previous_output.txid); - assert_ne!(node_txn[4].input[0].previous_output.txid, node_txn[1].input[0].previous_output.txid); } get_announce_close_broadcast_events(&nodes, 0, 1); assert_eq!(nodes[0].node.list_channels().len(), 0); @@ -2424,7 +2415,7 @@ fn test_htlc_on_chain_success() { // Broadcast HTLC Success transaction by C on received output from C's commitment tx on B's chain let commitment_tx = nodes[2].node.channel_state.lock().unwrap().by_id.get_mut(&chan_2.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); assert_eq!(commitment_tx.len(), 1); - check_spends!(commitment_tx[0], chan_2.3.clone()); + check_spends!(commitment_tx[0], chan_2.3); nodes[2].node.claim_funds(our_payment_preimage, 3_000_000); nodes[2].node.claim_funds(our_payment_preimage_2, 3_000_000); check_added_monitors!(nodes[2], 2); @@ -2443,8 +2434,8 @@ fn test_htlc_on_chain_success() { assert_eq!(node_txn[0], node_txn[5]); assert_eq!(node_txn[1], node_txn[6]); assert_eq!(node_txn[2], commitment_tx[0]); - check_spends!(node_txn[0], commitment_tx[0].clone()); - check_spends!(node_txn[1], commitment_tx[0].clone()); + check_spends!(node_txn[0], commitment_tx[0]); + check_spends!(node_txn[1], commitment_tx[0]); assert_eq!(node_txn[0].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); assert_eq!(node_txn[1].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output @@ -2483,8 +2474,8 @@ fn test_htlc_on_chain_success() { assert_eq!(node_txn.len(), if $htlc_offered { 7 } else { 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 * 2 (block-rescan) - check_spends!(node_txn[0], $commitment_tx.clone()); - check_spends!(node_txn[1], $commitment_tx.clone()); + check_spends!(node_txn[0], $commitment_tx); + check_spends!(node_txn[1], $commitment_tx); if $htlc_offered { assert_eq!(node_txn[0], node_txn[5]); assert_eq!(node_txn[1], node_txn[6]); @@ -2502,9 +2493,9 @@ fn test_htlc_on_chain_success() { 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 } - check_spends!(node_txn[2], $chan_tx.clone()); - check_spends!(node_txn[3], node_txn[2].clone()); - check_spends!(node_txn[4], node_txn[2].clone()); + 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); @@ -2523,18 +2514,18 @@ 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 = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); - check_spends!(commitment_tx[0], chan_1.3.clone()); + check_spends!(commitment_tx[0], chan_1.3); nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 1); check_closed_broadcast!(nodes[1], false); 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].clone()); + 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.clone()); + 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]); @@ -2591,7 +2582,7 @@ fn test_htlc_on_chain_timeout() { // Broadcast legit commitment tx from C on B's chain let commitment_tx = nodes[2].node.channel_state.lock().unwrap().by_id.get_mut(&chan_2.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); - check_spends!(commitment_tx[0], chan_2.3.clone()); + check_spends!(commitment_tx[0], chan_2.3); nodes[2].node.fail_htlc_backwards(&payment_hash); check_added_monitors!(nodes[2], 0); expect_pending_htlcs_forwardable!(nodes[2]); @@ -2613,7 +2604,7 @@ fn test_htlc_on_chain_timeout() { check_closed_broadcast!(nodes[2], false); let node_txn = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 1 (commitment tx) assert_eq!(node_txn.len(), 1); - check_spends!(node_txn[0], chan_2.3.clone()); + check_spends!(node_txn[0], chan_2.3); assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), 71); // Broadcast timeout transaction by B on received output from C's commitment tx on B's chain @@ -2623,21 +2614,20 @@ fn test_htlc_on_chain_timeout() { { let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 7); // ChannelManager : 2 (commitment tx, HTLC-Timeout tx), ChannelMonitor : (local commitment tx + HTLC-timeout) * 2 (block-rescan), timeout tx - assert_eq!(node_txn[1], node_txn[3]); - assert_eq!(node_txn[1], node_txn[5]); - assert_eq!(node_txn[2], node_txn[4]); - assert_eq!(node_txn[2], node_txn[6]); - check_spends!(node_txn[0], commitment_tx[0].clone()); - assert_eq!(node_txn[0].clone().input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[1], chan_2.3.clone()); - check_spends!(node_txn[2], node_txn[1].clone()); - 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[3], chan_2.3.clone()); - check_spends!(node_txn[4], node_txn[3].clone()); - assert_eq!(node_txn[3].input[0].witness.clone().last().unwrap().len(), 71); - assert_eq!(node_txn[4].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); - timeout_tx = node_txn[0].clone(); + assert_eq!(node_txn[0], node_txn[3]); + assert_eq!(node_txn[0], node_txn[5]); + assert_eq!(node_txn[1], node_txn[4]); + assert_eq!(node_txn[1], node_txn[6]); + + check_spends!(node_txn[2], commitment_tx[0]); + assert_eq!(node_txn[2].clone().input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); + + check_spends!(node_txn[0], chan_2.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); + + timeout_tx = node_txn[2].clone(); node_txn.clear(); } @@ -2665,16 +2655,16 @@ fn test_htlc_on_chain_timeout() { // Broadcast legit commitment tx from B on A's chain let commitment_tx = nodes[1].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); - check_spends!(commitment_tx[0], chan_1.3.clone()); + check_spends!(commitment_tx[0], chan_1.3); nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 200); check_closed_broadcast!(nodes[0], false); 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].clone()); + 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.clone()); - check_spends!(node_txn[2], node_txn[1].clone()); + 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); } @@ -4015,14 +4005,14 @@ fn test_claim_sizeable_push_msat() { check_closed_broadcast!(nodes[1], false); let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 1); - check_spends!(node_txn[0], chan.3.clone()); + check_spends!(node_txn[0], chan.3); assert_eq!(node_txn[0].output.len(), 2); // We can't force trimming of to_remote output as channel_reserve_satoshis block us to do so at channel opening let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()] }, 0); let spend_txn = check_spendable_outputs!(nodes[1], 1); assert_eq!(spend_txn.len(), 1); - check_spends!(spend_txn[0], node_txn[0].clone()); + check_spends!(spend_txn[0], node_txn[0]); } #[test] @@ -4040,7 +4030,7 @@ fn test_claim_on_remote_sizeable_push_msat() { let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 1); - check_spends!(node_txn[0], chan.3.clone()); + check_spends!(node_txn[0], chan.3); assert_eq!(node_txn[0].output.len(), 2); // We can't force trimming of to_remote output as channel_reserve_satoshis block us to do so at channel opening let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; @@ -4049,7 +4039,7 @@ fn test_claim_on_remote_sizeable_push_msat() { let spend_txn = check_spendable_outputs!(nodes[1], 1); assert_eq!(spend_txn.len(), 2); assert_eq!(spend_txn[0], spend_txn[1]); - check_spends!(spend_txn[0], node_txn[0].clone()); + check_spends!(spend_txn[0], node_txn[0]); } #[test] @@ -4075,11 +4065,10 @@ fn test_claim_on_remote_revoked_sizeable_push_msat() { let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); let spend_txn = check_spendable_outputs!(nodes[1], 1); - assert_eq!(spend_txn.len(), 4); + assert_eq!(spend_txn.len(), 3); assert_eq!(spend_txn[0], spend_txn[2]); // to_remote output on revoked remote commitment_tx - check_spends!(spend_txn[0], revoked_local_txn[0].clone()); - assert_eq!(spend_txn[1], spend_txn[3]); // to_local output on local commitment tx - check_spends!(spend_txn[1], node_txn[0].clone()); + check_spends!(spend_txn[0], revoked_local_txn[0]); + check_spends!(spend_txn[1], node_txn[0]); } #[test] @@ -4116,16 +4105,15 @@ fn test_static_spendable_outputs_preimage_tx() { // Check B's monitor was able to send back output descriptor event for preimage tx on A's commitment tx let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); // ChannelManager : 2 (local commitment tx + HTLC-Success), ChannelMonitor: preimage tx assert_eq!(node_txn.len(), 3); - check_spends!(node_txn[0], commitment_tx[0].clone()); + check_spends!(node_txn[0], commitment_tx[0]); assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT); eprintln!("{:?}", node_txn[1]); - check_spends!(node_txn[1], chan_1.3.clone()); + check_spends!(node_txn[1], chan_1.3); check_spends!(node_txn[2], node_txn[1]); let spend_txn = check_spendable_outputs!(nodes[1], 1); // , 0, 0, 1, 1); - assert_eq!(spend_txn.len(), 2); - assert_eq!(spend_txn[0], spend_txn[1]); - check_spends!(spend_txn[0], node_txn[0].clone()); + assert_eq!(spend_txn.len(), 1); + check_spends!(spend_txn[0], node_txn[0]); } #[test] @@ -4152,12 +4140,11 @@ fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() { let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 2); assert_eq!(node_txn[0].input.len(), 2); - check_spends!(node_txn[0], revoked_local_txn[0].clone()); + check_spends!(node_txn[0], revoked_local_txn[0]); let spend_txn = check_spendable_outputs!(nodes[1], 1); - assert_eq!(spend_txn.len(), 2); - assert_eq!(spend_txn[0], spend_txn[1]); - check_spends!(spend_txn[0], node_txn[0].clone()); + assert_eq!(spend_txn.len(), 1); + check_spends!(spend_txn[0], node_txn[0]); } #[test] @@ -4187,8 +4174,8 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() { assert_eq!(revoked_htlc_txn[0], revoked_htlc_txn[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].clone()); - check_spends!(revoked_htlc_txn[1], chan_1.3.clone()); + check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]); + check_spends!(revoked_htlc_txn[1], chan_1.3); // B will generate justice tx from A's revoked commitment/HTLC tx nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }, 1); @@ -4197,14 +4184,13 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() { let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 4 ); // ChannelMonitor: justice tx on revoked commitment, justice tx on revoked HTLC-timeout, adjusted justice tx, ChannelManager: local commitment tx assert_eq!(node_txn[2].input.len(), 1); - check_spends!(node_txn[2], revoked_htlc_txn[0].clone()); + check_spends!(node_txn[2], revoked_htlc_txn[0]); // Check B's ChannelMonitor was able to generate the right spendable output descriptor let spend_txn = check_spendable_outputs!(nodes[1], 1); - assert_eq!(spend_txn.len(), 3); - assert_eq!(spend_txn[0], spend_txn[1]); - check_spends!(spend_txn[0], node_txn[0].clone()); - check_spends!(spend_txn[2], node_txn[2].clone()); + assert_eq!(spend_txn.len(), 2); + check_spends!(spend_txn[0], node_txn[0]); + check_spends!(spend_txn[1], node_txn[2]); } #[test] @@ -4234,7 +4220,7 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_success_tx() { assert_eq!(revoked_htlc_txn[0], revoked_htlc_txn[2]); assert_eq!(revoked_htlc_txn[0].input.len(), 1); assert_eq!(revoked_htlc_txn[0].input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - check_spends!(revoked_htlc_txn[0], revoked_local_txn[0].clone()); + check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]); // A will generate justice tx from B's revoked commitment/HTLC tx nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()] }, 1); @@ -4243,16 +4229,15 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_success_tx() { let node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 3); // ChannelMonitor: justice tx on revoked commitment, justice tx on revoked HTLC-success, ChannelManager: local commitment tx assert_eq!(node_txn[2].input.len(), 1); - check_spends!(node_txn[2], revoked_htlc_txn[0].clone()); + check_spends!(node_txn[2], revoked_htlc_txn[0]); // Check A's ChannelMonitor was able to generate the right spendable output descriptor let spend_txn = check_spendable_outputs!(nodes[0], 1); - assert_eq!(spend_txn.len(), 5); + assert_eq!(spend_txn.len(), 4); assert_eq!(spend_txn[0], spend_txn[2]); - assert_eq!(spend_txn[1], spend_txn[3]); - check_spends!(spend_txn[0], revoked_local_txn[0].clone()); // spending to_remote output from revoked local tx - check_spends!(spend_txn[1], node_txn[0].clone()); // spending justice tx output from revoked local tx htlc received output - check_spends!(spend_txn[4], node_txn[2].clone()); // spending justice tx output on htlc success tx + check_spends!(spend_txn[0], revoked_local_txn[0]); // spending to_remote output from revoked local tx + check_spends!(spend_txn[1], node_txn[0]); // spending justice tx output from revoked local tx htlc received output + check_spends!(spend_txn[3], node_txn[2]); // spending justice tx output on htlc success tx } #[test] @@ -4281,7 +4266,7 @@ fn test_onchain_to_onchain_claim() { let (payment_preimage, _payment_hash) = route_payment(&nodes[0], &vec!(&nodes[1], &nodes[2]), 3000000); let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42}; let commitment_tx = nodes[2].node.channel_state.lock().unwrap().by_id.get_mut(&chan_2.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); - check_spends!(commitment_tx[0], chan_2.3.clone()); + check_spends!(commitment_tx[0], chan_2.3); nodes[2].node.claim_funds(payment_preimage, 3_000_000); check_added_monitors!(nodes[2], 1); let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id()); @@ -4298,8 +4283,8 @@ fn test_onchain_to_onchain_claim() { assert_eq!(c_txn[0], c_txn[2]); assert_eq!(c_txn[0], c_txn[3]); assert_eq!(commitment_tx[0], c_txn[1]); - check_spends!(c_txn[1], chan_2.3.clone()); - check_spends!(c_txn[2], c_txn[1].clone()); + check_spends!(c_txn[1], chan_2.3); + check_spends!(c_txn[2], c_txn[1]); assert_eq!(c_txn[1].input[0].witness.clone().last().unwrap().len(), 71); assert_eq!(c_txn[2].input[0].witness.clone().last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT); assert!(c_txn[0].output[0].script_pubkey.is_v0_p2wsh()); // revokeable output @@ -4312,11 +4297,11 @@ fn test_onchain_to_onchain_claim() { // 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].clone()); // HTLC-Timeout on 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].clone()); // timeout tx on C remote commitment tx, issued by ChannelMonitor, * 2 due to block rescan + check_spends!(b_txn[0], c_txn[1]); // timeout tx on C remote commitment tx, issued by ChannelMonitor, * 2 due to block rescan 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 assert_ne!(b_txn[2].lock_time, 0); // Timeout tx @@ -4345,8 +4330,8 @@ fn test_onchain_to_onchain_claim() { // 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].clone()); - check_spends!(b_txn[0], commitment_tx[0].clone()); + 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 @@ -4372,7 +4357,7 @@ fn test_duplicate_payment_hash_one_failure_one_success() { let commitment_txn = nodes[2].node.channel_state.lock().unwrap().by_id.get_mut(&chan_2.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); assert_eq!(commitment_txn[0].input.len(), 1); - check_spends!(commitment_txn[0], chan_2.3.clone()); + check_spends!(commitment_txn[0], chan_2.3); let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![commitment_txn[0].clone()] }, 1); @@ -4383,16 +4368,16 @@ fn test_duplicate_payment_hash_one_failure_one_success() { 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].clone()); + check_spends!(node_txn[0], commitment_txn[0]); assert_eq!(node_txn[0].input.len(), 1); - check_spends!(node_txn[1], commitment_txn[0].clone()); + 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.clone()); - check_spends!(node_txn[3], node_txn[2].clone()); - check_spends!(node_txn[4], node_txn[2].clone()); + 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(); } @@ -4410,7 +4395,7 @@ fn test_duplicate_payment_hash_one_failure_one_success() { } let htlc_success_txn: Vec<_> = nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); assert_eq!(htlc_success_txn.len(), 7); - check_spends!(htlc_success_txn[2], chan_2.3.clone()); + check_spends!(htlc_success_txn[2], chan_2.3); check_spends!(htlc_success_txn[3], htlc_success_txn[2]); check_spends!(htlc_success_txn[4], htlc_success_txn[2]); assert_eq!(htlc_success_txn[0], htlc_success_txn[5]); @@ -4420,8 +4405,8 @@ fn test_duplicate_payment_hash_one_failure_one_success() { 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]); - check_spends!(htlc_success_txn[0], commitment_txn[0].clone()); - check_spends!(htlc_success_txn[1], commitment_txn[0].clone()); + check_spends!(htlc_success_txn[0], commitment_txn[0]); + check_spends!(htlc_success_txn[1], commitment_txn[0]); nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![htlc_timeout_tx] }, 200); connect_blocks(&nodes[1].block_notifier, ANTI_REORG_DELAY - 1, 200, true, header.bitcoin_hash()); @@ -4489,7 +4474,7 @@ fn test_dynamic_spendable_outputs_local_htlc_success_tx() { let payment_preimage = route_payment(&nodes[0], &vec!(&nodes[1])[..], 9000000).0; let local_txn = nodes[1].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); assert_eq!(local_txn[0].input.len(), 1); - check_spends!(local_txn[0], chan_1.3.clone()); + check_spends!(local_txn[0], chan_1.3); // Give B knowledge of preimage to be able to generate a local HTLC-Success Tx nodes[1].node.claim_funds(payment_preimage, 9_000_000); @@ -4508,13 +4493,13 @@ fn test_dynamic_spendable_outputs_local_htlc_success_tx() { let node_txn = nodes[1].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(), ACCEPTED_HTLC_SCRIPT_WEIGHT); - check_spends!(node_txn[0], local_txn[0].clone()); + check_spends!(node_txn[0], local_txn[0]); // Verify that B is able to spend its own HTLC-Success tx thanks to spendable output event given back by its ChannelMonitor let spend_txn = check_spendable_outputs!(nodes[1], 1); assert_eq!(spend_txn.len(), 2); - check_spends!(spend_txn[0], node_txn[0].clone()); - check_spends!(spend_txn[1], node_txn[2].clone()); + check_spends!(spend_txn[0], node_txn[0]); + check_spends!(spend_txn[1], node_txn[2]); } fn do_test_fail_backwards_unrevoked_remote_announce(deliver_last_raa: bool, announce_latest: bool) { @@ -4783,7 +4768,7 @@ fn test_dynamic_spendable_outputs_local_htlc_timeout_tx() { route_payment(&nodes[0], &vec!(&nodes[1])[..], 9000000).0; let local_txn = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2).unwrap().channel_monitor().get_latest_local_commitment_txn(); assert_eq!(local_txn[0].input.len(), 1); - check_spends!(local_txn[0], chan_1.3.clone()); + check_spends!(local_txn[0], chan_1.3); // Timeout HTLC on A's chain and so it can generate a HTLC-Timeout tx let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; @@ -4793,7 +4778,7 @@ fn test_dynamic_spendable_outputs_local_htlc_timeout_tx() { 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].clone()); + check_spends!(node_txn[0], local_txn[0]); // Verify that A is able to spend its own HTLC-Timeout tx thanks to spendable output event given back by its ChannelMonitor let spend_txn = check_spendable_outputs!(nodes[0], 1); @@ -4804,8 +4789,8 @@ fn test_dynamic_spendable_outputs_local_htlc_timeout_tx() { assert_eq!(spend_txn[1], spend_txn[3]); assert_eq!(spend_txn[1], spend_txn[5]); assert_eq!(spend_txn[1], spend_txn[7]); - check_spends!(spend_txn[0], local_txn[0].clone()); - check_spends!(spend_txn[1], node_txn[0].clone()); + check_spends!(spend_txn[0], local_txn[0]); + check_spends!(spend_txn[1], node_txn[0]); } #[test] @@ -4824,7 +4809,7 @@ fn test_static_output_closing_tx() { nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 1); let spend_txn = check_spendable_outputs!(nodes[0], 2); assert_eq!(spend_txn.len(), 1); - check_spends!(spend_txn[0], closing_tx.clone()); + check_spends!(spend_txn[0], closing_tx); nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![closing_tx.clone()] }, 1); let spend_txn = check_spendable_outputs!(nodes[1], 2); @@ -6571,7 +6556,7 @@ fn test_data_loss_protect() { let logger: Arc = Arc::new(test_utils::TestLogger::with_id(format!("node {}", 0))); let mut chan_monitor = <(Sha256dHash, ChannelMonitor)>::read(&mut ::std::io::Cursor::new(previous_chan_monitor_state.0), Arc::clone(&logger)).unwrap().1; let chain_monitor = Arc::new(ChainWatchInterfaceUtil::new(Network::Testnet, Arc::clone(&logger))); - tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new()), broadcasted_txn: Mutex::new(HashSet::new())}; + tx_broadcaster = test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())}; fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: 253 }; keys_manager = test_utils::TestKeysInterface::new(&nodes[0].node_seed, Network::Testnet, Arc::clone(&logger)); monitor = test_utils::TestChannelMonitor::new(chain_monitor.clone(), &tx_broadcaster, logger.clone(), &fee_estimator); @@ -6653,13 +6638,13 @@ fn test_data_loss_protect() { // Check A is able to claim to_remote output let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); assert_eq!(node_txn.len(), 1); - check_spends!(node_txn[0], chan.3.clone()); + check_spends!(node_txn[0], chan.3); assert_eq!(node_txn[0].output.len(), 2); let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42}; nodes[0].block_notifier.block_connected(&Block { header, txdata: vec![node_txn[0].clone()]}, 1); let spend_txn = check_spendable_outputs!(nodes[0], 1); assert_eq!(spend_txn.len(), 1); - check_spends!(spend_txn[0], node_txn[0].clone()); + check_spends!(spend_txn[0], node_txn[0]); } #[test] @@ -6819,7 +6804,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() { assert_eq!(node_txn.len(), 3); // justice tx (broadcasted from ChannelMonitor) + local commitment tx + local HTLC-timeout (broadcasted from ChannelManager) assert_eq!(node_txn[0].input.len(), 3); // Penalty txn claims to_local, offered_htlc and received_htlc outputs assert_eq!(node_txn[0].output.len(), 1); - check_spends!(node_txn[0], revoked_txn[0].clone()); + 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; penalty_1 = node_txn[0].txid(); @@ -6836,7 +6821,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() { if node_txn[0].input[0].previous_output.txid == revoked_txid { assert_eq!(node_txn[0].input.len(), 3); // Penalty txn claims to_local, offered_htlc and received_htlc outputs assert_eq!(node_txn[0].output.len(), 1); - check_spends!(node_txn[0], revoked_txn[0].clone()); + check_spends!(node_txn[0], revoked_txn[0]); penalty_2 = node_txn[0].txid(); // Verify new bumped tx is different from last claiming transaction, we don't want spurrious rebroadcast assert_ne!(penalty_2, penalty_1); @@ -6859,7 +6844,7 @@ fn test_bump_penalty_txn_on_revoked_commitment() { if node_txn[0].input[0].previous_output.txid == revoked_txid { assert_eq!(node_txn[0].input.len(), 3); // Penalty txn claims to_local, offered_htlc and received_htlc outputs assert_eq!(node_txn[0].output.len(), 1); - check_spends!(node_txn[0], revoked_txn[0].clone()); + check_spends!(node_txn[0], revoked_txn[0]); penalty_3 = node_txn[0].txid(); // Verify new bumped tx is different from last claiming transaction, we don't want spurrious rebroadcast assert_ne!(penalty_3, penalty_2); @@ -6903,116 +6888,73 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { nodes[1].block_notifier.block_connected(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1); check_closed_broadcast!(nodes[1], false); - let mut received = ::std::usize::MAX; - let mut offered = ::std::usize::MAX; let revoked_htlc_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(revoked_htlc_txn.len(), 6); 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].clone()); + 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); - check_spends!(revoked_htlc_txn[1], revoked_local_txn[0].clone()); - received = 0; - offered = 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].clone()); + 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); - check_spends!(revoked_htlc_txn[0], revoked_local_txn[0].clone()); - received = 1; - offered = 0; + check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]); } // Broadcast set of revoked txn on A - let header_128 = connect_blocks(&nodes[0].block_notifier, 128, 0, true, header.bitcoin_hash()); + let header_128 = connect_blocks(&nodes[0].block_notifier, 128, 0, true, header.bitcoin_hash()); let header_129 = BlockHeader { version: 0x20000000, prev_blockhash: header_128, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; nodes[0].block_notifier.block_connected(&Block { header: header_129, txdata: vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone(), revoked_htlc_txn[1].clone()] }, 129); let first; - let second; let feerate_1; - let feerate_2; + let penalty_txn; { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 6); // 3 penalty txn on revoked commitment tx + A commitment tx + 2 penalty tnx on revoked HTLC txn + assert_eq!(node_txn.len(), 5); // 3 penalty txn on revoked commitment tx + A commitment tx + 1 penalty tnx on revoked HTLC txn // Verify claim tx are spending revoked HTLC txn - assert_eq!(node_txn[4].input.len(), 1); + 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].clone()); + check_spends!(node_txn[4], revoked_htlc_txn[0], revoked_htlc_txn[1]); first = node_txn[4].txid(); - assert_eq!(node_txn[5].input.len(), 1); - assert_eq!(node_txn[5].output.len(), 1); - check_spends!(node_txn[5], revoked_htlc_txn[1].clone()); - second = node_txn[5].txid(); // Store both feerates for later comparison - let fee_1 = revoked_htlc_txn[0].output[0].value - node_txn[4].output[0].value; + let fee_1 = revoked_htlc_txn[0].output[0].value + revoked_htlc_txn[1].output[0].value - node_txn[4].output[0].value; feerate_1 = fee_1 * 1000 / node_txn[4].get_weight() as u64; - let fee_2 = revoked_htlc_txn[1].output[0].value - node_txn[5].output[0].value; - feerate_2 = fee_2 * 1000 / node_txn[5].get_weight() as u64; + penalty_txn = vec![node_txn[0].clone(), node_txn[1].clone(), node_txn[2].clone()]; node_txn.clear(); } // Connect three more block to see if bumped penalty are issued for HTLC txn - let header_132 = connect_blocks(&nodes[0].block_notifier, 3, 129, true, header_129.bitcoin_hash()); - let penalty_local_tx; + let header_130 = BlockHeader { version: 0x20000000, prev_blockhash: header_129.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; + nodes[0].block_notifier.block_connected(&Block { header: header_130, txdata: penalty_txn }, 130); { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 3); // 2 bumped penalty txn on offered/received HTLC outputs of revoked commitment tx + 1 penalty tx on to_local of revoked commitment tx + 2 bumped penalty tx on revoked HTLC txn + assert_eq!(node_txn.len(), 2); // 2 bumped penalty txn on revoked commitment tx - check_spends!(node_txn[0], revoked_local_txn[0].clone()); - check_spends!(node_txn[1], revoked_local_txn[0].clone()); + check_spends!(node_txn[0], revoked_local_txn[0]); + check_spends!(node_txn[1], revoked_local_txn[0]); - check_spends!(node_txn[2], revoked_local_txn[0].clone()); - - penalty_local_tx = node_txn[2].clone(); node_txn.clear(); }; - // Few more blocks to broadcast and confirm penalty_local_tx - let header_133 = BlockHeader { version: 0x20000000, prev_blockhash: header_132, merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 }; - nodes[0].block_notifier.block_connected(&Block { header: header_133, txdata: vec![penalty_local_tx] }, 133); - let header_135 = connect_blocks(&nodes[0].block_notifier, 2, 133, true, header_133.bitcoin_hash()); - { - let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 1); - check_spends!(node_txn[0], revoked_local_txn[0].clone()); - node_txn.clear(); - } + + // Few more blocks to confirm penalty txn + let header_135 = connect_blocks(&nodes[0].block_notifier, 5, 130, true, header_130.bitcoin_hash()); + assert!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().is_empty()); let header_144 = connect_blocks(&nodes[0].block_notifier, 9, 135, true, header_135); let node_txn = { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 2); - - let mut penalty_offered = ::std::usize::MAX; - let mut penalty_received = ::std::usize::MAX; - - { - for (i, tx) in node_txn.iter().enumerate() { - if tx.input[0].previous_output.txid == revoked_htlc_txn[offered].txid() { - penalty_offered = i; - } else if tx.input[0].previous_output.txid == revoked_htlc_txn[received].txid() { - penalty_received = i; - } - } - } + assert_eq!(node_txn.len(), 1); - assert_eq!(node_txn[penalty_received].input.len(), 1); - assert_eq!(node_txn[penalty_received].output.len(), 1); - assert_eq!(node_txn[penalty_offered].input.len(), 1); - assert_eq!(node_txn[penalty_offered].output.len(), 1); - // Verify bumped tx is different and 25% bump heuristic - check_spends!(node_txn[penalty_offered], revoked_htlc_txn[offered].clone()); - assert_ne!(first, node_txn[penalty_offered].txid()); - let fee = revoked_htlc_txn[offered].output[0].value - node_txn[penalty_offered].output[0].value; - let new_feerate = fee * 1000 / node_txn[penalty_offered].get_weight() as u64; - assert!(new_feerate * 100 > feerate_1 * 125); - - check_spends!(node_txn[penalty_received], revoked_htlc_txn[received].clone()); - assert_ne!(second, node_txn[penalty_received].txid()); - let fee = revoked_htlc_txn[received].output[0].value - node_txn[penalty_received].output[0].value; - let new_feerate = fee * 1000 / node_txn[penalty_received].get_weight() as u64; - assert!(new_feerate * 100 > feerate_2 * 125); - let txn = vec![node_txn[0].clone(), node_txn[1].clone()]; + assert_eq!(node_txn[0].input.len(), 2); + check_spends!(node_txn[0], revoked_htlc_txn[0], revoked_htlc_txn[1]); + //// 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 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()]; node_txn.clear(); txn }; @@ -7022,7 +6964,7 @@ fn test_bump_penalty_txn_on_revoked_htlcs() { connect_blocks(&nodes[0].block_notifier, 20, 145, true, header_145.bitcoin_hash()); { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); - assert_eq!(node_txn.len(), 2); //TODO: fix check_spend_remote_htlc lack of watch output + assert_eq!(node_txn.len(), 1); //TODO: fix check_spend_remote_htlc lack of watch output node_txn.clear(); } check_closed_broadcast!(nodes[0], false); @@ -7068,8 +7010,8 @@ fn test_bump_penalty_txn_on_remote_commitment() { assert_eq!(node_txn.len(), 5); // 2 * claim tx (broadcasted from ChannelMonitor) + local commitment tx + local HTLC-timeout + local HTLC-success (broadcasted from ChannelManager) assert_eq!(node_txn[0].input.len(), 1); assert_eq!(node_txn[1].input.len(), 1); - check_spends!(node_txn[0], remote_txn[0].clone()); - check_spends!(node_txn[1], remote_txn[0].clone()); + 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]); @@ -7106,8 +7048,8 @@ fn test_bump_penalty_txn_on_remote_commitment() { assert_eq!(node_txn.len(), 2); assert_eq!(node_txn[0].input.len(), 1); assert_eq!(node_txn[1].input.len(), 1); - check_spends!(node_txn[0], remote_txn[0].clone()); - check_spends!(node_txn[1], remote_txn[0].clone()); + 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; @@ -7160,8 +7102,8 @@ fn test_set_outpoints_partial_claiming() { assert_eq!(remote_txn[0].output.len(), 4); assert_eq!(remote_txn[0].input.len(), 1); assert_eq!(remote_txn[0].input[0].previous_output.txid, chan.3.txid()); - check_spends!(remote_txn[1], remote_txn[0].clone()); - check_spends!(remote_txn[2], remote_txn[0].clone()); + check_spends!(remote_txn[1], remote_txn[0]); + check_spends!(remote_txn[2], remote_txn[0]); // Connect blocks on node A to advance height towards TEST_FINAL_CLTV let prev_header_100 = connect_blocks(&nodes[1].block_notifier, 100, 0, false, Default::default()); @@ -7180,8 +7122,8 @@ fn test_set_outpoints_partial_claiming() { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); // ChannelMonitor: claim tx, ChannelManager: local commitment tx + HTLC-Success*2 assert_eq!(node_txn.len(), 4); - check_spends!(node_txn[0], remote_txn[0].clone()); - check_spends!(node_txn[1], chan.3.clone()); + check_spends!(node_txn[0], remote_txn[0]); + 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[0].input.len(), 2); @@ -7195,8 +7137,8 @@ fn test_set_outpoints_partial_claiming() { let partial_claim_tx = { let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 3); - check_spends!(node_txn[1], node_txn[0].clone()); - check_spends!(node_txn[2], node_txn[0].clone()); + check_spends!(node_txn[1], node_txn[0]); + check_spends!(node_txn[2], node_txn[0]); assert_eq!(node_txn[1].input.len(), 1); assert_eq!(node_txn[2].input.len(), 1); node_txn[1].clone() @@ -7209,7 +7151,7 @@ fn test_set_outpoints_partial_claiming() { { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 1); - check_spends!(node_txn[0], remote_txn[0].clone()); + check_spends!(node_txn[0], remote_txn[0]); assert_eq!(node_txn[0].input.len(), 1); //dropped HTLC node_txn.clear(); } @@ -7220,7 +7162,7 @@ fn test_set_outpoints_partial_claiming() { { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 1); - check_spends!(node_txn[0], remote_txn[0].clone()); + check_spends!(node_txn[0], remote_txn[0]); assert_eq!(node_txn[0].input.len(), 2); //resurrected HTLC node_txn.clear(); } @@ -7292,9 +7234,9 @@ fn test_bump_txn_sanitize_tracking_maps() { let penalty_txn = { let mut node_txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap(); assert_eq!(node_txn.len(), 4); //ChannelMonitor: justice txn * 3, ChannelManager: local commitment tx - check_spends!(node_txn[0], revoked_local_txn[0].clone()); - check_spends!(node_txn[1], revoked_local_txn[0].clone()); - check_spends!(node_txn[2], revoked_local_txn[0].clone()); + check_spends!(node_txn[0], revoked_local_txn[0]); + check_spends!(node_txn[1], revoked_local_txn[0]); + check_spends!(node_txn[2], revoked_local_txn[0]); let penalty_txn = vec![node_txn[0].clone(), node_txn[1].clone(), node_txn[2].clone()]; node_txn.clear(); penalty_txn @@ -7305,8 +7247,8 @@ fn test_bump_txn_sanitize_tracking_maps() { { let monitors = nodes[0].chan_monitor.simple_monitor.monitors.lock().unwrap(); if let Some(monitor) = monitors.get(&OutPoint::new(chan.3.txid(), 0)) { - assert!(monitor.pending_claim_requests.is_empty()); - assert!(monitor.claimable_outpoints.is_empty()); + assert!(monitor.onchain_tx_handler.pending_claim_requests.is_empty()); + assert!(monitor.onchain_tx_handler.claimable_outpoints.is_empty()); } } }