@@ -3118,7 +3118,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
31183118 // First check if a counterparty commitment transaction has been broadcasted:
31193119 macro_rules! claim_htlcs {
31203120 ( $commitment_number: expr, $txid: expr, $htlcs: expr) => {
3121- let ( htlc_claim_reqs, _ ) = self . get_counterparty_output_claim_info ( $commitment_number, $txid, None , $htlcs, confirmed_spend_height) ;
3121+ let htlc_claim_reqs = self . get_counterparty_output_claims_for_preimage ( * payment_preimage , $commitment_number, $txid, $htlcs, confirmed_spend_height) ;
31223122 let conf_target = self . closure_conf_target( ) ;
31233123 self . onchain_tx_handler. update_claims_view_from_requests( htlc_claim_reqs, self . best_block. height, self . best_block. height, broadcaster, conf_target, fee_estimator, logger) ;
31243124 }
@@ -3728,7 +3728,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37283728 ( htlc, htlc_source. as_ref( ) . map( |htlc_source| htlc_source. as_ref( ) ) )
37293729 ) , logger) ;
37303730 let ( htlc_claim_reqs, counterparty_output_info) =
3731- self . get_counterparty_output_claim_info ( commitment_number, commitment_txid, Some ( tx ) , per_commitment_option , Some ( height) ) ;
3731+ self . get_counterparty_output_claim_info ( commitment_number, commitment_txid, tx , per_commitment_claimable_data , Some ( height) ) ;
37323732 to_counterparty_output_info = counterparty_output_info;
37333733 for req in htlc_claim_reqs {
37343734 claimable_outpoints. push ( req) ;
@@ -3738,78 +3738,162 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37383738 ( claimable_outpoints, to_counterparty_output_info)
37393739 }
37403740
3741- /// Returns the HTLC claim package templates and the counterparty output info
3742- fn get_counterparty_output_claim_info ( & self , commitment_number : u64 , commitment_txid : Txid , tx : Option < & Transaction > , per_commitment_option : Option < & Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > > , confirmation_height : Option < u32 > )
3743- -> ( Vec < PackageTemplate > , CommitmentTxCounterpartyOutputInfo ) {
3744- let mut claimable_outpoints = Vec :: new ( ) ;
3745- let mut to_counterparty_output_info: CommitmentTxCounterpartyOutputInfo = None ;
3741+ fn get_point_for_commitment_number ( & self , commitment_number : u64 ) -> Option < PublicKey > {
3742+ let per_commitment_points = & self . their_cur_per_commitment_points ?;
3743+
3744+ // If the counterparty commitment tx is the latest valid state, use their latest
3745+ // per-commitment point
3746+ if per_commitment_points. 0 == commitment_number {
3747+ Some ( per_commitment_points. 1 )
3748+ } else if let Some ( point) = per_commitment_points. 2 . as_ref ( ) {
3749+ // If counterparty commitment tx is the state previous to the latest valid state, use
3750+ // their previous per-commitment point (non-atomicity of revocation means it's valid for
3751+ // them to temporarily have two valid commitment txns from our viewpoint)
3752+ if per_commitment_points. 0 == commitment_number + 1 {
3753+ Some ( * point)
3754+ } else {
3755+ None
3756+ }
3757+ } else {
3758+ None
3759+ }
3760+ }
37463761
3762+ fn get_counterparty_output_claims_for_preimage (
3763+ & self , preimage : PaymentPreimage , commitment_number : u64 ,
3764+ commitment_txid : Txid ,
3765+ per_commitment_option : Option < & Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > > ,
3766+ confirmation_height : Option < u32 > ,
3767+ ) -> Vec < PackageTemplate > {
37473768 let per_commitment_claimable_data = match per_commitment_option {
37483769 Some ( outputs) => outputs,
3749- None => return ( claimable_outpoints , to_counterparty_output_info ) ,
3770+ None => return Vec :: new ( ) ,
37503771 } ;
3751- let per_commitment_points = match self . their_cur_per_commitment_points {
3752- Some ( points ) => points ,
3753- None => return ( claimable_outpoints , to_counterparty_output_info ) ,
3772+ let per_commitment_point = match self . get_point_for_commitment_number ( commitment_number ) {
3773+ Some ( point ) => point ,
3774+ None => return Vec :: new ( ) ,
37543775 } ;
37553776
3756- let per_commitment_point =
3757- // If the counterparty commitment tx is the latest valid state, use their latest
3758- // per-commitment point
3759- if per_commitment_points. 0 == commitment_number { & per_commitment_points. 1 }
3760- else if let Some ( point) = per_commitment_points. 2 . as_ref ( ) {
3761- // If counterparty commitment tx is the state previous to the latest valid state, use
3762- // their previous per-commitment point (non-atomicity of revocation means it's valid for
3763- // them to temporarily have two valid commitment txns from our viewpoint)
3764- if per_commitment_points. 0 == commitment_number + 1 {
3765- point
3766- } else { return ( claimable_outpoints, to_counterparty_output_info) ; }
3767- } else { return ( claimable_outpoints, to_counterparty_output_info) ; } ;
3768-
3769- if let Some ( transaction) = tx {
3770- let revocation_pubkey = RevocationKey :: from_basepoint (
3771- & self . onchain_tx_handler . secp_ctx , & self . holder_revocation_basepoint , & per_commitment_point) ;
3772-
3773- let delayed_key = DelayedPaymentKey :: from_basepoint ( & self . onchain_tx_handler . secp_ctx , & self . counterparty_commitment_params . counterparty_delayed_payment_base_key , & per_commitment_point) ;
3774-
3775- let revokeable_p2wsh = chan_utils:: get_revokeable_redeemscript ( & revocation_pubkey,
3776- self . counterparty_commitment_params . on_counterparty_tx_csv ,
3777- & delayed_key) . to_p2wsh ( ) ;
3778- for ( idx, outp) in transaction. output . iter ( ) . enumerate ( ) {
3779- if outp. script_pubkey == revokeable_p2wsh {
3780- to_counterparty_output_info =
3781- Some ( ( idx. try_into ( ) . expect ( "Can't have > 2^32 outputs" ) , outp. value ) ) ;
3777+ let matching_payment_hash = PaymentHash :: from ( preimage) ;
3778+ per_commitment_claimable_data
3779+ . iter ( )
3780+ . filter_map ( |( htlc, _) | {
3781+ if let Some ( transaction_output_index) = htlc. transaction_output_index {
3782+ if htlc. offered && htlc. payment_hash == matching_payment_hash {
3783+ let htlc_data = PackageSolvingData :: CounterpartyOfferedHTLCOutput (
3784+ CounterpartyOfferedHTLCOutput :: build (
3785+ per_commitment_point,
3786+ self . counterparty_commitment_params . counterparty_delayed_payment_base_key ,
3787+ self . counterparty_commitment_params . counterparty_htlc_base_key ,
3788+ preimage,
3789+ htlc. clone ( ) ,
3790+ self . onchain_tx_handler . channel_type_features ( ) . clone ( ) ,
3791+ confirmation_height,
3792+ ) ,
3793+ ) ;
3794+ Some ( PackageTemplate :: build_package (
3795+ commitment_txid,
3796+ transaction_output_index,
3797+ htlc_data,
3798+ htlc. cltv_expiry ,
3799+ ) )
3800+ } else {
3801+ None
3802+ }
3803+ } else {
3804+ None
37823805 }
3806+ } )
3807+ . collect ( )
3808+ }
3809+
3810+ /// Returns the HTLC claim package templates and the counterparty output info
3811+ fn get_counterparty_output_claim_info (
3812+ & self , commitment_number : u64 , commitment_txid : Txid ,
3813+ tx : & Transaction ,
3814+ per_commitment_claimable_data : & [ ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) ] ,
3815+ confirmation_height : Option < u32 > ,
3816+ ) -> ( Vec < PackageTemplate > , CommitmentTxCounterpartyOutputInfo ) {
3817+ let mut claimable_outpoints = Vec :: new ( ) ;
3818+ let mut to_counterparty_output_info: CommitmentTxCounterpartyOutputInfo = None ;
3819+
3820+ let per_commitment_point = match self . get_point_for_commitment_number ( commitment_number) {
3821+ Some ( point) => point,
3822+ None => return ( claimable_outpoints, to_counterparty_output_info) ,
3823+ } ;
3824+
3825+ let revocation_pubkey = RevocationKey :: from_basepoint (
3826+ & self . onchain_tx_handler . secp_ctx ,
3827+ & self . holder_revocation_basepoint ,
3828+ & per_commitment_point,
3829+ ) ;
3830+ let delayed_key = DelayedPaymentKey :: from_basepoint (
3831+ & self . onchain_tx_handler . secp_ctx ,
3832+ & self . counterparty_commitment_params . counterparty_delayed_payment_base_key ,
3833+ & per_commitment_point,
3834+ ) ;
3835+ let revokeable_p2wsh = chan_utils:: get_revokeable_redeemscript (
3836+ & revocation_pubkey,
3837+ self . counterparty_commitment_params . on_counterparty_tx_csv ,
3838+ & delayed_key,
3839+ )
3840+ . to_p2wsh ( ) ;
3841+ for ( idx, outp) in tx. output . iter ( ) . enumerate ( ) {
3842+ if outp. script_pubkey == revokeable_p2wsh {
3843+ to_counterparty_output_info =
3844+ Some ( ( idx. try_into ( ) . expect ( "Can't have > 2^32 outputs" ) , outp. value ) ) ;
37833845 }
37843846 }
37853847
3786- for & ( ref htlc, _) in per_commitment_claimable_data. iter ( ) {
3848+ for & ( ref htlc, _) in per_commitment_claimable_data. iter ( ) {
37873849 if let Some ( transaction_output_index) = htlc. transaction_output_index {
3788- if let Some ( transaction ) = tx {
3789- if transaction_output_index as usize >= transaction . output . len ( ) ||
3790- transaction . output [ transaction_output_index as usize ] . value != htlc. to_bitcoin_amount ( ) {
3791- // per_commitment_data is corrupt or our commitment signing key leaked!
3792- return ( claimable_outpoints , to_counterparty_output_info ) ;
3793- }
3850+ if transaction_output_index as usize > = tx. output . len ( )
3851+ || tx . output [ transaction_output_index as usize ] . value
3852+ != htlc. to_bitcoin_amount ( )
3853+ {
3854+ // per_commitment_data is corrupt or our commitment signing key leaked!
3855+ return ( claimable_outpoints , to_counterparty_output_info ) ;
37943856 }
3795- let preimage = if htlc. offered { if let Some ( ( p, _) ) = self . payment_preimages . get ( & htlc. payment_hash ) { Some ( * p) } else { None } } else { None } ;
3857+ let preimage = if htlc. offered {
3858+ if let Some ( ( p, _) ) = self . payment_preimages . get ( & htlc. payment_hash ) {
3859+ Some ( * p)
3860+ } else {
3861+ None
3862+ }
3863+ } else {
3864+ None
3865+ } ;
37963866 if preimage. is_some ( ) || !htlc. offered {
37973867 let counterparty_htlc_outp = if htlc. offered {
37983868 PackageSolvingData :: CounterpartyOfferedHTLCOutput (
3799- CounterpartyOfferedHTLCOutput :: build ( * per_commitment_point,
3869+ CounterpartyOfferedHTLCOutput :: build (
3870+ per_commitment_point,
38003871 self . counterparty_commitment_params . counterparty_delayed_payment_base_key ,
38013872 self . counterparty_commitment_params . counterparty_htlc_base_key ,
3802- preimage. unwrap ( ) , htlc. clone ( ) , self . onchain_tx_handler . channel_type_features ( ) . clone ( ) ,
3803- confirmation_height) )
3873+ preimage. unwrap ( ) ,
3874+ htlc. clone ( ) ,
3875+ self . onchain_tx_handler . channel_type_features ( ) . clone ( ) ,
3876+ confirmation_height,
3877+ ) ,
3878+ )
38043879 } else {
38053880 PackageSolvingData :: CounterpartyReceivedHTLCOutput (
3806- CounterpartyReceivedHTLCOutput :: build ( * per_commitment_point,
3881+ CounterpartyReceivedHTLCOutput :: build (
3882+ per_commitment_point,
38073883 self . counterparty_commitment_params . counterparty_delayed_payment_base_key ,
38083884 self . counterparty_commitment_params . counterparty_htlc_base_key ,
3809- htlc. clone ( ) , self . onchain_tx_handler . channel_type_features ( ) . clone ( ) ,
3810- confirmation_height) )
3885+ htlc. clone ( ) ,
3886+ self . onchain_tx_handler . channel_type_features ( ) . clone ( ) ,
3887+ confirmation_height,
3888+ ) ,
3889+ )
38113890 } ;
3812- let counterparty_package = PackageTemplate :: build_package ( commitment_txid, transaction_output_index, counterparty_htlc_outp, htlc. cltv_expiry ) ;
3891+ let counterparty_package = PackageTemplate :: build_package (
3892+ commitment_txid,
3893+ transaction_output_index,
3894+ counterparty_htlc_outp,
3895+ htlc. cltv_expiry ,
3896+ ) ;
38133897 claimable_outpoints. push ( counterparty_package) ;
38143898 }
38153899 }
0 commit comments