From d9c095275aaff80d3b1336b89bc07a691faa225c Mon Sep 17 00:00:00 2001 From: Leo Nash Date: Sun, 23 Feb 2025 07:49:14 +0000 Subject: [PATCH] move all commitment tx builds to new interface --- lightning/src/chain/channelmonitor.rs | 58 ++++++++++++++++++++------- lightning/src/ln/channel.rs | 28 ++++++++----- lightning/src/sign/tx_builder.rs | 6 ++- 3 files changed, 66 insertions(+), 26 deletions(-) diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index 10e2cd1c7e8..86fffdef843 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -547,6 +547,8 @@ pub(crate) enum ChannelMonitorUpdateStep { feerate_per_kw: Option, to_broadcaster_value_sat: Option, to_countersignatory_value_sat: Option, + value_to_self_with_offset_msat: Option, + counterparty_dust_limit_sat: Option, }, PaymentPreimage { payment_preimage: PaymentPreimage, @@ -598,6 +600,8 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep, (4, their_per_commitment_point, required), (5, to_countersignatory_value_sat, option), (6, htlc_outputs, required_vec), + (7, value_to_self_with_offset_msat, option), + (9, counterparty_dust_limit_sat, option), }, (2, PaymentPreimage) => { (0, payment_preimage, required), @@ -1024,8 +1028,8 @@ pub(crate) struct ChannelMonitorImpl { /// monitors created after 0.0.117. /// /// Ordering of tuple data: (their_per_commitment_point, feerate_per_kw, to_broadcaster_sats, - /// to_countersignatory_sats) - initial_counterparty_commitment_info: Option<(PublicKey, u32, u64, u64)>, + /// to_countersignatory_sats, value_to_self_msat, their_dust_limit) + initial_counterparty_commitment_info: Option<(PublicKey, u32, u64, u64, u64, u64)>, /// The first block height at which we had no remaining claimable balances. balances_empty_height: Option, @@ -1501,7 +1505,8 @@ impl ChannelMonitor { pub(crate) fn provide_initial_counterparty_commitment_tx( &self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option>)>, commitment_number: u64, their_cur_per_commitment_point: PublicKey, feerate_per_kw: u32, - to_broadcaster_value_sat: u64, to_countersignatory_value_sat: u64, logger: &L, + to_broadcaster_value_sat: u64, to_countersignatory_value_sat: u64, value_to_self_msat: u64, counterparty_dust_limit: u64, + logger: &L, ) where L::Target: Logger { @@ -1509,7 +1514,7 @@ impl ChannelMonitor { let logger = WithChannelMonitor::from_impl(logger, &*inner, None); inner.provide_initial_counterparty_commitment_tx(txid, htlc_outputs, commitment_number, their_cur_per_commitment_point, feerate_per_kw, - to_broadcaster_value_sat, to_countersignatory_value_sat, &logger); + to_broadcaster_value_sat, to_countersignatory_value_sat, value_to_self_msat, counterparty_dust_limit, &logger); } /// Informs this monitor of the latest counterparty (ie non-broadcastable) commitment transaction. @@ -2874,10 +2879,11 @@ impl ChannelMonitorImpl { fn provide_initial_counterparty_commitment_tx( &mut self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option>)>, commitment_number: u64, their_per_commitment_point: PublicKey, feerate_per_kw: u32, - to_broadcaster_value: u64, to_countersignatory_value: u64, logger: &WithChannelMonitor, + to_broadcaster_value: u64, to_countersignatory_value: u64, value_to_self_msat: u64, counterparty_dust_limit: u64, + logger: &WithChannelMonitor, ) where L::Target: Logger { self.initial_counterparty_commitment_info = Some((their_per_commitment_point.clone(), - feerate_per_kw, to_broadcaster_value, to_countersignatory_value)); + feerate_per_kw, to_broadcaster_value, to_countersignatory_value, value_to_self_msat, counterparty_dust_limit)); #[cfg(debug_assertions)] { let rebuilt_commitment_tx = self.initial_counterparty_commitment_tx().unwrap(); @@ -3437,14 +3443,17 @@ impl ChannelMonitorImpl { } fn initial_counterparty_commitment_tx(&mut self) -> Option { - let (their_per_commitment_point, feerate_per_kw, to_broadcaster_value, - to_countersignatory_value) = self.initial_counterparty_commitment_info?; - let htlc_outputs = vec![]; - - let commitment_tx = self.build_counterparty_commitment_tx(INITIAL_COMMITMENT_NUMBER, - &their_per_commitment_point, to_broadcaster_value, to_countersignatory_value, - feerate_per_kw, htlc_outputs); - Some(commitment_tx) + let (their_per_commitment_point, feerate_per_kw, _to_broadcaster_value, + _to_countersignatory_value, value_to_self_msat, dust_limit) = self.initial_counterparty_commitment_info?; + + let htlcs = Vec::new(); + let channel_transaction_parameters = &self.onchain_tx_handler.channel_transaction_parameters; + + use crate::sign::tx_builder::{SpecTxBuilder, TxBuilder}; + let tx_builder = SpecTxBuilder {}; + let stats = tx_builder.build_commitment_transaction(false, INITIAL_COMMITMENT_NUMBER, &their_per_commitment_point, channel_transaction_parameters, &self.onchain_tx_handler.secp_ctx, self.channel_value_satoshis, value_to_self_msat, htlcs, feerate_per_kw, dust_limit); + + Some(stats.tx) } fn build_counterparty_commitment_tx( @@ -3477,7 +3486,8 @@ impl ChannelMonitorImpl { ref htlc_outputs, commitment_number, their_per_commitment_point, feerate_per_kw: Some(feerate_per_kw), to_broadcaster_value_sat: Some(to_broadcaster_value), - to_countersignatory_value_sat: Some(to_countersignatory_value) } => { + to_countersignatory_value_sat: Some(to_countersignatory_value), + value_to_self_with_offset_msat: None, counterparty_dust_limit_sat: None } => { let nondust_htlcs = htlc_outputs.iter().filter_map(|(htlc, _)| { htlc.transaction_output_index.map(|_| (htlc.clone(), None)) @@ -3491,6 +3501,24 @@ impl ChannelMonitorImpl { Some(commitment_tx) }, + &ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid, + ref htlc_outputs, commitment_number, their_per_commitment_point, + feerate_per_kw: Some(feerate_per_kw), + to_broadcaster_value_sat: Some(_to_broadcaster_value), + to_countersignatory_value_sat: Some(_to_countersignatory_value), + value_to_self_with_offset_msat: Some(value_to_self_with_offset), counterparty_dust_limit_sat: Some(dust_limit) } => { + + let channel_transaction_parameters = &self.onchain_tx_handler.channel_transaction_parameters; + let htlcs = htlc_outputs.iter().map(|(htlc, source)| (htlc.clone(), source.as_ref().map(|s| s.as_ref()))).collect(); + + use crate::sign::tx_builder::{SpecTxBuilder, TxBuilder}; + let tx_builder = SpecTxBuilder {}; + let stats = tx_builder.build_commitment_transaction(false, commitment_number, &their_per_commitment_point, channel_transaction_parameters, &self.onchain_tx_handler.secp_ctx, self.channel_value_satoshis, value_to_self_with_offset, htlcs, feerate_per_kw, dust_limit); + + debug_assert_eq!(stats.tx.trust().txid(), commitment_txid); + + Some(stats.tx) + }, _ => None, } }).collect() diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index d688d1abef6..0ab0f71fdc9 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -848,6 +848,7 @@ pub(crate) struct CommitmentStats<'a> { pub(crate) htlcs_included: Vec<(HTLCOutputInCommitment, Option<&'a HTLCSource>)>, // the list of HTLCs (dust HTLCs *included*) which were not ignored when building the transaction pub(crate) local_balance_msat: u64, // local balance before fees *not* considering dust limits pub(crate) remote_balance_msat: u64, // remote balance before fees *not* considering dust limits + pub(crate) value_to_self_with_offset_msat: u64 // balance without htlcs, just accounting for the offset } /// Used when calculating whether we or the remote can afford an additional HTLC. @@ -1980,6 +1981,8 @@ trait InitialRemoteCommitmentReceiver where SP::Target: SignerProvide counterparty_initial_commitment_tx.feerate_per_kw(), counterparty_initial_commitment_tx.to_broadcaster_value_sat(), counterparty_initial_commitment_tx.to_countersignatory_value_sat(), + context.value_to_self_msat, + context.counterparty_dust_limit_satoshis, logger); context.cur_counterparty_commitment_transaction_number -= 1; @@ -8186,11 +8189,15 @@ impl FundedChannel where } self.context.resend_order = RAACommitmentOrder::RevokeAndACKFirst; - let (mut htlcs_ref, counterparty_commitment_tx) = + let commitment_stats = self.build_commitment_no_state_update(logger); - let counterparty_commitment_txid = counterparty_commitment_tx.trust().txid(); + let counterparty_commitment_txid = commitment_stats.tx.trust().txid(); let htlcs: Vec<(HTLCOutputInCommitment, Option>)> = - htlcs_ref.drain(..).map(|(htlc, htlc_source)| (htlc, htlc_source.map(|source_ref| Box::new(source_ref.clone())))).collect(); + commitment_stats.htlcs_included.into_iter().map(|(htlc, htlc_source)| (htlc, htlc_source.map(|source_ref| Box::new(source_ref.clone())))).collect(); + let feerate_per_kw = Some(commitment_stats.feerate_per_kw); + let to_broadcaster_value_sat = Some(commitment_stats.tx.to_broadcaster_value_sat()); + let to_countersignatory_value_sat = Some(commitment_stats.tx.to_countersignatory_value_sat()); + let value_to_self_with_offset_msat = Some(commitment_stats.value_to_self_with_offset_msat); if self.context.announcement_sigs_state == AnnouncementSigsState::MessageSent { self.context.announcement_sigs_state = AnnouncementSigsState::Committed; @@ -8205,9 +8212,13 @@ impl FundedChannel where htlc_outputs: htlcs.clone(), commitment_number: self.context.cur_counterparty_commitment_transaction_number, their_per_commitment_point: self.context.counterparty_cur_commitment_point.unwrap(), - feerate_per_kw: Some(counterparty_commitment_tx.feerate_per_kw()), - to_broadcaster_value_sat: Some(counterparty_commitment_tx.to_broadcaster_value_sat()), - to_countersignatory_value_sat: Some(counterparty_commitment_tx.to_countersignatory_value_sat()), + feerate_per_kw, + to_broadcaster_value_sat, + to_countersignatory_value_sat, + value_to_self_with_offset_msat, + counterparty_dust_limit_sat: Some(self.context.counterparty_dust_limit_satoshis), + //value_to_self_with_offset_msat: None, + //counterparty_dust_limit_sat: None, }], channel_id: Some(self.context.channel_id()), }; @@ -8216,12 +8227,11 @@ impl FundedChannel where } fn build_commitment_no_state_update(&self, logger: &L) - -> (Vec<(HTLCOutputInCommitment, Option<&HTLCSource>)>, CommitmentTransaction) + -> CommitmentStats where L::Target: Logger { let counterparty_keys = self.context.build_remote_transaction_keys(); let commitment_stats = self.context.build_commitment_transaction(self.context.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, true, logger); - let counterparty_commitment_tx = commitment_stats.tx; #[cfg(any(test, fuzzing))] { @@ -8241,7 +8251,7 @@ impl FundedChannel where } } - (commitment_stats.htlcs_included, counterparty_commitment_tx) + commitment_stats } /// Only fails in case of signer rejection. Used for channel_reestablish commitment_signed diff --git a/lightning/src/sign/tx_builder.rs b/lightning/src/sign/tx_builder.rs index 30035d14597..159ef00e4df 100644 --- a/lightning/src/sign/tx_builder.rs +++ b/lightning/src/sign/tx_builder.rs @@ -22,7 +22,7 @@ pub(crate) trait TxBuilder { fn build_commitment_transaction<'a>( &self, local: bool, commitment_number: u64, per_commitment_point: &PublicKey, channel_parameters: &ChannelTransactionParameters, secp_ctx: &Secp256k1, - channel_value_satoshis: u64, value_to_self_msat: u64, + channel_value_satoshis: u64, value_to_self_with_offset_msat: u64, htlcs_in_tx: Vec<(HTLCOutputInCommitment, Option<&'a HTLCSource>)>, feerate_per_kw: u32, broadcaster_dust_limit_satoshis: u64, ) -> CommitmentStats<'a>; @@ -36,7 +36,7 @@ impl TxBuilder for SpecTxBuilder { fn build_commitment_transaction<'a>( &self, local: bool, commitment_number: u64, per_commitment_point: &PublicKey, channel_parameters: &ChannelTransactionParameters, secp_ctx: &Secp256k1, - channel_value_satoshis: u64, mut value_to_self_msat: u64, + channel_value_satoshis: u64, value_to_self_with_offset_msat: u64, htlcs_in_tx: Vec<(HTLCOutputInCommitment, Option<&'a HTLCSource>)>, feerate_per_kw: u32, broadcaster_dust_limit_satoshis: u64, ) -> CommitmentStats<'a> { @@ -44,6 +44,7 @@ impl TxBuilder for SpecTxBuilder { let mut remote_htlc_total_msat = 0; let mut included_non_dust_htlcs = Vec::new(); let mut included_dust_htlcs = Vec::new(); + let mut value_to_self_msat = value_to_self_with_offset_msat; let params = if local { channel_parameters.as_holder_broadcastable() @@ -171,6 +172,7 @@ impl TxBuilder for SpecTxBuilder { htlcs_included: all_htlcs, local_balance_msat: value_to_self_msat, remote_balance_msat: value_to_remote_msat, + value_to_self_with_offset_msat, } } }