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