From 0d1e629567d76293021dd3416cc3866798a18478 Mon Sep 17 00:00:00 2001 From: Bryan Stitt Date: Mon, 26 Jun 2023 21:11:43 -0700 Subject: [PATCH] more tracing and error handling --- web3_proxy/src/jsonrpc.rs | 48 -------------------------- web3_proxy/src/rpcs/consensus.rs | 8 ++--- web3_proxy/src/rpcs/many.rs | 2 +- web3_proxy/src/rpcs/request.rs | 59 ++++++++++++++++++++------------ 4 files changed, 43 insertions(+), 74 deletions(-) diff --git a/web3_proxy/src/jsonrpc.rs b/web3_proxy/src/jsonrpc.rs index 84353a21..1eff1145 100644 --- a/web3_proxy/src/jsonrpc.rs +++ b/web3_proxy/src/jsonrpc.rs @@ -297,54 +297,6 @@ impl JsonRpcForwardedResponse { } } - // TODO: delete this. its on JsonRpcErrorData - pub fn from_ethers_error(e: ProviderError, id: Box) -> Web3ProxyResult { - // TODO: move turning ClientError into json to a helper function? - let code; - let message: String; - let data; - - match e { - ProviderError::JsonRpcClientError(err) => { - if let Some(err) = err.as_error_response() { - code = err.code; - message = err.message.clone(); - data = err.data.clone(); - } else if let Some(err) = err.as_serde_error() { - // this is not an rpc error. keep it as an error - // TODO: ankr gives us "rate limited" but ethers fails to parse because it tries to require id even though its optional - return Err(Web3ProxyError::BadResponse( - format!("parse error: {}", err).into(), - )); - } else { - return Err(anyhow::anyhow!("unexpected ethers error! {:?}", err).into()); - } - } - e => return Err(e.into()), - } - - Ok(Self { - jsonrpc: "2.0", - id, - result: None, - error: Some(JsonRpcErrorData { - code, - message: message.into(), - data, - }), - }) - } - - pub fn try_from_response_result( - result: Result, ProviderError>, - id: Box, - ) -> Web3ProxyResult { - match result { - Ok(response) => Ok(Self::from_raw_response(response, id)), - Err(e) => Self::from_ethers_error(e, id), - } - } - pub fn from_response_data(data: JsonRpcResponseEnum>, id: Box) -> Self { match data { JsonRpcResponseEnum::Result { value, .. } => Self::from_raw_response(value, id), diff --git a/web3_proxy/src/rpcs/consensus.rs b/web3_proxy/src/rpcs/consensus.rs index 60809493..8d5206ba 100644 --- a/web3_proxy/src/rpcs/consensus.rs +++ b/web3_proxy/src/rpcs/consensus.rs @@ -251,7 +251,7 @@ impl ConsensusWeb3Rpcs { if let Some(min_block_needed) = min_block_needed { if !self.has_block_data(rpc, min_block_needed) { trace!( - "{} is missing min_block_needed ({}). skipping", + "{} is missing min_block_needed ({}). will not work now", rpc, min_block_needed, ); @@ -262,7 +262,7 @@ impl ConsensusWeb3Rpcs { if let Some(max_block_needed) = max_block_needed { if !self.has_block_data(rpc, max_block_needed) { trace!( - "{} is missing max_block_needed ({}). skipping", + "{} is missing max_block_needed ({}). will not work now", rpc, max_block_needed, ); @@ -273,7 +273,7 @@ impl ConsensusWeb3Rpcs { // TODO: this might be a big perf hit. benchmark if let Some(x) = rpc.hard_limit_until.as_ref() { if *x.borrow() > Instant::now() { - trace!("{} is rate limited. skipping", rpc,); + trace!("{} is rate limited. will not work now", rpc,); return false; } } @@ -786,7 +786,7 @@ impl ConsensusFinder { if num_known < web3_rpcs.min_synced_rpcs { // this keeps us from serving requests when the proxy first starts - trace!("not enough servers known"); + info!(min_synced_rpcs=%web3_rpcs.min_synced_rpcs, "not enough servers known"); return Ok(None); } diff --git a/web3_proxy/src/rpcs/many.rs b/web3_proxy/src/rpcs/many.rs index 914d7351..7481ae97 100644 --- a/web3_proxy/src/rpcs/many.rs +++ b/web3_proxy/src/rpcs/many.rs @@ -887,7 +887,7 @@ impl Web3Rpcs { .await } - /// Track stats + /// Make a request with stat tracking. pub async fn request_with_metadata( &self, method: &str, diff --git a/web3_proxy/src/rpcs/request.rs b/web3_proxy/src/rpcs/request.rs index 41749688..0cef61fa 100644 --- a/web3_proxy/src/rpcs/request.rs +++ b/web3_proxy/src/rpcs/request.rs @@ -263,12 +263,12 @@ impl OpenRequestHandle { // check for "execution reverted" here // TODO: move this info a function on ResponseErrorType let response_type = if let ProviderError::JsonRpcClientError(err) = err { - // Http and Ws errors are very similar, but different types + // JsonRpc and Application errors get rolled into the JsonRpcClientError let msg = err.as_error_response().map(|x| x.message.clone()); - trace!("error message: {:?}", msg); - if let Some(msg) = msg { + trace!(%msg, "jsonrpc error message"); + if msg.starts_with("execution reverted") { trace!("revert from {}", self.rpc); ResponseTypes::Revert @@ -316,42 +316,59 @@ impl OpenRequestHandle { RequestErrorHandler::DebugLevel => { // TODO: think about this revert check more. sometimes we might want reverts logged so this needs a flag if matches!(response_type, ResponseTypes::Revert) { + trace!( + rpc=%self.rpc, + %method, + ?params, + ?err, + "revert", + ); + } else { debug!( - "bad response from {}! method={} params={:?} err={:?}", - self.rpc, method, params, err + rpc=%self.rpc, + %method, + ?params, + ?err, + "bad response", ); } } RequestErrorHandler::TraceLevel => { trace!( - "bad response from {}! method={} params={:?} err={:?}", - self.rpc, - method, - params, - err + rpc=%self.rpc, + %method, + ?params, + ?err, + "bad response", ); } RequestErrorHandler::ErrorLevel => { - // TODO: include params if not running in release mode + // TODO: only include params if not running in release mode error!( - "bad response from {}! method={} err={:?}", - self.rpc, method, err + rpc=%self.rpc, + %method, + ?params, + ?err, + "bad response", ); } RequestErrorHandler::WarnLevel => { - // TODO: include params if not running in release mode + // TODO: only include params if not running in release mode warn!( - "bad response from {}! method={} err={:?}", - self.rpc, method, err + rpc=%self.rpc, + %method, + ?params, + ?err, + "bad response", ); } RequestErrorHandler::Save => { trace!( - "bad response from {}! method={} params={:?} err={:?}", - self.rpc, - method, - params, - err + rpc=%self.rpc, + %method, + ?params, + ?err, + "bad response", ); // TODO: do not unwrap! (doesn't matter much since we check method as a string above)