@@ -826,6 +826,13 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
826
826
/// spending CSV for revocable outputs).
827
827
htlcs_resolved_on_chain : Vec < IrrevocablyResolvedHTLC > ,
828
828
829
+ /// The set of `SpendableOutput` events which we have already passed upstream to be claimed.
830
+ /// These are tracked explicitly to ensure that we don't generate the same events redundantly
831
+ /// if users duplicatively confirm old transactions. Specifically for transactions claiming a
832
+ /// revoked remote outpoint we otherwise have no tracking at all once they've reached
833
+ /// [`ANTI_REORG_DELAY`], so we have to track them here.
834
+ spendable_txids_confirmed : Vec < Txid > ,
835
+
829
836
// We simply modify best_block in Channel's block_connected so that serialization is
830
837
// consistent but hopefully the users' copy handles block_connected in a consistent way.
831
838
// (we do *not*, however, update them in update_monitor to ensure any local user copies keep
@@ -1071,6 +1078,7 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
1071
1078
( 7 , self . funding_spend_seen, required) ,
1072
1079
( 9 , self . counterparty_node_id, option) ,
1073
1080
( 11 , self . confirmed_commitment_tx_counterparty_output, option) ,
1081
+ ( 13 , self . spendable_txids_confirmed, vec_type) ,
1074
1082
} ) ;
1075
1083
1076
1084
Ok ( ( ) )
@@ -1179,6 +1187,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
1179
1187
funding_spend_confirmed : None ,
1180
1188
confirmed_commitment_tx_counterparty_output : None ,
1181
1189
htlcs_resolved_on_chain : Vec :: new ( ) ,
1190
+ spendable_txids_confirmed : Vec :: new ( ) ,
1182
1191
1183
1192
best_block,
1184
1193
counterparty_node_id : Some ( counterparty_node_id) ,
@@ -2860,7 +2869,37 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
2860
2869
2861
2870
let mut watch_outputs = Vec :: new ( ) ;
2862
2871
let mut claimable_outpoints = Vec :: new ( ) ;
2863
- for tx in & txn_matched {
2872
+ ' tx_iter: for tx in & txn_matched {
2873
+ let txid = tx. txid ( ) ;
2874
+ // If a transaction has already been confirmed, ensure we don't bother processing it duplicatively.
2875
+ if Some ( txid) == self . funding_spend_confirmed {
2876
+ log_debug ! ( logger, "Skipping redundant processing of funding-spend tx {} as it was previously confirmed" , txid) ;
2877
+ continue ' tx_iter;
2878
+ }
2879
+ for ev in self . onchain_events_awaiting_threshold_conf . iter ( ) {
2880
+ if ev. txid == txid {
2881
+ if let Some ( conf_hash) = ev. block_hash {
2882
+ assert_eq ! ( header. block_hash( ) , conf_hash,
2883
+ "Transaction {} was already confirmed and is being re-confirmed in a different block.\n \
2884
+ This indicates a severe bug in the transaction connection logic - a reorg should have been processed first!", ev. txid) ;
2885
+ }
2886
+ log_debug ! ( logger, "Skipping redundant processing of confirming tx {} as it was previously confirmed" , txid) ;
2887
+ continue ' tx_iter;
2888
+ }
2889
+ }
2890
+ for htlc in self . htlcs_resolved_on_chain . iter ( ) {
2891
+ if Some ( txid) == htlc. resolving_txid {
2892
+ log_debug ! ( logger, "Skipping redundant processing of HTLC resolution tx {} as it was previously confirmed" , txid) ;
2893
+ continue ' tx_iter;
2894
+ }
2895
+ }
2896
+ for spendable_txid in self . spendable_txids_confirmed . iter ( ) {
2897
+ if txid == * spendable_txid {
2898
+ log_debug ! ( logger, "Skipping redundant processing of spendable tx {} as it was previously confirmed" , txid) ;
2899
+ continue ' tx_iter;
2900
+ }
2901
+ }
2902
+
2864
2903
if tx. input . len ( ) == 1 {
2865
2904
// Assuming our keys were not leaked (in which case we're screwed no matter what),
2866
2905
// commitment transactions and HTLC transactions will all only ever have one input,
@@ -2870,7 +2909,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
2870
2909
if prevout. txid == self . funding_info . 0 . txid && prevout. vout == self . funding_info . 0 . index as u32 {
2871
2910
let mut balance_spendable_csv = None ;
2872
2911
log_info ! ( logger, "Channel {} closed by funding output spend in txid {}." ,
2873
- log_bytes!( self . funding_info. 0 . to_channel_id( ) ) , tx . txid( ) ) ;
2912
+ log_bytes!( self . funding_info. 0 . to_channel_id( ) ) , txid) ;
2874
2913
self . funding_spend_seen = true ;
2875
2914
let mut commitment_tx_to_counterparty_output = None ;
2876
2915
if ( tx. input [ 0 ] . sequence . 0 >> 8 * 3 ) as u8 == 0x80 && ( tx. lock_time . 0 >> 8 * 3 ) as u8 == 0x20 {
@@ -2893,7 +2932,6 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
2893
2932
}
2894
2933
}
2895
2934
}
2896
- let txid = tx. txid ( ) ;
2897
2935
self . onchain_events_awaiting_threshold_conf . push ( OnchainEventEntry {
2898
2936
txid,
2899
2937
transaction : Some ( ( * tx) . clone ( ) ) ,
@@ -3042,6 +3080,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
3042
3080
self . pending_events . push ( Event :: SpendableOutputs {
3043
3081
outputs : vec ! [ descriptor]
3044
3082
} ) ;
3083
+ self . spendable_txids_confirmed . push ( entry. txid ) ;
3045
3084
} ,
3046
3085
OnchainEvent :: HTLCSpendConfirmation { commitment_tx_output_idx, preimage, .. } => {
3047
3086
self . htlcs_resolved_on_chain . push ( IrrevocablyResolvedHTLC {
@@ -3777,13 +3816,15 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
3777
3816
let mut funding_spend_seen = Some ( false ) ;
3778
3817
let mut counterparty_node_id = None ;
3779
3818
let mut confirmed_commitment_tx_counterparty_output = None ;
3819
+ let mut spendable_txids_confirmed = Some ( Vec :: new ( ) ) ;
3780
3820
read_tlv_fields ! ( reader, {
3781
3821
( 1 , funding_spend_confirmed, option) ,
3782
3822
( 3 , htlcs_resolved_on_chain, vec_type) ,
3783
3823
( 5 , pending_monitor_events, vec_type) ,
3784
3824
( 7 , funding_spend_seen, option) ,
3785
3825
( 9 , counterparty_node_id, option) ,
3786
3826
( 11 , confirmed_commitment_tx_counterparty_output, option) ,
3827
+ ( 13 , spendable_txids_confirmed, vec_type) ,
3787
3828
} ) ;
3788
3829
3789
3830
let mut secp_ctx = Secp256k1 :: new ( ) ;
@@ -3836,6 +3877,7 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
3836
3877
funding_spend_confirmed,
3837
3878
confirmed_commitment_tx_counterparty_output,
3838
3879
htlcs_resolved_on_chain : htlcs_resolved_on_chain. unwrap ( ) ,
3880
+ spendable_txids_confirmed : spendable_txids_confirmed. unwrap ( ) ,
3839
3881
3840
3882
best_block,
3841
3883
counterparty_node_id,
0 commit comments