From e1d96ddbd3c7b5594058bc78cd1ee2ada121cca6 Mon Sep 17 00:00:00 2001 From: Leo Date: Mon, 15 Dec 2025 15:42:23 +0400 Subject: [PATCH 01/17] feat: clean up tracing in robust provider --- src/robust_provider/provider.rs | 98 ++++++++++------------------- src/robust_provider/subscription.rs | 48 ++++---------- 2 files changed, 45 insertions(+), 101 deletions(-) diff --git a/src/robust_provider/provider.rs b/src/robust_provider/provider.rs index 41f936c7..74e033fa 100644 --- a/src/robust_provider/provider.rs +++ b/src/robust_provider/provider.rs @@ -11,7 +11,7 @@ use alloy::{ use backon::{ExponentialBuilder, Retryable}; use thiserror::Error; use tokio::time::{error as TokioError, timeout}; -use tracing::{error, info}; +use tracing::{error, info, instrument, warn}; use crate::robust_provider::RobustSubscription; @@ -111,20 +111,17 @@ impl RobustProvider { /// # Errors /// /// See [retry errors](#retry-errors). + #[instrument(level = "debug", skip(self))] pub async fn get_block_by_number( &self, number: BlockNumberOrTag, ) -> Result { - info!("eth_getBlockByNumber called"); let result = self .try_operation_with_failover( move |provider| async move { provider.get_block_by_number(number).await }, false, ) .await; - if let Err(e) = &result { - error!(error = %e, "eth_getByBlockNumber failed"); - } result?.ok_or_else(|| Error::BlockNotFound(number.into())) } @@ -136,17 +133,14 @@ impl RobustProvider { /// # Errors /// /// See [retry errors](#retry-errors). + #[instrument(level = "debug", skip(self))] pub async fn get_block(&self, id: BlockId) -> Result { - info!("eth_getBlock called"); let result = self .try_operation_with_failover( |provider| async move { provider.get_block(id).await }, false, ) .await; - if let Err(e) = &result { - error!(error = %e, "eth_getByBlockNumber failed"); - } result?.ok_or_else(|| Error::BlockNotFound(id)) } @@ -157,19 +151,14 @@ impl RobustProvider { /// # Errors /// /// See [retry errors](#retry-errors). + #[instrument(level = "debug", skip(self))] pub async fn get_block_number(&self) -> Result { - info!("eth_getBlockNumber called"); - let result = self - .try_operation_with_failover( - move |provider| async move { provider.get_block_number().await }, - false, - ) - .await - .map_err(Error::from); - if let Err(e) = &result { - error!(error = %e, "eth_getBlockNumber failed"); - } - result + self.try_operation_with_failover( + move |provider| async move { provider.get_block_number().await }, + false, + ) + .await + .map_err(Error::from) } /// Get the block number for a given block identifier. @@ -183,17 +172,14 @@ impl RobustProvider { /// # Errors /// /// See [retry errors](#retry-errors). + #[instrument(level = "debug", skip(self))] pub async fn get_block_number_by_id(&self, block_id: BlockId) -> Result { - info!("get_block_number_by_id called"); let result = self .try_operation_with_failover( move |provider| async move { provider.get_block_number_by_id(block_id).await }, false, ) .await; - if let Err(e) = &result { - error!(error = %e, "get_block_number_by_id failed"); - } result?.ok_or_else(|| Error::BlockNotFound(block_id)) } @@ -210,8 +196,8 @@ impl RobustProvider { /// # Errors /// /// See [retry errors](#retry-errors). + #[instrument(level = "debug", skip(self))] pub async fn get_latest_confirmed(&self, confirmations: u64) -> Result { - info!("get_latest_confirmed called with confirmations={}", confirmations); let latest_block = self.get_block_number().await?; let confirmed_block = latest_block.saturating_sub(confirmations); Ok(confirmed_block) @@ -224,17 +210,14 @@ impl RobustProvider { /// # Errors /// /// See [retry errors](#retry-errors). + #[instrument(level = "debug", skip(self))] pub async fn get_block_by_hash(&self, hash: BlockHash) -> Result { - info!("eth_getBlockByHash called"); let result = self .try_operation_with_failover( move |provider| async move { provider.get_block_by_hash(hash).await }, false, ) .await; - if let Err(e) = &result { - error!(error = %e, "eth_getBlockByHash failed"); - } result?.ok_or_else(|| Error::BlockNotFound(hash.into())) } @@ -246,19 +229,14 @@ impl RobustProvider { /// # Errors /// /// See [retry errors](#retry-errors). + #[instrument(level = "debug", skip(self, filter))] pub async fn get_logs(&self, filter: &Filter) -> Result, Error> { - info!("eth_getLogs called"); - let result = self - .try_operation_with_failover( - move |provider| async move { provider.get_logs(filter).await }, - false, - ) - .await - .map_err(Error::from); - if let Err(e) = &result { - error!(error = %e, "eth_getLogs failed"); - } - result + self.try_operation_with_failover( + move |provider| async move { provider.get_logs(filter).await }, + false, + ) + .await + .map_err(Error::from) } /// Subscribe to new block headers with automatic failover and reconnection. @@ -273,8 +251,8 @@ impl RobustProvider { /// # Errors /// /// see [retry errors](#retry-errors). + #[instrument(level = "debug", skip(self))] pub async fn subscribe_blocks(&self) -> Result, Error> { - info!("eth_subscribe called"); let subscription = self .try_operation_with_failover( move |provider| async move { @@ -282,15 +260,9 @@ impl RobustProvider { }, true, ) - .await; + .await?; - match subscription { - Ok(sub) => Ok(RobustSubscription::new(sub, self.clone())), - Err(e) => { - error!(error = %e, "eth_subscribe failed"); - Err(e.into()) - } - } + Ok(RobustSubscription::new(subscription, self.clone())) } /// Execute `operation` with exponential backoff and a total timeout. @@ -361,31 +333,30 @@ impl RobustProvider { Fut: Future>>, { let num_fallbacks = self.fallback_providers.len(); - if num_fallbacks > 0 && start_index == 0 { - info!("Primary provider failed, trying fallback provider(s)"); - } let fallback_providers = self.fallback_providers.iter().enumerate().skip(start_index); for (fallback_idx, provider) in fallback_providers { if require_pubsub && !Self::supports_pubsub(provider) { - info!("Fallback provider {} doesn't support pubsub, skipping", fallback_idx + 1); + warn!(provider_num = fallback_idx + 1, "Fallback provider doesn't support pubsub, skipping"); continue; } - info!("Attempting fallback provider {}/{}", fallback_idx + 1, num_fallbacks); match self.try_provider_with_timeout(provider, &operation).await { Ok(value) => { - info!(provider_num = fallback_idx + 1, "Fallback provider succeeded"); + info!( + provider_num = fallback_idx + 1, + total_fallbacks = num_fallbacks, + "Switched to fallback provider" + ); return Ok((value, fallback_idx)); } Err(e) => { - error!(provider_num = fallback_idx + 1, err = %e, "Fallback provider failed"); last_error = e; } } } - // All fallbacks failed / skipped, return the last error - error!("All providers failed or timed out - returning the last providers attempt's error"); + + error!("All providers exhausted"); Err(last_error) } @@ -405,12 +376,7 @@ impl RobustProvider { timeout( self.call_timeout, - (|| operation(provider.clone())) - .retry(retry_strategy) - .notify(|err: &RpcError, dur: Duration| { - info!(error = %err, "RPC error retrying after {:?}", dur); - }) - .sleep(tokio::time::sleep), + (|| operation(provider.clone())).retry(retry_strategy).sleep(tokio::time::sleep), ) .await .map_err(CoreError::from)? diff --git a/src/robust_provider/subscription.rs b/src/robust_provider/subscription.rs index 4818a6b3..41a8d2c2 100644 --- a/src/robust_provider/subscription.rs +++ b/src/robust_provider/subscription.rs @@ -15,7 +15,7 @@ use thiserror::Error; use tokio::{sync::broadcast::error::RecvError, time::timeout}; use tokio_stream::Stream; use tokio_util::sync::ReusableBoxFuture; -use tracing::{error, info, warn}; +use tracing::{info, warn}; use crate::robust_provider::{RobustProvider, provider::CoreError}; @@ -44,14 +44,8 @@ impl From for Error { impl From for Error { fn from(err: RecvError) -> Self { match err { - RecvError::Closed => { - error!("Provider closed the subscription channel"); - Error::Closed - } - RecvError::Lagged(count) => { - error!(skipped = count, "Receiver lagged"); - Error::Lagged(count) - } + RecvError::Closed => Error::Closed, + RecvError::Lagged(count) => Error::Lagged(count), } } } @@ -123,17 +117,7 @@ impl RobustSubscription { } return Ok(header); } - Err(recv_error) => { - match recv_error { - RecvError::Closed => { - error!("Provider closed the subscription channel"); - } - RecvError::Lagged(count) => { - error!(skipped = count, "Receiver lagged"); - } - } - return Err(recv_error.into()); - } + Err(recv_error) => return Err(recv_error.into()), }, Err(elapsed_err) => { warn!( @@ -163,8 +147,6 @@ impl RobustSubscription { return false; } - info!("Attempting to reconnect to primary provider"); - let operation = move |provider: RootProvider| async move { provider.subscribe_blocks().await }; @@ -172,19 +154,15 @@ impl RobustSubscription { let subscription = self.robust_provider.try_provider_with_timeout(primary, &operation).await; - match subscription { - Ok(sub) => { - info!("Successfully reconnected to primary provider"); - self.subscription = sub; - self.current_fallback_index = None; - self.last_reconnect_attempt = None; - true - } - Err(e) => { - self.last_reconnect_attempt = Some(Instant::now()); - warn!(error = %e, "Failed to reconnect to primary provider"); - false - } + if let Ok(sub) = subscription { + info!("Reconnected to primary provider"); + self.subscription = sub; + self.current_fallback_index = None; + self.last_reconnect_attempt = None; + true + } else { + self.last_reconnect_attempt = Some(Instant::now()); + false } } From dbdae73f1b0baf98db300aab283c152cc7e8b74a Mon Sep 17 00:00:00 2001 From: Leo Date: Mon, 15 Dec 2025 15:47:03 +0400 Subject: [PATCH 02/17] fix: fmt --- src/robust_provider/provider.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/robust_provider/provider.rs b/src/robust_provider/provider.rs index 74e033fa..d3a90520 100644 --- a/src/robust_provider/provider.rs +++ b/src/robust_provider/provider.rs @@ -337,7 +337,10 @@ impl RobustProvider { let fallback_providers = self.fallback_providers.iter().enumerate().skip(start_index); for (fallback_idx, provider) in fallback_providers { if require_pubsub && !Self::supports_pubsub(provider) { - warn!(provider_num = fallback_idx + 1, "Fallback provider doesn't support pubsub, skipping"); + warn!( + provider_num = fallback_idx + 1, + "Fallback provider doesn't support pubsub, skipping" + ); continue; } From 8e7865dfdca87a6e2c1a16c904c7c231d42cab8a Mon Sep 17 00:00:00 2001 From: Leo Date: Mon, 15 Dec 2025 18:18:57 +0400 Subject: [PATCH 03/17] ref: add back err -> change to warn ref: err --- src/robust_provider/provider.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/robust_provider/provider.rs b/src/robust_provider/provider.rs index d3a90520..e8ffd768 100644 --- a/src/robust_provider/provider.rs +++ b/src/robust_provider/provider.rs @@ -354,6 +354,7 @@ impl RobustProvider { return Ok((value, fallback_idx)); } Err(e) => { + warn!(provider_num = fallback_idx + 1, err = %e, "Fallback provider failed"); last_error = e; } } From 2a17bb090c2ae1ab4ff219592516042d24d0c4b9 Mon Sep 17 00:00:00 2001 From: Leo Date: Mon, 15 Dec 2025 18:21:38 +0400 Subject: [PATCH 04/17] ref: warn to trace --- src/robust_provider/provider.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/robust_provider/provider.rs b/src/robust_provider/provider.rs index e8ffd768..77b97228 100644 --- a/src/robust_provider/provider.rs +++ b/src/robust_provider/provider.rs @@ -11,7 +11,7 @@ use alloy::{ use backon::{ExponentialBuilder, Retryable}; use thiserror::Error; use tokio::time::{error as TokioError, timeout}; -use tracing::{error, info, instrument, warn}; +use tracing::{error, info, instrument, trace, warn}; use crate::robust_provider::RobustSubscription; @@ -337,7 +337,7 @@ impl RobustProvider { let fallback_providers = self.fallback_providers.iter().enumerate().skip(start_index); for (fallback_idx, provider) in fallback_providers { if require_pubsub && !Self::supports_pubsub(provider) { - warn!( + trace!( provider_num = fallback_idx + 1, "Fallback provider doesn't support pubsub, skipping" ); From 59cc546ddbc4104152d0830e4f8170029bcdcb4b Mon Sep 17 00:00:00 2001 From: Leo Date: Tue, 16 Dec 2025 16:01:06 +0400 Subject: [PATCH 05/17] ref: add back trace --- src/robust_provider/subscription.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/robust_provider/subscription.rs b/src/robust_provider/subscription.rs index 41a8d2c2..bb48d3cc 100644 --- a/src/robust_provider/subscription.rs +++ b/src/robust_provider/subscription.rs @@ -15,7 +15,7 @@ use thiserror::Error; use tokio::{sync::broadcast::error::RecvError, time::timeout}; use tokio_stream::Stream; use tokio_util::sync::ReusableBoxFuture; -use tracing::{info, warn}; +use tracing::{info, trace, warn}; use crate::robust_provider::{RobustProvider, provider::CoreError}; @@ -147,6 +147,8 @@ impl RobustSubscription { return false; } + trace!("Attempting to reconnect to primary provider"); + let operation = move |provider: RootProvider| async move { provider.subscribe_blocks().await }; From 2a99eeb14da03d4aa87cd24dae5a4512f619165b Mon Sep 17 00:00:00 2001 From: Leo Date: Tue, 16 Dec 2025 16:09:16 +0400 Subject: [PATCH 06/17] feat: add trace instrument to try_fallback_providers --- src/robust_provider/provider.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/robust_provider/provider.rs b/src/robust_provider/provider.rs index 77b97228..4c1b8866 100644 --- a/src/robust_provider/provider.rs +++ b/src/robust_provider/provider.rs @@ -321,6 +321,7 @@ impl RobustProvider { .map(|(value, _idx)| value) } + #[instrument(level = "trace", skip(self))] pub(crate) async fn try_fallback_providers_from( &self, operation: F, @@ -344,6 +345,8 @@ impl RobustProvider { continue; } + trace!("Attempting fallback provider {}/{}", fallback_idx + 1, num_fallbacks); + match self.try_provider_with_timeout(provider, &operation).await { Ok(value) => { info!( From 61cc2d98a46be3e72bad538b0b2a6f2208051fcf Mon Sep 17 00:00:00 2001 From: Leo Date: Tue, 16 Dec 2025 16:12:33 +0400 Subject: [PATCH 07/17] ref: fix trace instrument --- src/robust_provider/provider.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/robust_provider/provider.rs b/src/robust_provider/provider.rs index 4c1b8866..3aaa9662 100644 --- a/src/robust_provider/provider.rs +++ b/src/robust_provider/provider.rs @@ -306,6 +306,7 @@ impl RobustProvider { self.try_fallback_providers(&operation, require_pubsub, last_error).await } + #[instrument(level = "trace", skip(self, operation, last_error))] pub(crate) async fn try_fallback_providers( &self, operation: F, @@ -321,7 +322,7 @@ impl RobustProvider { .map(|(value, _idx)| value) } - #[instrument(level = "trace", skip(self))] + #[instrument(level = "trace", skip(self, operation, last_error))] pub(crate) async fn try_fallback_providers_from( &self, operation: F, From a8a57efba7f56612dc4fd2151f4a7d853312e256 Mon Sep 17 00:00:00 2001 From: Leo Date: Wed, 17 Dec 2025 11:08:33 +0400 Subject: [PATCH 08/17] ref: remove instrument debug on rpc methods --- src/robust_provider/provider.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/robust_provider/provider.rs b/src/robust_provider/provider.rs index 3aaa9662..2cf12b25 100644 --- a/src/robust_provider/provider.rs +++ b/src/robust_provider/provider.rs @@ -111,7 +111,6 @@ impl RobustProvider { /// # Errors /// /// See [retry errors](#retry-errors). - #[instrument(level = "debug", skip(self))] pub async fn get_block_by_number( &self, number: BlockNumberOrTag, @@ -133,7 +132,6 @@ impl RobustProvider { /// # Errors /// /// See [retry errors](#retry-errors). - #[instrument(level = "debug", skip(self))] pub async fn get_block(&self, id: BlockId) -> Result { let result = self .try_operation_with_failover( @@ -151,7 +149,6 @@ impl RobustProvider { /// # Errors /// /// See [retry errors](#retry-errors). - #[instrument(level = "debug", skip(self))] pub async fn get_block_number(&self) -> Result { self.try_operation_with_failover( move |provider| async move { provider.get_block_number().await }, @@ -172,7 +169,6 @@ impl RobustProvider { /// # Errors /// /// See [retry errors](#retry-errors). - #[instrument(level = "debug", skip(self))] pub async fn get_block_number_by_id(&self, block_id: BlockId) -> Result { let result = self .try_operation_with_failover( @@ -196,7 +192,6 @@ impl RobustProvider { /// # Errors /// /// See [retry errors](#retry-errors). - #[instrument(level = "debug", skip(self))] pub async fn get_latest_confirmed(&self, confirmations: u64) -> Result { let latest_block = self.get_block_number().await?; let confirmed_block = latest_block.saturating_sub(confirmations); @@ -210,7 +205,6 @@ impl RobustProvider { /// # Errors /// /// See [retry errors](#retry-errors). - #[instrument(level = "debug", skip(self))] pub async fn get_block_by_hash(&self, hash: BlockHash) -> Result { let result = self .try_operation_with_failover( @@ -229,7 +223,6 @@ impl RobustProvider { /// # Errors /// /// See [retry errors](#retry-errors). - #[instrument(level = "debug", skip(self, filter))] pub async fn get_logs(&self, filter: &Filter) -> Result, Error> { self.try_operation_with_failover( move |provider| async move { provider.get_logs(filter).await }, @@ -251,7 +244,6 @@ impl RobustProvider { /// # Errors /// /// see [retry errors](#retry-errors). - #[instrument(level = "debug", skip(self))] pub async fn subscribe_blocks(&self) -> Result, Error> { let subscription = self .try_operation_with_failover( From a3892fd643b774da7c217d567e2191e419236595 Mon Sep 17 00:00:00 2001 From: Leo Date: Wed, 17 Dec 2025 11:09:56 +0400 Subject: [PATCH 09/17] feat: add trace instrument to robust --- src/robust_provider/subscription.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/robust_provider/subscription.rs b/src/robust_provider/subscription.rs index bb48d3cc..2d471e23 100644 --- a/src/robust_provider/subscription.rs +++ b/src/robust_provider/subscription.rs @@ -15,7 +15,7 @@ use thiserror::Error; use tokio::{sync::broadcast::error::RecvError, time::timeout}; use tokio_stream::Stream; use tokio_util::sync::ReusableBoxFuture; -use tracing::{info, trace, warn}; +use tracing::{info, instrument, trace, warn}; use crate::robust_provider::{RobustProvider, provider::CoreError}; @@ -133,6 +133,7 @@ impl RobustSubscription { /// Try to reconnect to the primary provider if enough time has elapsed. /// Returns true if reconnection was successful, false if it's not time yet or if it failed. + #[instrument(level = "trace", skip(self))] async fn try_reconnect_to_primary(&mut self, force: bool) -> bool { // Check if we should attempt reconnection let should_reconnect = force || From c38b1815b03d9867299df06d6cf2af099362c5e5 Mon Sep 17 00:00:00 2001 From: Leo Date: Thu, 18 Dec 2025 15:19:33 +0400 Subject: [PATCH 10/17] fix: trace --- src/robust_provider/provider.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/robust_provider/provider.rs b/src/robust_provider/provider.rs index 3c51a3e8..2e0f4a9e 100644 --- a/src/robust_provider/provider.rs +++ b/src/robust_provider/provider.rs @@ -337,7 +337,11 @@ impl RobustProvider { continue; } - trace!("Attempting fallback provider {}/{}", fallback_idx + 1, num_fallbacks); + trace!( + fallback_provider_index = fallback_idx + 1, + total_num_fallbacks = num_fallbacks, + "Attempting fallback provider" + ); match self.try_provider_with_timeout(provider, &operation).await { Ok(value) => { From 09a3d0298b619d7eb89b949ff1443d6f216b9f4e Mon Sep 17 00:00:00 2001 From: Leo Date: Thu, 18 Dec 2025 15:24:32 +0400 Subject: [PATCH 11/17] feat: use default traces where it makes sense --- src/robust_provider/provider.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/robust_provider/provider.rs b/src/robust_provider/provider.rs index 2e0f4a9e..2791a259 100644 --- a/src/robust_provider/provider.rs +++ b/src/robust_provider/provider.rs @@ -337,7 +337,7 @@ impl RobustProvider { continue; } - trace!( + tracing::trace!( fallback_provider_index = fallback_idx + 1, total_num_fallbacks = num_fallbacks, "Attempting fallback provider" @@ -353,13 +353,14 @@ impl RobustProvider { return Ok((value, fallback_idx)); } Err(e) => { - warn!(provider_num = fallback_idx + 1, err = %e, "Fallback provider failed"); + tracing::warn!(provider_num = fallback_idx + 1, err = %e, "Fallback provider failed"); last_error = e; } } } - error!("All providers exhausted"); + tracing::error!("All providers exhausted"); + Err(last_error) } From 24833e1551bf92712438404e9ecc6d5d50413b37 Mon Sep 17 00:00:00 2001 From: Leo Date: Fri, 19 Dec 2025 14:48:21 +0100 Subject: [PATCH 12/17] ref: remove some default traces + cfg feature on tracing for instrument --- src/robust_provider/provider.rs | 9 +++++---- src/robust_provider/subscription.rs | 5 ++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/robust_provider/provider.rs b/src/robust_provider/provider.rs index 674e9249..4c60e379 100644 --- a/src/robust_provider/provider.rs +++ b/src/robust_provider/provider.rs @@ -12,6 +12,7 @@ use backon::{ExponentialBuilder, Retryable}; use futures::TryFutureExt; use thiserror::Error; use tokio::time::{error as TokioError, timeout}; +#[cfg(feature = "tracing")] use tracing::instrument; use crate::robust_provider::RobustSubscription; @@ -322,7 +323,7 @@ impl RobustProvider { .await } - #[instrument(level = "trace", skip(self, operation, last_error))] + #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(self, operation, last_error)))] pub(crate) async fn try_fallback_providers( &self, operation: F, @@ -338,7 +339,7 @@ impl RobustProvider { .map(|(value, _idx)| value) } - #[instrument(level = "trace", skip(self, operation, last_error))] + #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(self, operation, last_error)))] pub(crate) async fn try_fallback_providers_from( &self, operation: F, @@ -362,7 +363,7 @@ impl RobustProvider { continue; } - tracing::trace!( + trace!( fallback_provider_index = fallback_idx + 1, total_num_fallbacks = num_fallbacks, "Attempting fallback provider" @@ -384,7 +385,7 @@ impl RobustProvider { } } - tracing::error!("All providers exhausted"); + tracing::error!("All providers failed"); Err(last_error) } diff --git a/src/robust_provider/subscription.rs b/src/robust_provider/subscription.rs index 28f032b7..6c4c51fe 100644 --- a/src/robust_provider/subscription.rs +++ b/src/robust_provider/subscription.rs @@ -4,6 +4,7 @@ use std::{ task::{Context, Poll, ready}, time::{Duration, Instant}, }; +#[cfg(feature = "tracing")] use tracing::instrument; use alloy::{ @@ -133,7 +134,7 @@ impl RobustSubscription { /// Try to reconnect to the primary provider if enough time has elapsed. /// Returns true if reconnection was successful, false if it's not time yet or if it failed. - #[instrument(level = "trace", skip(self))] + #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(self)))] async fn try_reconnect_to_primary(&mut self, force: bool) -> bool { // Check if we should attempt reconnection let should_reconnect = force || @@ -148,8 +149,6 @@ impl RobustSubscription { return false; } - trace!("Attempting to reconnect to primary provider"); - let operation = move |provider: RootProvider| async move { provider.subscribe_blocks().await }; From 6e331b71feb826e2973c29d6e2c8001d08c8a746 Mon Sep 17 00:00:00 2001 From: 0xNeshi Date: Mon, 22 Dec 2025 08:18:49 +0100 Subject: [PATCH 13/17] ref: inline instrument import --- src/robust_provider/provider.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/robust_provider/provider.rs b/src/robust_provider/provider.rs index 4c60e379..7fd15fb1 100644 --- a/src/robust_provider/provider.rs +++ b/src/robust_provider/provider.rs @@ -12,8 +12,6 @@ use backon::{ExponentialBuilder, Retryable}; use futures::TryFutureExt; use thiserror::Error; use tokio::time::{error as TokioError, timeout}; -#[cfg(feature = "tracing")] -use tracing::instrument; use crate::robust_provider::RobustSubscription; @@ -323,7 +321,10 @@ impl RobustProvider { .await } - #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(self, operation, last_error)))] + #[cfg_attr( + feature = "tracing", + tracing::instrument(level = "trace", skip(self, operation, last_error)) + )] pub(crate) async fn try_fallback_providers( &self, operation: F, @@ -339,7 +340,10 @@ impl RobustProvider { .map(|(value, _idx)| value) } - #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(self, operation, last_error)))] + #[cfg_attr( + feature = "tracing", + tracing::instrument(level = "trace", skip(self, operation, last_error)) + )] pub(crate) async fn try_fallback_providers_from( &self, operation: F, From 22346b8d7bfbc353826157eaf633a66d2ba8cedc Mon Sep 17 00:00:00 2001 From: 0xNeshi Date: Mon, 22 Dec 2025 08:20:52 +0100 Subject: [PATCH 14/17] ref: use try_fallback_providers_from instead of try_fallback_providers helper --- src/robust_provider/provider.rs | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/robust_provider/provider.rs b/src/robust_provider/provider.rs index 7fd15fb1..965a0d48 100644 --- a/src/robust_provider/provider.rs +++ b/src/robust_provider/provider.rs @@ -316,30 +316,12 @@ impl RobustProvider { let primary = self.primary(); self.try_provider_with_timeout(primary, &operation) .or_else(|last_error| { - self.try_fallback_providers(&operation, require_pubsub, last_error) + self.try_fallback_providers_from(&operation, require_pubsub, last_error, 0) + .map_ok(|(value, _)| value) }) .await } - #[cfg_attr( - feature = "tracing", - tracing::instrument(level = "trace", skip(self, operation, last_error)) - )] - pub(crate) async fn try_fallback_providers( - &self, - operation: F, - require_pubsub: bool, - last_error: CoreError, - ) -> Result - where - F: Fn(RootProvider) -> Fut, - Fut: Future>>, - { - self.try_fallback_providers_from(operation, require_pubsub, last_error, 0) - .await - .map(|(value, _idx)| value) - } - #[cfg_attr( feature = "tracing", tracing::instrument(level = "trace", skip(self, operation, last_error)) From 7a4be069088144b5a6df28c82f2a21015023c169 Mon Sep 17 00:00:00 2001 From: 0xNeshi Date: Mon, 22 Dec 2025 08:22:10 +0100 Subject: [PATCH 15/17] trace last_error in try_fallback_providers_from --- src/robust_provider/provider.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/robust_provider/provider.rs b/src/robust_provider/provider.rs index 965a0d48..f749449a 100644 --- a/src/robust_provider/provider.rs +++ b/src/robust_provider/provider.rs @@ -322,10 +322,7 @@ impl RobustProvider { .await } - #[cfg_attr( - feature = "tracing", - tracing::instrument(level = "trace", skip(self, operation, last_error)) - )] + #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", skip(self, operation)))] pub(crate) async fn try_fallback_providers_from( &self, operation: F, From 603fd875365039b60b2e684d948c9bf25be740b7 Mon Sep 17 00:00:00 2001 From: 0xNeshi Date: Mon, 22 Dec 2025 08:25:30 +0100 Subject: [PATCH 16/17] inline instrument import in subscription.rs --- src/robust_provider/subscription.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/robust_provider/subscription.rs b/src/robust_provider/subscription.rs index 6c4c51fe..94e008e2 100644 --- a/src/robust_provider/subscription.rs +++ b/src/robust_provider/subscription.rs @@ -4,8 +4,6 @@ use std::{ task::{Context, Poll, ready}, time::{Duration, Instant}, }; -#[cfg(feature = "tracing")] -use tracing::instrument; use alloy::{ network::Network, @@ -134,7 +132,7 @@ impl RobustSubscription { /// Try to reconnect to the primary provider if enough time has elapsed. /// Returns true if reconnection was successful, false if it's not time yet or if it failed. - #[cfg_attr(feature = "tracing", instrument(level = "trace", skip(self)))] + #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", skip(self)))] async fn try_reconnect_to_primary(&mut self, force: bool) -> bool { // Check if we should attempt reconnection let should_reconnect = force || From ae2db3302cab968438a46c3bd822ea9cf15c0794 Mon Sep 17 00:00:00 2001 From: 0xNeshi Date: Mon, 22 Dec 2025 08:25:37 +0100 Subject: [PATCH 17/17] instrument switch_to_fallback --- src/robust_provider/subscription.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/robust_provider/subscription.rs b/src/robust_provider/subscription.rs index 94e008e2..11ff4b70 100644 --- a/src/robust_provider/subscription.rs +++ b/src/robust_provider/subscription.rs @@ -166,6 +166,7 @@ impl RobustSubscription { } } + #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", skip(self)))] async fn switch_to_fallback(&mut self, last_error: CoreError) -> Result<(), Error> { // If we're on a fallback, try primary first before moving to next fallback if self.is_on_fallback() && self.try_reconnect_to_primary(true).await {