Skip to content

Commit d6482c8

Browse files
committed
Refactor BroadcasterInterface to include BroadcastType
Add a `BroadcastType` enum to provide context about the type of transaction being broadcast. This information can be useful for logging, filtering, or prioritization purposes. The `BroadcastType` variants are: - `Funding`: A funding transaction establishing a new channel - `CooperativeClose`: A cooperative close transaction - `UnilateralClose`: A force-close transaction - `AnchorBump`: An anchor transaction for CPFP fee-bumping - `Claim`: A transaction claiming outputs from commitment tx - `Sweep`: A transaction sweeping spendable outputs to wallet Co-Authored-By: HAL 9000 Signed-off-by: Elias Rohrer <dev@tnull.de>
1 parent 9e91b2e commit d6482c8

File tree

9 files changed

+78
-33
lines changed

9 files changed

+78
-33
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ use bitcoin::WPubkeyHash;
3636
use lightning::blinded_path::message::{BlindedMessagePath, MessageContext, MessageForwardNode};
3737
use lightning::blinded_path::payment::{BlindedPaymentPath, ReceiveTlvs};
3838
use lightning::chain;
39-
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
39+
use lightning::chain::chaininterface::{
40+
BroadcastType, BroadcasterInterface, ConfirmationTarget, FeeEstimator,
41+
};
4042
use lightning::chain::channelmonitor::{ChannelMonitor, MonitorEvent};
4143
use lightning::chain::transaction::OutPoint;
4244
use lightning::chain::{
@@ -159,8 +161,8 @@ pub struct TestBroadcaster {
159161
txn_broadcasted: RefCell<Vec<Transaction>>,
160162
}
161163
impl BroadcasterInterface for TestBroadcaster {
162-
fn broadcast_transactions(&self, txs: &[&Transaction]) {
163-
for tx in txs {
164+
fn broadcast_transactions(&self, txs: &[(&Transaction, BroadcastType)]) {
165+
for (tx, _broadcast_type) in txs {
164166
self.txn_broadcasted.borrow_mut().push((*tx).clone());
165167
}
166168
}

fuzz/src/full_stack.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ use bitcoin::WPubkeyHash;
3333
use lightning::blinded_path::message::{BlindedMessagePath, MessageContext, MessageForwardNode};
3434
use lightning::blinded_path::payment::{BlindedPaymentPath, ReceiveTlvs};
3535
use lightning::chain;
36-
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
36+
use lightning::chain::chaininterface::{
37+
BroadcastType, BroadcasterInterface, ConfirmationTarget, FeeEstimator,
38+
};
3739
use lightning::chain::chainmonitor;
3840
use lightning::chain::transaction::OutPoint;
3941
use lightning::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen};
@@ -184,8 +186,8 @@ struct TestBroadcaster {
184186
txn_broadcasted: Mutex<Vec<Transaction>>,
185187
}
186188
impl BroadcasterInterface for TestBroadcaster {
187-
fn broadcast_transactions(&self, txs: &[&Transaction]) {
188-
let owned_txs: Vec<Transaction> = txs.iter().map(|tx| (*tx).clone()).collect();
189+
fn broadcast_transactions(&self, txs: &[(&Transaction, BroadcastType)]) {
190+
let owned_txs: Vec<Transaction> = txs.iter().map(|(tx, _)| (*tx).clone()).collect();
189191
self.txn_broadcasted.lock().unwrap().extend(owned_txs);
190192
}
191193
}

lightning-liquidity/src/lsps2/service.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use crate::prelude::{new_hash_map, HashMap};
4040
use crate::sync::{Arc, Mutex, MutexGuard, RwLock};
4141
use crate::utils::async_poll::dummy_waker;
4242

43-
use lightning::chain::chaininterface::BroadcasterInterface;
43+
use lightning::chain::chaininterface::{BroadcastType, BroadcasterInterface};
4444
use lightning::events::HTLCHandlingFailureType;
4545
use lightning::ln::channelmanager::{AChannelManager, FailureCode, InterceptId};
4646
use lightning::ln::msgs::{ErrorAction, LightningError};
@@ -2039,7 +2039,7 @@ where
20392039
}
20402040

20412041
if let Some(funding_tx) = jit_channel.get_funding_tx() {
2042-
self.tx_broadcaster.broadcast_transactions(&[funding_tx]);
2042+
self.tx_broadcaster.broadcast_transactions(&[(funding_tx, BroadcastType::Funding)]);
20432043
}
20442044
}
20452045
}

lightning/src/chain/chaininterface.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,28 @@ use crate::prelude::*;
1919

2020
use bitcoin::transaction::Transaction;
2121

22+
/// Represents the class of transaction being broadcast.
23+
///
24+
/// This is used to provide context about the type of transaction being broadcast, which may be
25+
/// useful for logging, filtering, or prioritization purposes.
26+
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
27+
pub enum BroadcastType {
28+
/// A funding transaction establishing a new channel.
29+
Funding,
30+
/// A cooperative close transaction mutually agreed upon by both parties.
31+
CooperativeClose,
32+
/// A commitment transaction being broadcast to force-close the channel.
33+
Commitment,
34+
/// An anchor transaction used for CPFP fee-bumping a commitment transaction.
35+
Anchor,
36+
/// A transaction claiming outputs from a commitment transaction (HTLC claims, penalty/justice).
37+
Claim,
38+
/// An HTLC resolution transaction (HTLC-timeout or HTLC-success) for anchor channels.
39+
HtlcResolution,
40+
/// A transaction sweeping spendable outputs to the user's wallet.
41+
Sweep,
42+
}
43+
2244
// TODO: Define typed abstraction over feerates to handle their conversions.
2345
pub(crate) fn compute_feerate_sat_per_1000_weight(fee_sat: u64, weight: u64) -> u32 {
2446
(fee_sat * 1000 / weight).try_into().unwrap_or(u32::max_value())
@@ -45,7 +67,10 @@ pub trait BroadcasterInterface {
4567
///
4668
/// Bitcoin transaction packages are defined in BIP 331 and here:
4769
/// <https://github.com/bitcoin/bitcoin/blob/master/doc/policy/packages.md>
48-
fn broadcast_transactions(&self, txs: &[&Transaction]);
70+
///
71+
/// Each transaction is paired with a [`BroadcastType`] indicating the class of transaction
72+
/// being broadcast, which may be useful for logging, filtering, or prioritization.
73+
fn broadcast_transactions(&self, txs: &[(&Transaction, BroadcastType)]);
4974
}
5075

5176
/// An enum that represents the priority at which we want a transaction to confirm used for feerate

lightning/src/chain/onchaintx.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ use bitcoin::transaction::OutPoint as BitcoinOutPoint;
2323
use bitcoin::transaction::Transaction;
2424

2525
use crate::chain::chaininterface::ConfirmationTarget;
26-
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
26+
use crate::chain::chaininterface::{
27+
BroadcastType, BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator,
28+
};
2729
use crate::chain::channelmonitor::ANTI_REORG_DELAY;
2830
use crate::chain::package::{PackageSolvingData, PackageTemplate};
2931
use crate::chain::transaction::MaybeSignedTransaction;
@@ -516,7 +518,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
516518
if tx.is_fully_signed() {
517519
let log_start = if feerate_was_bumped { "Broadcasting RBF-bumped" } else { "Rebroadcasting" };
518520
log_info!(logger, "{} onchain {}", log_start, log_tx!(tx.0));
519-
broadcaster.broadcast_transactions(&[&tx.0]);
521+
broadcaster.broadcast_transactions(&[(&tx.0, BroadcastType::Claim)]);
520522
} else {
521523
log_info!(logger, "Waiting for signature of unsigned onchain transaction {}", tx.0.compute_txid());
522524
}
@@ -863,7 +865,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
863865
OnchainClaim::Tx(tx) => {
864866
if tx.is_fully_signed() {
865867
log_info!(logger, "Broadcasting onchain {}", log_tx!(tx.0));
866-
broadcaster.broadcast_transactions(&[&tx.0]);
868+
broadcaster.broadcast_transactions(&[(&tx.0, BroadcastType::Claim)]);
867869
} else {
868870
log_info!(logger, "Waiting for signature of unsigned onchain transaction {}", tx.0.compute_txid());
869871
}
@@ -1084,7 +1086,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
10841086
OnchainClaim::Tx(bump_tx) => {
10851087
if bump_tx.is_fully_signed() {
10861088
log_info!(logger, "Broadcasting RBF-bumped onchain {}", log_tx!(bump_tx.0));
1087-
broadcaster.broadcast_transactions(&[&bump_tx.0]);
1089+
broadcaster.broadcast_transactions(&[(&bump_tx.0, BroadcastType::Claim)]);
10881090
} else {
10891091
log_info!(logger, "Waiting for signature of RBF-bumped unsigned onchain transaction {}",
10901092
bump_tx.0.compute_txid());
@@ -1187,7 +1189,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
11871189
OnchainClaim::Tx(bump_tx) => {
11881190
if bump_tx.is_fully_signed() {
11891191
log_info!(logger, "Broadcasting onchain {}", log_tx!(bump_tx.0));
1190-
broadcaster.broadcast_transactions(&[&bump_tx.0]);
1192+
broadcaster.broadcast_transactions(&[(&bump_tx.0, BroadcastType::Claim)]);
11911193
} else {
11921194
log_info!(logger, "Waiting for signature of unsigned onchain transaction {}", bump_tx.0.compute_txid());
11931195
}

lightning/src/events/bump_transaction/mod.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use core::future::Future;
1818
use core::ops::Deref;
1919

2020
use crate::chain::chaininterface::{
21-
compute_feerate_sat_per_1000_weight, fee_for_weight, BroadcasterInterface,
21+
compute_feerate_sat_per_1000_weight, fee_for_weight, BroadcastType, BroadcasterInterface,
2222
};
2323
use crate::chain::ClaimId;
2424
use crate::io_extras::sink;
@@ -788,7 +788,7 @@ where
788788
log_debug!(self.logger, "Pre-signed commitment {} already has feerate {} sat/kW above required {} sat/kW, broadcasting.",
789789
commitment_tx.compute_txid(), commitment_tx_feerate_sat_per_1000_weight,
790790
package_target_feerate_sat_per_1000_weight);
791-
self.broadcaster.broadcast_transactions(&[&commitment_tx]);
791+
self.broadcaster.broadcast_transactions(&[(&commitment_tx, BroadcastType::Commitment)]);
792792
return Ok(());
793793
}
794794

@@ -955,7 +955,10 @@ where
955955
anchor_txid,
956956
commitment_tx.compute_txid()
957957
);
958-
self.broadcaster.broadcast_transactions(&[&commitment_tx, &anchor_tx]);
958+
self.broadcaster.broadcast_transactions(&[
959+
(&commitment_tx, BroadcastType::Commitment),
960+
(&anchor_tx, BroadcastType::Anchor),
961+
]);
959962
return Ok(());
960963
}
961964
}
@@ -1188,7 +1191,7 @@ where
11881191
}
11891192

11901193
log_info!(self.logger, "Broadcasting {}", log_tx!(htlc_tx));
1191-
self.broadcaster.broadcast_transactions(&[&htlc_tx]);
1194+
self.broadcaster.broadcast_transactions(&[(&htlc_tx, BroadcastType::HtlcResolution)]);
11921195
}
11931196

11941197
Ok(())

lightning/src/ln/channelmanager.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use crate::blinded_path::payment::{AsyncBolt12OfferContext, Bolt12OfferContext,
3939
use crate::blinded_path::NodeIdLookUp;
4040
use crate::chain;
4141
use crate::chain::chaininterface::{
42-
BroadcasterInterface, ConfirmationTarget, FeeEstimator, LowerBoundedFeeEstimator,
42+
BroadcastType, BroadcasterInterface, ConfirmationTarget, FeeEstimator, LowerBoundedFeeEstimator,
4343
};
4444
use crate::chain::channelmonitor::{
4545
Balance, ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, MonitorEvent,
@@ -6548,7 +6548,7 @@ where
65486548
"Broadcasting signed interactive funding transaction {}",
65496549
funding_tx.compute_txid()
65506550
);
6551-
self.tx_broadcaster.broadcast_transactions(&[funding_tx]);
6551+
self.tx_broadcaster.broadcast_transactions(&[(funding_tx, BroadcastType::Funding)]);
65526552
{
65536553
let mut pending_events = self.pending_events.lock().unwrap();
65546554
emit_channel_pending_event!(pending_events, channel);
@@ -9481,7 +9481,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
94819481
}
94829482
if let Some(tx) = batch_funding_tx {
94839483
log_info!(self.logger, "Broadcasting batch funding tx {}", tx.compute_txid());
9484-
self.tx_broadcaster.broadcast_transactions(&[&tx]);
9484+
self.tx_broadcaster.broadcast_transactions(&[(&tx, BroadcastType::Funding)]);
94859485
}
94869486
}
94879487
}
@@ -10147,7 +10147,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1014710147
};
1014810148
} else {
1014910149
log_info!(logger, "Broadcasting funding transaction with txid {}", tx.compute_txid());
10150-
self.tx_broadcaster.broadcast_transactions(&[&tx]);
10150+
self.tx_broadcaster.broadcast_transactions(&[(&tx, BroadcastType::Funding)]);
1015110151
}
1015210152
}
1015310153

@@ -11608,7 +11608,8 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1160811608
mem::drop(per_peer_state);
1160911609
if let Some((broadcast_tx, err)) = tx_err {
1161011610
log_info!(logger, "Broadcasting {}", log_tx!(broadcast_tx));
11611-
self.tx_broadcaster.broadcast_transactions(&[&broadcast_tx]);
11611+
self.tx_broadcaster
11612+
.broadcast_transactions(&[(&broadcast_tx, BroadcastType::CooperativeClose)]);
1161211613
let _ = self.handle_error(err, *counterparty_node_id);
1161311614
}
1161411615
Ok(())
@@ -12935,7 +12936,10 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1293512936
}
1293612937
if let Some(broadcast_tx) = msgs.signed_closing_tx {
1293712938
log_info!(logger, "Broadcasting closing tx {}", log_tx!(broadcast_tx));
12938-
self.tx_broadcaster.broadcast_transactions(&[&broadcast_tx]);
12939+
self.tx_broadcaster.broadcast_transactions(&[(
12940+
&broadcast_tx,
12941+
BroadcastType::CooperativeClose,
12942+
)]);
1293912943
}
1294012944
} else {
1294112945
// We don't know how to handle a channel_ready or signed_closing_tx for a
@@ -13062,7 +13066,10 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1306213066
handle_errors.push((*cp_id, Err(err)));
1306313067

1306413068
log_info!(logger, "Broadcasting {}", log_tx!(tx));
13065-
self.tx_broadcaster.broadcast_transactions(&[&tx]);
13069+
self.tx_broadcaster.broadcast_transactions(&[(
13070+
&tx,
13071+
BroadcastType::CooperativeClose,
13072+
)]);
1306613073
false
1306713074
} else {
1306813075
true

lightning/src/util/sweep.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
//! [`SpendableOutputDescriptor`]s, i.e., persists them in a given [`KVStoreSync`] and regularly retries
99
//! sweeping them.
1010
11-
use crate::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
11+
use crate::chain::chaininterface::{
12+
BroadcastType, BroadcasterInterface, ConfirmationTarget, FeeEstimator,
13+
};
1214
use crate::chain::channelmonitor::{ANTI_REORG_DELAY, ARCHIVAL_DELAY_BLOCKS};
1315
use crate::chain::{self, BestBlock, Confirm, Filter, Listen, WatchedOutput};
1416
use crate::io;
@@ -582,7 +584,7 @@ where
582584

583585
// Persistence completely successfully. If we have a spending transaction, we broadcast it.
584586
if let Some(spending_tx) = spending_tx {
585-
self.broadcaster.broadcast_transactions(&[&spending_tx]);
587+
self.broadcaster.broadcast_transactions(&[(&spending_tx, BroadcastType::Sweep)]);
586588
}
587589

588590
Ok(())

lightning/src/util/test_utils.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ use crate::blinded_path::message::{BlindedMessagePath, MessageForwardNode};
1212
use crate::blinded_path::payment::{BlindedPaymentPath, ReceiveTlvs};
1313
use crate::chain;
1414
use crate::chain::chaininterface;
15-
use crate::chain::chaininterface::ConfirmationTarget;
1615
#[cfg(any(test, feature = "_externalize_tests"))]
1716
use crate::chain::chaininterface::FEERATE_FLOOR_SATS_PER_KW;
17+
use crate::chain::chaininterface::{BroadcastType, ConfirmationTarget};
1818
use crate::chain::chainmonitor::{ChainMonitor, Persist};
1919
use crate::chain::channelmonitor::{
2020
ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, MonitorEvent,
@@ -1154,7 +1154,7 @@ impl TestBroadcaster {
11541154
}
11551155

11561156
impl chaininterface::BroadcasterInterface for TestBroadcaster {
1157-
fn broadcast_transactions(&self, txs: &[&Transaction]) {
1157+
fn broadcast_transactions(&self, txs: &[(&Transaction, BroadcastType)]) {
11581158
// Assert that any batch of transactions of length greater than 1 is sorted
11591159
// topologically, and is a `child-with-parents` package as defined in
11601160
// <https://github.com/bitcoin/bitcoin/blob/master/doc/policy/packages.md>.
@@ -1165,21 +1165,23 @@ impl chaininterface::BroadcasterInterface for TestBroadcaster {
11651165
// Right now LDK only ever broadcasts packages of length 2.
11661166
assert!(txs.len() <= 2);
11671167
if txs.len() == 2 {
1168-
let parent_txid = txs[0].compute_txid();
1168+
let parent_txid = txs[0].0.compute_txid();
11691169
assert!(txs[1]
1170+
.0
11701171
.input
11711172
.iter()
11721173
.map(|input| input.previous_output.txid)
11731174
.any(|txid| txid == parent_txid));
1174-
let child_txid = txs[1].compute_txid();
1175+
let child_txid = txs[1].0.compute_txid();
11751176
assert!(txs[0]
1177+
.0
11761178
.input
11771179
.iter()
11781180
.map(|input| input.previous_output.txid)
11791181
.all(|txid| txid != child_txid));
11801182
}
11811183

1182-
for tx in txs {
1184+
for (tx, _broadcast_type) in txs {
11831185
let lock_time = tx.lock_time.to_consensus_u32();
11841186
assert!(lock_time < 1_500_000_000);
11851187
if tx.lock_time.is_block_height()
@@ -1195,7 +1197,7 @@ impl chaininterface::BroadcasterInterface for TestBroadcaster {
11951197
}
11961198
}
11971199
}
1198-
let owned_txs: Vec<Transaction> = txs.iter().map(|tx| (*tx).clone()).collect();
1200+
let owned_txs: Vec<Transaction> = txs.iter().map(|(tx, _)| (*tx).clone()).collect();
11991201
self.txn_broadcasted.lock().unwrap().extend(owned_txs);
12001202
}
12011203
}

0 commit comments

Comments
 (0)