Skip to content

Commit 3626658

Browse files
committed
fix(cbf): add per-block-fetch timeout to wallet sync
Wrap individual get_block() calls in tokio::time::timeout using the existing per_request_timeout_secs config. Previously only the overall sync had a timeout; individual block fetches could hang indefinitely (kyoto lightningdevkit#556).
1 parent 8e097fb commit 3626658

1 file changed

Lines changed: 27 additions & 9 deletions

File tree

src/chain/cbf.rs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -684,11 +684,20 @@ impl CbfChainSource {
684684
// created outputs and spent inputs), so we include every transaction
685685
// from matched blocks and let BDK determine relevance.
686686
let mut tx_update = TxUpdate::default();
687+
let per_request_timeout =
688+
Duration::from_secs(self.sync_config.timeouts_config.per_request_timeout_secs.into());
687689
for (height, block_hash) in &matched {
688-
let indexed_block = requester.get_block(*block_hash).await.map_err(|e| {
689-
log_error!(self.logger, "Failed to fetch block {}: {:?}", block_hash, e);
690-
Error::WalletOperationFailed
691-
})?;
690+
let indexed_block =
691+
tokio::time::timeout(per_request_timeout, requester.get_block(*block_hash))
692+
.await
693+
.map_err(|_| {
694+
log_error!(self.logger, "Timed out fetching block {}", block_hash);
695+
Error::WalletOperationFailed
696+
})?
697+
.map_err(|e| {
698+
log_error!(self.logger, "Failed to fetch block {}: {:?}", block_hash, e);
699+
Error::WalletOperationFailed
700+
})?;
692701
let block = indexed_block.block;
693702
let block_id = BlockId { height: *height, hash: block.header.block_hash() };
694703
let conf_time =
@@ -797,12 +806,15 @@ impl CbfChainSource {
797806
// The compact block filter already matched our scripts (covering both
798807
// created outputs and spent inputs), so we confirm every transaction
799808
// from matched blocks and let LDK determine relevance.
809+
let per_request_timeout =
810+
Duration::from_secs(self.sync_config.timeouts_config.per_request_timeout_secs.into());
800811
for (height, block_hash) in &matched {
801812
confirm_block_transactions(
802813
&requester,
803814
*block_hash,
804815
*height,
805816
&confirmables,
817+
per_request_timeout,
806818
&self.logger,
807819
)
808820
.await?;
@@ -1181,12 +1193,18 @@ fn update_node_metrics_timestamp(
11811193
/// Fetch a block by hash and call `transactions_confirmed` on each confirmable.
11821194
async fn confirm_block_transactions(
11831195
requester: &Requester, block_hash: BlockHash, height: u32,
1184-
confirmables: &[&(dyn Confirm + Sync + Send)], logger: &Logger,
1196+
confirmables: &[&(dyn Confirm + Sync + Send)], per_request_timeout: Duration, logger: &Logger,
11851197
) -> Result<(), Error> {
1186-
let indexed_block = requester.get_block(block_hash).await.map_err(|e| {
1187-
log_error!(logger, "Failed to fetch block {}: {:?}", block_hash, e);
1188-
Error::TxSyncFailed
1189-
})?;
1198+
let indexed_block = tokio::time::timeout(per_request_timeout, requester.get_block(block_hash))
1199+
.await
1200+
.map_err(|_| {
1201+
log_error!(logger, "Timed out fetching block {}", block_hash);
1202+
Error::TxSyncFailed
1203+
})?
1204+
.map_err(|e| {
1205+
log_error!(logger, "Failed to fetch block {}: {:?}", block_hash, e);
1206+
Error::TxSyncFailed
1207+
})?;
11901208
let block = &indexed_block.block;
11911209
let header = &block.header;
11921210
let txdata: Vec<(usize, &Transaction)> = block.txdata.iter().enumerate().collect();

0 commit comments

Comments
 (0)