@@ -5037,24 +5037,34 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_timeout_tx() {
5037
5037
check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
5038
5038
5039
5039
let node_txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ;
5040
- 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
5041
- assert_eq ! ( node_txn[ 0 ] . input. len( ) , 2 ) ;
5042
- check_spends ! ( node_txn[ 0 ] , revoked_local_txn[ 0 ] ) ;
5043
- check_spends ! ( node_txn[ 1 ] , chan_1. 3 ) ;
5040
+ assert_eq ! ( node_txn. len( ) , 3 ) ; // ChannelMonitor: bogus justice tx, justice tx on revoked outputs, ChannelManager: local commitment tx
5041
+ // The first transaction generated is bogus - it spends both outputs of revoked_local_txn[0]
5042
+ // including the one already spent by revoked_htlc_txn[0]. That's OK, we'll spend with valid
5043
+ // transactions next...
5044
+ assert_eq ! ( node_txn[ 0 ] . input. len( ) , 3 ) ;
5045
+ check_spends ! ( node_txn[ 0 ] , revoked_local_txn[ 0 ] , revoked_htlc_txn[ 0 ] ) ;
5046
+
5047
+ assert_eq ! ( node_txn[ 1 ] . input. len( ) , 2 ) ;
5048
+ check_spends ! ( node_txn[ 1 ] , revoked_local_txn[ 0 ] , revoked_htlc_txn[ 0 ] ) ;
5049
+ if node_txn[ 1 ] . input [ 1 ] . previous_output . txid == revoked_htlc_txn[ 0 ] . txid ( ) {
5050
+ assert_ne ! ( node_txn[ 1 ] . input[ 0 ] . previous_output, revoked_htlc_txn[ 0 ] . input[ 0 ] . previous_output) ;
5051
+ } else {
5052
+ assert_eq ! ( node_txn[ 1 ] . input[ 0 ] . previous_output. txid, revoked_htlc_txn[ 0 ] . txid( ) ) ;
5053
+ assert_ne ! ( node_txn[ 1 ] . input[ 1 ] . previous_output, revoked_htlc_txn[ 0 ] . input[ 0 ] . previous_output) ;
5054
+ }
5055
+
5044
5056
assert_eq ! ( node_txn[ 2 ] . input. len( ) , 1 ) ;
5045
- check_spends ! ( node_txn[ 2 ] , revoked_htlc_txn[ 0 ] ) ;
5046
- assert_eq ! ( node_txn[ 3 ] . input. len( ) , 1 ) ;
5047
- check_spends ! ( node_txn[ 3 ] , revoked_local_txn[ 0 ] ) ;
5057
+ check_spends ! ( node_txn[ 2 ] , chan_1. 3 ) ;
5048
5058
5049
5059
let header_1 = BlockHeader { version : 0x20000000 , prev_blockhash : header. block_hash ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
5050
- nodes[ 1 ] . block_notifier . block_connected ( & Block { header : header_1, txdata : vec ! [ node_txn[ 0 ] . clone ( ) , node_txn [ 2 ] . clone( ) ] } , 1 ) ;
5060
+ nodes[ 1 ] . block_notifier . block_connected ( & Block { header : header_1, txdata : vec ! [ node_txn[ 1 ] . clone( ) ] } , 1 ) ;
5051
5061
connect_blocks ( & nodes[ 1 ] . block_notifier , ANTI_REORG_DELAY - 1 , 1 , true , header. block_hash ( ) ) ;
5052
5062
5053
5063
// Check B's ChannelMonitor was able to generate the right spendable output descriptor
5054
5064
let spend_txn = check_spendable_outputs ! ( nodes[ 1 ] , 1 , node_cfgs[ 1 ] . keys_manager, 100000 ) ;
5055
- assert_eq ! ( spend_txn. len( ) , 2 ) ;
5056
- check_spends ! ( spend_txn[ 0 ] , node_txn [ 0 ] ) ;
5057
- check_spends ! ( spend_txn[ 1 ] , node_txn[ 2 ] ) ;
5065
+ assert_eq ! ( spend_txn. len( ) , 1 ) ;
5066
+ assert_eq ! ( spend_txn[ 0 ] . input . len ( ) , 1 ) ;
5067
+ check_spends ! ( spend_txn[ 0 ] , node_txn[ 1 ] ) ;
5058
5068
}
5059
5069
5060
5070
#[ test]
@@ -5072,6 +5082,9 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_success_tx() {
5072
5082
assert_eq ! ( revoked_local_txn[ 0 ] . input. len( ) , 1 ) ;
5073
5083
assert_eq ! ( revoked_local_txn[ 0 ] . input[ 0 ] . previous_output. txid, chan_1. 3 . txid( ) ) ;
5074
5084
5085
+ // The to-be-revoked commitment tx should have one HTLC and one to_remote output
5086
+ assert_eq ! ( revoked_local_txn[ 0 ] . output. len( ) , 2 ) ;
5087
+
5075
5088
claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , payment_preimage, 3_000_000 ) ;
5076
5089
5077
5090
let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
@@ -5086,28 +5099,50 @@ fn test_static_spendable_outputs_justice_tx_revoked_htlc_success_tx() {
5086
5099
assert_eq ! ( revoked_htlc_txn[ 0 ] . input[ 0 ] . witness. last( ) . unwrap( ) . len( ) , ACCEPTED_HTLC_SCRIPT_WEIGHT ) ;
5087
5100
check_spends ! ( revoked_htlc_txn[ 0 ] , revoked_local_txn[ 0 ] ) ;
5088
5101
5102
+ // Check that the unspent (of two) outputs on revoked_local_txn[0] is a P2WPKH:
5103
+ let unspent_local_txn_output = revoked_htlc_txn[ 0 ] . input [ 0 ] . previous_output . vout as usize ^ 1 ;
5104
+ assert_eq ! ( revoked_local_txn[ 0 ] . output[ unspent_local_txn_output] . script_pubkey. len( ) , 2 + 20 ) ; // P2WPKH
5105
+
5089
5106
// A will generate justice tx from B's revoked commitment/HTLC tx
5090
5107
nodes[ 0 ] . block_notifier . block_connected ( & Block { header, txdata : vec ! [ revoked_local_txn[ 0 ] . clone( ) , revoked_htlc_txn[ 0 ] . clone( ) ] } , 1 ) ;
5091
5108
check_closed_broadcast ! ( nodes[ 0 ] , false ) ;
5092
5109
check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
5093
5110
5094
5111
let node_txn = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ;
5095
5112
assert_eq ! ( node_txn. len( ) , 3 ) ; // ChannelMonitor: justice tx on revoked commitment, justice tx on revoked HTLC-success, ChannelManager: local commitment tx
5096
- assert_eq ! ( node_txn[ 2 ] . input. len( ) , 1 ) ;
5097
- check_spends ! ( node_txn[ 2 ] , revoked_htlc_txn[ 0 ] ) ;
5113
+
5114
+ // The first transaction generated is bogus - it spends both outputs of revoked_local_txn[0]
5115
+ // including the one already spent by revoked_htlc_txn[0]. That's OK, we'll spend with valid
5116
+ // transactions next...
5117
+ assert_eq ! ( node_txn[ 0 ] . input. len( ) , 2 ) ;
5118
+ check_spends ! ( node_txn[ 0 ] , revoked_local_txn[ 0 ] , revoked_htlc_txn[ 0 ] ) ;
5119
+ if node_txn[ 0 ] . input [ 1 ] . previous_output . txid == revoked_htlc_txn[ 0 ] . txid ( ) {
5120
+ assert_eq ! ( node_txn[ 0 ] . input[ 0 ] . previous_output, revoked_htlc_txn[ 0 ] . input[ 0 ] . previous_output) ;
5121
+ } else {
5122
+ assert_eq ! ( node_txn[ 0 ] . input[ 0 ] . previous_output. txid, revoked_htlc_txn[ 0 ] . txid( ) ) ;
5123
+ assert_eq ! ( node_txn[ 0 ] . input[ 1 ] . previous_output, revoked_htlc_txn[ 0 ] . input[ 0 ] . previous_output) ;
5124
+ }
5125
+
5126
+ assert_eq ! ( node_txn[ 1 ] . input. len( ) , 1 ) ;
5127
+ check_spends ! ( node_txn[ 1 ] , revoked_htlc_txn[ 0 ] ) ;
5128
+
5129
+ check_spends ! ( node_txn[ 2 ] , chan_1. 3 ) ;
5098
5130
5099
5131
let header_1 = BlockHeader { version : 0x20000000 , prev_blockhash : header. block_hash ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
5100
- nodes[ 0 ] . block_notifier . block_connected ( & Block { header : header_1, txdata : vec ! [ node_txn[ 0 ] . clone ( ) , node_txn [ 2 ] . clone( ) ] } , 1 ) ;
5132
+ nodes[ 0 ] . block_notifier . block_connected ( & Block { header : header_1, txdata : vec ! [ node_txn[ 1 ] . clone( ) ] } , 1 ) ;
5101
5133
connect_blocks ( & nodes[ 0 ] . block_notifier , ANTI_REORG_DELAY - 1 , 1 , true , header. block_hash ( ) ) ;
5102
5134
5135
+ // Note that nodes[0]'s tx_broadcaster is still locked, so if we get here the channelmonitor
5136
+ // didn't try to generate any new transactions.
5137
+
5103
5138
// Check A's ChannelMonitor was able to generate the right spendable output descriptor
5104
5139
let spend_txn = check_spendable_outputs ! ( nodes[ 0 ] , 1 , node_cfgs[ 0 ] . keys_manager, 100000 ) ;
5105
- assert_eq ! ( spend_txn. len( ) , 5 ) ; // Duplicated SpendableOutput due to block rescan after revoked htlc output tracking
5140
+ assert_eq ! ( spend_txn. len( ) , 3 ) ; // Duplicated SpendableOutput due to block rescan after revoked htlc output tracking
5106
5141
assert_eq ! ( spend_txn[ 0 ] , spend_txn[ 1 ] ) ;
5107
- assert_eq ! ( spend_txn[ 0 ] , spend_txn [ 2 ] ) ;
5142
+ assert_eq ! ( spend_txn[ 0 ] . input . len ( ) , 1 ) ;
5108
5143
check_spends ! ( spend_txn[ 0 ] , revoked_local_txn[ 0 ] ) ; // spending to_remote output from revoked local tx
5109
- check_spends ! ( spend_txn[ 3 ] , node_txn [ 0 ] ) ; // spending justice tx output from revoked local tx htlc received output
5110
- check_spends ! ( spend_txn[ 4 ] , node_txn[ 2 ] ) ; // spending justice tx output on htlc success tx
5144
+ assert_ne ! ( spend_txn[ 0 ] . input [ 0 ] . previous_output , revoked_htlc_txn [ 0 ] . input [ 0 ] . previous_output ) ;
5145
+ check_spends ! ( spend_txn[ 2 ] , node_txn[ 1 ] ) ; // spending justice tx output on the htlc success tx
5111
5146
}
5112
5147
5113
5148
#[ test]
@@ -7757,54 +7792,95 @@ fn test_bump_penalty_txn_on_revoked_htlcs() {
7757
7792
check_spends ! ( revoked_htlc_txn[ 0 ] , revoked_local_txn[ 0 ] ) ;
7758
7793
assert_eq ! ( revoked_htlc_txn[ 1 ] . input. len( ) , 1 ) ;
7759
7794
assert_eq ! ( revoked_htlc_txn[ 1 ] . input[ 0 ] . witness. last( ) . unwrap( ) . len( ) , OFFERED_HTLC_SCRIPT_WEIGHT ) ;
7795
+ assert_eq ! ( revoked_htlc_txn[ 1 ] . output. len( ) , 1 ) ;
7760
7796
check_spends ! ( revoked_htlc_txn[ 1 ] , revoked_local_txn[ 0 ] ) ;
7761
7797
} else if revoked_htlc_txn[ 1 ] . input [ 0 ] . witness . last ( ) . unwrap ( ) . len ( ) == ACCEPTED_HTLC_SCRIPT_WEIGHT {
7762
7798
assert_eq ! ( revoked_htlc_txn[ 1 ] . input. len( ) , 1 ) ;
7763
7799
check_spends ! ( revoked_htlc_txn[ 1 ] , revoked_local_txn[ 0 ] ) ;
7764
7800
assert_eq ! ( revoked_htlc_txn[ 0 ] . input. len( ) , 1 ) ;
7765
7801
assert_eq ! ( revoked_htlc_txn[ 0 ] . input[ 0 ] . witness. last( ) . unwrap( ) . len( ) , OFFERED_HTLC_SCRIPT_WEIGHT ) ;
7802
+ assert_eq ! ( revoked_htlc_txn[ 0 ] . output. len( ) , 1 ) ;
7766
7803
check_spends ! ( revoked_htlc_txn[ 0 ] , revoked_local_txn[ 0 ] ) ;
7767
7804
}
7768
7805
7769
7806
// Broadcast set of revoked txn on A
7770
- let header_128 = connect_blocks ( & nodes[ 0 ] . block_notifier , 128 , 0 , true , header. block_hash ( ) ) ;
7807
+ let header_128 = BlockHeader { version : 0x20000000 , prev_blockhash : header. block_hash ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
7808
+ nodes[ 0 ] . block_notifier . block_connected ( & Block { header : header_128, txdata : vec ! [ revoked_local_txn[ 0 ] . clone( ) ] } , 128 ) ;
7771
7809
expect_pending_htlcs_forwardable_ignore ! ( nodes[ 0 ] ) ;
7772
-
7773
- let header_129 = BlockHeader { version : 0x20000000 , prev_blockhash : header_128, merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
7774
- 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 ) ;
7810
+ let header_129 = BlockHeader { version : 0x20000000 , prev_blockhash : header_128. block_hash ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
7811
+ nodes[ 0 ] . block_notifier . block_connected ( & Block { header : header_129, txdata : vec ! [ revoked_htlc_txn[ 0 ] . clone( ) , revoked_htlc_txn[ 1 ] . clone( ) ] } , 129 ) ;
7775
7812
let first;
7776
7813
let feerate_1;
7777
7814
let penalty_txn;
7778
7815
{
7779
7816
let mut node_txn = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ;
7780
7817
assert_eq ! ( node_txn. len( ) , 5 ) ; // 3 penalty txn on revoked commitment tx + A commitment tx + 1 penalty tnx on revoked HTLC txn
7781
7818
// Verify claim tx are spending revoked HTLC txn
7819
+
7820
+ // node_txn 0-2 each spend a separate revoked output from revoked_local_txn[0]
7821
+ // Note that node_txn[0] and node_txn[1] are bogus - they double spend the revoked_htlc_txn
7822
+ // which are included in the same block (they are broadcasted because we scan the
7823
+ // transactions linearly and generate claims as we go, they likely should be removed in the
7824
+ // future).
7825
+ assert_eq ! ( node_txn[ 0 ] . input. len( ) , 1 ) ;
7826
+ check_spends ! ( node_txn[ 0 ] , revoked_local_txn[ 0 ] ) ;
7827
+ assert_eq ! ( node_txn[ 1 ] . input. len( ) , 1 ) ;
7828
+ check_spends ! ( node_txn[ 1 ] , revoked_local_txn[ 0 ] ) ;
7829
+ assert_eq ! ( node_txn[ 2 ] . input. len( ) , 1 ) ;
7830
+ check_spends ! ( node_txn[ 2 ] , revoked_local_txn[ 0 ] ) ;
7831
+
7832
+ // Each of the three justice transactions claim a separate (single) output of the three
7833
+ // available, which we check here:
7834
+ assert_ne ! ( node_txn[ 0 ] . input[ 0 ] . previous_output, node_txn[ 1 ] . input[ 0 ] . previous_output) ;
7835
+ assert_ne ! ( node_txn[ 0 ] . input[ 0 ] . previous_output, node_txn[ 2 ] . input[ 0 ] . previous_output) ;
7836
+ assert_ne ! ( node_txn[ 1 ] . input[ 0 ] . previous_output, node_txn[ 2 ] . input[ 0 ] . previous_output) ;
7837
+
7838
+ assert_eq ! ( node_txn[ 0 ] . input[ 0 ] . previous_output, revoked_htlc_txn[ 0 ] . input[ 0 ] . previous_output) ;
7839
+ assert_eq ! ( node_txn[ 1 ] . input[ 0 ] . previous_output, revoked_htlc_txn[ 1 ] . input[ 0 ] . previous_output) ;
7840
+
7841
+ // node_txn[3] is the local commitment tx broadcast just because (and somewhat in case of
7842
+ // reorgs, though its not clear its ever worth broadcasting conflicting txn like this when
7843
+ // a remote commitment tx has already been confirmed).
7844
+ check_spends ! ( node_txn[ 3 ] , chan. 3 ) ;
7845
+
7846
+ // node_txn[4] spends the revoked outputs from the revoked_htlc_txn (which only have one
7847
+ // output, checked above).
7782
7848
assert_eq ! ( node_txn[ 4 ] . input. len( ) , 2 ) ;
7783
7849
assert_eq ! ( node_txn[ 4 ] . output. len( ) , 1 ) ;
7784
7850
check_spends ! ( node_txn[ 4 ] , revoked_htlc_txn[ 0 ] , revoked_htlc_txn[ 1 ] ) ;
7851
+
7785
7852
first = node_txn[ 4 ] . txid ( ) ;
7786
7853
// Store both feerates for later comparison
7787
7854
let fee_1 = revoked_htlc_txn[ 0 ] . output [ 0 ] . value + revoked_htlc_txn[ 1 ] . output [ 0 ] . value - node_txn[ 4 ] . output [ 0 ] . value ;
7788
7855
feerate_1 = fee_1 * 1000 / node_txn[ 4 ] . get_weight ( ) as u64 ;
7789
- penalty_txn = vec ! [ node_txn[ 0 ] . clone ( ) , node_txn [ 1 ] . clone ( ) , node_txn [ 2 ] . clone( ) ] ;
7856
+ penalty_txn = vec ! [ node_txn[ 2 ] . clone( ) ] ;
7790
7857
node_txn. clear ( ) ;
7791
7858
}
7792
7859
7793
- // Connect three more block to see if bumped penalty are issued for HTLC txn
7860
+ // Connect one more block to see if bumped penalty are issued for HTLC txn
7794
7861
let header_130 = BlockHeader { version : 0x20000000 , prev_blockhash : header_129. block_hash ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
7795
7862
nodes[ 0 ] . block_notifier . block_connected ( & Block { header : header_130, txdata : penalty_txn } , 130 ) ;
7863
+ let header_131 = BlockHeader { version : 0x20000000 , prev_blockhash : header_130. block_hash ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
7864
+ nodes[ 0 ] . block_notifier . block_connected ( & Block { header : header_131, txdata : Vec :: new ( ) } , 131 ) ;
7796
7865
{
7797
7866
let mut node_txn = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ;
7798
7867
assert_eq ! ( node_txn. len( ) , 2 ) ; // 2 bumped penalty txn on revoked commitment tx
7799
7868
7800
7869
check_spends ! ( node_txn[ 0 ] , revoked_local_txn[ 0 ] ) ;
7801
7870
check_spends ! ( node_txn[ 1 ] , revoked_local_txn[ 0 ] ) ;
7871
+ // Note that these are both bogus - they spend outputs already claimed in block 129:
7872
+ if node_txn[ 0 ] . input [ 0 ] . previous_output == revoked_htlc_txn[ 0 ] . input [ 0 ] . previous_output {
7873
+ assert_eq ! ( node_txn[ 1 ] . input[ 0 ] . previous_output, revoked_htlc_txn[ 1 ] . input[ 0 ] . previous_output) ;
7874
+ } else {
7875
+ assert_eq ! ( node_txn[ 0 ] . input[ 0 ] . previous_output, revoked_htlc_txn[ 1 ] . input[ 0 ] . previous_output) ;
7876
+ assert_eq ! ( node_txn[ 1 ] . input[ 0 ] . previous_output, revoked_htlc_txn[ 0 ] . input[ 0 ] . previous_output) ;
7877
+ }
7802
7878
7803
7879
node_txn. clear ( ) ;
7804
7880
} ;
7805
7881
7806
7882
// Few more blocks to confirm penalty txn
7807
- let header_135 = connect_blocks ( & nodes[ 0 ] . block_notifier , 5 , 130 , true , header_130 . block_hash ( ) ) ;
7883
+ let header_135 = connect_blocks ( & nodes[ 0 ] . block_notifier , 4 , 131 , true , header_131 . block_hash ( ) ) ;
7808
7884
assert ! ( nodes[ 0 ] . tx_broadcaster. txn_broadcasted. lock( ) . unwrap( ) . is_empty( ) ) ;
7809
7885
let header_144 = connect_blocks ( & nodes[ 0 ] . block_notifier , 9 , 135 , true , header_135) ;
7810
7886
let node_txn = {
0 commit comments