Add `counterparty_node_id` to `TrackedSpendableOutput`
What changed, and why it matters
This commit is a routine API and data-model enhancement. It adds an optional 'counterparty_node_id' field to the internal record that tracks spendable Lightning outputs, and threads that value through the sweeper methods. The field is optional and backward-compatible, so older stored records still load. There is no indication this fixes a security bug or introduces a vulnerability.
No security action required. Treat as a normal feature/API change during dependency review.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change extends TrackedSpendableOutput with an optional counterparty_node_id (TLV type 3, odd, for backward compatibility) and updates OutputSweeper::track_spendable_outputs and OutputSweeperSync::track_spendable_outputs to accept it. Serialization uses the existing TLV macro; absent values default to None. The test in lightning-background-processor is updated to pass the counterparty_node_id from Event::SpendableOutputs into the sweeper. No logic that handles secrets, signatures, or authorization is modified.
Changed components
lightning/src/util/sweep.rslightning-background-processor/src/lib.rsInspect captured patch +23 / −5
diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs
index d34ef7d..dce803e 100644
--- a/lightning-background-processor/src/lib.rs
+++ b/lightning-background-processor/src/lib.rs
@@ -3110,10 +3110,16 @@ mod tests {
let event =
receiver.recv_timeout(EVENT_DEADLINE).expect("Events not handled within deadline");
match event {
- Event::SpendableOutputs { outputs, channel_id, counterparty_node_id: _ } => {
+ Event::SpendableOutputs { outputs, channel_id, counterparty_node_id } => {
nodes[0]
.sweeper
- .track_spendable_outputs(outputs, channel_id, false, Some(153))
+ .track_spendable_outputs(
+ outputs,
+ channel_id,
+ counterparty_node_id,
+ false,
+ Some(153),
+ )
.unwrap();
},
_ => panic!("Unexpected event: {:?}", event),
diff --git a/lightning/src/util/sweep.rs b/lightning/src/util/sweep.rs
index 6815b39..b0e3b0b 100644
--- a/lightning/src/util/sweep.rs
+++ b/lightning/src/util/sweep.rs
@@ -32,7 +32,7 @@ use crate::{log_debug, log_error};
use bitcoin::block::Header;
use bitcoin::locktime::absolute::LockTime;
-use bitcoin::secp256k1::Secp256k1;
+use bitcoin::secp256k1::{PublicKey, Secp256k1};
use bitcoin::{BlockHash, ScriptBuf, Transaction, Txid};
use core::future::Future;
@@ -55,6 +55,13 @@ pub struct TrackedSpendableOutput {
///
/// Will be `None` if no `channel_id` was given to [`OutputSweeper::track_spendable_outputs`]
pub channel_id: Option<ChannelId>,
+ /// The `node_id` of the channel counterparty.
+ ///
+ /// Will be `None` if no `counterparty_node_id` was given to
+ /// [`OutputSweeper::track_spendable_outputs`].
+ ///
+ /// This will be `None` for outputs tracked with LDK 0.2 and prior.
+ pub counterparty_node_id: Option<PublicKey>,
/// The current status of the output spend.
pub status: OutputSpendStatus,
}
@@ -93,6 +100,7 @@ impl TrackedSpendableOutput {
impl_writeable_tlv_based!(TrackedSpendableOutput, {
(0, descriptor, required),
(2, channel_id, option),
+ (3, counterparty_node_id, option),
(4, status, required),
});
@@ -413,7 +421,8 @@ where
/// [`Event::SpendableOutputs`]: crate::events::Event::SpendableOutputs
pub async fn track_spendable_outputs(
&self, output_descriptors: Vec<SpendableOutputDescriptor>, channel_id: Option<ChannelId>,
- exclude_static_outputs: bool, delay_until_height: Option<u32>,
+ counterparty_node_id: Option<PublicKey>, exclude_static_outputs: bool,
+ delay_until_height: Option<u32>,
) -> Result<(), ()> {
let mut relevant_descriptors = output_descriptors
.into_iter()
@@ -432,6 +441,7 @@ where
let output_info = TrackedSpendableOutput {
descriptor,
channel_id,
+ counterparty_node_id,
status: OutputSpendStatus::PendingInitialBroadcast {
delayed_until_height: delay_until_height,
},
@@ -1010,11 +1020,13 @@ where
/// [`Event::SpendableOutputs`]: crate::events::Event::SpendableOutputs
pub fn track_spendable_outputs(
&self, output_descriptors: Vec<SpendableOutputDescriptor>, channel_id: Option<ChannelId>,
- exclude_static_outputs: bool, delay_until_height: Option<u32>,
+ counterparty_node_id: Option<PublicKey>, exclude_static_outputs: bool,
+ delay_until_height: Option<u32>,
) -> Result<(), ()> {
let mut fut = pin!(self.sweeper.track_spendable_outputs(
output_descriptors,
channel_id,
+ counterparty_node_id,
exclude_static_outputs,
delay_until_height,
));
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.