@@ -876,15 +876,20 @@ struct HTLCStats {
876
876
on_holder_tx_outbound_holding_cell_htlcs_count: u32, // dust HTLCs *non*-included
877
877
}
878
878
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 {
881
889
tx: CommitmentTransaction, // the transaction info
882
890
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
884
891
local_balance_msat: u64, // local balance before fees *not* considering dust limits
885
892
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
888
893
}
889
894
890
895
/// 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
2034
2039
) -> Result<CommitmentTransaction, ChannelError> where L::Target: Logger {
2035
2040
let funding_script = self.funding().get_funding_redeemscript();
2036
2041
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;
2038
2046
let trusted_tx = initial_commitment_tx.trust();
2039
2047
let initial_commitment_bitcoin_tx = trusted_tx.built_transaction();
2040
2048
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
2071
2079
}
2072
2080
};
2073
2081
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;
2075
2086
let counterparty_trusted_tx = counterparty_initial_commitment_tx.trust();
2076
2087
let counterparty_initial_bitcoin_tx = counterparty_trusted_tx.built_transaction();
2077
2088
@@ -3456,7 +3467,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3456
3467
/// generated by the peer which proposed adding the HTLCs, and thus we need to understand both
3457
3468
/// which peer generated this transaction and "to whom" this transaction flows.
3458
3469
#[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
3460
3472
where L::Target: Logger
3461
3473
{
3462
3474
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 {
3679
3691
}
3680
3692
});
3681
3693
3682
- CommitmentStats {
3694
+ let stats = CommitmentStats {
3683
3695
tx,
3684
3696
total_fee_sat,
3685
- htlcs_included: htlcs_in_tx,
3686
3697
local_balance_msat: value_to_self_msat,
3687
3698
remote_balance_msat: value_to_remote_msat,
3699
+ };
3700
+
3701
+ CommitmentData {
3702
+ stats,
3703
+ htlcs_included: htlcs_in_tx,
3688
3704
inbound_htlc_preimages,
3689
3705
outbound_htlc_preimages,
3690
3706
}
@@ -4473,8 +4489,10 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
4473
4489
SP::Target: SignerProvider,
4474
4490
L::Target: Logger
4475
4491
{
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;
4478
4496
match self.holder_signer {
4479
4497
// TODO (taproot|arik): move match into calling method for Taproot
4480
4498
ChannelSignerType::Ecdsa(ref ecdsa) => {
@@ -5474,7 +5492,11 @@ impl<SP: Deref> FundedChannel<SP> where
5474
5492
5475
5493
let funding_script = self.funding.get_funding_redeemscript();
5476
5494
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;
5478
5500
let commitment_txid = {
5479
5501
let trusted_tx = commitment_stats.tx.trust();
5480
5502
let bitcoin_tx = trusted_tx.built_transaction();
@@ -5489,7 +5511,7 @@ impl<SP: Deref> FundedChannel<SP> where
5489
5511
}
5490
5512
bitcoin_tx.txid
5491
5513
};
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();
5493
5515
5494
5516
// If our counterparty updated the channel fee in this commitment transaction, check that
5495
5517
// they can actually afford the new fee now.
@@ -5580,7 +5602,7 @@ impl<SP: Deref> FundedChannel<SP> where
5580
5602
self.funding.counterparty_funding_pubkey()
5581
5603
);
5582
5604
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)
5584
5606
.map_err(|_| ChannelError::close("Failed to validate our commitment".to_owned()))?;
5585
5607
5586
5608
// Update state now that we've passed all the can-fail calls...
@@ -6237,9 +6259,11 @@ impl<SP: Deref> FundedChannel<SP> where
6237
6259
// Before proposing a feerate update, check that we can actually afford the new fee.
6238
6260
let dust_exposure_limiting_feerate = self.context.get_dust_exposure_limiting_feerate(&fee_estimator);
6239
6261
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;
6243
6267
if holder_balance_msat < buffer_fee_msat + self.funding.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000 {
6244
6268
//TODO: auto-close after a number of failures?
6245
6269
log_debug!(logger, "Cannot afford to send new feerate at {}", feerate_per_kw);
@@ -6550,7 +6574,10 @@ impl<SP: Deref> FundedChannel<SP> where
6550
6574
self.holder_commitment_point.try_resolve_pending(&self.context.holder_signer, &self.context.secp_ctx, logger);
6551
6575
}
6552
6576
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;
6554
6581
self.context.get_funding_signed_msg(&self.funding.channel_transaction_parameters, logger, counterparty_initial_commitment_tx)
6555
6582
} else { None };
6556
6583
// 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
8486
8513
-> (Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>, CommitmentTransaction)
8487
8514
where L::Target: Logger
8488
8515
{
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;
8491
8520
8492
8521
#[cfg(any(test, fuzzing))]
8493
8522
{
@@ -8507,7 +8536,7 @@ impl<SP: Deref> FundedChannel<SP> where
8507
8536
}
8508
8537
}
8509
8538
8510
- (commitment_stats .htlcs_included, counterparty_commitment_tx)
8539
+ (commitment_data .htlcs_included, counterparty_commitment_tx)
8511
8540
}
8512
8541
8513
8542
/// Only fails in case of signer rejection. Used for channel_reestablish commitment_signed
@@ -8517,7 +8546,10 @@ impl<SP: Deref> FundedChannel<SP> where
8517
8546
#[cfg(any(test, fuzzing))]
8518
8547
self.build_commitment_no_state_update(logger);
8519
8548
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;
8521
8553
let counterparty_commitment_txid = commitment_stats.tx.trust().txid();
8522
8554
8523
8555
match &self.context.holder_signer {
@@ -8528,8 +8560,8 @@ impl<SP: Deref> FundedChannel<SP> where
8528
8560
let res = ecdsa.sign_counterparty_commitment(
8529
8561
&self.funding.channel_transaction_parameters,
8530
8562
&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,
8533
8565
&self.context.secp_ctx,
8534
8566
).map_err(|_| ChannelError::Ignore("Failed to get signatures for new commitment_signed".to_owned()))?;
8535
8567
signature = res.0;
@@ -8996,7 +9028,10 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
8996
9028
8997
9029
/// Only allowed after [`FundingScope::channel_transaction_parameters`] is set.
8998
9030
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;
9000
9035
let signature = match &self.context.holder_signer {
9001
9036
// TODO (taproot|arik): move match into calling method for Taproot
9002
9037
ChannelSignerType::Ecdsa(ecdsa) => {
@@ -11608,8 +11643,9 @@ mod tests {
11608
11643
( $counterparty_sig_hex: expr, $sig_hex: expr, $tx_hex: expr, $opt_anchors: expr, {
11609
11644
$( { $htlc_idx: expr, $counterparty_htlc_sig_hex: expr, $htlc_sig_hex: expr, $htlc_tx_hex: expr } ), *
11610
11645
} ) => { {
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;
11613
11649
let trusted_tx = commitment_tx.trust();
11614
11650
let unsigned_tx = trusted_tx.built_transaction();
11615
11651
let redeemscript = chan.funding.get_funding_redeemscript();
0 commit comments