What changed, and why it matters
This commit adds a new notification event called SplicePending to the Lightning Dev Kit library. It simply tells users when a splice (a way to resize a Lightning channel) has been negotiated and its funding transaction has been broadcast. There is no security fix or vulnerability here—this is a routine feature addition.
No security action needed. Treat as a normal feature/API addition.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces Event::SplicePending in lightning/src/events/mod.rs, including its enum variant, documentation, serialization (Writeable impl with type tag 50u8 and TLV fields), and deserialization (MaybeReadable impl). It is purely additive and exposes state information to event consumers. No logic changes affect channel security, transaction handling, or cryptographic operations.
Changed components
lightning/src/events/mod.rsInspect captured patch +67 / −0
diff --git a/lightning/src/events/mod.rs b/lightning/src/events/mod.rs
index d7a13d5..25669e2 100644
--- a/lightning/src/events/mod.rs
+++ b/lightning/src/events/mod.rs
@@ -1502,6 +1502,37 @@ pub enum Event {
/// [`ChainMonitor::get_claimable_balances`]: crate::chain::chainmonitor::ChainMonitor::get_claimable_balances
last_local_balance_msat: Option<u64>,
},
+ /// Used to indicate that a splice for the given `channel_id` has been negotiated and its
+ /// funding transaction has been broadcast.
+ ///
+ /// The splice is then considered pending until both parties have seen enough confirmations to
+ /// consider the funding locked. Once this occurs, an [`Event::ChannelReady`] will be emitted.
+ ///
+ /// Any UTXOs spent by the splice cannot be reused except by an RBF attempt for the same channel.
+ ///
+ /// # Failure Behavior and Persistence
+ /// This event will eventually be replayed after failures-to-handle (i.e., the event handler
+ /// returning `Err(ReplayEvent ())`) and will be persisted across restarts.
+ SplicePending {
+ /// The `channel_id` of the channel that has a pending splice funding transaction.
+ channel_id: ChannelId,
+ /// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound
+ /// channels, or to [`ChannelManager::accept_inbound_channel`] for inbound channels if
+ /// [`UserConfig::manually_accept_inbound_channels`] config flag is set to true. Otherwise
+ /// `user_channel_id` will be randomized for an inbound channel.
+ ///
+ /// [`ChannelManager::create_channel`]: crate::ln::channelmanager::ChannelManager::create_channel
+ /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel
+ /// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels
+ user_channel_id: u128,
+ /// The `node_id` of the channel counterparty.
+ counterparty_node_id: PublicKey,
+ /// The outpoint of the channel's splice funding transaction.
+ new_funding_txo: OutPoint,
+ /// The features that this channel will operate with. Currently, these will be the same
+ /// features that the channel was opened with, but in the future splices may change them.
+ channel_type: ChannelTypeFeatures,
+ },
/// Used to indicate to the user that they can abandon the funding transaction and recycle the
/// inputs for another purpose.
///
@@ -2228,6 +2259,22 @@ impl Writeable for Event {
// We never write out FundingTransactionReadyForSigning events as they will be regenerated when
// necessary.
},
+ &Event::SplicePending {
+ ref channel_id,
+ ref user_channel_id,
+ ref counterparty_node_id,
+ ref new_funding_txo,
+ ref channel_type,
+ } => {
+ 50u8.write(writer)?;
+ write_tlv_fields!(writer, {
+ (1, channel_id, required),
+ (3, channel_type, required),
+ (5, user_channel_id, required),
+ (7, counterparty_node_id, required),
+ (9, new_funding_txo, required),
+ });
+ },
// Note that, going forward, all new events must only write data inside of
// `write_tlv_fields`. Versions 0.0.101+ will ignore odd-numbered events that write
// data via `write_tlv_fields`.
@@ -2810,6 +2857,26 @@ impl MaybeReadable for Event {
47u8 => Ok(None),
// Note that we do not write a length-prefixed TLV for FundingTransactionReadyForSigning events.
49u8 => Ok(None),
+ 50u8 => {
+ let mut f = || {
+ _init_and_read_len_prefixed_tlv_fields!(reader, {
+ (1, channel_id, required),
+ (3, channel_type, required),
+ (5, user_channel_id, required),
+ (7, counterparty_node_id, required),
+ (9, new_funding_txo, required),
+ });
+
+ Ok(Some(Event::SplicePending {
+ channel_id: channel_id.0.unwrap(),
+ user_channel_id: user_channel_id.0.unwrap(),
+ counterparty_node_id: counterparty_node_id.0.unwrap(),
+ new_funding_txo: new_funding_txo.0.unwrap(),
+ channel_type: channel_type.0.unwrap(),
+ }))
+ };
+ f()
+ },
// Versions prior to 0.0.100 did not ignore odd types, instead returning InvalidValue.
// Version 0.0.100 failed to properly ignore odd types, possibly resulting in corrupt
// reads.
Why this scored 15/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.