Skip to content

Commit ce92195

Browse files
committed
Add timeout for Lightning syncing
.. even though we don't expect this to block, we're better safe than sorry and start to introduce timeouts for any calls we make to remote servers.
1 parent a5059f1 commit ce92195

File tree

4 files changed

+66
-39
lines changed

4 files changed

+66
-39
lines changed

bindings/ldk_node.udl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ enum NodeError {
162162
"OnchainTxSigningFailed",
163163
"MessageSigningFailed",
164164
"TxSyncFailed",
165+
"TxSyncTimeout",
165166
"GossipUpdateFailed",
166167
"LiquidityRequestFailed",
167168
"InvalidAddress",

src/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ pub(crate) const WALLET_SYNC_INTERVAL_MINIMUM_SECS: u64 = 10;
4949
// The timeout after which we abort a wallet syncing operation.
5050
pub(crate) const BDK_WALLET_SYNC_TIMEOUT_SECS: u64 = 90;
5151

52+
// The timeout after which we abort a wallet syncing operation.
53+
pub(crate) const LDK_WALLET_SYNC_TIMEOUT_SECS: u64 = 30;
54+
5255
// The length in bytes of our wallets' keys seed.
5356
pub(crate) const WALLET_KEYS_SEED_LEN: usize = 64;
5457

src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ pub enum Error {
4343
MessageSigningFailed,
4444
/// A transaction sync operation failed.
4545
TxSyncFailed,
46+
/// A transaction sync operation timed out.
47+
TxSyncTimeout,
4648
/// A gossip updating operation failed.
4749
GossipUpdateFailed,
4850
/// A liquidity request operation failed.
@@ -118,6 +120,7 @@ impl fmt::Display for Error {
118120
Self::OnchainTxSigningFailed => write!(f, "Failed to sign given transaction."),
119121
Self::MessageSigningFailed => write!(f, "Failed to sign given message."),
120122
Self::TxSyncFailed => write!(f, "Failed to sync transactions."),
123+
Self::TxSyncTimeout => write!(f, "Syncing transactions timed out."),
121124
Self::GossipUpdateFailed => write!(f, "Failed to update gossip data."),
122125
Self::LiquidityRequestFailed => write!(f, "Failed to request inbound liquidity."),
123126
Self::InvalidAddress => write!(f, "The given address is invalid."),

src/lib.rs

Lines changed: 59 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ pub use builder::BuildError;
123123
pub use builder::NodeBuilder as Builder;
124124

125125
use config::{
126-
default_user_config, NODE_ANN_BCAST_INTERVAL, PEER_RECONNECTION_INTERVAL,
127-
RESOLVED_CHANNEL_MONITOR_ARCHIVAL_INTERVAL, RGS_SYNC_INTERVAL,
126+
default_user_config, LDK_WALLET_SYNC_TIMEOUT_SECS, NODE_ANN_BCAST_INTERVAL,
127+
PEER_RECONNECTION_INTERVAL, RESOLVED_CHANNEL_MONITOR_ARCHIVAL_INTERVAL, RGS_SYNC_INTERVAL,
128128
WALLET_SYNC_INTERVAL_MINIMUM_SECS,
129129
};
130130
use connection::ConnectionManager;
@@ -377,25 +377,31 @@ impl Node {
377377
&*sync_sweeper as &(dyn Confirm + Sync + Send),
378378
];
379379
let now = Instant::now();
380-
match tx_sync.sync(confirmables).await {
381-
Ok(()) => {
382-
log_trace!(
383-
sync_logger,
384-
"Background sync of Lightning wallet finished in {}ms.",
385-
now.elapsed().as_millis()
386-
);
387-
let unix_time_secs_opt =
388-
SystemTime::now().duration_since(UNIX_EPOCH).ok().map(|d| d.as_secs());
389-
*sync_wallet_timestamp.write().unwrap() = unix_time_secs_opt;
390-
391-
periodically_archive_fully_resolved_monitors(
392-
Arc::clone(&archive_cman),
393-
Arc::clone(&archive_cmon),
394-
Arc::clone(&sync_monitor_archival_height)
395-
);
380+
let timeout_fut = tokio::time::timeout(Duration::from_secs(LDK_WALLET_SYNC_TIMEOUT_SECS), tx_sync.sync(confirmables));
381+
match timeout_fut.await {
382+
Ok(res) => match res {
383+
Ok(()) => {
384+
log_trace!(
385+
sync_logger,
386+
"Background sync of Lightning wallet finished in {}ms.",
387+
now.elapsed().as_millis()
388+
);
389+
let unix_time_secs_opt =
390+
SystemTime::now().duration_since(UNIX_EPOCH).ok().map(|d| d.as_secs());
391+
*sync_wallet_timestamp.write().unwrap() = unix_time_secs_opt;
392+
393+
periodically_archive_fully_resolved_monitors(
394+
Arc::clone(&archive_cman),
395+
Arc::clone(&archive_cmon),
396+
Arc::clone(&sync_monitor_archival_height)
397+
);
398+
}
399+
Err(e) => {
400+
log_error!(sync_logger, "Background sync of Lightning wallet failed: {}", e)
401+
}
396402
}
397403
Err(e) => {
398-
log_error!(sync_logger, "Background sync of Lightning wallet failed: {}", e)
404+
log_error!(sync_logger, "Background sync of Lightning wallet timed out: {}", e)
399405
}
400406
}
401407
}
@@ -1167,6 +1173,8 @@ impl Node {
11671173
tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap().block_on(
11681174
async move {
11691175
let now = Instant::now();
1176+
// We don't add an additional timeout here, as `Wallet::sync` already returns
1177+
// after a timeout.
11701178
match wallet.sync().await {
11711179
Ok(()) => {
11721180
log_info!(
@@ -1187,6 +1195,8 @@ impl Node {
11871195
};
11881196

11891197
let now = Instant::now();
1198+
// We don't add an additional timeout here, as
1199+
// `FeeEstimator::update_fee_estimates` already returns after a timeout.
11901200
match fee_estimator.update_fee_estimates().await {
11911201
Ok(()) => {
11921202
log_info!(
@@ -1207,30 +1217,40 @@ impl Node {
12071217
}
12081218

12091219
let now = Instant::now();
1210-
match tx_sync.sync(confirmables).await {
1211-
Ok(()) => {
1212-
log_info!(
1213-
sync_logger,
1214-
"Sync of Lightning wallet finished in {}ms.",
1215-
now.elapsed().as_millis()
1216-
);
1220+
let tx_sync_timeout_fut = tokio::time::timeout(
1221+
Duration::from_secs(LDK_WALLET_SYNC_TIMEOUT_SECS),
1222+
tx_sync.sync(confirmables),
1223+
);
1224+
match tx_sync_timeout_fut.await {
1225+
Ok(res) => match res {
1226+
Ok(()) => {
1227+
log_info!(
1228+
sync_logger,
1229+
"Sync of Lightning wallet finished in {}ms.",
1230+
now.elapsed().as_millis()
1231+
);
12171232

1218-
let unix_time_secs_opt = SystemTime::now()
1219-
.duration_since(UNIX_EPOCH)
1220-
.ok()
1221-
.map(|d| d.as_secs());
1222-
*sync_wallet_timestamp.write().unwrap() = unix_time_secs_opt;
1233+
let unix_time_secs_opt = SystemTime::now()
1234+
.duration_since(UNIX_EPOCH)
1235+
.ok()
1236+
.map(|d| d.as_secs());
1237+
*sync_wallet_timestamp.write().unwrap() = unix_time_secs_opt;
12231238

1224-
periodically_archive_fully_resolved_monitors(
1225-
archive_cman,
1226-
archive_cmon,
1227-
sync_monitor_archival_height,
1228-
);
1229-
Ok(())
1239+
periodically_archive_fully_resolved_monitors(
1240+
archive_cman,
1241+
archive_cmon,
1242+
sync_monitor_archival_height,
1243+
);
1244+
Ok(())
1245+
},
1246+
Err(e) => {
1247+
log_error!(sync_logger, "Sync of Lightning wallet failed: {}", e);
1248+
Err(e.into())
1249+
},
12301250
},
12311251
Err(e) => {
1232-
log_error!(sync_logger, "Sync of Lightning wallet failed: {}", e);
1233-
Err(e.into())
1252+
log_error!(sync_logger, "Sync of Lightning wallet timed out: {}", e);
1253+
Err(Error::TxSyncTimeout)
12341254
},
12351255
}
12361256
},

0 commit comments

Comments
 (0)