Skip to content

Commit 3a328d4

Browse files
authored
Merge pull request #307 from tnull/2024-06-archive-fully-resolved-monitors
Periodically archive fully resolved channel monitors
2 parents 9c44041 + accd3c8 commit 3a328d4

File tree

3 files changed

+80
-2
lines changed

3 files changed

+80
-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 RESOLVED_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: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ pub use builder::BuildError;
123123
pub use builder::NodeBuilder as Builder;
124124

125125
use config::{
126-
NODE_ANN_BCAST_INTERVAL, PEER_RECONNECTION_INTERVAL, RGS_SYNC_INTERVAL,
126+
NODE_ANN_BCAST_INTERVAL, PEER_RECONNECTION_INTERVAL,
127+
RESOLVED_CHANNEL_MONITOR_ARCHIVAL_INTERVAL, RGS_SYNC_INTERVAL,
127128
WALLET_SYNC_INTERVAL_MINIMUM_SECS,
128129
};
129130
use connection::ConnectionManager;
@@ -200,6 +201,7 @@ pub struct Node {
200201
latest_fee_rate_cache_update_timestamp: Arc<RwLock<Option<u64>>>,
201202
latest_rgs_snapshot_timestamp: Arc<RwLock<Option<u64>>>,
202203
latest_node_announcement_broadcast_timestamp: Arc<RwLock<Option<u64>>>,
204+
latest_channel_monitor_archival_height: Arc<RwLock<Option<u32>>>,
203205
}
204206

205207
impl Node {
@@ -345,10 +347,13 @@ impl Node {
345347

346348
let tx_sync = Arc::clone(&self.tx_sync);
347349
let sync_cman = Arc::clone(&self.channel_manager);
350+
let archive_cman = Arc::clone(&self.channel_manager);
348351
let sync_cmon = Arc::clone(&self.chain_monitor);
352+
let archive_cmon = Arc::clone(&self.chain_monitor);
349353
let sync_sweeper = Arc::clone(&self.output_sweeper);
350354
let sync_logger = Arc::clone(&self.logger);
351355
let sync_wallet_timestamp = Arc::clone(&self.latest_wallet_sync_timestamp);
356+
let sync_monitor_archival_height = Arc::clone(&self.latest_channel_monitor_archival_height);
352357
let mut stop_sync = self.stop_sender.subscribe();
353358
let wallet_sync_interval_secs =
354359
self.config.wallet_sync_interval_secs.max(WALLET_SYNC_INTERVAL_MINIMUM_SECS);
@@ -378,6 +383,12 @@ impl Node {
378383
let unix_time_secs_opt =
379384
SystemTime::now().duration_since(UNIX_EPOCH).ok().map(|d| d.as_secs());
380385
*sync_wallet_timestamp.write().unwrap() = unix_time_secs_opt;
386+
387+
periodically_archive_fully_resolved_monitors(
388+
Arc::clone(&archive_cman),
389+
Arc::clone(&archive_cmon),
390+
Arc::clone(&sync_monitor_archival_height)
391+
);
381392
}
382393
Err(e) => {
383394
log_error!(sync_logger, "Background sync of Lightning wallet failed: {}", e)
@@ -1115,7 +1126,8 @@ impl Node {
11151126
}
11161127
}
11171128

1118-
/// Manually sync the LDK and BDK wallets with the current chain state.
1129+
/// Manually sync the LDK and BDK wallets with the current chain state and update the fee rate
1130+
/// cache.
11191131
///
11201132
/// **Note:** The wallets are regularly synced in the background, which is configurable via
11211133
/// [`Config::onchain_wallet_sync_interval_secs`] and [`Config::wallet_sync_interval_secs`].
@@ -1130,14 +1142,22 @@ impl Node {
11301142
let wallet = Arc::clone(&self.wallet);
11311143
let tx_sync = Arc::clone(&self.tx_sync);
11321144
let sync_cman = Arc::clone(&self.channel_manager);
1145+
let archive_cman = Arc::clone(&self.channel_manager);
11331146
let sync_cmon = Arc::clone(&self.chain_monitor);
1147+
let archive_cmon = Arc::clone(&self.chain_monitor);
1148+
let fee_estimator = Arc::clone(&self.fee_estimator);
11341149
let sync_sweeper = Arc::clone(&self.output_sweeper);
11351150
let sync_logger = Arc::clone(&self.logger);
11361151
let confirmables = vec![
11371152
&*sync_cman as &(dyn Confirm + Sync + Send),
11381153
&*sync_cmon as &(dyn Confirm + Sync + Send),
11391154
&*sync_sweeper as &(dyn Confirm + Sync + Send),
11401155
];
1156+
let sync_wallet_timestamp = Arc::clone(&self.latest_wallet_sync_timestamp);
1157+
let sync_fee_rate_update_timestamp =
1158+
Arc::clone(&self.latest_fee_rate_cache_update_timestamp);
1159+
let sync_onchain_wallet_timestamp = Arc::clone(&self.latest_onchain_wallet_sync_timestamp);
1160+
let sync_monitor_archival_height = Arc::clone(&self.latest_channel_monitor_archival_height);
11411161

11421162
tokio::task::block_in_place(move || {
11431163
tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap().block_on(
@@ -1150,13 +1170,38 @@ impl Node {
11501170
"Sync of on-chain wallet finished in {}ms.",
11511171
now.elapsed().as_millis()
11521172
);
1173+
let unix_time_secs_opt = SystemTime::now()
1174+
.duration_since(UNIX_EPOCH)
1175+
.ok()
1176+
.map(|d| d.as_secs());
1177+
*sync_onchain_wallet_timestamp.write().unwrap() = unix_time_secs_opt;
11531178
},
11541179
Err(e) => {
11551180
log_error!(sync_logger, "Sync of on-chain wallet failed: {}", e);
11561181
return Err(e);
11571182
},
11581183
};
11591184

1185+
let now = Instant::now();
1186+
match fee_estimator.update_fee_estimates().await {
1187+
Ok(()) => {
1188+
log_info!(
1189+
sync_logger,
1190+
"Fee rate cache update finished in {}ms.",
1191+
now.elapsed().as_millis()
1192+
);
1193+
let unix_time_secs_opt = SystemTime::now()
1194+
.duration_since(UNIX_EPOCH)
1195+
.ok()
1196+
.map(|d| d.as_secs());
1197+
*sync_fee_rate_update_timestamp.write().unwrap() = unix_time_secs_opt;
1198+
},
1199+
Err(e) => {
1200+
log_error!(sync_logger, "Fee rate cache update failed: {}", e,);
1201+
return Err(e);
1202+
},
1203+
}
1204+
11601205
let now = Instant::now();
11611206
match tx_sync.sync(confirmables).await {
11621207
Ok(()) => {
@@ -1165,6 +1210,18 @@ impl Node {
11651210
"Sync of Lightning wallet finished in {}ms.",
11661211
now.elapsed().as_millis()
11671212
);
1213+
1214+
let unix_time_secs_opt = SystemTime::now()
1215+
.duration_since(UNIX_EPOCH)
1216+
.ok()
1217+
.map(|d| d.as_secs());
1218+
*sync_wallet_timestamp.write().unwrap() = unix_time_secs_opt;
1219+
1220+
periodically_archive_fully_resolved_monitors(
1221+
archive_cman,
1222+
archive_cmon,
1223+
sync_monitor_archival_height,
1224+
);
11681225
Ok(())
11691226
},
11701227
Err(e) => {
@@ -1500,3 +1557,19 @@ pub(crate) fn total_anchor_channels_reserve_sats(
15001557
* anchor_channels_config.per_channel_reserve_sats
15011558
})
15021559
}
1560+
1561+
fn periodically_archive_fully_resolved_monitors(
1562+
channel_manager: Arc<ChannelManager>, chain_monitor: Arc<ChainMonitor>,
1563+
latest_channel_monitor_archival_height: Arc<RwLock<Option<u32>>>,
1564+
) {
1565+
let mut latest_archival_height_lock = latest_channel_monitor_archival_height.write().unwrap();
1566+
let cur_height = channel_manager.current_best_block().height;
1567+
let should_archive = latest_archival_height_lock
1568+
.as_ref()
1569+
.map_or(true, |h| cur_height >= h + RESOLVED_CHANNEL_MONITOR_ARCHIVAL_INTERVAL);
1570+
1571+
if should_archive {
1572+
chain_monitor.archive_fully_resolved_channel_monitors();
1573+
*latest_archival_height_lock = Some(cur_height);
1574+
}
1575+
}

0 commit comments

Comments
 (0)