Skip to content

Commit 760e5e7

Browse files
committed
Make sync timeouts configurable
Previously, the timeouts applied to chain syncing weren't configurable to users. While historically there were good reasons for this (mostly to avoid leaving the Node in a blocked state for extended periods during chain syncing), by now we should be good to let the users configure timeouts ~freely, if they deem it fit. Here we allow for exactly that. Signed-off-by: Elias Rohrer <dev@tnull.de>
1 parent ba16c92 commit 760e5e7

8 files changed

Lines changed: 149 additions & 59 deletions

File tree

bindings/ldk_node.udl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,22 @@ dictionary BackgroundSyncConfig {
2626
u64 fee_rate_cache_update_interval_secs;
2727
};
2828

29+
dictionary SyncTimeoutsConfig {
30+
u64 onchain_wallet_sync_timeout_secs;
31+
u64 lightning_wallet_sync_timeout_secs;
32+
u64 fee_rate_cache_update_timeout_secs;
33+
u64 tx_broadcast_timeout_secs;
34+
u8 per_request_timeout_secs;
35+
};
36+
2937
dictionary EsploraSyncConfig {
3038
BackgroundSyncConfig? background_sync_config;
39+
SyncTimeoutsConfig timeouts_config;
3140
};
3241

3342
dictionary ElectrumSyncConfig {
3443
BackgroundSyncConfig? background_sync_config;
44+
SyncTimeoutsConfig timeouts_config;
3545
};
3646

3747
dictionary LSPS2ServiceConfig {

src/chain/bitcoind.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ use serde::Serialize;
3131

3232
use super::WalletSyncStatus;
3333
use crate::config::{
34-
BitcoindRestClientConfig, Config, FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS, TX_BROADCAST_TIMEOUT_SECS,
34+
BitcoindRestClientConfig, Config, DEFAULT_FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS,
35+
DEFAULT_TX_BROADCAST_TIMEOUT_SECS,
3536
};
3637
use crate::fee_estimator::{
3738
apply_post_estimation_adjustments, get_all_conf_targets, get_num_block_defaults_for_target,
@@ -466,7 +467,7 @@ impl BitcoindChainSource {
466467
macro_rules! get_fee_rate_update {
467468
($estimation_fut:expr) => {{
468469
let update_res = tokio::time::timeout(
469-
Duration::from_secs(FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS),
470+
Duration::from_secs(DEFAULT_FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS),
470471
$estimation_fut,
471472
)
472473
.await
@@ -584,7 +585,7 @@ impl BitcoindChainSource {
584585
for tx in &package {
585586
let txid = tx.compute_txid();
586587
let timeout_fut = tokio::time::timeout(
587-
Duration::from_secs(TX_BROADCAST_TIMEOUT_SECS),
588+
Duration::from_secs(DEFAULT_TX_BROADCAST_TIMEOUT_SECS),
588589
self.api_client.broadcast_transaction(tx),
589590
);
590591
match timeout_fut.await {

src/chain/electrum.rs

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,7 @@ use lightning::util::ser::Writeable;
2424
use lightning_transaction_sync::ElectrumSyncClient;
2525

2626
use super::WalletSyncStatus;
27-
use crate::config::{
28-
Config, ElectrumSyncConfig, BDK_CLIENT_STOP_GAP, BDK_WALLET_SYNC_TIMEOUT_SECS,
29-
FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS, LDK_WALLET_SYNC_TIMEOUT_SECS, TX_BROADCAST_TIMEOUT_SECS,
30-
};
27+
use crate::config::{Config, ElectrumSyncConfig, BDK_CLIENT_STOP_GAP};
3128
use crate::error::Error;
3229
use crate::fee_estimator::{
3330
apply_post_estimation_adjustments, get_all_conf_targets, get_num_block_defaults_for_target,
@@ -41,7 +38,6 @@ use crate::NodeMetrics;
4138

4239
const BDK_ELECTRUM_CLIENT_BATCH_SIZE: usize = 5;
4340
const ELECTRUM_CLIENT_NUM_RETRIES: u8 = 3;
44-
const ELECTRUM_CLIENT_TIMEOUT_SECS: u8 = 10;
4541

4642
pub(super) struct ElectrumChainSource {
4743
server_url: String,
@@ -82,6 +78,7 @@ impl ElectrumChainSource {
8278
pub(super) fn start(&self, runtime: Arc<Runtime>) -> Result<(), Error> {
8379
self.electrum_runtime_status.write().unwrap().start(
8480
self.server_url.clone(),
81+
self.sync_config.clone(),
8582
Arc::clone(&runtime),
8683
Arc::clone(&self.config),
8784
Arc::clone(&self.logger),
@@ -318,13 +315,14 @@ impl ElectrumRuntimeStatus {
318315
}
319316

320317
pub(super) fn start(
321-
&mut self, server_url: String, runtime: Arc<Runtime>, config: Arc<Config>,
322-
logger: Arc<Logger>,
318+
&mut self, server_url: String, sync_config: ElectrumSyncConfig, runtime: Arc<Runtime>,
319+
config: Arc<Config>, logger: Arc<Logger>,
323320
) -> Result<(), Error> {
324321
match self {
325322
Self::Stopped { pending_registered_txs, pending_registered_outputs } => {
326323
let client = Arc::new(ElectrumRuntimeClient::new(
327-
server_url.clone(),
324+
server_url,
325+
sync_config,
328326
runtime,
329327
config,
330328
logger,
@@ -380,6 +378,7 @@ impl ElectrumRuntimeStatus {
380378

381379
struct ElectrumRuntimeClient {
382380
electrum_client: Arc<ElectrumClient>,
381+
sync_config: ElectrumSyncConfig,
383382
bdk_electrum_client: Arc<BdkElectrumClient<Arc<ElectrumClient>>>,
384383
tx_sync: Arc<ElectrumSyncClient<Arc<Logger>>>,
385384
runtime: Arc<Runtime>,
@@ -389,11 +388,12 @@ struct ElectrumRuntimeClient {
389388

390389
impl ElectrumRuntimeClient {
391390
fn new(
392-
server_url: String, runtime: Arc<Runtime>, config: Arc<Config>, logger: Arc<Logger>,
391+
server_url: String, sync_config: ElectrumSyncConfig, runtime: Arc<Runtime>,
392+
config: Arc<Config>, logger: Arc<Logger>,
393393
) -> Result<Self, Error> {
394394
let electrum_config = ElectrumConfigBuilder::new()
395395
.retry(ELECTRUM_CLIENT_NUM_RETRIES)
396-
.timeout(Some(ELECTRUM_CLIENT_TIMEOUT_SECS))
396+
.timeout(Some(sync_config.timeouts_config.per_request_timeout_secs))
397397
.build();
398398

399399
let electrum_client = Arc::new(
@@ -409,7 +409,15 @@ impl ElectrumRuntimeClient {
409409
Error::ConnectionFailed
410410
})?,
411411
);
412-
Ok(Self { electrum_client, bdk_electrum_client, tx_sync, runtime, config, logger })
412+
Ok(Self {
413+
electrum_client,
414+
sync_config,
415+
bdk_electrum_client,
416+
tx_sync,
417+
runtime,
418+
config,
419+
logger,
420+
})
413421
}
414422

415423
async fn sync_confirmables(
@@ -419,8 +427,12 @@ impl ElectrumRuntimeClient {
419427

420428
let tx_sync = Arc::clone(&self.tx_sync);
421429
let spawn_fut = self.runtime.spawn_blocking(move || tx_sync.sync(confirmables));
422-
let timeout_fut =
423-
tokio::time::timeout(Duration::from_secs(LDK_WALLET_SYNC_TIMEOUT_SECS), spawn_fut);
430+
let timeout_fut = tokio::time::timeout(
431+
Duration::from_secs(
432+
self.sync_config.timeouts_config.lightning_wallet_sync_timeout_secs,
433+
),
434+
spawn_fut,
435+
);
424436

425437
let res = timeout_fut
426438
.await
@@ -461,8 +473,10 @@ impl ElectrumRuntimeClient {
461473
true,
462474
)
463475
});
464-
let wallet_sync_timeout_fut =
465-
tokio::time::timeout(Duration::from_secs(BDK_WALLET_SYNC_TIMEOUT_SECS), spawn_fut);
476+
let wallet_sync_timeout_fut = tokio::time::timeout(
477+
Duration::from_secs(self.sync_config.timeouts_config.onchain_wallet_sync_timeout_secs),
478+
spawn_fut,
479+
);
466480

467481
wallet_sync_timeout_fut
468482
.await
@@ -490,8 +504,10 @@ impl ElectrumRuntimeClient {
490504
let spawn_fut = self.runtime.spawn_blocking(move || {
491505
bdk_electrum_client.sync(request, BDK_ELECTRUM_CLIENT_BATCH_SIZE, true)
492506
});
493-
let wallet_sync_timeout_fut =
494-
tokio::time::timeout(Duration::from_secs(BDK_WALLET_SYNC_TIMEOUT_SECS), spawn_fut);
507+
let wallet_sync_timeout_fut = tokio::time::timeout(
508+
Duration::from_secs(self.sync_config.timeouts_config.onchain_wallet_sync_timeout_secs),
509+
spawn_fut,
510+
);
495511

496512
wallet_sync_timeout_fut
497513
.await
@@ -517,8 +533,10 @@ impl ElectrumRuntimeClient {
517533

518534
let spawn_fut =
519535
self.runtime.spawn_blocking(move || electrum_client.transaction_broadcast(&tx));
520-
let timeout_fut =
521-
tokio::time::timeout(Duration::from_secs(TX_BROADCAST_TIMEOUT_SECS), spawn_fut);
536+
let timeout_fut = tokio::time::timeout(
537+
Duration::from_secs(self.sync_config.timeouts_config.tx_broadcast_timeout_secs),
538+
spawn_fut,
539+
);
522540

523541
match timeout_fut.await {
524542
Ok(res) => match res {
@@ -565,7 +583,9 @@ impl ElectrumRuntimeClient {
565583
let spawn_fut = self.runtime.spawn_blocking(move || electrum_client.batch_call(&batch));
566584

567585
let timeout_fut = tokio::time::timeout(
568-
Duration::from_secs(FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS),
586+
Duration::from_secs(
587+
self.sync_config.timeouts_config.fee_rate_cache_update_timeout_secs,
588+
),
569589
spawn_fut,
570590
);
571591

src/chain/esplora.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,7 @@ use lightning::util::ser::Writeable;
1717
use lightning_transaction_sync::EsploraSyncClient;
1818

1919
use super::WalletSyncStatus;
20-
use crate::config::{
21-
Config, EsploraSyncConfig, BDK_CLIENT_CONCURRENCY, BDK_CLIENT_STOP_GAP,
22-
BDK_WALLET_SYNC_TIMEOUT_SECS, DEFAULT_ESPLORA_CLIENT_TIMEOUT_SECS,
23-
FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS, LDK_WALLET_SYNC_TIMEOUT_SECS, TX_BROADCAST_TIMEOUT_SECS,
24-
};
20+
use crate::config::{Config, EsploraSyncConfig, BDK_CLIENT_CONCURRENCY, BDK_CLIENT_STOP_GAP};
2521
use crate::fee_estimator::{
2622
apply_post_estimation_adjustments, get_all_conf_targets, get_num_block_defaults_for_target,
2723
OnchainFeeEstimator,
@@ -51,7 +47,8 @@ impl EsploraChainSource {
5147
logger: Arc<Logger>, node_metrics: Arc<RwLock<NodeMetrics>>,
5248
) -> Self {
5349
let mut client_builder = esplora_client::Builder::new(&server_url);
54-
client_builder = client_builder.timeout(DEFAULT_ESPLORA_CLIENT_TIMEOUT_SECS);
50+
client_builder =
51+
client_builder.timeout(sync_config.timeouts_config.per_request_timeout_secs as u64);
5552

5653
for (header_name, header_value) in &headers {
5754
client_builder = client_builder.header(header_name, header_value);
@@ -183,14 +180,18 @@ impl EsploraChainSource {
183180
if incremental_sync {
184181
let sync_request = onchain_wallet.get_incremental_sync_request();
185182
let wallet_sync_timeout_fut = tokio::time::timeout(
186-
Duration::from_secs(BDK_WALLET_SYNC_TIMEOUT_SECS),
183+
Duration::from_secs(
184+
self.sync_config.timeouts_config.onchain_wallet_sync_timeout_secs,
185+
),
187186
self.esplora_client.sync(sync_request, BDK_CLIENT_CONCURRENCY),
188187
);
189188
get_and_apply_wallet_update!(wallet_sync_timeout_fut)
190189
} else {
191190
let full_scan_request = onchain_wallet.get_full_scan_request();
192191
let wallet_sync_timeout_fut = tokio::time::timeout(
193-
Duration::from_secs(BDK_WALLET_SYNC_TIMEOUT_SECS),
192+
Duration::from_secs(
193+
self.sync_config.timeouts_config.onchain_wallet_sync_timeout_secs,
194+
),
194195
self.esplora_client.full_scan(
195196
full_scan_request,
196197
BDK_CLIENT_STOP_GAP,
@@ -240,7 +241,9 @@ impl EsploraChainSource {
240241
];
241242

242243
let timeout_fut = tokio::time::timeout(
243-
Duration::from_secs(LDK_WALLET_SYNC_TIMEOUT_SECS),
244+
Duration::from_secs(
245+
self.sync_config.timeouts_config.lightning_wallet_sync_timeout_secs as u64,
246+
),
244247
self.tx_sync.sync(confirmables),
245248
);
246249
let now = Instant::now();
@@ -278,7 +281,9 @@ impl EsploraChainSource {
278281
pub(crate) async fn update_fee_rate_estimates(&self) -> Result<(), Error> {
279282
let now = Instant::now();
280283
let estimates = tokio::time::timeout(
281-
Duration::from_secs(FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS),
284+
Duration::from_secs(
285+
self.sync_config.timeouts_config.fee_rate_cache_update_timeout_secs,
286+
),
282287
self.esplora_client.get_fee_estimates(),
283288
)
284289
.await
@@ -351,7 +356,7 @@ impl EsploraChainSource {
351356
for tx in &package {
352357
let txid = tx.compute_txid();
353358
let timeout_fut = tokio::time::timeout(
354-
Duration::from_secs(TX_BROADCAST_TIMEOUT_SECS),
359+
Duration::from_secs(self.sync_config.timeouts_config.tx_broadcast_timeout_secs),
355360
self.esplora_client.broadcast(tx),
356361
);
357362
match timeout_fut.await {

0 commit comments

Comments
 (0)