@@ -44,7 +44,7 @@ use crate::chain::package::{
4444use crate :: chain:: transaction:: { OutPoint , TransactionData } ;
4545use crate :: chain:: { BestBlock , WatchedOutput } ;
4646use crate :: events:: bump_transaction:: { AnchorDescriptor , BumpTransactionEvent } ;
47- use crate :: events:: { ClosureReason , Event , EventHandler , ReplayEvent } ;
47+ use crate :: events:: { ClosureReason , Event , EventHandler , FundingInfo , ReplayEvent } ;
4848use crate :: ln:: chan_utils:: {
4949 self , ChannelTransactionParameters , CommitmentTransaction , CounterpartyCommitmentSecrets ,
5050 HTLCClaim , HTLCOutputInCommitment , HolderCommitmentTransaction ,
@@ -688,6 +688,8 @@ pub(crate) enum ChannelMonitorUpdateStep {
688688 channel_parameters : ChannelTransactionParameters ,
689689 holder_commitment_tx : HolderCommitmentTransaction ,
690690 counterparty_commitment_tx : CommitmentTransaction ,
691+ contributed_inputs : Vec < BitcoinOutPoint > ,
692+ contributed_outputs : Vec < ScriptBuf > ,
691693 } ,
692694 RenegotiatedFundingLocked {
693695 funding_txid : Txid ,
@@ -773,6 +775,8 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
773775 ( 1 , channel_parameters, ( required: ReadableArgs , None ) ) ,
774776 ( 3 , holder_commitment_tx, required) ,
775777 ( 5 , counterparty_commitment_tx, required) ,
778+ ( 7 , contributed_inputs, optional_vec) ,
779+ ( 9 , contributed_outputs, optional_vec) ,
776780 } ,
777781 ( 12 , RenegotiatedFundingLocked ) => {
778782 ( 1 , funding_txid, required) ,
@@ -1166,6 +1170,10 @@ struct FundingScope {
11661170 // transaction for which we have deleted claim information on some watchtowers.
11671171 current_holder_commitment_tx : HolderCommitmentTransaction ,
11681172 prev_holder_commitment_tx : Option < HolderCommitmentTransaction > ,
1173+
1174+ /// Inputs and outputs we contributed when negotiating the corresponding funding transaction.
1175+ contributed_inputs : Option < Vec < BitcoinOutPoint > > ,
1176+ contributed_outputs : Option < Vec < ScriptBuf > > ,
11691177}
11701178
11711179impl FundingScope {
@@ -1194,6 +1202,8 @@ impl_writeable_tlv_based!(FundingScope, {
11941202 ( 7 , current_holder_commitment_tx, required) ,
11951203 ( 9 , prev_holder_commitment_tx, option) ,
11961204 ( 11 , counterparty_claimable_outpoints, required) ,
1205+ ( 13 , contributed_inputs, option) ,
1206+ ( 15 , contributed_outputs, option) ,
11971207} ) ;
11981208
11991209#[ derive( Clone , PartialEq ) ]
@@ -1755,6 +1765,8 @@ pub(crate) fn write_chanmon_internal<Signer: EcdsaChannelSigner, W: Writer>(
17551765 ( 34 , channel_monitor. alternative_funding_confirmed, option) ,
17561766 ( 35 , channel_monitor. is_manual_broadcast, required) ,
17571767 ( 37 , channel_monitor. funding_seen_onchain, required) ,
1768+ ( 39 , channel_monitor. funding. contributed_inputs, option) ,
1769+ ( 41 , channel_monitor. funding. contributed_outputs, option) ,
17581770 } ) ;
17591771
17601772 Ok ( ( ) )
@@ -1904,6 +1916,9 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
19041916
19051917 current_holder_commitment_tx : initial_holder_commitment_tx,
19061918 prev_holder_commitment_tx : None ,
1919+
1920+ contributed_inputs : None ,
1921+ contributed_outputs : None ,
19071922 } ,
19081923 pending_funding : vec ! [ ] ,
19091924
@@ -3958,6 +3973,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
39583973 & mut self , logger : & WithContext < L > , channel_parameters : & ChannelTransactionParameters ,
39593974 alternative_holder_commitment_tx : & HolderCommitmentTransaction ,
39603975 alternative_counterparty_commitment_tx : & CommitmentTransaction ,
3976+ contributed_inputs : & [ BitcoinOutPoint ] , contributed_outputs : & [ ScriptBuf ] ,
39613977 ) -> Result < ( ) , ( ) > {
39623978 let alternative_counterparty_commitment_txid =
39633979 alternative_counterparty_commitment_tx. trust ( ) . txid ( ) ;
@@ -4024,6 +4040,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
40244040 counterparty_claimable_outpoints,
40254041 current_holder_commitment_tx : alternative_holder_commitment_tx. clone ( ) ,
40264042 prev_holder_commitment_tx : None ,
4043+ contributed_inputs : Some ( contributed_inputs. to_vec ( ) ) ,
4044+ contributed_outputs : Some ( contributed_outputs. to_vec ( ) ) ,
40274045 } ;
40284046 let alternative_funding_outpoint = alternative_funding. funding_outpoint ( ) ;
40294047
@@ -4080,6 +4098,58 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
40804098 Ok ( ( ) )
40814099 }
40824100
4101+ fn queue_discard_funding_event (
4102+ & mut self , discarded_funding : impl Iterator < Item = FundingScope > ,
4103+ ) {
4104+ let ( mut discarded_inputs, mut discarded_outputs) = ( new_hash_set ( ) , new_hash_set ( ) ) ;
4105+ for funding in discarded_funding {
4106+ if funding. contributed_inputs . is_none ( ) && funding. contributed_outputs . is_none ( ) {
4107+ self . pending_events . push ( Event :: DiscardFunding {
4108+ channel_id : self . channel_id ,
4109+ funding_info : FundingInfo :: OutPoint { outpoint : funding. funding_outpoint ( ) } ,
4110+ } ) ;
4111+ } else {
4112+ // Filter out any inputs/outputs that were already included in the locked funding
4113+ // transaction.
4114+ if let Some ( mut maybe_discarded_inputs) = funding. contributed_inputs {
4115+ maybe_discarded_inputs. retain ( |input| {
4116+ let is_input_in_locked_funding = self
4117+ . funding
4118+ . contributed_inputs
4119+ . as_ref ( )
4120+ . map ( |inputs| inputs. contains ( input) )
4121+ // The recently locked funding did not contain any contributed inputs.
4122+ . unwrap_or ( false ) ;
4123+ !is_input_in_locked_funding
4124+ } ) ;
4125+ discarded_inputs. extend ( maybe_discarded_inputs) ;
4126+ }
4127+ if let Some ( mut maybe_discarded_outputs) = funding. contributed_outputs {
4128+ maybe_discarded_outputs. retain ( |output| {
4129+ let is_output_in_locked_funding = self
4130+ . funding
4131+ . contributed_outputs
4132+ . as_ref ( )
4133+ . map ( |outputs| outputs. contains ( output) )
4134+ // The recently locked funding did not contain any contributed outputs.
4135+ . unwrap_or ( false ) ;
4136+ !is_output_in_locked_funding
4137+ } ) ;
4138+ discarded_outputs. extend ( maybe_discarded_outputs) ;
4139+ }
4140+ }
4141+ }
4142+ if !discarded_inputs. is_empty ( ) || !discarded_outputs. is_empty ( ) {
4143+ self . pending_events . push ( Event :: DiscardFunding {
4144+ channel_id : self . channel_id ,
4145+ funding_info : FundingInfo :: Contribution {
4146+ inputs : discarded_inputs. into_iter ( ) . collect ( ) ,
4147+ outputs : discarded_outputs. into_iter ( ) . collect ( ) ,
4148+ } ,
4149+ } ) ;
4150+ }
4151+ }
4152+
40834153 fn promote_funding ( & mut self , new_funding_txid : Txid ) -> Result < ( ) , ( ) > {
40844154 let prev_funding_txid = self . funding . funding_txid ( ) ;
40854155
@@ -4110,18 +4180,20 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
41104180 let no_further_updates_allowed = self . no_further_updates_allowed ( ) ;
41114181
41124182 // The swap above places the previous `FundingScope` into `pending_funding`.
4113- for funding in self . pending_funding . drain ( ..) {
4114- let funding_txid = funding. funding_txid ( ) ;
4115- self . outputs_to_watch . remove ( & funding_txid) ;
4116- if no_further_updates_allowed && funding_txid != prev_funding_txid {
4117- self . pending_events . push ( Event :: DiscardFunding {
4118- channel_id : self . channel_id ,
4119- funding_info : crate :: events:: FundingInfo :: OutPoint {
4120- outpoint : funding. funding_outpoint ( ) ,
4121- } ,
4122- } ) ;
4123- }
4183+ for funding in & self . pending_funding {
4184+ self . outputs_to_watch . remove ( & funding. funding_txid ( ) ) ;
41244185 }
4186+ let mut discarded_funding = Vec :: new ( ) ;
4187+ mem:: swap ( & mut self . pending_funding , & mut discarded_funding) ;
4188+ let discarded_funding = discarded_funding
4189+ . into_iter ( )
4190+ // The previous funding is filtered out since it was already locked, so nothing needs to
4191+ // be discarded.
4192+ . filter ( |funding| {
4193+ no_further_updates_allowed && funding. funding_txid ( ) != prev_funding_txid
4194+ } ) ;
4195+ self . queue_discard_funding_event ( discarded_funding) ;
4196+
41254197 if let Some ( ( alternative_funding_txid, _) ) = self . alternative_funding_confirmed . take ( ) {
41264198 // In exceedingly rare cases, it's possible there was a reorg that caused a potential funding to
41274199 // be locked in that this `ChannelMonitor` has not yet seen. Thus, we avoid a runtime assertion
@@ -4238,11 +4310,13 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
42384310 } ,
42394311 ChannelMonitorUpdateStep :: RenegotiatedFunding {
42404312 channel_parameters, holder_commitment_tx, counterparty_commitment_tx,
4313+ contributed_inputs, contributed_outputs,
42414314 } => {
42424315 log_trace ! ( logger, "Updating ChannelMonitor with alternative holder and counterparty commitment transactions for funding txid {}" ,
42434316 channel_parameters. funding_outpoint. unwrap( ) . txid) ;
42444317 if let Err ( _) = self . renegotiated_funding (
42454318 logger, channel_parameters, holder_commitment_tx, counterparty_commitment_tx,
4319+ contributed_inputs, contributed_outputs,
42464320 ) {
42474321 ret = Err ( ( ) ) ;
42484322 }
@@ -5809,15 +5883,14 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
58095883 self . funding_spend_confirmed = Some ( entry. txid ) ;
58105884 self . confirmed_commitment_tx_counterparty_output = commitment_tx_to_counterparty_output;
58115885 if self . alternative_funding_confirmed . is_none ( ) {
5812- for funding in self . pending_funding . drain ( ..) {
5886+ // We saw a confirmed commitment for our currently locked funding, so
5887+ // discard all pending ones.
5888+ for funding in & self . pending_funding {
58135889 self . outputs_to_watch . remove ( & funding. funding_txid ( ) ) ;
5814- self . pending_events . push ( Event :: DiscardFunding {
5815- channel_id : self . channel_id ,
5816- funding_info : crate :: events:: FundingInfo :: OutPoint {
5817- outpoint : funding. funding_outpoint ( ) ,
5818- } ,
5819- } ) ;
58205890 }
5891+ let mut discarded_funding = Vec :: new ( ) ;
5892+ mem:: swap ( & mut self . pending_funding , & mut discarded_funding) ;
5893+ self . queue_discard_funding_event ( discarded_funding. into_iter ( ) ) ;
58215894 }
58225895 } ,
58235896 OnchainEvent :: AlternativeFundingConfirmation { } => {
@@ -6694,6 +6767,8 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
66946767 let mut alternative_funding_confirmed = None ;
66956768 let mut is_manual_broadcast = RequiredWrapper ( None ) ;
66966769 let mut funding_seen_onchain = RequiredWrapper ( None ) ;
6770+ let mut current_funding_contributed_inputs = None ;
6771+ let mut current_funding_contributed_outputs = None ;
66976772 read_tlv_fields ! ( reader, {
66986773 ( 1 , funding_spend_confirmed, option) ,
66996774 ( 3 , htlcs_resolved_on_chain, optional_vec) ,
@@ -6716,6 +6791,8 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
67166791 ( 34 , alternative_funding_confirmed, option) ,
67176792 ( 35 , is_manual_broadcast, ( default_value, false ) ) ,
67186793 ( 37 , funding_seen_onchain, ( default_value, true ) ) ,
6794+ ( 39 , current_funding_contributed_inputs, option) ,
6795+ ( 41 , current_funding_contributed_outputs, option) ,
67196796 } ) ;
67206797 // Note that `payment_preimages_with_info` was added (and is always written) in LDK 0.1, so
67216798 // we can use it to determine if this monitor was last written by LDK 0.1 or later.
@@ -6830,6 +6907,8 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
68306907
68316908 current_holder_commitment_tx,
68326909 prev_holder_commitment_tx,
6910+ contributed_inputs : current_funding_contributed_inputs,
6911+ contributed_outputs : current_funding_contributed_outputs,
68336912 } ,
68346913 pending_funding : pending_funding. unwrap_or ( vec ! [ ] ) ,
68356914 is_manual_broadcast : is_manual_broadcast. 0 . unwrap ( ) ,
0 commit comments