Skip to content

Commit 8c6e969

Browse files
committed
Track historical SCIDs from previous funding
When a splice is locked, the SCID from the previous funding transaction needs to be remembered so that pending HTLCs can be handled properly. Additionally, when they need to be cleaned up once they should no longer be used. Track these SCIDs as splices are locked and clean any up as blocks are connected.
1 parent 97f2122 commit 8c6e969

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

lightning/src/ln/channel.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ use crate::util::ser::{Readable, ReadableArgs, RequiredWrapper, TransactionU16Le
6666
use crate::util::logger::{Logger, Record, WithContext};
6767
use crate::util::errors::APIError;
6868
use crate::util::config::{UserConfig, ChannelConfig, LegacyChannelConfig, ChannelHandshakeConfig, ChannelHandshakeLimits, MaxDustHTLCExposure};
69-
use crate::util::scid_utils::scid_from_parts;
69+
use crate::util::scid_utils::{block_from_scid, scid_from_parts};
7070

7171
use alloc::collections::{btree_map, BTreeMap};
7272

@@ -1303,6 +1303,11 @@ pub(crate) const UNFUNDED_CHANNEL_AGE_LIMIT_TICKS: usize = 60;
13031303
/// Number of blocks needed for an output from a coinbase transaction to be spendable.
13041304
pub(crate) const COINBASE_MATURITY: u32 = 100;
13051305

1306+
/// The number of blocks to wait for a channel_announcement to propagate such that payments using an
1307+
/// older SCID can still be relayed. Once the spend of the previous funding transaction has reached
1308+
/// this number of confirmations, the corresponding SCID will be forgotten.
1309+
const CHANNEL_ANNOUNCEMENT_PROPAGATION_DELAY: u32 = 12;
1310+
13061311
struct PendingChannelMonitorUpdate {
13071312
update: ChannelMonitorUpdate,
13081313
}
@@ -2280,6 +2285,10 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
22802285
// blinded paths instead of simple scid+node_id aliases.
22812286
outbound_scid_alias: u64,
22822287

2288+
/// Short channel ids used by any prior FundingScope. These are maintained such that
2289+
/// ChannelManager can look up the channel for any pending HTLCs.
2290+
historical_scids: Vec<u64>,
2291+
22832292
// We track whether we already emitted a `ChannelPending` event.
22842293
channel_pending_event_emitted: bool,
22852294

@@ -3097,6 +3106,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
30973106

30983107
latest_inbound_scid_alias: None,
30993108
outbound_scid_alias: 0,
3109+
historical_scids: Vec::new(),
31003110

31013111
channel_pending_event_emitted: false,
31023112
funding_tx_broadcast_safe_event_emitted: false,
@@ -3338,6 +3348,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
33383348

33393349
latest_inbound_scid_alias: None,
33403350
outbound_scid_alias,
3351+
historical_scids: Vec::new(),
33413352

33423353
channel_pending_event_emitted: false,
33433354
funding_tx_broadcast_safe_event_emitted: false,
@@ -5392,6 +5403,11 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
53925403

53935404
Ok(())
53945405
}
5406+
5407+
/// Returns SCIDs that have been associated with the channel's funding transactions.
5408+
pub fn historical_scids(&self) -> &[u64] {
5409+
&self.historical_scids[..]
5410+
}
53955411
}
53965412

53975413
// Internal utility functions for channels
@@ -5579,6 +5595,9 @@ pub(super) struct FundedChannel<SP: Deref> where SP::Target: SignerProvider {
55795595
#[cfg(splicing)]
55805596
macro_rules! promote_splice_funding {
55815597
($self: expr, $funding: expr) => {
5598+
if let Some(scid) = $self.funding.short_channel_id {
5599+
$self.context.historical_scids.push(scid);
5600+
}
55825601
core::mem::swap(&mut $self.funding, $funding);
55835602
$self.pending_splice = None;
55845603
$self.pending_funding.clear();
@@ -10280,6 +10299,28 @@ impl<SP: Deref> FundedChannel<SP> where
1028010299
pub fn has_pending_splice(&self) -> bool {
1028110300
self.pending_splice.is_some()
1028210301
}
10302+
10303+
pub fn remove_legacy_scids_before_block(&mut self, height: u32) -> alloc::vec::Drain<u64> {
10304+
let end = self.funding
10305+
.get_short_channel_id()
10306+
.and_then(|current_scid| {
10307+
let historical_scids = &self.context.historical_scids;
10308+
historical_scids
10309+
.iter()
10310+
.zip(historical_scids.iter().skip(1).chain(core::iter::once(&current_scid)))
10311+
.map(|(_, next_scid)| {
10312+
let funding_height = block_from_scid(*next_scid);
10313+
let retain_scid = funding_height + CHANNEL_ANNOUNCEMENT_PROPAGATION_DELAY - 1 > height;
10314+
retain_scid
10315+
})
10316+
.position(|retain_scid| retain_scid)
10317+
})
10318+
.unwrap_or(0);
10319+
10320+
// Drains the oldest historical SCIDs until reaching one without
10321+
// CHANNEL_ANNOUNCEMENT_PROPAGATION_DELAY confirmations.
10322+
self.context.historical_scids.drain(0..end)
10323+
}
1028310324
}
1028410325

1028510326
/// A not-yet-funded outbound (from holder) channel using V1 channel establishment.
@@ -11658,6 +11699,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1165811699
(57, holding_cell_failure_attribution_data, optional_vec), // Added in 0.2
1165911700
(58, self.interactive_tx_signing_session, option), // Added in 0.2
1166011701
(59, self.funding.minimum_depth_override, option), // Added in 0.2
11702+
(60, self.context.historical_scids, optional_vec), // Added in 0.2
1166111703
});
1166211704

1166311705
Ok(())
@@ -11973,6 +12015,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1197312015
let mut is_manual_broadcast = None;
1197412016

1197512017
let mut pending_funding = Some(Vec::new());
12018+
let mut historical_scids = Some(Vec::new());
1197612019

1197712020
let mut interactive_tx_signing_session: Option<InteractiveTxSigningSession> = None;
1197812021

@@ -12018,6 +12061,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1201812061
(57, holding_cell_failure_attribution_data, optional_vec),
1201912062
(58, interactive_tx_signing_session, option), // Added in 0.2
1202012063
(59, minimum_depth_override, option), // Added in 0.2
12064+
(60, historical_scids, optional_vec), // Added in 0.2
1202112065
});
1202212066

1202312067
let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -12291,6 +12335,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1229112335
latest_inbound_scid_alias,
1229212336
// Later in the ChannelManager deserialization phase we scan for channels and assign scid aliases if its missing
1229312337
outbound_scid_alias,
12338+
historical_scids: historical_scids.unwrap(),
1229412339

1229512340
funding_tx_broadcast_safe_event_emitted: funding_tx_broadcast_safe_event_emitted.unwrap_or(false),
1229612341
channel_pending_event_emitted: channel_pending_event_emitted.unwrap_or(true),

lightning/src/ln/channelmanager.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3172,6 +3172,9 @@ macro_rules! locked_close_channel {
31723172
debug_assert!(alias_removed);
31733173
}
31743174
short_to_chan_info.remove(&$channel_context.outbound_scid_alias());
3175+
for scid in $channel_context.historical_scids() {
3176+
short_to_chan_info.remove(scid);
3177+
}
31753178
}}
31763179
}
31773180

@@ -11964,6 +11967,18 @@ where
1196411967
channel.check_for_stale_feerate(&logger, feerate)?;
1196511968
}
1196611969
}
11970+
11971+
// Remove any SCIDs used by older funding transactions
11972+
{
11973+
let legacy_scids = channel.remove_legacy_scids_before_block(height);
11974+
if !legacy_scids.as_slice().is_empty() {
11975+
let mut short_to_chan_info = self.short_to_chan_info.write().unwrap();
11976+
for scid in legacy_scids {
11977+
short_to_chan_info.remove(&scid);
11978+
}
11979+
}
11980+
}
11981+
1196711982
channel.best_block_updated(height, header.time, self.chain_hash, &self.node_signer, &self.default_configuration, &&WithChannelContext::from(&self.logger, &channel.context, None))
1196811983
});
1196911984

@@ -14339,6 +14354,11 @@ where
1433914354
if let Some(short_channel_id) = channel.funding.get_short_channel_id() {
1434014355
short_to_chan_info.insert(short_channel_id, (channel.context.get_counterparty_node_id(), channel.context.channel_id()));
1434114356
}
14357+
14358+
for short_channel_id in channel.context.historical_scids() {
14359+
short_to_chan_info.insert(*short_channel_id, (channel.context.get_counterparty_node_id(), channel.context.channel_id()));
14360+
}
14361+
1434214362
per_peer_state.entry(channel.context.get_counterparty_node_id())
1434314363
.or_insert_with(|| Mutex::new(empty_peer_state()))
1434414364
.get_mut().unwrap()

0 commit comments

Comments
 (0)