@@ -3118,7 +3118,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3118
3118
// First check if a counterparty commitment transaction has been broadcasted:
3119
3119
macro_rules! claim_htlcs {
3120
3120
( $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) ;
3122
3122
let conf_target = self . closure_conf_target( ) ;
3123
3123
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) ;
3124
3124
}
@@ -3728,7 +3728,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3728
3728
( htlc, htlc_source. as_ref( ) . map( |htlc_source| htlc_source. as_ref( ) ) )
3729
3729
) , logger) ;
3730
3730
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) ) ;
3732
3732
to_counterparty_output_info = counterparty_output_info;
3733
3733
for req in htlc_claim_reqs {
3734
3734
claimable_outpoints. push ( req) ;
@@ -3738,78 +3738,162 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3738
3738
( claimable_outpoints, to_counterparty_output_info)
3739
3739
}
3740
3740
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
+ }
3746
3761
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 > {
3747
3768
let per_commitment_claimable_data = match per_commitment_option {
3748
3769
Some ( outputs) => outputs,
3749
- None => return ( claimable_outpoints , to_counterparty_output_info ) ,
3770
+ None => return Vec :: new ( ) ,
3750
3771
} ;
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 ( ) ,
3754
3775
} ;
3755
3776
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
3782
3805
}
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 ) ) ;
3783
3845
}
3784
3846
}
3785
3847
3786
- for & ( ref htlc, _) in per_commitment_claimable_data. iter ( ) {
3848
+ for & ( ref htlc, _) in per_commitment_claimable_data. iter ( ) {
3787
3849
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 ) ;
3794
3856
}
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
+ } ;
3796
3866
if preimage. is_some ( ) || !htlc. offered {
3797
3867
let counterparty_htlc_outp = if htlc. offered {
3798
3868
PackageSolvingData :: CounterpartyOfferedHTLCOutput (
3799
- CounterpartyOfferedHTLCOutput :: build ( * per_commitment_point,
3869
+ CounterpartyOfferedHTLCOutput :: build (
3870
+ per_commitment_point,
3800
3871
self . counterparty_commitment_params . counterparty_delayed_payment_base_key ,
3801
3872
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
+ )
3804
3879
} else {
3805
3880
PackageSolvingData :: CounterpartyReceivedHTLCOutput (
3806
- CounterpartyReceivedHTLCOutput :: build ( * per_commitment_point,
3881
+ CounterpartyReceivedHTLCOutput :: build (
3882
+ per_commitment_point,
3807
3883
self . counterparty_commitment_params . counterparty_delayed_payment_base_key ,
3808
3884
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
+ )
3811
3890
} ;
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
+ ) ;
3813
3897
claimable_outpoints. push ( counterparty_package) ;
3814
3898
}
3815
3899
}
0 commit comments