Skip to content

Commit aa4718b

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 a0e1d78 commit aa4718b

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();
@@ -10279,6 +10298,28 @@ impl<SP: Deref> FundedChannel<SP> where
1027910298
pub fn has_pending_splice(&self) -> bool {
1028010299
self.pending_splice.is_some()
1028110300
}
10301+
10302+
pub fn remove_legacy_scids_before_block(&mut self, height: u32) -> alloc::vec::Drain<u64> {
10303+
let end = self.funding
10304+
.get_short_channel_id()
10305+
.and_then(|current_scid| {
10306+
let historical_scids = &self.context.historical_scids;
10307+
historical_scids
10308+
.iter()
10309+
.zip(historical_scids.iter().skip(1).chain(core::iter::once(&current_scid)))
10310+
.map(|(_, next_scid)| {
10311+
let funding_height = block_from_scid(*next_scid);
10312+
let retain_scid = funding_height + CHANNEL_ANNOUNCEMENT_PROPAGATION_DELAY - 1 > height;
10313+
retain_scid
10314+
})
10315+
.position(|retain_scid| retain_scid)
10316+
})
10317+
.unwrap_or(0);
10318+
10319+
// Drains the oldest historical SCIDs until reaching one without
10320+
// CHANNEL_ANNOUNCEMENT_PROPAGATION_DELAY confirmations.
10321+
self.context.historical_scids.drain(0..end)
10322+
}
1028210323
}
1028310324

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

1166211704
Ok(())
@@ -11972,6 +12014,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1197212014
let mut is_manual_broadcast = None;
1197312015

1197412016
let mut pending_funding = Some(Vec::new());
12017+
let mut historical_scids = Some(Vec::new());
1197512018

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

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

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

1229412339
funding_tx_broadcast_safe_event_emitted: funding_tx_broadcast_safe_event_emitted.unwrap_or(false),
1229512340
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

@@ -11957,6 +11960,18 @@ where
1195711960
channel.check_for_stale_feerate(&logger, feerate)?;
1195811961
}
1195911962
}
11963+
11964+
// Remove any SCIDs used by older funding transactions
11965+
{
11966+
let legacy_scids = channel.remove_legacy_scids_before_block(height);
11967+
if !legacy_scids.as_slice().is_empty() {
11968+
let mut short_to_chan_info = self.short_to_chan_info.write().unwrap();
11969+
for scid in legacy_scids {
11970+
short_to_chan_info.remove(&scid);
11971+
}
11972+
}
11973+
}
11974+
1196011975
channel.best_block_updated(height, header.time, self.chain_hash, &self.node_signer, &self.default_configuration, &&WithChannelContext::from(&self.logger, &channel.context, None))
1196111976
});
1196211977

@@ -14332,6 +14347,11 @@ where
1433214347
if let Some(short_channel_id) = channel.funding.get_short_channel_id() {
1433314348
short_to_chan_info.insert(short_channel_id, (channel.context.get_counterparty_node_id(), channel.context.channel_id()));
1433414349
}
14350+
14351+
for short_channel_id in channel.context.historical_scids() {
14352+
short_to_chan_info.insert(*short_channel_id, (channel.context.get_counterparty_node_id(), channel.context.channel_id()));
14353+
}
14354+
1433514355
per_peer_state.entry(channel.context.get_counterparty_node_id())
1433614356
.or_insert_with(|| Mutex::new(empty_peer_state()))
1433714357
.get_mut().unwrap()

0 commit comments

Comments
 (0)