Skip to content

Commit e94b5c9

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 cdf46ea commit e94b5c9

File tree

1 file changed

+64
-28
lines changed

1 file changed

+64
-28
lines changed

lightning/src/ln/channel.rs

Lines changed: 64 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)