Skip to content

Commit 3954355

Browse files
committed
Add exponential backoff for sync failures
Previously, chain synchronization failures would retry immediately without any delay, which could lead to tight retry loops and high CPU usage during failures. This change introduces exponential backoff for transient errors, starting at 2 seconds and doubling each time up to a maximum of 300 seconds. Persistent errors also now delay retries by the maximum backoff duration to prevent rapid loops while maintaining eventual recovery. Fixes #587
1 parent 243c874 commit 3954355

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

src/chain/mod.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use lightning_transaction_sync::EsploraSyncClient;
3636
use lightning_block_sync::gossip::UtxoSource;
3737
use lightning_block_sync::init::{synchronize_listeners, validate_best_block_header};
3838
use lightning_block_sync::poll::{ChainPoller, ChainTip, ValidatedBlockHeader};
39-
use lightning_block_sync::SpvClient;
39+
use lightning_block_sync::{BlockSourceErrorKind, SpvClient};
4040

4141
use bdk_esplora::EsploraAsyncExt;
4242
use bdk_wallet::Update as BdkUpdate;
@@ -425,6 +425,9 @@ impl ChainSource {
425425
"Starting initial synchronization of chain listeners. This might take a while..",
426426
);
427427

428+
let mut backoff = CHAIN_POLLING_INTERVAL_SECS;
429+
const MAX_BACKOFF_SECS: u64 = 300;
430+
428431
loop {
429432
let channel_manager_best_block_hash =
430433
channel_manager.current_best_block().block_hash;
@@ -504,8 +507,24 @@ impl ChainSource {
504507

505508
Err(e) => {
506509
log_error!(logger, "Failed to synchronize chain listeners: {:?}", e);
507-
tokio::time::sleep(Duration::from_secs(CHAIN_POLLING_INTERVAL_SECS))
508-
.await;
510+
if e.kind() == BlockSourceErrorKind::Transient {
511+
log_info!(
512+
logger,
513+
"Transient error syncing chain listeners: {:?}. Retrying in {} seconds.",
514+
e,
515+
backoff
516+
);
517+
tokio::time::sleep(Duration::from_secs(backoff)).await;
518+
backoff = std::cmp::min(backoff * 2, MAX_BACKOFF_SECS);
519+
} else {
520+
log_error!(
521+
logger,
522+
"Persistent error syncing chain listeners: {:?}. Retrying in {} seconds.",
523+
e,
524+
MAX_BACKOFF_SECS
525+
);
526+
tokio::time::sleep(Duration::from_secs(MAX_BACKOFF_SECS)).await;
527+
}
509528
},
510529
}
511530
}

0 commit comments

Comments
 (0)