@@ -3833,7 +3833,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
38333833 // First check if a counterparty commitment transaction has been broadcasted:
38343834 macro_rules! claim_htlcs {
38353835 ( $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) ;
38373837 let conf_target = self . closure_conf_target( ) ;
38383838 self . onchain_tx_handler. update_claims_view_from_requests(
38393839 htlc_claim_reqs, self . best_block. height, self . best_block. height, broadcaster,
@@ -4732,7 +4732,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
47324732 ( htlc, htlc_source. as_ref( ) . map( |htlc_source| htlc_source. as_ref( ) ) )
47334733 ) , logger) ;
47344734 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) ) ;
47364736 to_counterparty_output_info = counterparty_output_info;
47374737 for req in htlc_claim_reqs {
47384738 claimable_outpoints. push ( req) ;
@@ -4742,87 +4742,156 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
47424742 ( claimable_outpoints, to_counterparty_output_info)
47434743 }
47444744
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+
47454812 /// Returns the HTLC claim package templates and the counterparty output info
4746- #[ rustfmt:: skip]
47474813 fn get_counterparty_output_claim_info (
47484814 & 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 > > ) ] ,
47514817 confirmation_height : Option < u32 > ,
47524818 ) -> ( Vec < PackageTemplate > , CommitmentTxCounterpartyOutputInfo ) {
47534819 let mut claimable_outpoints = Vec :: new ( ) ;
47544820 let mut to_counterparty_output_info: CommitmentTxCounterpartyOutputInfo = None ;
47554821
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,
47624824 None => return ( claimable_outpoints, to_counterparty_output_info) ,
47634825 } ;
47644826
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 ) ) ;
47924847 }
47934848 }
47944849
4795- for & ( ref htlc, _) in per_commitment_claimable_data. iter ( ) {
4850+ for & ( ref htlc, _) in per_commitment_claimable_data. iter ( ) {
47964851 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 ) ;
48034858 }
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+ } ;
48054868 if preimage. is_some ( ) || !htlc. offered {
48064869 let counterparty_htlc_outp = if htlc. offered {
48074870 PackageSolvingData :: CounterpartyOfferedHTLCOutput (
48084871 CounterpartyOfferedHTLCOutput :: build (
4809- * per_commitment_point, preimage. unwrap ( ) ,
4872+ per_commitment_point,
4873+ preimage. unwrap ( ) ,
48104874 htlc. clone ( ) ,
48114875 funding_spent. channel_parameters . clone ( ) ,
48124876 confirmation_height,
4813- )
4877+ ) ,
48144878 )
48154879 } else {
48164880 PackageSolvingData :: CounterpartyReceivedHTLCOutput (
48174881 CounterpartyReceivedHTLCOutput :: build (
4818- * per_commitment_point,
4882+ per_commitment_point,
48194883 htlc. clone ( ) ,
48204884 funding_spent. channel_parameters . clone ( ) ,
48214885 confirmation_height,
4822- )
4886+ ) ,
48234887 )
48244888 } ;
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+ ) ;
48264895 claimable_outpoints. push ( counterparty_package) ;
48274896 }
48284897 }
0 commit comments