Skip to content

Commit de73ddc

Browse files
committed
Periodically archive fully-resolved channel monitors
Previously, LDK was very conservative and kept channel monitors around ~forever or until the user manually decided to prune them. Recently it introduced the `ChainMonitor::archive_fully_resolved_monitors` method, which we now call periodically: every time a wallet sync succeeds, we check whether the latest archival height is 6 blocks in the past and call `archive_fully_resolved_monitors`. As this is not permanently persisted, we will always try to archive any pruned monitors when the first background sync after fresh initialization succeeds, ensuring we call it regularly also on short-lived sessions, e.g, on mobile.
1 parent 2562f52 commit de73ddc

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

src/builder.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,7 @@ fn build_with_store_internal(
979979
let latest_fee_rate_cache_update_timestamp = Arc::new(RwLock::new(None));
980980
let latest_rgs_snapshot_timestamp = Arc::new(RwLock::new(None));
981981
let latest_node_announcement_broadcast_timestamp = Arc::new(RwLock::new(None));
982+
let latest_channel_monitor_archival_height = Arc::new(RwLock::new(None));
982983

983984
Ok(Node {
984985
runtime,
@@ -1010,6 +1011,7 @@ fn build_with_store_internal(
10101011
latest_fee_rate_cache_update_timestamp,
10111012
latest_rgs_snapshot_timestamp,
10121013
latest_node_announcement_broadcast_timestamp,
1014+
latest_channel_monitor_archival_height,
10131015
})
10141016
}
10151017

src/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ pub(crate) const DEFAULT_ESPLORA_SERVER_URL: &str = "https://blockstream.info/ap
3030
// The timeout after which we abandon retrying failed payments.
3131
pub(crate) const LDK_PAYMENT_RETRY_TIMEOUT: Duration = Duration::from_secs(10);
3232

33+
// The interval (in block height) after which we retry archiving fully resolved channel monitors.
34+
pub(crate) const LDK_CHANNEL_MONITOR_ARCHIVAL_INTERVAL: u32 = 6;
35+
3336
// The time in-between peer reconnection attempts.
3437
pub(crate) const PEER_RECONNECTION_INTERVAL: Duration = Duration::from_secs(10);
3538

src/lib.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ pub use builder::BuildError;
122122
pub use builder::NodeBuilder as Builder;
123123

124124
use config::{
125-
NODE_ANN_BCAST_INTERVAL, PEER_RECONNECTION_INTERVAL, RGS_SYNC_INTERVAL,
126-
WALLET_SYNC_INTERVAL_MINIMUM_SECS,
125+
LDK_CHANNEL_MONITOR_ARCHIVAL_INTERVAL, NODE_ANN_BCAST_INTERVAL, PEER_RECONNECTION_INTERVAL,
126+
RGS_SYNC_INTERVAL, WALLET_SYNC_INTERVAL_MINIMUM_SECS,
127127
};
128128
use connection::ConnectionManager;
129129
use event::{EventHandler, EventQueue};
@@ -198,6 +198,7 @@ pub struct Node {
198198
latest_fee_rate_cache_update_timestamp: Arc<RwLock<Option<u64>>>,
199199
latest_rgs_snapshot_timestamp: Arc<RwLock<Option<u64>>>,
200200
latest_node_announcement_broadcast_timestamp: Arc<RwLock<Option<u64>>>,
201+
latest_channel_monitor_archival_height: Arc<RwLock<Option<u32>>>,
201202
}
202203

203204
impl Node {
@@ -343,10 +344,13 @@ impl Node {
343344

344345
let tx_sync = Arc::clone(&self.tx_sync);
345346
let sync_cman = Arc::clone(&self.channel_manager);
347+
let archive_cman = Arc::clone(&self.channel_manager);
346348
let sync_cmon = Arc::clone(&self.chain_monitor);
349+
let archive_cmon = Arc::clone(&self.chain_monitor);
347350
let sync_sweeper = Arc::clone(&self.output_sweeper);
348351
let sync_logger = Arc::clone(&self.logger);
349352
let sync_wallet_timestamp = Arc::clone(&self.latest_wallet_sync_timestamp);
353+
let sync_monitor_archival_height = Arc::clone(&self.latest_channel_monitor_archival_height);
350354
let mut stop_sync = self.stop_sender.subscribe();
351355
let wallet_sync_interval_secs =
352356
self.config.wallet_sync_interval_secs.max(WALLET_SYNC_INTERVAL_MINIMUM_SECS);
@@ -376,6 +380,12 @@ impl Node {
376380
let unix_time_secs_opt =
377381
SystemTime::now().duration_since(UNIX_EPOCH).ok().map(|d| d.as_secs());
378382
*sync_wallet_timestamp.write().unwrap() = unix_time_secs_opt;
383+
384+
periodically_archive_fully_resolved_monitors(
385+
Arc::clone(&archive_cman),
386+
Arc::clone(&archive_cmon),
387+
Arc::clone(&sync_monitor_archival_height)
388+
);
379389
}
380390
Err(e) => {
381391
log_error!(sync_logger, "Background sync of Lightning wallet failed: {}", e)
@@ -1128,14 +1138,17 @@ impl Node {
11281138
let wallet = Arc::clone(&self.wallet);
11291139
let tx_sync = Arc::clone(&self.tx_sync);
11301140
let sync_cman = Arc::clone(&self.channel_manager);
1141+
let archive_cman = Arc::clone(&self.channel_manager);
11311142
let sync_cmon = Arc::clone(&self.chain_monitor);
1143+
let archive_cmon = Arc::clone(&self.chain_monitor);
11321144
let sync_sweeper = Arc::clone(&self.output_sweeper);
11331145
let sync_logger = Arc::clone(&self.logger);
11341146
let confirmables = vec![
11351147
&*sync_cman as &(dyn Confirm + Sync + Send),
11361148
&*sync_cmon as &(dyn Confirm + Sync + Send),
11371149
&*sync_sweeper as &(dyn Confirm + Sync + Send),
11381150
];
1151+
let sync_monitor_archival_height = Arc::clone(&self.latest_channel_monitor_archival_height);
11391152

11401153
tokio::task::block_in_place(move || {
11411154
tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap().block_on(
@@ -1163,6 +1176,12 @@ impl Node {
11631176
"Sync of Lightning wallet finished in {}ms.",
11641177
now.elapsed().as_millis()
11651178
);
1179+
1180+
periodically_archive_fully_resolved_monitors(
1181+
archive_cman,
1182+
archive_cmon,
1183+
sync_monitor_archival_height,
1184+
);
11661185
Ok(())
11671186
},
11681187
Err(e) => {
@@ -1486,3 +1505,19 @@ pub(crate) fn total_anchor_channels_reserve_sats(
14861505
* anchor_channels_config.per_channel_reserve_sats
14871506
})
14881507
}
1508+
1509+
fn periodically_archive_fully_resolved_monitors(
1510+
channel_manager: Arc<ChannelManager>, chain_monitor: Arc<ChainMonitor>,
1511+
latest_channel_monitor_archival_height: Arc<RwLock<Option<u32>>>,
1512+
) {
1513+
let mut latest_archival_height_lock = latest_channel_monitor_archival_height.write().unwrap();
1514+
let cur_height = channel_manager.current_best_block().height;
1515+
let should_archive = latest_archival_height_lock
1516+
.as_ref()
1517+
.map_or(true, |h| cur_height >= h + LDK_CHANNEL_MONITOR_ARCHIVAL_INTERVAL);
1518+
1519+
if should_archive {
1520+
chain_monitor.archive_fully_resolved_channel_monitors();
1521+
*latest_archival_height_lock = Some(cur_height);
1522+
}
1523+
}

0 commit comments

Comments
 (0)