From 7bd6efd8482b6106a080c265ac38dbf995bc7704 Mon Sep 17 00:00:00 2001 From: Micaiah Reid <4290054+vabanaerytk@users.noreply.github.com> Date: Tue, 19 Mar 2024 11:14:09 -0400 Subject: [PATCH] fix: log errors on block download failure; implement max retries (#503) ### Description Before this PR, Chainhook would loop infinitely if there is a problem downloading a BTC block, and it wouldn't log much information as to what was causing the failure. This PR implements better logging, and breaks out of the loop at 10 failed attempts. --- .../chainhook-sdk/src/indexer/bitcoin/mod.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/components/chainhook-sdk/src/indexer/bitcoin/mod.rs b/components/chainhook-sdk/src/indexer/bitcoin/mod.rs index 44c999b..997c2c0 100644 --- a/components/chainhook-sdk/src/indexer/bitcoin/mod.rs +++ b/components/chainhook-sdk/src/indexer/bitcoin/mod.rs @@ -153,18 +153,21 @@ pub async fn download_and_parse_block_with_retry( ctx: &Context, ) -> Result { let mut errors_count = 0; + let max_retries = 10; let block = loop { match download_and_parse_block(http_client, block_hash, bitcoin_config, ctx).await { Ok(result) => break result, - Err(_e) => { + Err(e) => { errors_count += 1; - if errors_count > 3 { + if errors_count > 3 && errors_count < max_retries { ctx.try_log(|logger| { slog::warn!( logger, - "unable to fetch and parse block #{block_hash}: will retry in a few seconds (attempt #{errors_count}).", + "unable to fetch and parse block #{block_hash}: will retry in a few seconds (attempt #{errors_count}). Error: {e}", ) }); + } else if errors_count == max_retries { + return Err(format!("unable to fetch and parse block #{block_hash} after {errors_count} attempts. Error: {e}")); } std::thread::sleep(std::time::Duration::from_secs(1)); } @@ -180,18 +183,21 @@ pub async fn retrieve_block_hash_with_retry( ctx: &Context, ) -> Result { let mut errors_count = 0; + let max_retries = 10; let block_hash = loop { match retrieve_block_hash(http_client, block_height, bitcoin_config, ctx).await { Ok(result) => break result, - Err(_e) => { + Err(e) => { errors_count += 1; - if errors_count > 3 { + if errors_count > 3 && errors_count < max_retries { ctx.try_log(|logger| { slog::warn!( logger, - "unable to retrieve block hash #{block_height}: will retry in a few seconds (attempt #{errors_count}).", + "unable to retrieve block hash #{block_height}: will retry in a few seconds (attempt #{errors_count}). Error: {e}", ) }); + } else if errors_count == max_retries { + return Err(format!("unable to retrieve block hash #{block_height} after {errors_count} attempts. Error: {e}")); } std::thread::sleep(std::time::Duration::from_secs(2)); }