@@ -1669,6 +1669,33 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
16691669 current_height, & broadcaster, & fee_estimator, & logger,
16701670 ) ;
16711671 }
1672+
1673+ /// Returns the descriptor for a relevant output (i.e., one that we can spend) within the
1674+ /// transaction if one exists and the transaction has at least [`ANTI_REORG_DELAY`]
1675+ /// confirmations.
1676+ ///
1677+ /// Descriptors returned by this method are primarily exposed via [`Event::SpendableOutputs`]
1678+ /// once they are no longer under reorg risk. This method serves as a way to retrieve these
1679+ /// descriptors at a later time, either for historical purposes, or to replay any
1680+ /// missed/unhandled descriptors. For the purpose of gathering historical records, if the
1681+ /// channel close has fully resolved (i.e., [`ChannelMonitor::get_claimable_balances`] returns
1682+ /// an empty set), you can retrieve all spendable outputs by providing all descendant spending
1683+ /// transactions starting from the channel's funding or closing transaction that have at least
1684+ /// [`ANTI_REORG_DELAY`] confirmations.
1685+ ///
1686+ /// `tx` is a transaction we'll scan the outputs of. Any transaction can be provided. If an
1687+ /// output which can be spent by us is found, a descriptor is returned.
1688+ ///
1689+ /// `confirmation_height` must be the height of the block in which `tx` was included in.
1690+ pub fn get_spendable_output ( & self , tx : & Transaction , confirmation_height : u32 ) -> Option < SpendableOutputDescriptor > {
1691+ let inner = self . inner . lock ( ) . unwrap ( ) ;
1692+ let current_height = inner. best_block . height ;
1693+ if current_height. saturating_sub ( ANTI_REORG_DELAY ) + 1 >= confirmation_height {
1694+ inner. get_spendable_output ( tx)
1695+ } else {
1696+ None
1697+ }
1698+ }
16721699}
16731700
16741701impl < Signer : WriteableEcdsaChannelSigner > ChannelMonitorImpl < Signer > {
@@ -3441,7 +3468,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34413468 }
34423469 self . is_resolving_htlc_output ( & tx, height, & block_hash, & logger) ;
34433470
3444- self . is_paying_spendable_output ( & tx, height, & block_hash, & logger) ;
3471+ self . check_tx_and_push_spendable_output ( & tx, height, & block_hash, & logger) ;
34453472 }
34463473 }
34473474
@@ -3987,9 +4014,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
39874014 }
39884015 }
39894016
3990- /// Check if any transaction broadcasted is paying fund back to some address we can assume to own
3991- fn is_paying_spendable_output < L : Deref > ( & mut self , tx : & Transaction , height : u32 , block_hash : & BlockHash , logger : & L ) where L :: Target : Logger {
3992- let mut spendable_output = None ;
4017+ fn get_spendable_output ( & self , tx : & Transaction ) -> Option < SpendableOutputDescriptor > {
39934018 for ( i, outp) in tx. output . iter ( ) . enumerate ( ) { // There is max one spendable output for any channel tx, including ones generated by us
39944019 if i > :: core:: u16:: MAX as usize {
39954020 // While it is possible that an output exists on chain which is greater than the
@@ -4006,15 +4031,14 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
40064031 continue ;
40074032 }
40084033 if outp. script_pubkey == self . destination_script {
4009- spendable_output = Some ( SpendableOutputDescriptor :: StaticOutput {
4034+ return Some ( SpendableOutputDescriptor :: StaticOutput {
40104035 outpoint : OutPoint { txid : tx. txid ( ) , index : i as u16 } ,
40114036 output : outp. clone ( ) ,
40124037 } ) ;
4013- break ;
40144038 }
40154039 if let Some ( ref broadcasted_holder_revokable_script) = self . broadcasted_holder_revokable_script {
40164040 if broadcasted_holder_revokable_script. 0 == outp. script_pubkey {
4017- spendable_output = Some ( SpendableOutputDescriptor :: DelayedPaymentOutput ( DelayedPaymentOutputDescriptor {
4041+ return Some ( SpendableOutputDescriptor :: DelayedPaymentOutput ( DelayedPaymentOutputDescriptor {
40184042 outpoint : OutPoint { txid : tx. txid ( ) , index : i as u16 } ,
40194043 per_commitment_point : broadcasted_holder_revokable_script. 1 ,
40204044 to_self_delay : self . on_holder_tx_csv ,
@@ -4023,27 +4047,32 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
40234047 channel_keys_id : self . channel_keys_id ,
40244048 channel_value_satoshis : self . channel_value_satoshis ,
40254049 } ) ) ;
4026- break ;
40274050 }
40284051 }
40294052 if self . counterparty_payment_script == outp. script_pubkey {
4030- spendable_output = Some ( SpendableOutputDescriptor :: StaticPaymentOutput ( StaticPaymentOutputDescriptor {
4053+ return Some ( SpendableOutputDescriptor :: StaticPaymentOutput ( StaticPaymentOutputDescriptor {
40314054 outpoint : OutPoint { txid : tx. txid ( ) , index : i as u16 } ,
40324055 output : outp. clone ( ) ,
40334056 channel_keys_id : self . channel_keys_id ,
40344057 channel_value_satoshis : self . channel_value_satoshis ,
40354058 } ) ) ;
4036- break ;
40374059 }
40384060 if self . shutdown_script . as_ref ( ) == Some ( & outp. script_pubkey ) {
4039- spendable_output = Some ( SpendableOutputDescriptor :: StaticOutput {
4061+ return Some ( SpendableOutputDescriptor :: StaticOutput {
40404062 outpoint : OutPoint { txid : tx. txid ( ) , index : i as u16 } ,
40414063 output : outp. clone ( ) ,
40424064 } ) ;
4043- break ;
40444065 }
40454066 }
4046- if let Some ( spendable_output) = spendable_output {
4067+ None
4068+ }
4069+
4070+ /// Checks if the confirmed transaction is paying funds back to some address we can assume to
4071+ /// own.
4072+ fn check_tx_and_push_spendable_output < L : Deref > (
4073+ & mut self , tx : & Transaction , height : u32 , block_hash : & BlockHash , logger : & L ,
4074+ ) where L :: Target : Logger {
4075+ if let Some ( spendable_output) = self . get_spendable_output ( tx) {
40474076 let entry = OnchainEventEntry {
40484077 txid : tx. txid ( ) ,
40494078 transaction : Some ( tx. clone ( ) ) ,
0 commit comments