Skip to content

Commit f089e04

Browse files
committed
Tweak return values of ChannelContext::build_commitment_transaction
We choose to include in `CommitmentStats` only fields that will be calculated or constructed solely by custom transaction builders. The other fields are created by channel, and placed in a new struct we call `CommitmentData`.
1 parent 00bf32d commit f089e04

File tree

1 file changed

+46
-28
lines changed

1 file changed

+46
-28
lines changed

lightning/src/ln/channel.rs

+46-28
Original file line numberDiff line numberDiff line change
@@ -875,15 +875,20 @@ struct HTLCStats {
875875
on_holder_tx_outbound_holding_cell_htlcs_count: u32, // dust HTLCs *non*-included
876876
}
877877

878+
/// An enum gathering data on a commitment, either local or remote.
879+
struct CommitmentData<'a> {
880+
stats: CommitmentStats,
881+
htlcs_included: Vec<(HTLCOutputInCommitment, Option<&'a HTLCSource>)>, // the list of HTLCs (dust HTLCs *included*) which were not ignored when building the transaction
882+
outbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful offered HTLCs since last commitment
883+
inbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful received HTLCs since last commitment
884+
}
885+
878886
/// An enum gathering stats on commitment transaction, either local or remote.
879-
struct CommitmentStats<'a> {
887+
struct CommitmentStats {
880888
tx: CommitmentTransaction, // the transaction info
881889
total_fee_sat: u64, // the total fee included in the transaction
882-
htlcs_included: Vec<(HTLCOutputInCommitment, Option<&'a HTLCSource>)>, // the list of HTLCs (dust HTLCs *included*) which were not ignored when building the transaction
883890
local_balance_msat: u64, // local balance before fees *not* considering dust limits
884891
remote_balance_msat: u64, // remote balance before fees *not* considering dust limits
885-
outbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful offered HTLCs since last commitment
886-
inbound_htlc_preimages: Vec<PaymentPreimage>, // preimages for successful received HTLCs since last commitment
887892
}
888893

889894
/// Used when calculating whether we or the remote can afford an additional HTLC.
@@ -1966,7 +1971,8 @@ trait InitialRemoteCommitmentReceiver<SP: Deref> where SP::Target: SignerProvide
19661971
) -> Result<CommitmentTransaction, ChannelError> where L::Target: Logger {
19671972
let funding_script = self.context().get_funding_redeemscript();
19681973

1969-
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;
1974+
let commitment_data = self.context().build_commitment_transaction(self.funding(), holder_commitment_point.transaction_number(), &holder_commitment_point.current_point(), true, false, logger);
1975+
let initial_commitment_tx = commitment_data.stats.tx;
19701976
let trusted_tx = initial_commitment_tx.trust();
19711977
let initial_commitment_bitcoin_tx = trusted_tx.built_transaction();
19721978
let sighash = initial_commitment_bitcoin_tx.get_sighash_all(&funding_script, self.funding().channel_value_satoshis);
@@ -2003,7 +2009,8 @@ trait InitialRemoteCommitmentReceiver<SP: Deref> where SP::Target: SignerProvide
20032009
}
20042010
};
20052011
let context = self.context();
2006-
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;
2012+
let commitment_data = context.build_commitment_transaction(self.funding(), context.cur_counterparty_commitment_transaction_number, &context.counterparty_cur_commitment_point.unwrap(), false, false, logger);
2013+
let counterparty_initial_commitment_tx = commitment_data.stats.tx;
20072014
let counterparty_trusted_tx = counterparty_initial_commitment_tx.trust();
20082015
let counterparty_initial_bitcoin_tx = counterparty_trusted_tx.built_transaction();
20092016

@@ -3408,7 +3415,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
34083415
/// generated by the peer which proposed adding the HTLCs, and thus we need to understand both
34093416
/// which peer generated this transaction and "to whom" this transaction flows.
34103417
#[inline]
3411-
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
3418+
fn build_commitment_transaction<L: Deref>(&self, funding: &FundingScope, commitment_number: u64, per_commitment_point: &PublicKey, local: bool, generated_by_local: bool, logger: &L)
3419+
-> CommitmentData
34123420
where L::Target: Logger
34133421
{
34143422
let num_htlcs = self.pending_inbound_htlcs.len() + self.pending_outbound_htlcs.len();
@@ -3637,12 +3645,16 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
36373645
}
36383646
});
36393647

3640-
CommitmentStats {
3648+
let stats = CommitmentStats {
36413649
tx,
36423650
total_fee_sat,
3643-
htlcs_included: htlcs_in_tx,
36443651
local_balance_msat: value_to_self_msat,
36453652
remote_balance_msat: value_to_remote_msat,
3653+
};
3654+
3655+
CommitmentData {
3656+
stats,
3657+
htlcs_included: htlcs_in_tx,
36463658
inbound_htlc_preimages,
36473659
outbound_htlc_preimages,
36483660
}
@@ -4441,8 +4453,9 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
44414453
SP::Target: SignerProvider,
44424454
L::Target: Logger
44434455
{
4444-
let counterparty_initial_commitment_tx = self.build_commitment_transaction(
4445-
funding, self.cur_counterparty_commitment_transaction_number, &self.counterparty_cur_commitment_point.unwrap(), false, false, logger).tx;
4456+
let commitment_data = self.build_commitment_transaction(
4457+
funding, self.cur_counterparty_commitment_transaction_number, &self.counterparty_cur_commitment_point.unwrap(), false, false, logger);
4458+
let counterparty_initial_commitment_tx = commitment_data.stats.tx;
44464459
match self.holder_signer {
44474460
// TODO (taproot|arik): move match into calling method for Taproot
44484461
ChannelSignerType::Ecdsa(ref ecdsa) => {
@@ -5435,7 +5448,8 @@ impl<SP: Deref> FundedChannel<SP> where
54355448

54365449
let funding_script = self.context.get_funding_redeemscript();
54375450

5438-
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);
5451+
let commitment_data = self.context.build_commitment_transaction(&self.funding, self.holder_commitment_point.transaction_number(), &self.holder_commitment_point.current_point(), true, false, logger);
5452+
let commitment_stats = commitment_data.stats;
54395453
let commitment_txid = {
54405454
let trusted_tx = commitment_stats.tx.trust();
54415455
let bitcoin_tx = trusted_tx.built_transaction();
@@ -5450,7 +5464,7 @@ impl<SP: Deref> FundedChannel<SP> where
54505464
}
54515465
bitcoin_tx.txid
54525466
};
5453-
let mut htlcs_cloned: Vec<_> = commitment_stats.htlcs_included.iter().map(|htlc| (htlc.0.clone(), htlc.1.map(|h| h.clone()))).collect();
5467+
let mut htlcs_cloned: Vec<_> = commitment_data.htlcs_included.iter().map(|htlc| (htlc.0.clone(), htlc.1.map(|h| h.clone()))).collect();
54545468

54555469
// If our counterparty updated the channel fee in this commitment transaction, check that
54565470
// they can actually afford the new fee now.
@@ -5541,7 +5555,7 @@ impl<SP: Deref> FundedChannel<SP> where
55415555
self.context.counterparty_funding_pubkey()
55425556
);
55435557

5544-
self.context.holder_signer.as_ref().validate_holder_commitment(&holder_commitment_tx, commitment_stats.outbound_htlc_preimages)
5558+
self.context.holder_signer.as_ref().validate_holder_commitment(&holder_commitment_tx, commitment_data.outbound_htlc_preimages)
55455559
.map_err(|_| ChannelError::close("Failed to validate our commitment".to_owned()))?;
55465560

55475561
// Update state now that we've passed all the can-fail calls...
@@ -6198,9 +6212,9 @@ impl<SP: Deref> FundedChannel<SP> where
61986212
// Before proposing a feerate update, check that we can actually afford the new fee.
61996213
let dust_exposure_limiting_feerate = self.context.get_dust_exposure_limiting_feerate(&fee_estimator);
62006214
let htlc_stats = self.context.get_pending_htlc_stats(Some(feerate_per_kw), dust_exposure_limiting_feerate);
6201-
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);
6202-
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;
6203-
let holder_balance_msat = commitment_stats.local_balance_msat - htlc_stats.outbound_holding_cell_msat;
6215+
let commitment_data = self.context.build_commitment_transaction(&self.funding, self.holder_commitment_point.transaction_number(), &self.holder_commitment_point.current_point(), true, true, logger);
6216+
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;
6217+
let holder_balance_msat = commitment_data.stats.local_balance_msat - htlc_stats.outbound_holding_cell_msat;
62046218
if holder_balance_msat < buffer_fee_msat + self.funding.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000 {
62056219
//TODO: auto-close after a number of failures?
62066220
log_debug!(logger, "Cannot afford to send new feerate at {}", feerate_per_kw);
@@ -6511,7 +6525,8 @@ impl<SP: Deref> FundedChannel<SP> where
65116525
self.holder_commitment_point.try_resolve_pending(&self.context.holder_signer, &self.context.secp_ctx, logger);
65126526
}
65136527
let funding_signed = if self.context.signer_pending_funding && !self.context.is_outbound() {
6514-
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;
6528+
let commitment_data = 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);
6529+
let counterparty_initial_commitment_tx = commitment_data.stats.tx;
65156530
self.context.get_funding_signed_msg(logger, counterparty_initial_commitment_tx)
65166531
} else { None };
65176532
// Provide a `channel_ready` message if we need to, but only if we're _not_ still pending
@@ -8447,8 +8462,8 @@ impl<SP: Deref> FundedChannel<SP> where
84478462
-> (Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>, CommitmentTransaction)
84488463
where L::Target: Logger
84498464
{
8450-
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);
8451-
let counterparty_commitment_tx = commitment_stats.tx;
8465+
let commitment_data = self.context.build_commitment_transaction(&self.funding, self.context.cur_counterparty_commitment_transaction_number, &self.context.counterparty_cur_commitment_point.unwrap(), false, true, logger);
8466+
let counterparty_commitment_tx = commitment_data.stats.tx;
84528467

84538468
#[cfg(any(test, fuzzing))]
84548469
{
@@ -8468,7 +8483,7 @@ impl<SP: Deref> FundedChannel<SP> where
84688483
}
84698484
}
84708485

8471-
(commitment_stats.htlcs_included, counterparty_commitment_tx)
8486+
(commitment_data.htlcs_included, counterparty_commitment_tx)
84728487
}
84738488

84748489
/// Only fails in case of signer rejection. Used for channel_reestablish commitment_signed
@@ -8478,23 +8493,25 @@ impl<SP: Deref> FundedChannel<SP> where
84788493
#[cfg(any(test, fuzzing))]
84798494
self.build_commitment_no_state_update(logger);
84808495

8481-
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);
8496+
let commitment_data = self.context.build_commitment_transaction(&self.funding, self.context.cur_counterparty_commitment_transaction_number, &self.context.counterparty_cur_commitment_point.unwrap(), false, true, logger);
8497+
let commitment_stats = commitment_data.stats;
8498+
let htlcs_included = commitment_data.htlcs_included;
84828499
let counterparty_commitment_txid = commitment_stats.tx.trust().txid();
84838500

84848501
match &self.context.holder_signer {
84858502
ChannelSignerType::Ecdsa(ecdsa) => {
84868503
let (signature, htlc_signatures);
84878504

84888505
{
8489-
let mut htlcs = Vec::with_capacity(commitment_stats.htlcs_included.len());
8490-
for &(ref htlc, _) in commitment_stats.htlcs_included.iter() {
8506+
let mut htlcs = Vec::with_capacity(htlcs_included.len());
8507+
for &(ref htlc, _) in htlcs_included.iter() {
84918508
htlcs.push(htlc);
84928509
}
84938510

84948511
let res = ecdsa.sign_counterparty_commitment(
84958512
&commitment_stats.tx,
8496-
commitment_stats.inbound_htlc_preimages,
8497-
commitment_stats.outbound_htlc_preimages,
8513+
commitment_data.inbound_htlc_preimages,
8514+
commitment_data.outbound_htlc_preimages,
84988515
&self.context.secp_ctx,
84998516
).map_err(|_| ChannelError::Ignore("Failed to get signatures for new commitment_signed".to_owned()))?;
85008517
signature = res.0;
@@ -8522,7 +8539,7 @@ impl<SP: Deref> FundedChannel<SP> where
85228539
batch: None,
85238540
#[cfg(taproot)]
85248541
partial_signature_with_nonce: None,
8525-
}, (counterparty_commitment_txid, commitment_stats.htlcs_included)))
8542+
}, (counterparty_commitment_txid, htlcs_included)))
85268543
},
85278544
// TODO (taproot|arik)
85288545
#[cfg(taproot)]
@@ -8957,7 +8974,8 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
89578974

89588975
/// Only allowed after [`ChannelContext::channel_transaction_parameters`] is set.
89598976
fn get_funding_created_msg<L: Deref>(&mut self, logger: &L) -> Option<msgs::FundingCreated> where L::Target: Logger {
8960-
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;
8977+
let commitment_data = self.context.build_commitment_transaction(&self.funding, self.context.cur_counterparty_commitment_transaction_number, &self.context.counterparty_cur_commitment_point.unwrap(), false, false, logger);
8978+
let counterparty_initial_commitment_tx = commitment_data.stats.tx;
89618979
let signature = match &self.context.holder_signer {
89628980
// TODO (taproot|arik): move match into calling method for Taproot
89638981
ChannelSignerType::Ecdsa(ecdsa) => {

0 commit comments

Comments
 (0)