@@ -875,15 +875,20 @@ struct HTLCStats {
875
875
on_holder_tx_outbound_holding_cell_htlcs_count: u32, // dust HTLCs *non*-included
876
876
}
877
877
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
+
878
886
/// An enum gathering stats on commitment transaction, either local or remote.
879
- struct CommitmentStats<'a> {
887
+ struct CommitmentStats {
880
888
tx: CommitmentTransaction, // the transaction info
881
889
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
883
890
local_balance_msat: u64, // local balance before fees *not* considering dust limits
884
891
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
887
892
}
888
893
889
894
/// 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
1966
1971
) -> Result<CommitmentTransaction, ChannelError> where L::Target: Logger {
1967
1972
let funding_script = self.context().get_funding_redeemscript();
1968
1973
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;
1970
1976
let trusted_tx = initial_commitment_tx.trust();
1971
1977
let initial_commitment_bitcoin_tx = trusted_tx.built_transaction();
1972
1978
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
2003
2009
}
2004
2010
};
2005
2011
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;
2007
2014
let counterparty_trusted_tx = counterparty_initial_commitment_tx.trust();
2008
2015
let counterparty_initial_bitcoin_tx = counterparty_trusted_tx.built_transaction();
2009
2016
@@ -3408,7 +3415,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3408
3415
/// generated by the peer which proposed adding the HTLCs, and thus we need to understand both
3409
3416
/// which peer generated this transaction and "to whom" this transaction flows.
3410
3417
#[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
3412
3420
where L::Target: Logger
3413
3421
{
3414
3422
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 {
3637
3645
}
3638
3646
});
3639
3647
3640
- CommitmentStats {
3648
+ let stats = CommitmentStats {
3641
3649
tx,
3642
3650
total_fee_sat,
3643
- htlcs_included: htlcs_in_tx,
3644
3651
local_balance_msat: value_to_self_msat,
3645
3652
remote_balance_msat: value_to_remote_msat,
3653
+ };
3654
+
3655
+ CommitmentData {
3656
+ stats,
3657
+ htlcs_included: htlcs_in_tx,
3646
3658
inbound_htlc_preimages,
3647
3659
outbound_htlc_preimages,
3648
3660
}
@@ -4441,8 +4453,9 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
4441
4453
SP::Target: SignerProvider,
4442
4454
L::Target: Logger
4443
4455
{
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;
4446
4459
match self.holder_signer {
4447
4460
// TODO (taproot|arik): move match into calling method for Taproot
4448
4461
ChannelSignerType::Ecdsa(ref ecdsa) => {
@@ -5435,7 +5448,8 @@ impl<SP: Deref> FundedChannel<SP> where
5435
5448
5436
5449
let funding_script = self.context.get_funding_redeemscript();
5437
5450
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;
5439
5453
let commitment_txid = {
5440
5454
let trusted_tx = commitment_stats.tx.trust();
5441
5455
let bitcoin_tx = trusted_tx.built_transaction();
@@ -5450,7 +5464,7 @@ impl<SP: Deref> FundedChannel<SP> where
5450
5464
}
5451
5465
bitcoin_tx.txid
5452
5466
};
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();
5454
5468
5455
5469
// If our counterparty updated the channel fee in this commitment transaction, check that
5456
5470
// they can actually afford the new fee now.
@@ -5541,7 +5555,7 @@ impl<SP: Deref> FundedChannel<SP> where
5541
5555
self.context.counterparty_funding_pubkey()
5542
5556
);
5543
5557
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)
5545
5559
.map_err(|_| ChannelError::close("Failed to validate our commitment".to_owned()))?;
5546
5560
5547
5561
// Update state now that we've passed all the can-fail calls...
@@ -6198,9 +6212,9 @@ impl<SP: Deref> FundedChannel<SP> where
6198
6212
// Before proposing a feerate update, check that we can actually afford the new fee.
6199
6213
let dust_exposure_limiting_feerate = self.context.get_dust_exposure_limiting_feerate(&fee_estimator);
6200
6214
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;
6204
6218
if holder_balance_msat < buffer_fee_msat + self.funding.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000 {
6205
6219
//TODO: auto-close after a number of failures?
6206
6220
log_debug!(logger, "Cannot afford to send new feerate at {}", feerate_per_kw);
@@ -6511,7 +6525,8 @@ impl<SP: Deref> FundedChannel<SP> where
6511
6525
self.holder_commitment_point.try_resolve_pending(&self.context.holder_signer, &self.context.secp_ctx, logger);
6512
6526
}
6513
6527
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;
6515
6530
self.context.get_funding_signed_msg(logger, counterparty_initial_commitment_tx)
6516
6531
} else { None };
6517
6532
// 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
8447
8462
-> (Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>, CommitmentTransaction)
8448
8463
where L::Target: Logger
8449
8464
{
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;
8452
8467
8453
8468
#[cfg(any(test, fuzzing))]
8454
8469
{
@@ -8468,7 +8483,7 @@ impl<SP: Deref> FundedChannel<SP> where
8468
8483
}
8469
8484
}
8470
8485
8471
- (commitment_stats .htlcs_included, counterparty_commitment_tx)
8486
+ (commitment_data .htlcs_included, counterparty_commitment_tx)
8472
8487
}
8473
8488
8474
8489
/// Only fails in case of signer rejection. Used for channel_reestablish commitment_signed
@@ -8478,23 +8493,25 @@ impl<SP: Deref> FundedChannel<SP> where
8478
8493
#[cfg(any(test, fuzzing))]
8479
8494
self.build_commitment_no_state_update(logger);
8480
8495
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;
8482
8499
let counterparty_commitment_txid = commitment_stats.tx.trust().txid();
8483
8500
8484
8501
match &self.context.holder_signer {
8485
8502
ChannelSignerType::Ecdsa(ecdsa) => {
8486
8503
let (signature, htlc_signatures);
8487
8504
8488
8505
{
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() {
8491
8508
htlcs.push(htlc);
8492
8509
}
8493
8510
8494
8511
let res = ecdsa.sign_counterparty_commitment(
8495
8512
&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,
8498
8515
&self.context.secp_ctx,
8499
8516
).map_err(|_| ChannelError::Ignore("Failed to get signatures for new commitment_signed".to_owned()))?;
8500
8517
signature = res.0;
@@ -8522,7 +8539,7 @@ impl<SP: Deref> FundedChannel<SP> where
8522
8539
batch: None,
8523
8540
#[cfg(taproot)]
8524
8541
partial_signature_with_nonce: None,
8525
- }, (counterparty_commitment_txid, commitment_stats. htlcs_included)))
8542
+ }, (counterparty_commitment_txid, htlcs_included)))
8526
8543
},
8527
8544
// TODO (taproot|arik)
8528
8545
#[cfg(taproot)]
@@ -8957,7 +8974,8 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
8957
8974
8958
8975
/// Only allowed after [`ChannelContext::channel_transaction_parameters`] is set.
8959
8976
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;
8961
8979
let signature = match &self.context.holder_signer {
8962
8980
// TODO (taproot|arik): move match into calling method for Taproot
8963
8981
ChannelSignerType::Ecdsa(ecdsa) => {
0 commit comments