@@ -876,15 +876,20 @@ struct HTLCStats {
876876 on_holder_tx_outbound_holding_cell_htlcs_count: u32, // dust HTLCs *non*-included
877877}
878878
879- /// An enum gathering stats on commitment transaction, either local or remote.
880- struct CommitmentStats<'a> {
879+ /// A struct gathering data on a commitment, either local or remote.
880+ struct CommitmentData<'a> {
881+ stats: CommitmentStats,
882+ htlcs_included: Vec<(HTLCOutputInCommitment, Option<&'a HTLCSource>)>, // the list of HTLCs (dust HTLCs *included*) which were not ignored when building the transaction
883+ outbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful offered HTLCs since last commitment
884+ inbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful received HTLCs since last commitment
885+ }
886+
887+ /// A struct gathering stats on commitment transaction, either local or remote.
888+ struct CommitmentStats {
881889 tx: CommitmentTransaction, // the transaction info
882890 total_fee_sat: u64, // the total fee included in the transaction
883- htlcs_included: Vec<(HTLCOutputInCommitment, Option<&'a HTLCSource>)>, // the list of HTLCs (dust HTLCs *included*) which were not ignored when building the transaction
884891 local_balance_msat: u64, // local balance before fees *not* considering dust limits
885892 remote_balance_msat: u64, // remote balance before fees *not* considering dust limits
886- outbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful offered HTLCs since last commitment
887- inbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful received HTLCs since last commitment
888893}
889894
890895/// Used when calculating whether we or the remote can afford an additional HTLC.
@@ -2034,7 +2039,10 @@ trait InitialRemoteCommitmentReceiver<SP: Deref> where SP::Target: SignerProvide
20342039 ) -> Result<CommitmentTransaction, ChannelError> where L::Target: Logger {
20352040 let funding_script = self.funding().get_funding_redeemscript();
20362041
2037- let initial_commitment_tx = self.context().build_commitment_transaction(self.funding(), holder_commitment_point.transaction_number(), &holder_commitment_point.current_point(), true, false, logger).tx;
2042+ let commitment_data = self.context().build_commitment_transaction(self.funding(),
2043+ holder_commitment_point.transaction_number(), &holder_commitment_point.current_point(),
2044+ true, false, logger);
2045+ let initial_commitment_tx = commitment_data.stats.tx;
20382046 let trusted_tx = initial_commitment_tx.trust();
20392047 let initial_commitment_bitcoin_tx = trusted_tx.built_transaction();
20402048 let sighash = initial_commitment_bitcoin_tx.get_sighash_all(&funding_script, self.funding().get_value_satoshis());
@@ -2071,7 +2079,10 @@ trait InitialRemoteCommitmentReceiver<SP: Deref> where SP::Target: SignerProvide
20712079 }
20722080 };
20732081 let context = self.context();
2074- let counterparty_initial_commitment_tx = context.build_commitment_transaction(self.funding(), context.cur_counterparty_commitment_transaction_number, &context.counterparty_cur_commitment_point.unwrap(), false, false, logger).tx;
2082+ let commitment_data = context.build_commitment_transaction(self.funding(),
2083+ context.cur_counterparty_commitment_transaction_number,
2084+ &context.counterparty_cur_commitment_point.unwrap(), false, false, logger);
2085+ let counterparty_initial_commitment_tx = commitment_data.stats.tx;
20752086 let counterparty_trusted_tx = counterparty_initial_commitment_tx.trust();
20762087 let counterparty_initial_bitcoin_tx = counterparty_trusted_tx.built_transaction();
20772088
@@ -3456,7 +3467,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
34563467 /// generated by the peer which proposed adding the HTLCs, and thus we need to understand both
34573468 /// which peer generated this transaction and "to whom" this transaction flows.
34583469 #[inline]
3459- fn build_commitment_transaction<L: Deref>(&self, funding: &FundingScope, commitment_number: u64, per_commitment_point: &PublicKey, local: bool, generated_by_local: bool, logger: &L) -> CommitmentStats
3470+ fn build_commitment_transaction<L: Deref>(&self, funding: &FundingScope, commitment_number: u64, per_commitment_point: &PublicKey, local: bool, generated_by_local: bool, logger: &L)
3471+ -> CommitmentData
34603472 where L::Target: Logger
34613473 {
34623474 let num_htlcs = self.pending_inbound_htlcs.len() + self.pending_outbound_htlcs.len();
@@ -3679,12 +3691,16 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
36793691 }
36803692 });
36813693
3682- CommitmentStats {
3694+ let stats = CommitmentStats {
36833695 tx,
36843696 total_fee_sat,
3685- htlcs_included: htlcs_in_tx,
36863697 local_balance_msat: value_to_self_msat,
36873698 remote_balance_msat: value_to_remote_msat,
3699+ };
3700+
3701+ CommitmentData {
3702+ stats,
3703+ htlcs_included: htlcs_in_tx,
36883704 inbound_htlc_preimages,
36893705 outbound_htlc_preimages,
36903706 }
@@ -4473,8 +4489,10 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
44734489 SP::Target: SignerProvider,
44744490 L::Target: Logger
44754491 {
4476- let counterparty_initial_commitment_tx = self.build_commitment_transaction(
4477- funding, self.cur_counterparty_commitment_transaction_number, &self.counterparty_cur_commitment_point.unwrap(), false, false, logger).tx;
4492+ let commitment_data = self.build_commitment_transaction(funding,
4493+ self.cur_counterparty_commitment_transaction_number,
4494+ &self.counterparty_cur_commitment_point.unwrap(), false, false, logger);
4495+ let counterparty_initial_commitment_tx = commitment_data.stats.tx;
44784496 match self.holder_signer {
44794497 // TODO (taproot|arik): move match into calling method for Taproot
44804498 ChannelSignerType::Ecdsa(ref ecdsa) => {
@@ -5474,7 +5492,11 @@ impl<SP: Deref> FundedChannel<SP> where
54745492
54755493 let funding_script = self.funding.get_funding_redeemscript();
54765494
5477- let commitment_stats = self.context.build_commitment_transaction(&self.funding, self.holder_commitment_point.transaction_number(), &self.holder_commitment_point.current_point(), true, false, logger);
5495+ let commitment_data = self.context.build_commitment_transaction(&self.funding,
5496+ self.holder_commitment_point.transaction_number(),
5497+ &self.holder_commitment_point.current_point(), true, false, logger
5498+ );
5499+ let commitment_stats = commitment_data.stats;
54785500 let commitment_txid = {
54795501 let trusted_tx = commitment_stats.tx.trust();
54805502 let bitcoin_tx = trusted_tx.built_transaction();
@@ -5489,7 +5511,7 @@ impl<SP: Deref> FundedChannel<SP> where
54895511 }
54905512 bitcoin_tx.txid
54915513 };
5492- let mut htlcs_cloned: Vec<_> = commitment_stats .htlcs_included.iter().map(|htlc| (htlc.0.clone(), htlc.1.map(|h| h.clone()))).collect();
5514+ let mut htlcs_cloned: Vec<_> = commitment_data .htlcs_included.iter().map(|htlc| (htlc.0.clone(), htlc.1.map(|h| h.clone()))).collect();
54935515
54945516 // If our counterparty updated the channel fee in this commitment transaction, check that
54955517 // they can actually afford the new fee now.
@@ -5580,7 +5602,7 @@ impl<SP: Deref> FundedChannel<SP> where
55805602 self.funding.counterparty_funding_pubkey()
55815603 );
55825604
5583- self.context.holder_signer.as_ref().validate_holder_commitment(&holder_commitment_tx, commitment_stats .outbound_htlc_preimages)
5605+ self.context.holder_signer.as_ref().validate_holder_commitment(&holder_commitment_tx, commitment_data .outbound_htlc_preimages)
55845606 .map_err(|_| ChannelError::close("Failed to validate our commitment".to_owned()))?;
55855607
55865608 // Update state now that we've passed all the can-fail calls...
@@ -6237,9 +6259,11 @@ impl<SP: Deref> FundedChannel<SP> where
62376259 // Before proposing a feerate update, check that we can actually afford the new fee.
62386260 let dust_exposure_limiting_feerate = self.context.get_dust_exposure_limiting_feerate(&fee_estimator);
62396261 let htlc_stats = self.context.get_pending_htlc_stats(Some(feerate_per_kw), dust_exposure_limiting_feerate);
6240- let commitment_stats = self.context.build_commitment_transaction(&self.funding, self.holder_commitment_point.transaction_number(), &self.holder_commitment_point.current_point(), true, true, logger);
6241- let buffer_fee_msat = commit_tx_fee_sat(feerate_per_kw, commitment_stats.tx.htlcs().len() + htlc_stats.on_holder_tx_outbound_holding_cell_htlcs_count as usize + CONCURRENT_INBOUND_HTLC_FEE_BUFFER as usize, self.context.get_channel_type()) * 1000;
6242- let holder_balance_msat = commitment_stats.local_balance_msat - htlc_stats.outbound_holding_cell_msat;
6262+ let commitment_data = self.context.build_commitment_transaction(&self.funding,
6263+ self.holder_commitment_point.transaction_number(),
6264+ &self.holder_commitment_point.current_point(), true, true, logger);
6265+ let buffer_fee_msat = commit_tx_fee_sat(feerate_per_kw, commitment_data.stats.tx.htlcs().len() + htlc_stats.on_holder_tx_outbound_holding_cell_htlcs_count as usize + CONCURRENT_INBOUND_HTLC_FEE_BUFFER as usize, self.context.get_channel_type()) * 1000;
6266+ let holder_balance_msat = commitment_data.stats.local_balance_msat - htlc_stats.outbound_holding_cell_msat;
62436267 if holder_balance_msat < buffer_fee_msat + self.funding.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000 {
62446268 //TODO: auto-close after a number of failures?
62456269 log_debug!(logger, "Cannot afford to send new feerate at {}", feerate_per_kw);
@@ -6550,7 +6574,10 @@ impl<SP: Deref> FundedChannel<SP> where
65506574 self.holder_commitment_point.try_resolve_pending(&self.context.holder_signer, &self.context.secp_ctx, logger);
65516575 }
65526576 let funding_signed = if self.context.signer_pending_funding && !self.funding.is_outbound() {
6553- let counterparty_initial_commitment_tx = self.context.build_commitment_transaction(&self.funding, self.context.cur_counterparty_commitment_transaction_number + 1, &self.context.counterparty_cur_commitment_point.unwrap(), false, false, logger).tx;
6577+ let commitment_data = self.context.build_commitment_transaction(&self.funding,
6578+ self.context.cur_counterparty_commitment_transaction_number + 1,
6579+ &self.context.counterparty_cur_commitment_point.unwrap(), false, false, logger);
6580+ let counterparty_initial_commitment_tx = commitment_data.stats.tx;
65546581 self.context.get_funding_signed_msg(&self.funding.channel_transaction_parameters, logger, counterparty_initial_commitment_tx)
65556582 } else { None };
65566583 // Provide a `channel_ready` message if we need to, but only if we're _not_ still pending
@@ -8486,8 +8513,10 @@ impl<SP: Deref> FundedChannel<SP> where
84868513 -> (Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>, CommitmentTransaction)
84878514 where L::Target: Logger
84888515 {
8489- let commitment_stats = self.context.build_commitment_transaction(&self.funding, self.context.cur_counterparty_commitment_transaction_number, &self.context.counterparty_cur_commitment_point.unwrap(), false, true, logger);
8490- let counterparty_commitment_tx = commitment_stats.tx;
8516+ let commitment_data = self.context.build_commitment_transaction(&self.funding,
8517+ self.context.cur_counterparty_commitment_transaction_number,
8518+ &self.context.counterparty_cur_commitment_point.unwrap(), false, true, logger);
8519+ let counterparty_commitment_tx = commitment_data.stats.tx;
84918520
84928521 #[cfg(any(test, fuzzing))]
84938522 {
@@ -8507,7 +8536,7 @@ impl<SP: Deref> FundedChannel<SP> where
85078536 }
85088537 }
85098538
8510- (commitment_stats .htlcs_included, counterparty_commitment_tx)
8539+ (commitment_data .htlcs_included, counterparty_commitment_tx)
85118540 }
85128541
85138542 /// Only fails in case of signer rejection. Used for channel_reestablish commitment_signed
@@ -8517,7 +8546,10 @@ impl<SP: Deref> FundedChannel<SP> where
85178546 #[cfg(any(test, fuzzing))]
85188547 self.build_commitment_no_state_update(logger);
85198548
8520- let commitment_stats = self.context.build_commitment_transaction(&self.funding, self.context.cur_counterparty_commitment_transaction_number, &self.context.counterparty_cur_commitment_point.unwrap(), false, true, logger);
8549+ let commitment_data = self.context.build_commitment_transaction(&self.funding,
8550+ self.context.cur_counterparty_commitment_transaction_number,
8551+ &self.context.counterparty_cur_commitment_point.unwrap(), false, true, logger);
8552+ let commitment_stats = commitment_data.stats;
85218553 let counterparty_commitment_txid = commitment_stats.tx.trust().txid();
85228554
85238555 match &self.context.holder_signer {
@@ -8528,8 +8560,8 @@ impl<SP: Deref> FundedChannel<SP> where
85288560 let res = ecdsa.sign_counterparty_commitment(
85298561 &self.funding.channel_transaction_parameters,
85308562 &commitment_stats.tx,
8531- commitment_stats .inbound_htlc_preimages,
8532- commitment_stats .outbound_htlc_preimages,
8563+ commitment_data .inbound_htlc_preimages,
8564+ commitment_data .outbound_htlc_preimages,
85338565 &self.context.secp_ctx,
85348566 ).map_err(|_| ChannelError::Ignore("Failed to get signatures for new commitment_signed".to_owned()))?;
85358567 signature = res.0;
@@ -8996,7 +9028,10 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
89969028
89979029 /// Only allowed after [`FundingScope::channel_transaction_parameters`] is set.
89989030 fn get_funding_created_msg<L: Deref>(&mut self, logger: &L) -> Option<msgs::FundingCreated> where L::Target: Logger {
8999- let counterparty_initial_commitment_tx = self.context.build_commitment_transaction(&self.funding, self.context.cur_counterparty_commitment_transaction_number, &self.context.counterparty_cur_commitment_point.unwrap(), false, false, logger).tx;
9031+ let commitment_data = self.context.build_commitment_transaction(&self.funding,
9032+ self.context.cur_counterparty_commitment_transaction_number,
9033+ &self.context.counterparty_cur_commitment_point.unwrap(), false, false, logger);
9034+ let counterparty_initial_commitment_tx = commitment_data.stats.tx;
90009035 let signature = match &self.context.holder_signer {
90019036 // TODO (taproot|arik): move match into calling method for Taproot
90029037 ChannelSignerType::Ecdsa(ecdsa) => {
@@ -11608,8 +11643,9 @@ mod tests {
1160811643 ( $counterparty_sig_hex: expr, $sig_hex: expr, $tx_hex: expr, $opt_anchors: expr, {
1160911644 $( { $htlc_idx: expr, $counterparty_htlc_sig_hex: expr, $htlc_sig_hex: expr, $htlc_tx_hex: expr } ), *
1161011645 } ) => { {
11611- let commitment_stats = chan.context.build_commitment_transaction(&chan.funding, 0xffffffffffff - 42, &per_commitment_point, true, false, &logger);
11612- let commitment_tx = commitment_stats.tx;
11646+ let commitment_data = chan.context.build_commitment_transaction(&chan.funding,
11647+ 0xffffffffffff - 42, &per_commitment_point, true, false, &logger);
11648+ let commitment_tx = commitment_data.stats.tx;
1161311649 let trusted_tx = commitment_tx.trust();
1161411650 let unsigned_tx = trusted_tx.built_transaction();
1161511651 let redeemscript = chan.funding.get_funding_redeemscript();
0 commit comments