Skip to content

Commit 583b2b0

Browse files
committed
Make ChannelClosed persistence idempotent and retry on failure
Fall back to the already-persisted record for is_outbound/is_announced when in-memory sets are empty on replay, use insert_or_update to avoid overwriting correct values, and propagate persist failures as ReplayEvent.
1 parent 1960f50 commit 583b2b0

1 file changed

Lines changed: 16 additions & 3 deletions

File tree

src/event.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1643,17 +1643,27 @@ where
16431643
log_info!(self.logger, "Channel {} closed due to: {}", channel_id, reason);
16441644

16451645
let user_channel_id = UserChannelId(user_channel_id);
1646-
let is_outbound = self
1646+
let is_outbound_from_set = self
16471647
.outbound_channel_ids
16481648
.lock()
16491649
.expect("Lock poisoned")
16501650
.remove(&user_channel_id);
1651-
let is_announced = self
1651+
let is_announced_from_set = self
16521652
.announced_channel_ids
16531653
.lock()
16541654
.expect("Lock poisoned")
16551655
.remove(&user_channel_id);
16561656

1657+
// On replay (after a restart or after handle_event returns ReplayEvent),
1658+
// the channel is no longer in list_channels() and the in-memory sets are
1659+
// not repopulated for it, so .remove() returns false. Fall back to any
1660+
// already-persisted record so we don't overwrite correct values with false.
1661+
let (is_outbound, is_announced) = self
1662+
.closed_channel_store
1663+
.get(&user_channel_id)
1664+
.map(|existing| (existing.is_outbound, existing.is_announced))
1665+
.unwrap_or((is_outbound_from_set, is_announced_from_set));
1666+
16571667
let closed_at = SystemTime::now()
16581668
.duration_since(UNIX_EPOCH)
16591669
.unwrap_or(Duration::ZERO)
@@ -1675,19 +1685,22 @@ where
16751685
closed_at,
16761686
};
16771687

1678-
if let Err(e) = self.closed_channel_store.insert(record) {
1688+
if let Err(e) = self.closed_channel_store.insert_or_update(record) {
16791689
log_error!(
16801690
self.logger,
16811691
"Failed to persist closed channel {}: {}",
16821692
channel_id,
16831693
e
16841694
);
1695+
return Err(ReplayEvent());
16851696
}
16861697

16871698
let event = Event::ChannelClosed {
16881699
channel_id,
16891700
user_channel_id,
16901701
counterparty_node_id: counterparty_node_id
1702+
// Since LDK Node v0.2 this is expected to always be set. See
1703+
// CHANGELOG.md for details on the serialization compatibility break.
16911704
.expect("counterparty_node_id must be set for closed channels"),
16921705
reason: Some(reason),
16931706
channel_capacity_sats,

0 commit comments

Comments
 (0)