Skip to content

Commit 3b939c0

Browse files
authored
Merge pull request #4001 from wvanlint/wvanlint/always_emit_bump_event
Always emit bump events, even when fees are sufficient
2 parents 83da6c3 + d99e59b commit 3b939c0

File tree

6 files changed

+99
-42
lines changed

6 files changed

+99
-42
lines changed

lightning/src/chain/onchaintx.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use bitcoin::secp256k1::{ecdsa::Signature, Secp256k1};
2323
use bitcoin::transaction::OutPoint as BitcoinOutPoint;
2424
use bitcoin::transaction::Transaction;
2525

26-
use crate::chain::chaininterface::{compute_feerate_sat_per_1000_weight, ConfirmationTarget};
26+
use crate::chain::chaininterface::ConfirmationTarget;
2727
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
2828
use crate::chain::channelmonitor::ANTI_REORG_DELAY;
2929
use crate::chain::package::{PackageSolvingData, PackageTemplate};
@@ -670,19 +670,8 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
670670

671671
let fee_sat = input_amount_sats - tx.output.iter()
672672
.map(|output| output.value.to_sat()).sum::<u64>();
673-
let commitment_tx_feerate_sat_per_1000_weight =
674-
compute_feerate_sat_per_1000_weight(fee_sat, tx.weight().to_wu());
675673
let package_target_feerate_sat_per_1000_weight = cached_request
676674
.compute_package_feerate(fee_estimator, conf_target, feerate_strategy);
677-
if commitment_tx_feerate_sat_per_1000_weight >= package_target_feerate_sat_per_1000_weight {
678-
log_debug!(logger, "Pre-signed commitment {} already has feerate {} sat/kW above required {} sat/kW",
679-
tx.compute_txid(), commitment_tx_feerate_sat_per_1000_weight,
680-
package_target_feerate_sat_per_1000_weight);
681-
// The commitment transaction already meets the required feerate and doesn't
682-
// need a CPFP. We still want to return something other than the event to
683-
// register the claim.
684-
return Some((new_timer, 0, OnchainClaim::Tx(MaybeSignedTransaction(tx))));
685-
}
686675

687676
// We'll locate an anchor output we can spend within the commitment transaction.
688677
let channel_parameters = output.channel_parameters.as_ref()

lightning/src/events/bump_transaction/mod.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ pub mod sync;
1616
use alloc::collections::BTreeMap;
1717
use core::ops::Deref;
1818

19-
use crate::chain::chaininterface::{fee_for_weight, BroadcasterInterface};
19+
use crate::chain::chaininterface::{
20+
compute_feerate_sat_per_1000_weight, fee_for_weight, BroadcasterInterface,
21+
};
2022
use crate::chain::ClaimId;
2123
use crate::io_extras::sink;
2224
use crate::ln::chan_utils;
@@ -123,7 +125,9 @@ pub enum BumpTransactionEvent {
123125
/// and child anchor transactions), possibly resulting in a loss of funds. Once the transaction
124126
/// is constructed, it must be fully signed for and broadcast by the consumer of the event
125127
/// along with the `commitment_tx` enclosed. Note that the `commitment_tx` must always be
126-
/// broadcast first, as the child anchor transaction depends on it.
128+
/// broadcast first, as the child anchor transaction depends on it. It is also possible that the
129+
/// feerate of the commitment transaction is already sufficient, in which case the child anchor
130+
/// transaction is not needed and only the commitment transaction should be broadcast.
127131
///
128132
/// The consumer should be able to sign for any of the additional inputs included within the
129133
/// child anchor transaction. To sign its anchor input, an [`EcdsaChannelSigner`] should be
@@ -658,6 +662,19 @@ where
658662
commitment_tx: &Transaction, commitment_tx_fee_sat: u64,
659663
anchor_descriptor: &AnchorDescriptor,
660664
) -> Result<(), ()> {
665+
// First, check if the commitment transaction has sufficient fees on its own.
666+
let commitment_tx_feerate_sat_per_1000_weight = compute_feerate_sat_per_1000_weight(
667+
commitment_tx_fee_sat,
668+
commitment_tx.weight().to_wu(),
669+
);
670+
if commitment_tx_feerate_sat_per_1000_weight >= package_target_feerate_sat_per_1000_weight {
671+
log_debug!(self.logger, "Pre-signed commitment {} already has feerate {} sat/kW above required {} sat/kW, broadcasting.",
672+
commitment_tx.compute_txid(), commitment_tx_feerate_sat_per_1000_weight,
673+
package_target_feerate_sat_per_1000_weight);
674+
self.broadcaster.broadcast_transactions(&[&commitment_tx]);
675+
return Ok(());
676+
}
677+
661678
// Our commitment transaction already has fees allocated to it, so we should take them into
662679
// account. We do so by pretending the commitment transaction's fee and weight are part of
663680
// the anchor input.

lightning/src/ln/async_signer_tests.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,9 @@ fn do_test_async_holder_signatures(anchors: bool, remote_commitment: bool) {
10511051
&nodes[0].logger,
10521052
);
10531053
}
1054+
if anchors {
1055+
handle_bump_close_event(closing_node);
1056+
}
10541057

10551058
let commitment_tx = {
10561059
let mut txn = closing_node.tx_broadcaster.txn_broadcast();

lightning/src/ln/functional_test_utils.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2211,21 +2211,37 @@ macro_rules! check_closed_event {
22112211
};
22122212
}
22132213

2214-
pub fn handle_bump_htlc_event(node: &Node, count: usize) {
2214+
pub fn handle_bump_events(node: &Node, expected_close: bool, expected_htlc_count: usize) {
22152215
let events = node.chain_monitor.chain_monitor.get_and_clear_pending_events();
2216-
assert_eq!(events.len(), count);
2217-
for event in events {
2216+
let mut close = false;
2217+
let mut htlc_count = 0;
2218+
for event in &events {
22182219
match event {
2219-
Event::BumpTransaction(bump_event) => {
2220-
if let BumpTransactionEvent::HTLCResolution { .. } = &bump_event {
2221-
} else {
2222-
panic!();
2223-
}
2224-
node.bump_tx_handler.handle_event(&bump_event);
2220+
Event::BumpTransaction(bump @ BumpTransactionEvent::ChannelClose { .. }) => {
2221+
close = true;
2222+
node.bump_tx_handler.handle_event(&bump);
22252223
},
2226-
_ => panic!(),
2224+
Event::BumpTransaction(bump @ BumpTransactionEvent::HTLCResolution { .. }) => {
2225+
htlc_count += 1;
2226+
node.bump_tx_handler.handle_event(&bump);
2227+
},
2228+
_ => panic!("Unexpected non-bump event: {:?}.", event),
22272229
}
22282230
}
2231+
assert_eq!(close, expected_close, "Expected a bump close event, found {:?}.", events);
2232+
assert_eq!(
2233+
htlc_count, expected_htlc_count,
2234+
"Expected {} bump HTLC events, found {:?}",
2235+
expected_htlc_count, events
2236+
);
2237+
}
2238+
2239+
pub fn handle_bump_close_event(node: &Node) {
2240+
handle_bump_events(node, true, 0);
2241+
}
2242+
2243+
pub fn handle_bump_htlc_event(node: &Node, count: usize) {
2244+
handle_bump_events(node, false, count);
22292245
}
22302246

22312247
pub fn close_channel<'a, 'b, 'c>(

lightning/src/ln/monitor_tests.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,9 @@ fn do_test_balances_on_local_commitment_htlcs(anchors: bool) {
896896
check_closed_broadcast!(nodes[0], true);
897897
let reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
898898
check_closed_event!(nodes[0], 1, reason, [nodes[1].node.get_our_node_id()], 1000000);
899+
if anchors {
900+
handle_bump_close_event(&nodes[0]);
901+
}
899902
let commitment_tx = {
900903
let mut txn = nodes[0].tx_broadcaster.unique_txn_broadcast();
901904
assert_eq!(txn.len(), 1);
@@ -905,9 +908,15 @@ fn do_test_balances_on_local_commitment_htlcs(anchors: bool) {
905908
};
906909
let commitment_tx_conf_height_a = block_from_scid(mine_transaction(&nodes[0], &commitment_tx));
907910
if nodes[0].connect_style.borrow().updates_best_block_first() {
911+
if anchors {
912+
handle_bump_close_event(&nodes[0]);
913+
}
908914
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
909-
assert_eq!(txn.len(), 1);
915+
assert_eq!(txn.len(), if anchors { 2 } else { 1 });
910916
assert_eq!(txn[0].compute_txid(), commitment_tx.compute_txid());
917+
if anchors {
918+
check_spends!(txn[1], txn[0]); // Anchor output spend.
919+
}
911920
}
912921

913922
let htlc_balance_known_preimage = Balance::MaybeTimeoutClaimableHTLC {
@@ -2486,6 +2495,7 @@ fn do_test_yield_anchors_events(have_htlcs: bool) {
24862495
nodes[1].node.force_close_broadcasting_latest_txn(&chan_id, &nodes[0].node.get_our_node_id(), "".to_string()).unwrap();
24872496
}
24882497
{
2498+
handle_bump_close_event(&nodes[1]);
24892499
let txn = nodes[1].tx_broadcaster.txn_broadcast();
24902500
assert_eq!(txn.len(), 1);
24912501
check_spends!(txn[0], funding_tx);
@@ -2553,15 +2563,18 @@ fn do_test_yield_anchors_events(have_htlcs: bool) {
25532563
}
25542564

25552565
{
2566+
if nodes[1].connect_style.borrow().updates_best_block_first() {
2567+
handle_bump_close_event(&nodes[1]);
2568+
}
25562569
let mut txn = nodes[1].tx_broadcaster.unique_txn_broadcast();
25572570
// Both HTLC claims are pinnable at this point,
25582571
// and will be broadcast in a single transaction.
2559-
assert_eq!(txn.len(), if nodes[1].connect_style.borrow().updates_best_block_first() { 2 } else { 1 });
2572+
assert_eq!(txn.len(), if nodes[1].connect_style.borrow().updates_best_block_first() { 3 } else { 1 });
25602573
if nodes[1].connect_style.borrow().updates_best_block_first() {
2561-
let new_commitment_tx = txn.remove(0);
2562-
check_spends!(new_commitment_tx, funding_tx);
2574+
check_spends!(txn[1], funding_tx);
2575+
check_spends!(txn[2], txn[1]); // Anchor output spend.
25632576
}
2564-
let htlc_claim_tx = txn.pop().unwrap();
2577+
let htlc_claim_tx = &txn[0];
25652578
assert_eq!(htlc_claim_tx.input.len(), 2);
25662579
assert_eq!(htlc_claim_tx.input[0].previous_output.vout, 2);
25672580
assert_eq!(htlc_claim_tx.input[1].previous_output.vout, 3);
@@ -2952,6 +2965,7 @@ fn do_test_anchors_monitor_fixes_counterparty_payment_script_on_reload(confirm_c
29522965
let reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
29532966
check_closed_event!(&nodes[0], 1, reason, false,
29542967
[nodes[1].node.get_our_node_id()], 100000);
2968+
handle_bump_close_event(&nodes[0]);
29552969

29562970
let commitment_tx = {
29572971
let mut txn = nodes[0].tx_broadcaster.unique_txn_broadcast();
@@ -3036,6 +3050,9 @@ fn do_test_monitor_claims_with_random_signatures(anchors: bool, confirm_counterp
30363050
get_monitor!(closing_node, chan_id).broadcast_latest_holder_commitment_txn(
30373051
&closing_node.tx_broadcaster, &closing_node.fee_estimator, &closing_node.logger
30383052
);
3053+
if anchors {
3054+
handle_bump_close_event(&closing_node);
3055+
}
30393056

30403057
// The commitment transaction comes first.
30413058
let commitment_tx = {

lightning/src/ln/reorg_tests.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,9 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
844844
check_closed_broadcast(&nodes[0], 1, true);
845845
check_added_monitors(&nodes[0], 1);
846846
check_closed_event(&nodes[0], 1, ClosureReason::HTLCsTimedOut, false, &[nodes[1].node.get_our_node_id()], 100_000);
847+
if anchors {
848+
handle_bump_close_event(&nodes[0]);
849+
}
847850

848851
{
849852
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
@@ -870,6 +873,9 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
870873
check_added_monitors(&nodes[1], 1);
871874
let reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
872875
check_closed_event(&nodes[1], 1, reason, false, &[nodes[0].node.get_our_node_id()], 100_000);
876+
if anchors {
877+
handle_bump_close_event(&nodes[1]);
878+
}
873879

874880
let commitment_b = {
875881
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
@@ -882,13 +888,23 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
882888
// Confirm B's commitment, A should now broadcast an HTLC timeout for commitment B.
883889
mine_transaction(&nodes[0], &commitment_b);
884890
{
885-
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
886891
if nodes[0].connect_style.borrow().updates_best_block_first() {
887892
// `commitment_a` is rebroadcast because the best block was updated prior to seeing
888893
// `commitment_b`.
889-
assert_eq!(txn.len(), 2);
890-
check_spends!(txn.last().unwrap(), commitment_b);
894+
if anchors {
895+
handle_bump_close_event(&nodes[0]);
896+
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
897+
assert_eq!(txn.len(), 3);
898+
check_spends!(txn[0], commitment_b);
899+
check_spends!(txn[1], funding_tx);
900+
check_spends!(txn[2], txn[1]); // Anchor output spend transaction.
901+
} else {
902+
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
903+
assert_eq!(txn.len(), 2);
904+
check_spends!(txn.last().unwrap(), commitment_b);
905+
}
891906
} else {
907+
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
892908
assert_eq!(txn.len(), 1);
893909
check_spends!(txn[0], commitment_b);
894910
}
@@ -898,11 +914,15 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
898914
// blocks, one to get us back to the original height, and another to retry our pending claims.
899915
disconnect_blocks(&nodes[0], 1);
900916
connect_blocks(&nodes[0], 2);
917+
if anchors {
918+
handle_bump_close_event(&nodes[0]);
919+
}
901920
{
902921
let mut txn = nodes[0].tx_broadcaster.unique_txn_broadcast();
903922
if anchors {
904-
assert_eq!(txn.len(), 1);
923+
assert_eq!(txn.len(), 2);
905924
check_spends!(txn[0], funding_tx);
925+
check_spends!(txn[1], txn[0]); // Anchor output spend.
906926
} else {
907927
assert_eq!(txn.len(), 2);
908928
check_spends!(txn[0], txn[1]); // HTLC timeout A
@@ -977,6 +997,7 @@ fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool) {
977997
let message = "Channel force-closed".to_owned();
978998
let reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
979999
check_closed_event(&nodes[1], 1, reason, false, &[node_a_id], 10_000_000);
1000+
handle_bump_close_event(&nodes[1]);
9801001

9811002
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
9821003
assert_eq!(txn.len(), 1);
@@ -990,19 +1011,13 @@ fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool) {
9901011
check_added_monitors(&nodes[0], 1);
9911012

9921013
mine_transaction(&nodes[1], &commitment_tx);
993-
let mut bump_events = nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_events();
994-
assert_eq!(bump_events.len(), 1);
995-
match bump_events.pop().unwrap() {
996-
Event::BumpTransaction(bump_event) => {
997-
nodes[1].bump_tx_handler.handle_event(&bump_event);
998-
},
999-
ev => panic!("Unexpected event {ev:?}"),
1000-
}
1014+
handle_bump_events(&nodes[1], nodes[1].connect_style.borrow().updates_best_block_first(), 1);
10011015

10021016
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
10031017
if nodes[1].connect_style.borrow().updates_best_block_first() {
1004-
assert_eq!(txn.len(), 2, "{txn:?}");
1018+
assert_eq!(txn.len(), 3, "{txn:?}");
10051019
check_spends!(txn[0], funding_tx);
1020+
check_spends!(txn[1], txn[0]); // Anchor output spend.
10061021
} else {
10071022
assert_eq!(txn.len(), 1, "{txn:?}");
10081023
}

0 commit comments

Comments
 (0)