diff --git a/Cargo.lock b/Cargo.lock index 17d366faefa6..f2d6aceb7b67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -150,7 +150,26 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "alloy-primitives" version = "0.3.2" -source = "git+https://github.com/alloy-rs/core#0c21fcc48eab0b52c20d3e98c739bac862aad8ff" +source = "git+https://github.com/alloy-rs/core?rev=5733dc1b3987b0d2f2677d055de85fd5f721b2fd#5733dc1b3987b0d2f2677d055de85fd5f721b2fd" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more", + "hex-literal", + "itoa", + "proptest", + "rand 0.8.5", + "ruint", + "serde", + "tiny-keccak", +] + +[[package]] +name = "alloy-primitives" +version = "0.3.2" +source = "git+https://github.com/alloy-rs/core#fb5fcc26a14f297652a6e7edff395be350544d62" dependencies = [ "alloy-rlp", "arbitrary", @@ -193,6 +212,31 @@ dependencies = [ "syn 2.0.37", ] +[[package]] +name = "alloy-sol-macro" +version = "0.3.2" +source = "git+https://github.com/alloy-rs/core?rev=5733dc1b3987b0d2f2677d055de85fd5f721b2fd#5733dc1b3987b0d2f2677d055de85fd5f721b2fd" +dependencies = [ + "dunce", + "heck", + "proc-macro2", + "quote", + "syn 2.0.37", + "syn-solidity", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-types" +version = "0.3.2" +source = "git+https://github.com/alloy-rs/core?rev=5733dc1b3987b0d2f2677d055de85fd5f721b2fd#5733dc1b3987b0d2f2677d055de85fd5f721b2fd" +dependencies = [ + "alloy-primitives 0.3.2 (git+https://github.com/alloy-rs/core?rev=5733dc1b3987b0d2f2677d055de85fd5f721b2fd)", + "alloy-sol-macro", + "const-hex", + "serde", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -5912,8 +5956,9 @@ dependencies = [ name = "reth-primitives" version = "0.1.0-alpha.9" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.3.2 (git+https://github.com/alloy-rs/core)", "alloy-rlp", + "alloy-sol-types", "arbitrary", "assert_matches", "byteorder", @@ -6344,7 +6389,7 @@ name = "revm-primitives" version = "1.1.2" source = "git+https://github.com/Evalir/revm/?branch=reintroduce-alloy-rebased#ded453ea768a80dbcf27de56b0d35b68c92f140c" dependencies = [ - "alloy-primitives", + "alloy-primitives 0.3.2 (git+https://github.com/alloy-rs/core)", "alloy-rlp", "arbitrary", "auto_impl", @@ -7361,6 +7406,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn-solidity" +version = "0.3.2" +source = "git+https://github.com/alloy-rs/core?rev=5733dc1b3987b0d2f2677d055de85fd5f721b2fd#5733dc1b3987b0d2f2677d055de85fd5f721b2fd" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.37", +] + [[package]] name = "synstructure" version = "0.12.6" diff --git a/Cargo.toml b/Cargo.toml index d5599f590891..06d684159bf2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,6 +106,7 @@ revm-primitives = { git = "https://github.com/Evalir/revm/", branch = "reintrodu ## eth alloy-primitives = "0.3" alloy-rlp = "0.3" +alloy-sol-types = "0.3" ethers-core = { version = "2.0", default-features = false } ethers-providers = { version = "2.0", default-features = false } ethers-signers = { version = "2.0", default-features = false } @@ -180,3 +181,4 @@ serial_test = "2" # TODO [patch.crates-io] alloy-primitives = { git = "https://github.com/alloy-rs/core" } +alloy-sol-types = { git = "https://github.com/alloy-rs/core", rev = "5733dc1b3987b0d2f2677d055de85fd5f721b2fd" } diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 678cea1c75a9..d110038a6ee5 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -16,6 +16,7 @@ revm-primitives = { workspace = true, features = ["serde"] } # ethereum alloy-primitives = { workspace = true, features = ["rand", "rlp"] } alloy-rlp = { workspace = true, features = ["arrayvec"] } +alloy-sol-types.workspace = true ethers-core = { workspace = true, default-features = false } ruint = { version = "1.9.0", features = ["primitive-types", "rlp"] } diff --git a/crates/primitives/src/abi.rs b/crates/primitives/src/abi.rs index 97f232674f51..d4a950238ee8 100644 --- a/crates/primitives/src/abi.rs +++ b/crates/primitives/src/abi.rs @@ -1,19 +1,29 @@ //! Eth ABI helpers. -// TODO: Use `alloy_sol_types::ContractError` - use crate::constants::SELECTOR_LEN; -use ethers_core::abi::AbiDecode; +use alloy_sol_types::{GenericContractError, SolInterface}; /// Returns the revert reason from the given output data, if it's an abi encoded String. Returns /// `None` if the output is not long enough to contain a function selector or the content is not a /// valid abi encoded String. /// /// **Note:** it's assumed the `out` buffer starts with the call's signature -pub fn decode_revert_reason(out: impl AsRef<[u8]>) -> Option { - let out = out.as_ref(); +pub fn decode_revert_reason(out: &[u8]) -> Option { + // Ensure the output data is long enough to contain a function selector. if out.len() < SELECTOR_LEN { return None } - String::decode(&out[SELECTOR_LEN..]).ok() + + // Try to decode as a generic contract error. + if let Ok(error) = GenericContractError::decode(out, true) { + return Some(error.to_string()) + } + + // If that fails, try to decode as a regular string. + if let Ok(decoded_string) = std::str::from_utf8(out) { + return Some(decoded_string.to_string()) + } + + // If both attempts fail, return None. + None } diff --git a/crates/revm/revm-inspectors/src/tracing/types.rs b/crates/revm/revm-inspectors/src/tracing/types.rs index 3f4320a49ed0..57e3f245bb05 100644 --- a/crates/revm/revm-inspectors/src/tracing/types.rs +++ b/crates/revm/revm-inspectors/src/tracing/types.rs @@ -482,7 +482,7 @@ impl CallTraceNode { // we need to populate error and revert reason if !self.trace.success { - call_frame.revert_reason = decode_revert_reason(self.trace.output.clone()); + call_frame.revert_reason = decode_revert_reason(self.trace.output.as_ref()); // Note: the call tracer mimics parity's trace transaction and geth maps errors to parity style error messages, call_frame.error = self.trace.as_error(TraceStyle::Parity); } diff --git a/crates/rpc/rpc/src/eth/error.rs b/crates/rpc/rpc/src/eth/error.rs index 6a3c04f2ce14..85758ea5d1a9 100644 --- a/crates/rpc/rpc/src/eth/error.rs +++ b/crates/rpc/rpc/src/eth/error.rs @@ -492,7 +492,7 @@ impl RevertError { impl std::fmt::Display for RevertError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str("execution reverted")?; - if let Some(reason) = self.output.as_ref().and_then(decode_revert_reason) { + if let Some(reason) = self.output.as_ref().and_then(|bytes| decode_revert_reason(bytes)) { write!(f, ": {reason}")?; } Ok(())