Skip to content

Commit 2c9f80b

Browse files
Gather to-decode HTLC fwds from channels on manager read
We have an overarching goal of (mostly) getting rid of ChannelManager persistence and rebuilding the ChannelManager's state from existing ChannelMonitors, due to issues when the two structs are out-of-sync on restart. The main issue that can arise is channel force closure. Here we start this process by rebuilding ChannelManager::decode_update_add_htlcs from the Channels, which will soon be included in the ChannelMonitors as part of a different series of PRs. The newly built map is not yet used but will be in the next commit.
1 parent e8d0711 commit 2c9f80b

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

lightning/src/ln/channel.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7773,6 +7773,20 @@ where
77737773
Ok(())
77747774
}
77757775

7776+
/// Useful for reconstructing forwarded HTLCs when deserializing the `ChannelManager`.
7777+
pub(super) fn get_inbound_committed_update_adds(&self) -> Vec<msgs::UpdateAddHTLC> {
7778+
self.context
7779+
.pending_inbound_htlcs
7780+
.iter()
7781+
.filter_map(|htlc| match htlc.state {
7782+
InboundHTLCState::Committed { ref update_add_htlc_opt } => {
7783+
update_add_htlc_opt.clone()
7784+
},
7785+
_ => None,
7786+
})
7787+
.collect()
7788+
}
7789+
77767790
/// Marks an outbound HTLC which we have received update_fail/fulfill/malformed
77777791
#[inline]
77787792
fn mark_outbound_htlc_removed(

lightning/src/ln/channelmanager.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17353,6 +17353,7 @@ where
1735317353
decode_update_add_htlcs_legacy.unwrap_or_else(|| new_hash_map());
1735417354
let mut pending_intercepted_htlcs_legacy =
1735517355
pending_intercepted_htlcs_legacy.unwrap_or_else(|| new_hash_map());
17356+
let mut decode_update_add_htlcs = new_hash_map();
1735617357
let peer_storage_dir: Vec<(PublicKey, Vec<u8>)> = peer_storage_dir.unwrap_or_else(Vec::new);
1735717358
if fake_scid_rand_bytes.is_none() {
1735817359
fake_scid_rand_bytes = Some(args.entropy_source.get_secure_random_bytes());
@@ -17664,6 +17665,21 @@ where
1766417665
let mut peer_state_lock = peer_state_mtx.lock().unwrap();
1766517666
let peer_state = &mut *peer_state_lock;
1766617667
is_channel_closed = !peer_state.channel_by_id.contains_key(channel_id);
17668+
if let Some(chan) = peer_state.channel_by_id.get(channel_id) {
17669+
if let Some(funded_chan) = chan.as_funded() {
17670+
let inbound_committed_update_adds =
17671+
funded_chan.get_inbound_committed_update_adds();
17672+
if !inbound_committed_update_adds.is_empty() {
17673+
// Reconstruct `ChannelManager::decode_update_add_htlcs` from the serialized
17674+
// `Channel`. We are moving away from writing the `decode_update_add_htlcs` map as
17675+
// part of getting rid of `ChannelManager` persistence.
17676+
decode_update_add_htlcs.insert(
17677+
funded_chan.context.outbound_scid_alias(),
17678+
inbound_committed_update_adds,
17679+
);
17680+
}
17681+
}
17682+
}
1766717683
}
1766817684

1766917685
if is_channel_closed {
@@ -17725,6 +17741,12 @@ where
1772517741
// still have an entry for this HTLC in `forward_htlcs` or
1772617742
// `pending_intercepted_htlcs`, we were apparently not persisted after
1772717743
// the monitor was when forwarding the payment.
17744+
dedup_decode_update_add_htlcs(
17745+
&mut decode_update_add_htlcs,
17746+
&prev_hop_data,
17747+
"HTLC was forwarded to the closed channel",
17748+
&args.logger,
17749+
);
1772817750
dedup_decode_update_add_htlcs(
1772917751
&mut decode_update_add_htlcs_legacy,
1773017752
&prev_hop_data,
@@ -18215,6 +18237,28 @@ where
1821518237
}
1821618238
}
1821718239

18240+
for (src, _, _, _, _, _) in failed_htlcs.iter() {
18241+
if let HTLCSource::PreviousHopData(prev_hop_data) = src {
18242+
dedup_decode_update_add_htlcs(
18243+
&mut decode_update_add_htlcs,
18244+
prev_hop_data,
18245+
"HTLC was failed backwards during manager read",
18246+
&args.logger,
18247+
);
18248+
}
18249+
}
18250+
18251+
for htlcs in claimable_payments.values().map(|pmt| &pmt.htlcs) {
18252+
for prev_hop_data in htlcs.iter().map(|h| &h.prev_hop) {
18253+
dedup_decode_update_add_htlcs(
18254+
&mut decode_update_add_htlcs,
18255+
prev_hop_data,
18256+
"HTLC was already decoded and marked as a claimable payment",
18257+
&args.logger,
18258+
);
18259+
}
18260+
}
18261+
1821818262
let best_block = BestBlock::new(best_block_hash, best_block_height);
1821918263
let flow = OffersMessageFlow::new(
1822018264
chain_hash,

0 commit comments

Comments
 (0)