@@ -15,7 +15,7 @@ use crate::chain;
1515use crate::chain::{ChannelMonitorUpdateStatus, Confirm, Listen, Watch};
1616use crate::chain::chaininterface::LowerBoundedFeeEstimator;
1717use crate::chain::channelmonitor;
18- use crate::chain::channelmonitor::{Balance, ChannelMonitorUpdateStep, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY};
18+ use crate::chain::channelmonitor::{Balance, ChannelMonitorUpdateStep, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY, COUNTERPARTY_CLAIMABLE_WITHIN_BLOCKS_PINNABLE };
1919use crate::chain::transaction::OutPoint;
2020use crate::sign::{ecdsa::EcdsaChannelSigner, EntropySource, OutputSpender, SignerProvider};
2121use crate::events::bump_transaction::WalletSource;
@@ -2645,14 +2645,12 @@ fn test_justice_tx_htlc_timeout() {
26452645 mine_transaction(&nodes[1], &revoked_local_txn[0]);
26462646 {
26472647 let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
2648- // The unpinnable, revoked to_self output, and the pinnable, revoked htlc output will
2649- // be claimed in separate transactions.
2650- assert_eq!(node_txn.len(), 2);
2651- for tx in node_txn.iter() {
2652- assert_eq!(tx.input.len(), 1);
2653- check_spends!(tx, revoked_local_txn[0]);
2654- }
2655- assert_ne!(node_txn[0].input[0].previous_output, node_txn[1].input[0].previous_output);
2648+ // The revoked HTLC output is not pinnable for another `TEST_FINAL_CLTV` blocks, and is
2649+ // thus claimed in the same transaction with the revoked to_self output.
2650+ assert_eq!(node_txn.len(), 1);
2651+ assert_eq!(node_txn[0].input.len(), 2);
2652+ check_spends!(node_txn[0], revoked_local_txn[0]);
2653+ assert_ne!(node_txn[0].input[0].previous_output, node_txn[0].input[1].previous_output);
26562654 node_txn.clear();
26572655 }
26582656 check_added_monitors!(nodes[1], 1);
@@ -2872,28 +2870,26 @@ fn claim_htlc_outputs() {
28722870 assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
28732871
28742872 let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
2875- assert_eq!(node_txn.len(), 2); // Two penalty transactions:
2876- assert_eq!(node_txn[0].input.len(), 1); // Claims the unpinnable, revoked output.
2877- assert_eq!(node_txn[1].input.len(), 2); // Claims both pinnable, revoked HTLC outputs separately.
2878- check_spends!(node_txn[0], revoked_local_txn[0]);
2879- check_spends!(node_txn[1], revoked_local_txn[0]);
2880- assert_ne!(node_txn[0].input[0].previous_output, node_txn[1].input[0].previous_output);
2881- assert_ne!(node_txn[0].input[0].previous_output, node_txn[1].input[1].previous_output);
2882- assert_ne!(node_txn[1].input[0].previous_output, node_txn[1].input[1].previous_output);
2873+ assert_eq!(node_txn.len(), 2); // ChannelMonitor: penalty txn
2874+
2875+ // The ChannelMonitor should claim the accepted HTLC output separately from the offered
2876+ // HTLC and to_self outputs.
2877+ let accepted_claim = node_txn.iter().filter(|tx| tx.input.len() == 1).next().unwrap();
2878+ let offered_to_self_claim = node_txn.iter().filter(|tx| tx.input.len() == 2).next().unwrap();
2879+ check_spends!(accepted_claim, revoked_local_txn[0]);
2880+ check_spends!(offered_to_self_claim, revoked_local_txn[0]);
2881+ assert_eq!(accepted_claim.input[0].witness.last().unwrap().len(), ACCEPTED_HTLC_SCRIPT_WEIGHT);
28832882
28842883 let mut witness_lens = BTreeSet::new();
2885- witness_lens.insert(node_txn[0].input[0].witness.last().unwrap().len());
2886- witness_lens.insert(node_txn[1].input[0].witness.last().unwrap().len());
2887- witness_lens.insert(node_txn[1].input[1].witness.last().unwrap().len());
2888- assert_eq!(witness_lens.len(), 3);
2884+ witness_lens.insert(offered_to_self_claim.input[0].witness.last().unwrap().len());
2885+ witness_lens.insert(offered_to_self_claim.input[1].witness.last().unwrap().len());
2886+ assert_eq!(witness_lens.len(), 2);
28892887 assert_eq!(*witness_lens.iter().skip(0).next().unwrap(), 77); // revoked to_local
2890- assert_eq!(*witness_lens.iter().skip(1).next().unwrap(), OFFERED_HTLC_SCRIPT_WEIGHT); // revoked offered HTLC
2891- assert_eq!(*witness_lens.iter().skip(2).next().unwrap(), ACCEPTED_HTLC_SCRIPT_WEIGHT); // revoked received HTLC
2888+ assert_eq!(*witness_lens.iter().skip(1).next().unwrap(), OFFERED_HTLC_SCRIPT_WEIGHT);
28922889
2893- // Finally, mine the penalty transactions and check that we get an HTLC failure after
2890+ // Finally, mine the penalty transaction and check that we get an HTLC failure after
28942891 // ANTI_REORG_DELAY confirmations.
2895- mine_transaction(&nodes[1], &node_txn[0]);
2896- mine_transaction(&nodes[1], &node_txn[1]);
2892+ mine_transaction(&nodes[1], accepted_claim);
28972893 connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1);
28982894 expect_payment_failed!(nodes[1], payment_hash_2, false);
28992895 }
@@ -5056,8 +5052,7 @@ fn test_static_spendable_outputs_timeout_tx() {
50565052 check_spends!(spend_txn[2], node_txn[0], commitment_tx[0]); // All outputs
50575053}
50585054
5059- #[test]
5060- fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() {
5055+ fn do_test_static_spendable_outputs_justice_tx_revoked_commitment_tx(split_tx: bool) {
50615056 let chanmon_cfgs = create_chanmon_cfgs(2);
50625057 let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
50635058 let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
@@ -5073,20 +5068,28 @@ fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() {
50735068
50745069 claim_payment(&nodes[0], &vec!(&nodes[1])[..], payment_preimage);
50755070
5071+ if split_tx {
5072+ connect_blocks(&nodes[1], TEST_FINAL_CLTV - COUNTERPARTY_CLAIMABLE_WITHIN_BLOCKS_PINNABLE + 1);
5073+ }
5074+
50765075 mine_transaction(&nodes[1], &revoked_local_txn[0]);
50775076 check_closed_broadcast!(nodes[1], true);
50785077 check_added_monitors!(nodes[1], 1);
50795078 check_closed_event!(nodes[1], 1, ClosureReason::CommitmentTxConfirmed, [nodes[0].node.get_our_node_id()], 100000);
50805079
5081- // The unpinnable, revoked to_self output and the pinnable, revoked HTLC output will be claimed
5082- // in separate transactions.
5080+ // If the HTLC expires in more than COUNTERPARTY_CLAIMABLE_WITHIN_BLOCKS_PINNABLE blocks, we'll
5081+ // claim both the revoked and HTLC outputs in one transaction, otherwise we'll split them as we
5082+ // consider the HTLC output as pinnable and want to claim pinnable and unpinnable outputs
5083+ // separately.
50835084 let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone();
5084- assert_eq!(node_txn.len(), 2 );
5085+ assert_eq!(node_txn.len(), if split_tx { 2 } else { 1 } );
50855086 for tx in node_txn.iter() {
5086- assert_eq!(tx.input.len(), 1 );
5087+ assert_eq!(tx.input.len(), if split_tx { 1 } else { 2 } );
50875088 check_spends!(tx, revoked_local_txn[0]);
50885089 }
5089- assert_ne!(node_txn[0].input[0].previous_output, node_txn[1].input[0].previous_output);
5090+ if split_tx {
5091+ assert_ne!(node_txn[0].input[0].previous_output, node_txn[1].input[0].previous_output);
5092+ }
50905093
50915094 mine_transaction(&nodes[1], &node_txn[0]);
50925095 connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1);
@@ -5096,6 +5099,12 @@ fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() {
50965099 check_spends!(spend_txn[0], node_txn[0]);
50975100}
50985101
5102+ #[test]
5103+ fn test_static_spendable_outputs_justice_tx_revoked_commitment_tx() {
5104+ do_test_static_spendable_outputs_justice_tx_revoked_commitment_tx(true);
5105+ do_test_static_spendable_outputs_justice_tx_revoked_commitment_tx(false);
5106+ }
5107+
50995108#[test]
51005109fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() {
51015110 let mut chanmon_cfgs = create_chanmon_cfgs(2);
@@ -5128,6 +5137,10 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() {
51285137 check_spends!(revoked_htlc_txn[0], revoked_local_txn[0]);
51295138 assert_ne!(revoked_htlc_txn[0].lock_time, LockTime::ZERO); // HTLC-Timeout
51305139
5140+ // In order to connect `revoked_htlc_txn[0]` we must first advance the chain by
5141+ // `TEST_FINAL_CLTV` blocks as otherwise the transaction is consensus-invalid due to its
5142+ // locktime.
5143+ connect_blocks(&nodes[1], TEST_FINAL_CLTV);
51315144 // B will generate justice tx from A's revoked commitment/HTLC tx
51325145 connect_block(&nodes[1], &create_dummy_block(nodes[1].best_block_hash(), 42, vec![revoked_local_txn[0].clone(), revoked_htlc_txn[0].clone()]));
51335146 check_closed_broadcast!(nodes[1], true);
0 commit comments