Skip to content

Commit f58f00f

Browse files
committed
Add timeout for on-chain syncing
.. to make progress and unblock the `Mutex` even if BDK's wallet `sync` would never return.
1 parent 82ab9ac commit f58f00f

File tree

4 files changed

+44
-23
lines changed

4 files changed

+44
-23
lines changed

bindings/ldk_node.udl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ enum NodeError {
166166
"PersistenceFailed",
167167
"FeerateEstimationUpdateFailed",
168168
"WalletOperationFailed",
169+
"WalletOperationTimeout",
169170
"OnchainTxSigningFailed",
170171
"MessageSigningFailed",
171172
"TxSyncFailed",

src/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ pub(crate) const NODE_ANN_BCAST_INTERVAL: Duration = Duration::from_secs(60 * 60
4646
// The lower limit which we apply to any configured wallet sync intervals.
4747
pub(crate) const WALLET_SYNC_INTERVAL_MINIMUM_SECS: u64 = 10;
4848

49+
// The timeout after which we abort a wallet syncing operation.
50+
pub(crate) const BDK_WALLET_SYNC_TIMEOUT_SECS: u64 = 90;
51+
4952
// The length in bytes of our wallets' keys seed.
5053
pub(crate) const WALLET_KEYS_SEED_LEN: usize = 64;
5154

src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ pub enum Error {
3535
FeerateEstimationUpdateFailed,
3636
/// A wallet operation failed.
3737
WalletOperationFailed,
38+
/// A wallet operation timed out.
39+
WalletOperationTimeout,
3840
/// A signing operation for transaction failed.
3941
OnchainTxSigningFailed,
4042
/// A signing operation for message failed.
@@ -112,6 +114,7 @@ impl fmt::Display for Error {
112114
write!(f, "Failed to update fee rate estimates.")
113115
},
114116
Self::WalletOperationFailed => write!(f, "Failed to conduct wallet operation."),
117+
Self::WalletOperationTimeout => write!(f, "A wallet operation timed out."),
115118
Self::OnchainTxSigningFailed => write!(f, "Failed to sign given transaction."),
116119
Self::MessageSigningFailed => write!(f, "Failed to sign given message."),
117120
Self::TxSyncFailed => write!(f, "Failed to sync transactions."),

src/wallet.rs

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::logger::{log_error, log_info, log_trace, Logger};
22

3+
use crate::config::BDK_WALLET_SYNC_TIMEOUT_SECS;
34
use crate::Error;
45

56
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
@@ -35,6 +36,7 @@ use bitcoin::{ScriptBuf, Transaction, TxOut, Txid};
3536

3637
use std::ops::{Deref, DerefMut};
3738
use std::sync::{Arc, Mutex, RwLock};
39+
use std::time::Duration;
3840

3941
enum WalletSyncStatus {
4042
Completed,
@@ -98,34 +100,46 @@ where
98100

99101
let res = {
100102
let wallet_lock = self.inner.lock().unwrap();
101-
match wallet_lock.sync(&self.blockchain, SyncOptions { progress: None }).await {
102-
Ok(()) => {
103-
// TODO: Drop this workaround after BDK 1.0 upgrade.
104-
// Update balance cache after syncing.
105-
if let Ok(balance) = wallet_lock.get_balance() {
106-
*self.balance_cache.write().unwrap() = balance;
107-
}
108-
Ok(())
109-
},
110-
Err(e) => match e {
111-
bdk::Error::Esplora(ref be) => match **be {
112-
bdk::blockchain::esplora::EsploraError::Reqwest(_) => {
113-
log_error!(
114-
self.logger,
115-
"Sync failed due to HTTP connection error: {}",
116-
e
117-
);
118-
Err(From::from(e))
103+
104+
let wallet_sync_timeout_fut = tokio::time::timeout(
105+
Duration::from_secs(BDK_WALLET_SYNC_TIMEOUT_SECS),
106+
wallet_lock.sync(&self.blockchain, SyncOptions { progress: None }),
107+
);
108+
109+
match wallet_sync_timeout_fut.await {
110+
Ok(res) => match res {
111+
Ok(()) => {
112+
// TODO: Drop this workaround after BDK 1.0 upgrade.
113+
// Update balance cache after syncing.
114+
if let Ok(balance) = wallet_lock.get_balance() {
115+
*self.balance_cache.write().unwrap() = balance;
116+
}
117+
Ok(())
118+
},
119+
Err(e) => match e {
120+
bdk::Error::Esplora(ref be) => match **be {
121+
bdk::blockchain::esplora::EsploraError::Reqwest(_) => {
122+
log_error!(
123+
self.logger,
124+
"Sync failed due to HTTP connection error: {}",
125+
e
126+
);
127+
Err(From::from(e))
128+
},
129+
_ => {
130+
log_error!(self.logger, "Sync failed due to Esplora error: {}", e);
131+
Err(From::from(e))
132+
},
119133
},
120134
_ => {
121-
log_error!(self.logger, "Sync failed due to Esplora error: {}", e);
135+
log_error!(self.logger, "Wallet sync error: {}", e);
122136
Err(From::from(e))
123137
},
124138
},
125-
_ => {
126-
log_error!(self.logger, "Wallet sync error: {}", e);
127-
Err(From::from(e))
128-
},
139+
},
140+
Err(e) => {
141+
log_error!(self.logger, "On-chain wallet sync timed out: {}", e);
142+
Err(Error::WalletOperationTimeout)
129143
},
130144
}
131145
};

0 commit comments

Comments
 (0)