From 2a75b0d5d7b70574b9c902a4b54d1c294f5539c7 Mon Sep 17 00:00:00 2001 From: niveda Date: Tue, 10 Dec 2024 12:17:43 -0800 Subject: [PATCH 1/4] fix: rebase --- crates/builder/src/sender/bloxroute.rs | 4 +++- crates/builder/src/sender/mod.rs | 12 +++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/crates/builder/src/sender/bloxroute.rs b/crates/builder/src/sender/bloxroute.rs index 4e9e7ac37..ba10580ae 100644 --- a/crates/builder/src/sender/bloxroute.rs +++ b/crates/builder/src/sender/bloxroute.rs @@ -157,7 +157,9 @@ struct BloxrouteResponse { impl From for TxSenderError { fn from(value: jsonrpsee::core::ClientError) -> Self { if let jsonrpsee::core::ClientError::Call(e) = &value { - if let Some(e) = super::parse_known_call_execution_failed(e.message()) { + if let Some(e) = + super::parse_known_call_execution_failed(e.message(), &(e.code() as i64)) + { return e; } } diff --git a/crates/builder/src/sender/mod.rs b/crates/builder/src/sender/mod.rs index 78ddd9eb7..02ed1a72e 100644 --- a/crates/builder/src/sender/mod.rs +++ b/crates/builder/src/sender/mod.rs @@ -240,7 +240,7 @@ impl From for TxSenderError { ProviderError::RPC(e) => { if let Some(e) = e.as_error_resp() { // Client impls use different error codes, just match on the message - if let Some(e) = parse_known_call_execution_failed(&e.message) { + if let Some(e) = parse_known_call_execution_failed(&e.message, &e.code) { e } else { TxSenderError::Other(value.into()) @@ -257,9 +257,15 @@ impl From for TxSenderError { // Geth: https://github.com/ethereum/go-ethereum/blob/23800122b37695be50565f8221858a16ce1763db/core/txpool/errors.go#L31 // Reth: https://github.com/paradigmxyz/reth/blob/8e4a917ec1aa70b3779083454ff2d5ecf6b44168/crates/rpc/rpc-eth-types/src/error/mod.rs#L624 // Erigon: https://github.com/erigontech/erigon/blob/96fabf3fd1a4ddce26b845ffe2b6cfb50d5b4b2d/txnprovider/txpool/txpoolcfg/txpoolcfg.go#L124 -fn parse_known_call_execution_failed(e: &str) -> Option { +fn parse_known_call_execution_failed(message: &str, code: &i64) -> Option { + // The error code is -32003 or -32005 when condition is not met, we check this first before checking the message + // https://eips.ethereum.org/EIPS/eip-7796 + if *code == -32003 || *code == -32005 { + return Some(TxSenderError::ConditionNotMet); + } + // String match on the error message when an error code is not available // DEVELOPER NOTE: ensure to put the most specific matches first - match &e.to_lowercase() { + match &message.to_lowercase() { // geth. Reth & erigon don't have similar x if x.contains("future transaction tries to replace pending") => { Some(TxSenderError::Rejected) From 029e64fc424305b3f2c088642dfe7f9b4ba39768 Mon Sep 17 00:00:00 2001 From: niveda Date: Tue, 10 Dec 2024 12:20:26 -0800 Subject: [PATCH 2/4] fix: rebase --- crates/builder/src/sender/mod.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/builder/src/sender/mod.rs b/crates/builder/src/sender/mod.rs index 02ed1a72e..66b85e721 100644 --- a/crates/builder/src/sender/mod.rs +++ b/crates/builder/src/sender/mod.rs @@ -280,10 +280,6 @@ fn parse_known_call_execution_failed(message: &str, code: &i64) -> Option Some(TxSenderError::NonceTooLow), - // Arbitrum conditional sender error message - x if x.contains("storage slot value condition not met") => { - Some(TxSenderError::ConditionNotMet) - } // geth x if x.contains("transaction underpriced") => Some(TxSenderError::Underpriced), // reth From e979527c38e572fc4e61c8350ead0225ea53eff1 Mon Sep 17 00:00:00 2001 From: niveda Date: Tue, 10 Dec 2024 12:23:26 -0800 Subject: [PATCH 3/4] fix: fix comment --- crates/builder/src/sender/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/builder/src/sender/mod.rs b/crates/builder/src/sender/mod.rs index 66b85e721..7801297d1 100644 --- a/crates/builder/src/sender/mod.rs +++ b/crates/builder/src/sender/mod.rs @@ -258,7 +258,7 @@ impl From for TxSenderError { // Reth: https://github.com/paradigmxyz/reth/blob/8e4a917ec1aa70b3779083454ff2d5ecf6b44168/crates/rpc/rpc-eth-types/src/error/mod.rs#L624 // Erigon: https://github.com/erigontech/erigon/blob/96fabf3fd1a4ddce26b845ffe2b6cfb50d5b4b2d/txnprovider/txpool/txpoolcfg/txpoolcfg.go#L124 fn parse_known_call_execution_failed(message: &str, code: &i64) -> Option { - // The error code is -32003 or -32005 when condition is not met, we check this first before checking the message + // The error code is -32003 or -32005 when condition is not met, we check error codes before checking the message // https://eips.ethereum.org/EIPS/eip-7796 if *code == -32003 || *code == -32005 { return Some(TxSenderError::ConditionNotMet); From 5c34bae92c279c323574985c1871ff75f2d728a0 Mon Sep 17 00:00:00 2001 From: niveda Date: Tue, 10 Dec 2024 14:02:51 -0800 Subject: [PATCH 4/4] fix: pr comments --- crates/builder/src/sender/bloxroute.rs | 3 +- crates/builder/src/sender/mod.rs | 62 +++++++++++++++----------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/crates/builder/src/sender/bloxroute.rs b/crates/builder/src/sender/bloxroute.rs index ba10580ae..7687b87ed 100644 --- a/crates/builder/src/sender/bloxroute.rs +++ b/crates/builder/src/sender/bloxroute.rs @@ -157,8 +157,7 @@ struct BloxrouteResponse { impl From for TxSenderError { fn from(value: jsonrpsee::core::ClientError) -> Self { if let jsonrpsee::core::ClientError::Call(e) = &value { - if let Some(e) = - super::parse_known_call_execution_failed(e.message(), &(e.code() as i64)) + if let Some(e) = super::parse_known_call_execution_failed(e.message(), e.code() as i64) { return e; } diff --git a/crates/builder/src/sender/mod.rs b/crates/builder/src/sender/mod.rs index 7801297d1..9c94c8961 100644 --- a/crates/builder/src/sender/mod.rs +++ b/crates/builder/src/sender/mod.rs @@ -240,7 +240,7 @@ impl From for TxSenderError { ProviderError::RPC(e) => { if let Some(e) = e.as_error_resp() { // Client impls use different error codes, just match on the message - if let Some(e) = parse_known_call_execution_failed(&e.message, &e.code) { + if let Some(e) = parse_known_call_execution_failed(&e.message, e.code) { e } else { TxSenderError::Other(value.into()) @@ -257,35 +257,43 @@ impl From for TxSenderError { // Geth: https://github.com/ethereum/go-ethereum/blob/23800122b37695be50565f8221858a16ce1763db/core/txpool/errors.go#L31 // Reth: https://github.com/paradigmxyz/reth/blob/8e4a917ec1aa70b3779083454ff2d5ecf6b44168/crates/rpc/rpc-eth-types/src/error/mod.rs#L624 // Erigon: https://github.com/erigontech/erigon/blob/96fabf3fd1a4ddce26b845ffe2b6cfb50d5b4b2d/txnprovider/txpool/txpoolcfg/txpoolcfg.go#L124 -fn parse_known_call_execution_failed(message: &str, code: &i64) -> Option { - // The error code is -32003 or -32005 when condition is not met, we check error codes before checking the message - // https://eips.ethereum.org/EIPS/eip-7796 - if *code == -32003 || *code == -32005 { +fn parse_known_call_execution_failed(message: &str, code: i64) -> Option { + // Check error codes before checking the message + // The error code is -32003 or -32005 when condition is not met: https://eips.ethereum.org/EIPS/eip-7796 + if code == -32003 || code == -32005 { return Some(TxSenderError::ConditionNotMet); } // String match on the error message when an error code is not available // DEVELOPER NOTE: ensure to put the most specific matches first - match &message.to_lowercase() { - // geth. Reth & erigon don't have similar - x if x.contains("future transaction tries to replace pending") => { - Some(TxSenderError::Rejected) - } - // geth & reth - x if x.contains("replacement transaction underpriced") => { - Some(TxSenderError::ReplacementUnderpriced) - } - // erigon - x if x.contains("could not replace existing tx") => { - Some(TxSenderError::ReplacementUnderpriced) - } - // geth, erigon, reth - x if x.contains("nonce too low") => Some(TxSenderError::NonceTooLow), - // geth - x if x.contains("transaction underpriced") => Some(TxSenderError::Underpriced), - // reth - x if x.contains("txpool is full") => Some(TxSenderError::Underpriced), - // erigon - x if x.contains("underpriced") => Some(TxSenderError::Underpriced), - _ => None, + let lowercase_message = message.to_lowercase(); + // geth. Reth & erigon don't have similar + if lowercase_message.contains("future transaction tries to replace pending") { + return Some(TxSenderError::Rejected); + } + // geth & reth + if lowercase_message.contains("replacement transaction underpriced") { + return Some(TxSenderError::ReplacementUnderpriced); + } + // erigon + if lowercase_message.contains("could not replace existing tx") { + return Some(TxSenderError::ReplacementUnderpriced); + } + // geth, erigon, reth + if lowercase_message.contains("nonce too low") { + return Some(TxSenderError::NonceTooLow); + } + // geth + if lowercase_message.contains("transaction underpriced") { + return Some(TxSenderError::Underpriced); + } + // reth + if lowercase_message.contains("txpool is full") { + return Some(TxSenderError::Underpriced); + } + // erigon + if lowercase_message.contains("underpriced") { + return Some(TxSenderError::Underpriced); } + // No known error matched + None }