mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(revm): use GenericRevertReason type (#5854)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
@ -1,9 +1,9 @@
|
||||
//! Types for representing call trace items.
|
||||
|
||||
use crate::tracing::{config::TraceStyle, utils::convert_memory};
|
||||
use crate::tracing::{config::TraceStyle, utils, utils::convert_memory};
|
||||
pub use alloy_primitives::Log;
|
||||
use alloy_primitives::{Address, Bytes, U256, U64};
|
||||
use alloy_sol_types::decode_revert_reason;
|
||||
|
||||
use reth_rpc_types::trace::{
|
||||
geth::{CallFrame, CallLogFrame, GethDefaultTracingOptions, StructLog},
|
||||
parity::{
|
||||
@ -347,9 +347,7 @@ impl CallTraceNode {
|
||||
|
||||
// we need to populate error and revert reason
|
||||
if !self.trace.success {
|
||||
// decode the revert reason, but don't include it if it's empty
|
||||
call_frame.revert_reason = decode_revert_reason(self.trace.output.as_ref())
|
||||
.filter(|reason| !reason.is_empty());
|
||||
call_frame.revert_reason = utils::maybe_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, <https://github.com/ethereum/go-ethereum/blob/34d507215951fb3f4a5983b65e127577989a6db8/eth/tracers/native/call_flat.go#L39-L55>
|
||||
call_frame.error = self.trace.as_error_msg(TraceStyle::Parity);
|
||||
@ -679,14 +677,3 @@ impl AsRef<[u8]> for RecordedMemory {
|
||||
self.as_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn decode_empty_revert() {
|
||||
let reason = decode_revert_reason("".as_bytes());
|
||||
assert_eq!(reason, Some("".to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
//! Util functions for revm related ops
|
||||
|
||||
use alloy_primitives::{hex, Address, Bytes, B256};
|
||||
use alloy_sol_types::{ContractError, GenericRevertReason};
|
||||
use revm::{
|
||||
interpreter::CreateInputs,
|
||||
primitives::{CreateScheme, SpecId, KECCAK_EMPTY},
|
||||
@ -58,3 +59,45 @@ pub(crate) fn load_account_code<DB: DatabaseRef>(
|
||||
})
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
/// Returns a non empty revert reason if the output is a revert/error.
|
||||
#[inline]
|
||||
pub(crate) fn maybe_revert_reason(output: &[u8]) -> Option<String> {
|
||||
let reason = match GenericRevertReason::decode(output)? {
|
||||
GenericRevertReason::ContractError(err) => {
|
||||
match err {
|
||||
ContractError::Revert(revert) => {
|
||||
// return the raw revert reason and don't use the revert's display message
|
||||
revert.reason
|
||||
}
|
||||
err => err.to_string(),
|
||||
}
|
||||
}
|
||||
GenericRevertReason::RawString(err) => err,
|
||||
};
|
||||
if reason.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(reason)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use alloy_sol_types::{GenericContractError, SolInterface};
|
||||
|
||||
#[test]
|
||||
fn decode_empty_revert() {
|
||||
let reason = GenericRevertReason::decode("".as_bytes()).map(|x| x.to_string());
|
||||
assert_eq!(reason, Some("".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_revert_reason() {
|
||||
let err = GenericContractError::Revert("my revert".into());
|
||||
let encoded = err.abi_encode();
|
||||
let reason = maybe_revert_reason(&encoded).unwrap();
|
||||
assert_eq!(reason, "my revert");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user