@@ -3833,7 +3833,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3833
3833
// First check if a counterparty commitment transaction has been broadcasted:
3834
3834
macro_rules! claim_htlcs {
3835
3835
( $commitment_number: expr, $txid: expr, $htlcs: expr) => {
3836
- let ( htlc_claim_reqs, _ ) = self . get_counterparty_output_claim_info ( funding_spent, $commitment_number, $txid, None , $htlcs, confirmed_spend_height) ;
3836
+ let htlc_claim_reqs = self . get_counterparty_output_claims_for_preimage ( * payment_preimage , funding_spent, $commitment_number, $txid, $htlcs, confirmed_spend_height) ;
3837
3837
let conf_target = self . closure_conf_target( ) ;
3838
3838
self . onchain_tx_handler. update_claims_view_from_requests(
3839
3839
htlc_claim_reqs, self . best_block. height, self . best_block. height, broadcaster,
@@ -4732,7 +4732,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
4732
4732
( htlc, htlc_source. as_ref( ) . map( |htlc_source| htlc_source. as_ref( ) ) )
4733
4733
) , logger) ;
4734
4734
let ( htlc_claim_reqs, counterparty_output_info) =
4735
- self . get_counterparty_output_claim_info ( funding_spent, commitment_number, commitment_txid, Some ( commitment_tx) , per_commitment_option , Some ( height) ) ;
4735
+ self . get_counterparty_output_claim_info ( funding_spent, commitment_number, commitment_txid, commitment_tx, per_commitment_claimable_data , Some ( height) ) ;
4736
4736
to_counterparty_output_info = counterparty_output_info;
4737
4737
for req in htlc_claim_reqs {
4738
4738
claimable_outpoints. push ( req) ;
@@ -4742,87 +4742,156 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
4742
4742
( claimable_outpoints, to_counterparty_output_info)
4743
4743
}
4744
4744
4745
+ fn get_point_for_commitment_number ( & self , commitment_number : u64 ) -> Option < PublicKey > {
4746
+ let per_commitment_points = & self . their_cur_per_commitment_points ?;
4747
+
4748
+ // If the counterparty commitment tx is the latest valid state, use their latest
4749
+ // per-commitment point
4750
+ if per_commitment_points. 0 == commitment_number {
4751
+ Some ( per_commitment_points. 1 )
4752
+ } else if let Some ( point) = per_commitment_points. 2 . as_ref ( ) {
4753
+ // If counterparty commitment tx is the state previous to the latest valid state, use
4754
+ // their previous per-commitment point (non-atomicity of revocation means it's valid for
4755
+ // them to temporarily have two valid commitment txns from our viewpoint)
4756
+ if per_commitment_points. 0 == commitment_number + 1 {
4757
+ Some ( * point)
4758
+ } else {
4759
+ None
4760
+ }
4761
+ } else {
4762
+ None
4763
+ }
4764
+ }
4765
+
4766
+ fn get_counterparty_output_claims_for_preimage (
4767
+ & self , preimage : PaymentPreimage , funding_spent : & FundingScope , commitment_number : u64 ,
4768
+ commitment_txid : Txid ,
4769
+ per_commitment_option : Option < & Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > > ,
4770
+ confirmation_height : Option < u32 > ,
4771
+ ) -> Vec < PackageTemplate > {
4772
+ let per_commitment_claimable_data = match per_commitment_option {
4773
+ Some ( outputs) => outputs,
4774
+ None => return Vec :: new ( ) ,
4775
+ } ;
4776
+ let per_commitment_point = match self . get_point_for_commitment_number ( commitment_number) {
4777
+ Some ( point) => point,
4778
+ None => return Vec :: new ( ) ,
4779
+ } ;
4780
+
4781
+ let matching_payment_hash = PaymentHash :: from ( preimage) ;
4782
+ per_commitment_claimable_data
4783
+ . iter ( )
4784
+ . filter_map ( |( htlc, _) | {
4785
+ if let Some ( transaction_output_index) = htlc. transaction_output_index {
4786
+ if htlc. offered && htlc. payment_hash == matching_payment_hash {
4787
+ let htlc_data = PackageSolvingData :: CounterpartyOfferedHTLCOutput (
4788
+ CounterpartyOfferedHTLCOutput :: build (
4789
+ per_commitment_point,
4790
+ preimage,
4791
+ htlc. clone ( ) ,
4792
+ funding_spent. channel_parameters . clone ( ) ,
4793
+ confirmation_height,
4794
+ ) ,
4795
+ ) ;
4796
+ Some ( PackageTemplate :: build_package (
4797
+ commitment_txid,
4798
+ transaction_output_index,
4799
+ htlc_data,
4800
+ htlc. cltv_expiry ,
4801
+ ) )
4802
+ } else {
4803
+ None
4804
+ }
4805
+ } else {
4806
+ None
4807
+ }
4808
+ } )
4809
+ . collect ( )
4810
+ }
4811
+
4745
4812
/// Returns the HTLC claim package templates and the counterparty output info
4746
- #[ rustfmt:: skip]
4747
4813
fn get_counterparty_output_claim_info (
4748
4814
& self , funding_spent : & FundingScope , commitment_number : u64 , commitment_txid : Txid ,
4749
- tx : Option < & Transaction > ,
4750
- per_commitment_option : Option < & Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > > ,
4815
+ tx : & Transaction ,
4816
+ per_commitment_claimable_data : & [ ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) ] ,
4751
4817
confirmation_height : Option < u32 > ,
4752
4818
) -> ( Vec < PackageTemplate > , CommitmentTxCounterpartyOutputInfo ) {
4753
4819
let mut claimable_outpoints = Vec :: new ( ) ;
4754
4820
let mut to_counterparty_output_info: CommitmentTxCounterpartyOutputInfo = None ;
4755
4821
4756
- let per_commitment_claimable_data = match per_commitment_option {
4757
- Some ( outputs) => outputs,
4758
- None => return ( claimable_outpoints, to_counterparty_output_info) ,
4759
- } ;
4760
- let per_commitment_points = match self . their_cur_per_commitment_points {
4761
- Some ( points) => points,
4822
+ let per_commitment_point = match self . get_point_for_commitment_number ( commitment_number) {
4823
+ Some ( point) => point,
4762
4824
None => return ( claimable_outpoints, to_counterparty_output_info) ,
4763
4825
} ;
4764
4826
4765
- let per_commitment_point =
4766
- // If the counterparty commitment tx is the latest valid state, use their latest
4767
- // per-commitment point
4768
- if per_commitment_points. 0 == commitment_number { & per_commitment_points. 1 }
4769
- else if let Some ( point) = per_commitment_points. 2 . as_ref ( ) {
4770
- // If counterparty commitment tx is the state previous to the latest valid state, use
4771
- // their previous per-commitment point (non-atomicity of revocation means it's valid for
4772
- // them to temporarily have two valid commitment txns from our viewpoint)
4773
- if per_commitment_points. 0 == commitment_number + 1 {
4774
- point
4775
- } else { return ( claimable_outpoints, to_counterparty_output_info) ; }
4776
- } else { return ( claimable_outpoints, to_counterparty_output_info) ; } ;
4777
-
4778
- if let Some ( transaction) = tx {
4779
- let revocation_pubkey = RevocationKey :: from_basepoint (
4780
- & self . onchain_tx_handler . secp_ctx , & self . holder_revocation_basepoint , & per_commitment_point) ;
4781
-
4782
- let delayed_key = DelayedPaymentKey :: from_basepoint ( & self . onchain_tx_handler . secp_ctx , & self . counterparty_commitment_params . counterparty_delayed_payment_base_key , & per_commitment_point) ;
4783
-
4784
- let revokeable_p2wsh = chan_utils:: get_revokeable_redeemscript ( & revocation_pubkey,
4785
- self . counterparty_commitment_params . on_counterparty_tx_csv ,
4786
- & delayed_key) . to_p2wsh ( ) ;
4787
- for ( idx, outp) in transaction. output . iter ( ) . enumerate ( ) {
4788
- if outp. script_pubkey == revokeable_p2wsh {
4789
- to_counterparty_output_info =
4790
- Some ( ( idx. try_into ( ) . expect ( "Can't have > 2^32 outputs" ) , outp. value ) ) ;
4791
- }
4827
+ let revocation_pubkey = RevocationKey :: from_basepoint (
4828
+ & self . onchain_tx_handler . secp_ctx ,
4829
+ & self . holder_revocation_basepoint ,
4830
+ & per_commitment_point,
4831
+ ) ;
4832
+ let delayed_key = DelayedPaymentKey :: from_basepoint (
4833
+ & self . onchain_tx_handler . secp_ctx ,
4834
+ & self . counterparty_commitment_params . counterparty_delayed_payment_base_key ,
4835
+ & per_commitment_point,
4836
+ ) ;
4837
+ let revokeable_p2wsh = chan_utils:: get_revokeable_redeemscript (
4838
+ & revocation_pubkey,
4839
+ self . counterparty_commitment_params . on_counterparty_tx_csv ,
4840
+ & delayed_key,
4841
+ )
4842
+ . to_p2wsh ( ) ;
4843
+ for ( idx, outp) in tx. output . iter ( ) . enumerate ( ) {
4844
+ if outp. script_pubkey == revokeable_p2wsh {
4845
+ to_counterparty_output_info =
4846
+ Some ( ( idx. try_into ( ) . expect ( "Can't have > 2^32 outputs" ) , outp. value ) ) ;
4792
4847
}
4793
4848
}
4794
4849
4795
- for & ( ref htlc, _) in per_commitment_claimable_data. iter ( ) {
4850
+ for & ( ref htlc, _) in per_commitment_claimable_data. iter ( ) {
4796
4851
if let Some ( transaction_output_index) = htlc. transaction_output_index {
4797
- if let Some ( transaction ) = tx {
4798
- if transaction_output_index as usize >= transaction . output . len ( ) ||
4799
- transaction . output [ transaction_output_index as usize ] . value != htlc. to_bitcoin_amount ( ) {
4800
- // per_commitment_data is corrupt or our commitment signing key leaked!
4801
- return ( claimable_outpoints , to_counterparty_output_info ) ;
4802
- }
4852
+ if transaction_output_index as usize > = tx. output . len ( )
4853
+ || tx . output [ transaction_output_index as usize ] . value
4854
+ != htlc. to_bitcoin_amount ( )
4855
+ {
4856
+ // per_commitment_data is corrupt or our commitment signing key leaked!
4857
+ return ( claimable_outpoints , to_counterparty_output_info ) ;
4803
4858
}
4804
- let preimage = if htlc. offered { if let Some ( ( p, _) ) = self . payment_preimages . get ( & htlc. payment_hash ) { Some ( * p) } else { None } } else { None } ;
4859
+ let preimage = if htlc. offered {
4860
+ if let Some ( ( p, _) ) = self . payment_preimages . get ( & htlc. payment_hash ) {
4861
+ Some ( * p)
4862
+ } else {
4863
+ None
4864
+ }
4865
+ } else {
4866
+ None
4867
+ } ;
4805
4868
if preimage. is_some ( ) || !htlc. offered {
4806
4869
let counterparty_htlc_outp = if htlc. offered {
4807
4870
PackageSolvingData :: CounterpartyOfferedHTLCOutput (
4808
4871
CounterpartyOfferedHTLCOutput :: build (
4809
- * per_commitment_point, preimage. unwrap ( ) ,
4872
+ per_commitment_point,
4873
+ preimage. unwrap ( ) ,
4810
4874
htlc. clone ( ) ,
4811
4875
funding_spent. channel_parameters . clone ( ) ,
4812
4876
confirmation_height,
4813
- )
4877
+ ) ,
4814
4878
)
4815
4879
} else {
4816
4880
PackageSolvingData :: CounterpartyReceivedHTLCOutput (
4817
4881
CounterpartyReceivedHTLCOutput :: build (
4818
- * per_commitment_point,
4882
+ per_commitment_point,
4819
4883
htlc. clone ( ) ,
4820
4884
funding_spent. channel_parameters . clone ( ) ,
4821
4885
confirmation_height,
4822
- )
4886
+ ) ,
4823
4887
)
4824
4888
} ;
4825
- let counterparty_package = PackageTemplate :: build_package ( commitment_txid, transaction_output_index, counterparty_htlc_outp, htlc. cltv_expiry ) ;
4889
+ let counterparty_package = PackageTemplate :: build_package (
4890
+ commitment_txid,
4891
+ transaction_output_index,
4892
+ counterparty_htlc_outp,
4893
+ htlc. cltv_expiry ,
4894
+ ) ;
4826
4895
claimable_outpoints. push ( counterparty_package) ;
4827
4896
}
4828
4897
}
0 commit comments