Skip to content

[Custom Transactions] Add TxBuilder trait, support fixed additional outputs #3775

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -987,9 +987,8 @@ struct CommitmentData<'a> {
/// A struct gathering stats on a commitment transaction, either local or remote.
struct CommitmentStats {
total_fee_sat: u64, // the total fee included in the transaction
total_anchors_sat: u64, // the sum of the anchors' amounts
local_balance_before_fee_anchors_msat: u64, // local balance before fees and anchors *not* considering dust limits
remote_balance_before_fee_anchors_msat: u64, // remote balance before fees and anchors *not* considering dust limits
local_balance_before_fee_msat: u64, // local balance before fees *not* considering dust limits
remote_balance_before_fee_msat: u64, // remote balance before fees *not* considering dust limits
}

/// Used when calculating whether we or the remote can afford an additional HTLC.
Expand Down Expand Up @@ -3773,7 +3772,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
if update_fee {
debug_assert!(!funding.is_outbound());
let counterparty_reserve_we_require_msat = funding.holder_selected_channel_reserve_satoshis * 1000;
if commitment_data.stats.remote_balance_before_fee_anchors_msat < commitment_data.stats.total_fee_sat * 1000 + counterparty_reserve_we_require_msat {
if commitment_data.stats.remote_balance_before_fee_msat < commitment_data.stats.total_fee_sat * 1000 + counterparty_reserve_we_require_msat {
return Err(ChannelError::close("Funding remote cannot afford proposed new fee".to_owned()));
}
}
Expand Down Expand Up @@ -3933,11 +3932,23 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
let total_fee_sat = commit_tx_fee_sat(feerate_per_kw, non_dust_htlc_count, &funding.channel_transaction_parameters.channel_type_features);
let total_anchors_sat = if funding.channel_transaction_parameters.channel_type_features.supports_anchors_zero_fee_htlc_tx() { ANCHOR_OUTPUT_VALUE_SATOSHI * 2 } else { 0 };

// We MUST use saturating subs here, as the funder's balance is not guaranteed to be greater
// than or equal to `total_anchors_sat`.
//
// This is because when the remote party sends an `update_fee` message, we build the new
// commitment transaction *before* checking whether the remote party's balance is enough to
// cover the total anchor sum.

if funding.is_outbound() {
value_to_self_msat = value_to_self_msat.saturating_sub(total_anchors_sat * 1000);
} else {
value_to_remote_msat = value_to_remote_msat.saturating_sub(total_anchors_sat * 1000);
}

CommitmentStats {
total_fee_sat,
total_anchors_sat,
local_balance_before_fee_anchors_msat: value_to_self_msat,
remote_balance_before_fee_anchors_msat: value_to_remote_msat,
local_balance_before_fee_msat: value_to_self_msat,
remote_balance_before_fee_msat: value_to_remote_msat,
}
}

Expand All @@ -3964,9 +3975,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
let stats = self.build_commitment_stats(funding, local, generated_by_local);
let CommitmentStats {
total_fee_sat,
total_anchors_sat,
local_balance_before_fee_anchors_msat,
remote_balance_before_fee_anchors_msat
local_balance_before_fee_msat,
remote_balance_before_fee_msat
} = stats;

let num_htlcs = self.pending_inbound_htlcs.len() + self.pending_outbound_htlcs.len();
Expand Down Expand Up @@ -4037,9 +4047,9 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
// cover the total fee and the anchors.

let (value_to_self, value_to_remote) = if funding.is_outbound() {
((local_balance_before_fee_anchors_msat / 1000).saturating_sub(total_anchors_sat).saturating_sub(total_fee_sat), remote_balance_before_fee_anchors_msat / 1000)
((local_balance_before_fee_msat / 1000).saturating_sub(total_fee_sat), remote_balance_before_fee_msat / 1000)
} else {
(local_balance_before_fee_anchors_msat / 1000, (remote_balance_before_fee_anchors_msat / 1000).saturating_sub(total_anchors_sat).saturating_sub(total_fee_sat))
(local_balance_before_fee_msat / 1000, (remote_balance_before_fee_msat / 1000).saturating_sub(total_fee_sat))
};

let mut to_broadcaster_value_sat = if local { value_to_self } else { value_to_remote };
Expand Down Expand Up @@ -6667,7 +6677,7 @@ impl<SP: Deref> FundedChannel<SP> where
&self.holder_commitment_point.current_point(), true, true, logger,
);
let buffer_fee_msat = commit_tx_fee_sat(feerate_per_kw, commitment_data.tx.nondust_htlcs().len() + htlc_stats.on_holder_tx_outbound_holding_cell_htlcs_count as usize + CONCURRENT_INBOUND_HTLC_FEE_BUFFER as usize, self.funding.get_channel_type()) * 1000;
let holder_balance_msat = commitment_data.stats.local_balance_before_fee_anchors_msat - htlc_stats.outbound_holding_cell_msat;
let holder_balance_msat = commitment_data.stats.local_balance_before_fee_msat - htlc_stats.outbound_holding_cell_msat;
if holder_balance_msat < buffer_fee_msat + self.funding.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000 {
//TODO: auto-close after a number of failures?
log_debug!(logger, "Cannot afford to send new feerate at {}", feerate_per_kw);
Expand Down