@@ -586,6 +586,11 @@ pub(crate) enum ChannelMonitorUpdateStep {
586586 claimed_htlcs : Vec < ( SentHTLCId , PaymentPreimage ) > ,
587587 nondust_htlc_sources : Vec < HTLCSource > ,
588588 } ,
589+ LatestHolderCommitment {
590+ commitment_txs : Vec < HolderCommitmentTransaction > ,
591+ htlc_data : CommitmentHTLCData ,
592+ claimed_htlcs : Vec < ( SentHTLCId , PaymentPreimage ) > ,
593+ } ,
589594 LatestCounterpartyCommitmentTXInfo {
590595 commitment_txid : Txid ,
591596 htlc_outputs : Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > ,
@@ -632,6 +637,7 @@ impl ChannelMonitorUpdateStep {
632637 fn variant_name ( & self ) -> & ' static str {
633638 match self {
634639 ChannelMonitorUpdateStep :: LatestHolderCommitmentTXInfo { .. } => "LatestHolderCommitmentTXInfo" ,
640+ ChannelMonitorUpdateStep :: LatestHolderCommitment { .. } => "LatestHolderCommitment" ,
635641 ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTXInfo { .. } => "LatestCounterpartyCommitmentTXInfo" ,
636642 ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTX { .. } => "LatestCounterpartyCommitmentTX" ,
637643 ChannelMonitorUpdateStep :: PaymentPreimage { .. } => "PaymentPreimage" ,
@@ -676,6 +682,10 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
676682 ( 6 , LatestCounterpartyCommitmentTX ) => {
677683 ( 0 , htlc_outputs, required_vec) ,
678684 ( 2 , commitment_tx, required) ,
685+ ( 8 , LatestHolderCommitment ) => {
686+ ( 1 , commitment_txs, required_vec) ,
687+ ( 3 , htlc_data, required) ,
688+ ( 5 , claimed_htlcs, required_vec) ,
679689 } ,
680690 ( 10 , RenegotiatedFunding ) => {
681691 ( 1 , channel_parameters, ( required: ReadableArgs , None ) ) ,
@@ -932,12 +942,12 @@ impl<Signer: EcdsaChannelSigner> Clone for ChannelMonitor<Signer> where Signer:
932942 }
933943}
934944
935- #[ derive( Clone , PartialEq ) ]
936- struct CommitmentHTLCData {
945+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
946+ pub ( crate ) struct CommitmentHTLCData {
937947 // These must be sorted in increasing output index order to match the expected order of the
938948 // HTLCs in the `CommitmentTransaction`.
939- nondust_htlc_sources : Vec < HTLCSource > ,
940- dust_htlcs : Vec < ( HTLCOutputInCommitment , Option < HTLCSource > ) > ,
949+ pub nondust_htlc_sources: Vec <HTLCSource >,
950+ pub dust_htlcs: Vec <( HTLCOutputInCommitment , Option <HTLCSource >) >,
941951}
942952
943953impl CommitmentHTLCData {
@@ -946,6 +956,11 @@ impl CommitmentHTLCData {
946956 }
947957}
948958
959+ impl_writeable_tlv_based!( CommitmentHTLCData , {
960+ ( 1 , nondust_htlc_sources, required_vec) ,
961+ ( 3 , dust_htlcs, required_vec) ,
962+ } ) ;
963+
949964impl TryFrom <HolderSignedTx > for CommitmentHTLCData {
950965 type Error = ( ) ;
951966 fn try_from( value: HolderSignedTx ) -> Result <Self , Self :: Error > {
@@ -3192,11 +3207,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
31923207 /// up-to-date as our holder commitment transaction is updated.
31933208 /// Panics if set_on_holder_tx_csv has never been called.
31943209 fn provide_latest_holder_commitment_tx(
3195- & mut self , mut holder_commitment_tx : HolderCommitmentTransaction ,
3210+ & mut self , holder_commitment_tx: HolderCommitmentTransaction ,
31963211 htlc_outputs: Vec <( HTLCOutputInCommitment , Option <Signature >, Option <HTLCSource >) >,
31973212 claimed_htlcs: & [ ( SentHTLCId , PaymentPreimage ) ] , mut nondust_htlc_sources: Vec <HTLCSource >,
3198- ) {
3199- let dust_htlcs : Vec < _ > = if htlc_outputs. iter ( ) . any ( |( _, s, _) | s. is_some ( ) ) {
3213+ ) -> Result < ( ) , & ' static str > {
3214+ let htlc_data = if htlc_outputs. iter( ) . any( |( _, s, _) | s. is_some( ) ) {
32003215 // If we have non-dust HTLCs in htlc_outputs, ensure they match the HTLCs in the
32013216 // `holder_commitment_tx`. In the future, we'll no longer provide the redundant data
32023217 // and just pass in source data via `nondust_htlc_sources`.
@@ -3224,7 +3239,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32243239 None
32253240 } ) . collect( ) ;
32263241
3227- dust_htlcs
3242+ CommitmentHTLCData { nondust_htlc_sources , dust_htlcs }
32283243 } else {
32293244 // If we don't have any non-dust HTLCs in htlc_outputs, assume they were all passed via
32303245 // `nondust_htlc_sources`, building up the final htlc_outputs by combining
@@ -3251,30 +3266,67 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32513266 assert!( sources. next( ) . is_none( ) , "All HTLC sources should have been exhausted" ) ;
32523267
32533268 // This only includes dust HTLCs as checked above.
3254- htlc_outputs. into_iter ( ) . map ( |( htlc, _, source) | ( htlc, source) ) . collect ( )
3269+ let dust_htlcs = htlc_outputs. into_iter( ) . map( |( htlc, _, source) | ( htlc, source) ) . collect( ) ;
3270+
3271+ CommitmentHTLCData { nondust_htlc_sources, dust_htlcs }
32553272 } ;
32563273
3257- self . current_holder_commitment_number = holder_commitment_tx. trust ( ) . commitment_number ( ) ;
3258- self . onchain_tx_handler . provide_latest_holder_tx ( holder_commitment_tx. clone ( ) ) ;
3274+ self . update_holder_commitment_data(
3275+ vec![ holder_commitment_tx] , htlc_data, claimed_htlcs. to_vec( ) ,
3276+ )
3277+ }
32593278
3260- mem:: swap ( & mut holder_commitment_tx, & mut self . funding . current_holder_commitment_tx ) ;
3261- self . funding . prev_holder_commitment_tx = Some ( holder_commitment_tx) ;
3262- let mut holder_htlc_data = CommitmentHTLCData { nondust_htlc_sources, dust_htlcs } ;
3263- mem:: swap ( & mut holder_htlc_data, & mut self . current_holder_htlc_data ) ;
3264- self . prev_holder_htlc_data = Some ( holder_htlc_data) ;
3279+ fn update_holder_commitment_data(
3280+ & mut self , mut commitment_txs: Vec <HolderCommitmentTransaction >,
3281+ mut htlc_data: CommitmentHTLCData , claimed_htlcs: Vec <( SentHTLCId , PaymentPreimage ) >,
3282+ ) -> Result <( ) , & ' static str > {
3283+ if self . pending_funding. len( ) + 1 != commitment_txs. len( ) {
3284+ return Err ( "Commitment transaction(s) mismatch" ) ;
3285+ }
3286+
3287+ let mut current_funding_commitment = commitment_txs. remove( 0 ) ;
3288+ let holder_commitment_number = current_funding_commitment. commitment_number( ) ;
3289+ for ( pending_funding, mut commitment_tx) in self . pending_funding. iter_mut( ) . zip( commitment_txs. into_iter( ) ) {
3290+ let trusted_tx = commitment_tx. trust( ) ;
3291+ if trusted_tx. commitment_number( ) != holder_commitment_number {
3292+ return Err ( "Commitment number mismatch" ) ;
3293+ }
3294+
3295+ let funding_outpoint_spent =
3296+ trusted_tx. built_transaction( ) . transaction. tx_in( 0 ) . map( |input| input. previous_output) . ok( ) ;
3297+ let expected_funding_outpoint_spent =
3298+ pending_funding. channel_parameters. funding_outpoint. map( |op| op. into_bitcoin_outpoint( ) ) ;
3299+ if funding_outpoint_spent != expected_funding_outpoint_spent {
3300+ return Err ( "Funding outpoint mismatch" ) ;
3301+ }
3302+
3303+ mem:: swap( & mut commitment_tx, & mut pending_funding. current_holder_commitment_tx) ;
3304+ pending_funding. prev_holder_commitment_tx = Some ( commitment_tx) ;
3305+ }
3306+
3307+ self . current_holder_commitment_number = holder_commitment_number;
3308+ self . onchain_tx_handler. provide_latest_holder_tx( current_funding_commitment. clone( ) ) ;
3309+ mem:: swap( & mut current_funding_commitment, & mut self . funding. current_holder_commitment_tx) ;
3310+ self . funding. prev_holder_commitment_tx = Some ( current_funding_commitment) ;
3311+
3312+ mem:: swap( & mut htlc_data, & mut self . current_holder_htlc_data) ;
3313+ self . prev_holder_htlc_data = Some ( htlc_data) ;
32653314
32663315 for ( claimed_htlc_id, claimed_preimage) in claimed_htlcs {
32673316 #[ cfg( debug_assertions) ] {
32683317 let cur_counterparty_htlcs = self . funding. counterparty_claimable_outpoints. get(
3269- & self . funding . current_counterparty_commitment_txid . unwrap ( ) ) . unwrap ( ) ;
3318+ & self . funding. current_counterparty_commitment_txid. unwrap( )
3319+ ) . unwrap( ) ;
32703320 assert!( cur_counterparty_htlcs. iter( ) . any( |( _, source_opt) | {
32713321 if let Some ( source) = source_opt {
3272- SentHTLCId :: from_source( source) == * claimed_htlc_id
3322+ SentHTLCId :: from_source( source) == claimed_htlc_id
32733323 } else { false }
32743324 } ) ) ;
32753325 }
3276- self . counterparty_fulfilled_htlcs . insert ( * claimed_htlc_id, * claimed_preimage) ;
3326+ self . counterparty_fulfilled_htlcs. insert( claimed_htlc_id, claimed_preimage) ;
32773327 }
3328+
3329+ Ok ( ( ) )
32783330 }
32793331
32803332 /// Provides a payment_hash->payment_preimage mapping. Will be automatically pruned when all
@@ -3579,9 +3631,25 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
35793631 ChannelMonitorUpdateStep :: LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, claimed_htlcs, nondust_htlc_sources } => {
35803632 log_trace!( logger, "Updating ChannelMonitor with latest holder commitment transaction info" ) ;
35813633 if self . lockdown_from_offchain { panic!( ) ; }
3582- self . provide_latest_holder_commitment_tx ( commitment_tx. clone ( ) , htlc_outputs. clone ( ) , & claimed_htlcs, nondust_htlc_sources. clone ( ) ) ;
3634+ if let Err ( e) = self . provide_latest_holder_commitment_tx(
3635+ commitment_tx. clone( ) , htlc_outputs. clone( ) , & claimed_htlcs,
3636+ nondust_htlc_sources. clone( )
3637+ ) {
3638+ log_error!( logger, "Failed updating latest holder commitment transaction info: {}" , e) ;
3639+ }
35833640 }
3584- // Soon we will drop the `LatestCounterpartyCommitmentTXInfo` variant in favor of `LatestCounterpartyCommitmentTX`.
3641+ ChannelMonitorUpdateStep :: LatestHolderCommitment {
3642+ commitment_txs, htlc_data, claimed_htlcs,
3643+ } => {
3644+ log_trace!( logger, "Updating ChannelMonitor with latest holder commitment" ) ;
3645+ assert!( !self . lockdown_from_offchain) ;
3646+ if let Err ( e) = self . update_holder_commitment_data(
3647+ commitment_txs. clone( ) , htlc_data. clone( ) , claimed_htlcs. clone( ) ,
3648+ ) {
3649+ log_error!( logger, "Failed updating latest holder commitment state: {}" , e) ;
3650+ }
3651+ } ,
3652+ // Soon we will drop the `LatestCounterpartyCommitmentTXInfo` variant in favor of `LatestCounterpartyCommitment`.
35853653 // For now we just add the code to handle the new updates.
35863654 // Next step: in channel, switch channel monitor updates to use the `LatestCounterpartyCommitmentTX` variant.
35873655 ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number, their_per_commitment_point, .. } => {
@@ -3664,6 +3732,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
36643732 for update in updates. updates. iter( ) {
36653733 match update {
36663734 ChannelMonitorUpdateStep :: LatestHolderCommitmentTXInfo { .. }
3735+ |ChannelMonitorUpdateStep :: LatestHolderCommitment { .. }
36673736 |ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTXInfo { .. }
36683737 |ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTX { .. }
36693738 |ChannelMonitorUpdateStep :: ShutdownScript { .. }
0 commit comments