Skip to content

Commit 610ef9a

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 3a85fcd commit 610ef9a

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
@@ -157,6 +157,7 @@ enum NodeError {
157157
"PersistenceFailed",
158158
"FeerateEstimationUpdateFailed",
159159
"WalletOperationFailed",
160+
"WalletOperationTimeout",
160161
"OnchainTxSigningFailed",
161162
"MessageSigningFailed",
162163
"TxSyncFailed",

src/config.rs

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

45+
// The timeout after which we abort a wallet syncing operation.
46+
pub(crate) const BDK_WALLET_SYNC_TIMEOUT_SECS: u64 = 90;
47+
4548
// The length in bytes of our wallets' keys seed.
4649
pub(crate) const WALLET_KEYS_SEED_LEN: usize = 64;
4750

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.
@@ -110,6 +112,7 @@ impl fmt::Display for Error {
110112
write!(f, "Failed to update fee rate estimates.")
111113
},
112114
Self::WalletOperationFailed => write!(f, "Failed to conduct wallet operation."),
115+
Self::WalletOperationTimeout => write!(f, "A wallet operation timed out."),
113116
Self::OnchainTxSigningFailed => write!(f, "Failed to sign given transaction."),
114117
Self::MessageSigningFailed => write!(f, "Failed to sign given message."),
115118
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};
@@ -36,6 +37,7 @@ use bitcoin::{ScriptBuf, Transaction, TxOut, Txid};
3637
use std::mem;
3738
use std::ops::{Deref, DerefMut};
3839
use std::sync::{Arc, Mutex, RwLock};
40+
use std::time::Duration;
3941

4042
enum WalletSyncStatus {
4143
Completed,
@@ -100,34 +102,46 @@ where
100102
let res = {
101103
let sync_options = SyncOptions { progress: None };
102104
let wallet_lock = self.inner.lock().unwrap();
103-
match wallet_lock.sync(&self.blockchain, sync_options).await {
104-
Ok(()) => {
105-
// TODO: Drop this workaround after BDK 1.0 upgrade.
106-
// Update balance cache after syncing.
107-
if let Ok(balance) = wallet_lock.get_balance() {
108-
*self.balance_cache.write().unwrap() = balance;
109-
}
110-
Ok(())
111-
},
112-
Err(e) => match e {
113-
bdk::Error::Esplora(ref be) => match **be {
114-
bdk::blockchain::esplora::EsploraError::Reqwest(_) => {
115-
log_error!(
116-
self.logger,
117-
"Sync failed due to HTTP connection error: {}",
118-
e
119-
);
120-
Err(From::from(e))
105+
106+
let timeout_fut = tokio::time::timeout(
107+
Duration::from_secs(BDK_WALLET_SYNC_TIMEOUT_SECS),
108+
wallet_lock.sync(&self.blockchain, sync_options),
109+
);
110+
111+
match timeout_fut.await {
112+
Ok(res) => match res {
113+
Ok(()) => {
114+
// TODO: Drop this workaround after BDK 1.0 upgrade.
115+
// Update balance cache after syncing.
116+
if let Ok(balance) = wallet_lock.get_balance() {
117+
*self.balance_cache.write().unwrap() = balance;
118+
}
119+
Ok(())
120+
},
121+
Err(e) => match e {
122+
bdk::Error::Esplora(ref be) => match **be {
123+
bdk::blockchain::esplora::EsploraError::Reqwest(_) => {
124+
log_error!(
125+
self.logger,
126+
"Sync failed due to HTTP connection error: {}",
127+
e
128+
);
129+
Err(From::from(e))
130+
},
131+
_ => {
132+
log_error!(self.logger, "Sync failed due to Esplora error: {}", e);
133+
Err(From::from(e))
134+
},
121135
},
122136
_ => {
123-
log_error!(self.logger, "Sync failed due to Esplora error: {}", e);
137+
log_error!(self.logger, "Wallet sync error: {}", e);
124138
Err(From::from(e))
125139
},
126140
},
127-
_ => {
128-
log_error!(self.logger, "Wallet sync error: {}", e);
129-
Err(From::from(e))
130-
},
141+
},
142+
Err(e) => {
143+
log_error!(self.logger, "On-chain wallet sync timed out: {}", e);
144+
Err(Error::WalletOperationTimeout)
131145
},
132146
}
133147
};

0 commit comments

Comments
 (0)