@@ -826,6 +826,13 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
826826 /// spending CSV for revocable outputs).
827827 htlcs_resolved_on_chain : Vec < IrrevocablyResolvedHTLC > ,
828828
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+
829836 // We simply modify best_block in Channel's block_connected so that serialization is
830837 // consistent but hopefully the users' copy handles block_connected in a consistent way.
831838 // (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> {
10711078 ( 7 , self . funding_spend_seen, required) ,
10721079 ( 9 , self . counterparty_node_id, option) ,
10731080 ( 11 , self . confirmed_commitment_tx_counterparty_output, option) ,
1081+ ( 13 , self . spendable_txids_confirmed, vec_type) ,
10741082 } ) ;
10751083
10761084 Ok ( ( ) )
@@ -1179,6 +1187,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
11791187 funding_spend_confirmed : None ,
11801188 confirmed_commitment_tx_counterparty_output : None ,
11811189 htlcs_resolved_on_chain : Vec :: new ( ) ,
1190+ spendable_txids_confirmed : Vec :: new ( ) ,
11821191
11831192 best_block,
11841193 counterparty_node_id : Some ( counterparty_node_id) ,
@@ -2860,7 +2869,37 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
28602869
28612870 let mut watch_outputs = Vec :: new ( ) ;
28622871 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+
28642903 if tx. input . len ( ) == 1 {
28652904 // Assuming our keys were not leaked (in which case we're screwed no matter what),
28662905 // commitment transactions and HTLC transactions will all only ever have one input,
@@ -2870,7 +2909,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
28702909 if prevout. txid == self . funding_info . 0 . txid && prevout. vout == self . funding_info . 0 . index as u32 {
28712910 let mut balance_spendable_csv = None ;
28722911 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) ;
28742913 self . funding_spend_seen = true ;
28752914 let mut commitment_tx_to_counterparty_output = None ;
28762915 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> {
28932932 }
28942933 }
28952934 }
2896- let txid = tx. txid ( ) ;
28972935 self . onchain_events_awaiting_threshold_conf . push ( OnchainEventEntry {
28982936 txid,
28992937 transaction : Some ( ( * tx) . clone ( ) ) ,
@@ -3042,6 +3080,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
30423080 self . pending_events . push ( Event :: SpendableOutputs {
30433081 outputs : vec ! [ descriptor]
30443082 } ) ;
3083+ self . spendable_txids_confirmed . push ( entry. txid ) ;
30453084 } ,
30463085 OnchainEvent :: HTLCSpendConfirmation { commitment_tx_output_idx, preimage, .. } => {
30473086 self . htlcs_resolved_on_chain . push ( IrrevocablyResolvedHTLC {
@@ -3777,13 +3816,15 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
37773816 let mut funding_spend_seen = Some ( false ) ;
37783817 let mut counterparty_node_id = None ;
37793818 let mut confirmed_commitment_tx_counterparty_output = None ;
3819+ let mut spendable_txids_confirmed = Some ( Vec :: new ( ) ) ;
37803820 read_tlv_fields ! ( reader, {
37813821 ( 1 , funding_spend_confirmed, option) ,
37823822 ( 3 , htlcs_resolved_on_chain, vec_type) ,
37833823 ( 5 , pending_monitor_events, vec_type) ,
37843824 ( 7 , funding_spend_seen, option) ,
37853825 ( 9 , counterparty_node_id, option) ,
37863826 ( 11 , confirmed_commitment_tx_counterparty_output, option) ,
3827+ ( 13 , spendable_txids_confirmed, vec_type) ,
37873828 } ) ;
37883829
37893830 let mut secp_ctx = Secp256k1 :: new ( ) ;
@@ -3836,6 +3877,7 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K>
38363877 funding_spend_confirmed,
38373878 confirmed_commitment_tx_counterparty_output,
38383879 htlcs_resolved_on_chain : htlcs_resolved_on_chain. unwrap ( ) ,
3880+ spendable_txids_confirmed : spendable_txids_confirmed. unwrap ( ) ,
38393881
38403882 best_block,
38413883 counterparty_node_id,
0 commit comments