Skip to content

Commit 5e3e347

Browse files
Don't persist inbound committed onions in prod
A few PRs ago, we started persisting inbound committed HTLC onions in Channels. These onions were persisted to lay groundwork for reconstructing the ChannelManager's pending HTLC maps from them in a future version. However, we've since discovered a different direction where we can instead reconstruct these same maps using persistent monitor events, which may mean that we don't need to persist these onions. Since persisting a bunch of onions on every manager write is a big commitment that we're not fully confident in yet, switch it off for now until we either confirm the monitor events direction and can delete all this onion persisting code OR realize that we definitely do need it.
1 parent 4cbd074 commit 5e3e347

3 files changed

Lines changed: 23 additions & 22 deletions

File tree

lightning-tests/src/upgrade_downgrade_tests.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -540,11 +540,10 @@ fn upgrade_mid_htlc_intercept_forward() {
540540
}
541541

542542
fn do_upgrade_mid_htlc_forward(test: MidHtlcForwardCase) {
543-
// In 0.3, we started reconstructing the `ChannelManager`'s HTLC forwards maps from the HTLCs
544-
// contained in `Channel`s, as part of removing the requirement to regularly persist the
545-
// `ChannelManager`. However, HTLC forwards can only be reconstructed this way if they were
546-
// received on 0.3 or higher. Test that HTLC forwards that were serialized on <=0.2 will still
547-
// succeed when read on 0.3+.
543+
// In an upcoming version, we plan to start reconstructing the `ChannelManager`'s HTLC forwards
544+
// maps from the HTLCs contained in `Channel`s, as part of removing the requirement to regularly
545+
// persist the `ChannelManager`. Preemptively test that HTLC forwards that were serialized on
546+
// <=0.2 will still succeed when read on this upcoming version.
548547
let (node_a_ser, node_b_ser, node_c_ser, mon_a_1_ser, mon_b_1_ser, mon_b_2_ser, mon_c_1_ser);
549548
let (node_a_id, node_b_id, node_c_id);
550549
let (payment_secret_bytes, payment_hash_bytes, payment_preimage_bytes);

lightning/src/ln/channel.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,7 @@ enum InboundUpdateAdd {
368368
blinded_failure: Option<BlindedFailure>,
369369
outbound_hop: OutboundHop,
370370
},
371-
/// This HTLC was received pre-LDK 0.3, before we started persisting the onion for inbound
372-
/// committed HTLCs.
371+
/// This HTLC was received before we started persisting the onion for inbound committed HTLCs.
373372
Legacy,
374373
}
375374

@@ -7982,8 +7981,9 @@ where
79827981
Ok(())
79837982
}
79847983

7985-
/// Returns true if any committed inbound HTLCs were received pre-LDK 0.3 and cannot be used
7986-
/// during `ChannelManager` deserialization to reconstruct the set of pending HTLCs.
7984+
/// Returns true if any committed inbound HTLCs were received before we started serializing
7985+
/// inbound committed payment onions in `Channel` and cannot be used during `ChannelManager`
7986+
/// deserialization to reconstruct the set of pending HTLCs.
79877987
pub(super) fn has_legacy_inbound_htlcs(&self) -> bool {
79887988
self.context.pending_inbound_htlcs.iter().any(|htlc| {
79897989
matches!(
@@ -15570,6 +15570,7 @@ impl<SP: SignerProvider> Writeable for FundedChannel<SP> {
1557015570
}
1557115571
}
1557215572
let mut removed_htlc_attribution_data: Vec<&Option<AttributionData>> = Vec::new();
15573+
#[cfg_attr(not(test), allow(unused_mut))]
1557315574
let mut inbound_committed_update_adds: Vec<&InboundUpdateAdd> = Vec::new();
1557415575
(self.context.pending_inbound_htlcs.len() as u64 - dropped_inbound_htlcs).write(writer)?;
1557515576
for htlc in self.context.pending_inbound_htlcs.iter() {
@@ -15590,9 +15591,10 @@ impl<SP: SignerProvider> Writeable for FundedChannel<SP> {
1559015591
2u8.write(writer)?;
1559115592
htlc_resolution.write(writer)?;
1559215593
},
15593-
&InboundHTLCState::Committed { ref update_add_htlc } => {
15594+
&InboundHTLCState::Committed { update_add_htlc: ref _update_add } => {
1559415595
3u8.write(writer)?;
15595-
inbound_committed_update_adds.push(update_add_htlc);
15596+
#[cfg(test)]
15597+
inbound_committed_update_adds.push(_update_add);
1559615598
},
1559715599
&InboundHTLCState::LocalRemoved(ref removal_reason) => {
1559815600
4u8.write(writer)?;

lightning/src/ln/channelmanager.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17600,16 +17600,16 @@ pub fn provided_init_features(config: &UserConfig) -> InitFeatures {
1760017600
const SERIALIZATION_VERSION: u8 = 1;
1760117601
const MIN_SERIALIZATION_VERSION: u8 = 1;
1760217602

17603-
// We plan to start writing this version in 0.5.
17603+
// We plan to start writing this version a few versions after we start writing inbound committed
17604+
// payment onions in `Channel`, which is already done in tests but not yet switched on in prod.
1760417605
//
17605-
// LDK 0.5+ will reconstruct the set of pending HTLCs from `Channel{Monitor}` data that started
17606-
// being written in 0.3, ignoring legacy `ChannelManager` HTLC maps on read and not writing them.
17607-
// LDK 0.5+ will automatically fail to read if the pending HTLC set cannot be reconstructed, i.e.
17608-
// if we were last written with pending HTLCs on 0.2- or if the new 0.3+ fields are missing.
17606+
// If we see this version on read, we will use said onions when reconstructing the set of pending
17607+
// HTLCs, ignoring legacy `ChannelManager` HTLC maps on read and not writing them. We'll also
17608+
// automatically fail to read if the pending HTLC set cannot be reconstructed, i.e. if the new
17609+
// payment onion field is missing.
1760917610
//
17610-
// If 0.3 or 0.4 reads this manager version, it knows that the legacy maps were not written and
17611-
// acts accordingly.
17612-
const RECONSTRUCT_HTLCS_FROM_CHANS_VERSION: u8 = 2;
17611+
// Left as `None` for now until we are committed to writing inbound committed onions in `Channel`s.
17612+
const RECONSTRUCT_HTLCS_FROM_CHANS_VERSION: Option<u8> = None;
1761317613

1761417614
impl_writeable_tlv_based!(PhantomRouteHints, {
1761517615
(2, channels, required_vec),
@@ -18435,7 +18435,7 @@ impl<'a, ES: EntropySource, SP: SignerProvider, L: Logger>
1843518435
}
1843618436

1843718437
let forward_htlcs_legacy: HashMap<u64, Vec<HTLCForwardInfo>> =
18438-
if version < RECONSTRUCT_HTLCS_FROM_CHANS_VERSION {
18438+
if RECONSTRUCT_HTLCS_FROM_CHANS_VERSION.map_or(true, |v| version < v) {
1843918439
let forward_htlcs_count: u64 = Readable::read(reader)?;
1844018440
let mut fwds = hash_map_with_capacity(cmp::min(forward_htlcs_count as usize, 128));
1844118441
for _ in 0..forward_htlcs_count {
@@ -19573,7 +19573,8 @@ impl<
1957319573
// `reconstruct_manager_from_monitors` is set below. Currently we set in tests randomly to
1957419574
// ensure the legacy codepaths also have test coverage.
1957519575
#[cfg(not(test))]
19576-
let reconstruct_manager_from_monitors = _version >= RECONSTRUCT_HTLCS_FROM_CHANS_VERSION;
19576+
let reconstruct_manager_from_monitors =
19577+
RECONSTRUCT_HTLCS_FROM_CHANS_VERSION.map_or(false, |v| _version >= v);
1957719578
#[cfg(test)]
1957819579
let reconstruct_manager_from_monitors =
1957919580
args.reconstruct_manager_from_monitors.unwrap_or_else(|| {
@@ -19636,7 +19637,6 @@ impl<
1963619637
if reconstruct_manager_from_monitors {
1963719638
if let Some(chan) = peer_state.channel_by_id.get(channel_id) {
1963819639
if let Some(funded_chan) = chan.as_funded() {
19639-
// Legacy HTLCs are from pre-LDK 0.3 and cannot be reconstructed.
1964019640
if funded_chan.has_legacy_inbound_htlcs() {
1964119641
return Err(DecodeError::InvalidValue);
1964219642
}

0 commit comments

Comments
 (0)