Skip to content

Commit 990c500

Browse files
committed
Avoid yielding ChannelClose bump events with sufficient feerate
There's no need to yield such an event when the commitment transaction already meets the target feerate on its own, so we can simply broadcast it without an anchor child transaction. This may be a common occurrence until we are less aggressive about feerate updates.
1 parent 19de435 commit 990c500

File tree

4 files changed

+23
-17
lines changed

4 files changed

+23
-17
lines changed

lightning/src/chain/onchaintx.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use bitcoin::hash_types::{Txid, BlockHash};
2222
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
2323
use bitcoin::secp256k1;
2424

25+
use crate::chain::chaininterface::compute_feerate_sat_per_1000_weight;
2526
use crate::sign::{ChannelSigner, EntropySource, SignerProvider};
2627
use crate::ln::msgs::DecodeError;
2728
use crate::ln::PaymentPreimage;
@@ -623,19 +624,31 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
623624
return inputs.find_map(|input| match input {
624625
// Commitment inputs with anchors support are the only untractable inputs supported
625626
// thus far that require external funding.
626-
PackageSolvingData::HolderFundingOutput(..) => {
627+
PackageSolvingData::HolderFundingOutput(output) => {
627628
debug_assert_eq!(tx.txid(), self.holder_commitment.trust().txid(),
628629
"Holder commitment transaction mismatch");
630+
631+
let conf_target = ConfirmationTarget::HighPriority;
632+
let package_target_feerate_sat_per_1000_weight = cached_request
633+
.compute_package_feerate(fee_estimator, conf_target, force_feerate_bump);
634+
if let Some(input_amount_sat) = output.funding_amount {
635+
let fee_sat = input_amount_sat - tx.output.iter().map(|output| output.value).sum::<u64>();
636+
if compute_feerate_sat_per_1000_weight(fee_sat, tx.weight() as u64) >=
637+
package_target_feerate_sat_per_1000_weight
638+
{
639+
log_debug!(logger, "Commitment transaction {} already meets required feerate {} sat/kW",
640+
tx.txid(), package_target_feerate_sat_per_1000_weight);
641+
return Some((new_timer, 0, OnchainClaim::Tx(tx.clone())));
642+
}
643+
}
644+
629645
// We'll locate an anchor output we can spend within the commitment transaction.
630646
let funding_pubkey = &self.channel_transaction_parameters.holder_pubkeys.funding_pubkey;
631647
match chan_utils::get_anchor_output(&tx, funding_pubkey) {
632648
// An anchor output was found, so we should yield a funding event externally.
633649
Some((idx, _)) => {
634650
// TODO: Use a lower confirmation target when both our and the
635651
// counterparty's latest commitment don't have any HTLCs present.
636-
let conf_target = ConfirmationTarget::HighPriority;
637-
let package_target_feerate_sat_per_1000_weight = cached_request
638-
.compute_package_feerate(fee_estimator, conf_target, force_feerate_bump);
639652
Some((
640653
new_timer,
641654
package_target_feerate_sat_per_1000_weight as u64,
@@ -739,6 +752,9 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
739752
) {
740753
req.set_timer(new_timer);
741754
req.set_feerate(new_feerate);
755+
// Once a pending claim has an id assigned, it remains fixed until the claim is
756+
// satisfied, regardless of whether the claim switches between different variants of
757+
// `OnchainClaim`.
742758
let claim_id = match claim {
743759
OnchainClaim::Tx(tx) => {
744760
log_info!(logger, "Broadcasting onchain {}", log_tx!(tx));

lightning/src/chain/package.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ impl Readable for HolderHTLCOutput {
429429
#[derive(Clone, PartialEq, Eq)]
430430
pub(crate) struct HolderFundingOutput {
431431
funding_redeemscript: Script,
432-
funding_amount: Option<u64>,
432+
pub(crate) funding_amount: Option<u64>,
433433
channel_type_features: ChannelTypeFeatures,
434434
}
435435

lightning/src/events/bump_transaction.rs

-12
Original file line numberDiff line numberDiff line change
@@ -700,18 +700,6 @@ where
700700
&self, claim_id: ClaimId, package_target_feerate_sat_per_1000_weight: u32,
701701
commitment_tx: &Transaction, commitment_tx_fee_sat: u64, anchor_descriptor: &AnchorDescriptor,
702702
) -> Result<(), ()> {
703-
// Compute the feerate the anchor transaction must meet to meet the overall feerate for the
704-
// package (commitment + anchor transactions).
705-
let commitment_tx_sat_per_1000_weight: u32 = compute_feerate_sat_per_1000_weight(
706-
commitment_tx_fee_sat, commitment_tx.weight() as u64,
707-
);
708-
if commitment_tx_sat_per_1000_weight >= package_target_feerate_sat_per_1000_weight {
709-
// If the commitment transaction already has a feerate high enough on its own, broadcast
710-
// it as is without a child.
711-
self.broadcaster.broadcast_transactions(&[&commitment_tx]);
712-
return Ok(());
713-
}
714-
715703
let mut anchor_tx = self.build_anchor_tx(
716704
claim_id, package_target_feerate_sat_per_1000_weight, commitment_tx, anchor_descriptor,
717705
)?;

lightning/src/ln/monitor_tests.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1878,6 +1878,7 @@ fn test_yield_anchors_events() {
18781878

18791879
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
18801880

1881+
*nodes[0].fee_estimator.sat_per_kw.lock().unwrap() *= 2;
18811882
connect_blocks(&nodes[0], TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS + 1);
18821883
check_closed_broadcast!(&nodes[0], true);
18831884
assert!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().is_empty());
@@ -2054,6 +2055,7 @@ fn test_anchors_aggregated_revoked_htlc_tx() {
20542055
// Bob force closes by restarting with the outdated state, prompting the ChannelMonitors to
20552056
// broadcast the latest commitment transaction known to them, which in our case is the one with
20562057
// the HTLCs still pending.
2058+
*nodes[1].fee_estimator.sat_per_kw.lock().unwrap() *= 2;
20572059
nodes[1].node.timer_tick_occurred();
20582060
check_added_monitors(&nodes[1], 2);
20592061
check_closed_event!(&nodes[1], 2, ClosureReason::OutdatedChannelManager);

0 commit comments

Comments
 (0)