mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
feat(rpc): kickoff geth traces (#1772)
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
//! Geth trace builder
|
||||
|
||||
use crate::tracing::{types::CallTraceNode, TraceInspectorConfig};
|
||||
use crate::tracing::{types::CallTraceNode, TracingInspectorConfig};
|
||||
use reth_primitives::{Address, JsonU256, H256, U256};
|
||||
use reth_rpc_types::trace::geth::*;
|
||||
use revm::interpreter::opcode;
|
||||
@ -12,12 +12,12 @@ pub struct GethTraceBuilder {
|
||||
/// Recorded trace nodes.
|
||||
nodes: Vec<CallTraceNode>,
|
||||
/// How the traces were recorded
|
||||
_config: TraceInspectorConfig,
|
||||
_config: TracingInspectorConfig,
|
||||
}
|
||||
|
||||
impl GethTraceBuilder {
|
||||
/// Returns a new instance of the builder
|
||||
pub(crate) fn new(nodes: Vec<CallTraceNode>, _config: TraceInspectorConfig) -> Self {
|
||||
pub(crate) fn new(nodes: Vec<CallTraceNode>, _config: TracingInspectorConfig) -> Self {
|
||||
Self { nodes, _config }
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ impl GethTraceBuilder {
|
||||
storage: &mut HashMap<Address, BTreeMap<H256, H256>>,
|
||||
trace_node: &CallTraceNode,
|
||||
struct_logs: &mut Vec<StructLog>,
|
||||
opts: &GethDebugTracingOptions,
|
||||
opts: &GethDefaultTracingOptions,
|
||||
) {
|
||||
let mut child_id = 0;
|
||||
// Iterate over the steps inside the given trace
|
||||
@ -80,7 +80,7 @@ impl GethTraceBuilder {
|
||||
&self,
|
||||
// TODO(mattsse): This should be the total gas used, or gas used by last CallTrace?
|
||||
receipt_gas_used: U256,
|
||||
opts: GethDebugTracingOptions,
|
||||
opts: GethDefaultTracingOptions,
|
||||
) -> DefaultFrame {
|
||||
if self.nodes.is_empty() {
|
||||
return Default::default()
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::tracing::{types::CallTraceNode, TraceInspectorConfig};
|
||||
use crate::tracing::{types::CallTraceNode, TracingInspectorConfig};
|
||||
use reth_rpc_types::{trace::parity::*, TransactionInfo};
|
||||
|
||||
/// A type for creating parity style traces
|
||||
@ -7,12 +7,12 @@ pub struct ParityTraceBuilder {
|
||||
/// Recorded trace nodes
|
||||
nodes: Vec<CallTraceNode>,
|
||||
/// How the traces were recorded
|
||||
_config: TraceInspectorConfig,
|
||||
_config: TracingInspectorConfig,
|
||||
}
|
||||
|
||||
impl ParityTraceBuilder {
|
||||
/// Returns a new instance of the builder
|
||||
pub(crate) fn new(nodes: Vec<CallTraceNode>, _config: TraceInspectorConfig) -> Self {
|
||||
pub(crate) fn new(nodes: Vec<CallTraceNode>, _config: TracingInspectorConfig) -> Self {
|
||||
Self { nodes, _config }
|
||||
}
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/// Gives guidance to the [TracingInspector](crate::tracing::TracingInspector).
|
||||
///
|
||||
/// Use [TraceInspectorConfig::default_parity] or [TraceInspectorConfig::default_geth] to get the
|
||||
/// default configs for specific styles of traces.
|
||||
/// Use [TracingInspectorConfig::default_parity] or [TracingInspectorConfig::default_geth] to get
|
||||
/// the default configs for specific styles of traces.
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub struct TraceInspectorConfig {
|
||||
pub struct TracingInspectorConfig {
|
||||
/// Whether to record every individual opcode level step.
|
||||
pub record_steps: bool,
|
||||
/// Whether to record individual memory snapshots.
|
||||
@ -14,7 +14,7 @@ pub struct TraceInspectorConfig {
|
||||
pub record_state_diff: bool,
|
||||
}
|
||||
|
||||
impl TraceInspectorConfig {
|
||||
impl TracingInspectorConfig {
|
||||
/// Returns a config with everything enabled.
|
||||
pub const fn all() -> Self {
|
||||
Self {
|
||||
|
||||
@ -23,7 +23,7 @@ mod config;
|
||||
mod types;
|
||||
mod utils;
|
||||
pub use builder::{geth::GethTraceBuilder, parity::ParityTraceBuilder};
|
||||
pub use config::TraceInspectorConfig;
|
||||
pub use config::TracingInspectorConfig;
|
||||
|
||||
/// An inspector that collects call traces.
|
||||
///
|
||||
@ -36,7 +36,7 @@ pub use config::TraceInspectorConfig;
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TracingInspector {
|
||||
/// Configures what and how the inspector records traces.
|
||||
config: TraceInspectorConfig,
|
||||
config: TracingInspectorConfig,
|
||||
/// Records all call traces
|
||||
traces: CallTraceArena,
|
||||
trace_stack: Vec<usize>,
|
||||
@ -52,7 +52,7 @@ pub struct TracingInspector {
|
||||
|
||||
impl TracingInspector {
|
||||
/// Returns a new instance for the given config
|
||||
pub fn new(config: TraceInspectorConfig) -> Self {
|
||||
pub fn new(config: TracingInspectorConfig) -> Self {
|
||||
Self {
|
||||
config,
|
||||
traces: Default::default(),
|
||||
|
||||
@ -39,6 +39,8 @@ pub struct CallLogFrame {
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CallConfig {
|
||||
/// When set to true, this will only trace the primary (top-level) call and not any sub-calls.
|
||||
/// It eliminates the additional processing for each call frame
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub only_top_call: Option<bool>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
@ -60,7 +62,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_serialize_call_trace() {
|
||||
let mut opts = GethDebugTracingCallOptions::default();
|
||||
opts.tracing_options.disable_storage = Some(false);
|
||||
opts.tracing_options.config.disable_storage = Some(false);
|
||||
opts.tracing_options.tracer =
|
||||
Some(GethDebugTracerType::BuiltInTracer(GethDebugBuiltInTracerType::CallTracer));
|
||||
opts.tracing_options.tracer_config =
|
||||
|
||||
@ -134,12 +134,28 @@ impl From<serde_json::Value> for GethTrace {
|
||||
/// See <https://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers>
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||
pub enum GethDebugBuiltInTracerType {
|
||||
/// The 4byteTracer collects the function selectors of every function executed in the lifetime
|
||||
/// of a transaction, along with the size of the supplied call data. The result is a
|
||||
/// [FourByteFrame] where the keys are SELECTOR-CALLDATASIZE and the values are number of
|
||||
/// occurrences of this key.
|
||||
#[serde(rename = "4byteTracer")]
|
||||
FourByteTracer,
|
||||
/// The callTracer tracks all the call frames executed during a transaction, including depth 0.
|
||||
/// The result will be a nested list of call frames, resembling how EVM works. They form a tree
|
||||
/// with the top-level call at root and sub-calls as children of the higher levels.
|
||||
#[serde(rename = "callTracer")]
|
||||
CallTracer,
|
||||
/// The prestate tracer has two modes: prestate and diff. The prestate mode returns the
|
||||
/// accounts necessary to execute a given transaction. diff mode returns the differences
|
||||
/// between the transaction's pre and post-state (i.e. what changed because the transaction
|
||||
/// happened). The prestateTracer defaults to prestate mode. It reexecutes the given
|
||||
/// transaction and tracks every part of state that is touched. This is similar to the concept
|
||||
/// of a stateless witness, the difference being this tracer doesn't return any cryptographic
|
||||
/// proof, rather only the trie leaves. The result is an object. The keys are addresses of
|
||||
/// accounts.
|
||||
#[serde(rename = "prestateTracer")]
|
||||
PreStateTracer,
|
||||
/// This tracer is noop. It returns an empty object and is only meant for testing the setup.
|
||||
#[serde(rename = "noopTracer")]
|
||||
NoopTracer,
|
||||
}
|
||||
@ -152,6 +168,22 @@ pub enum GethDebugBuiltInTracerConfig {
|
||||
PreStateTracer(PreStateConfig),
|
||||
}
|
||||
|
||||
// === impl GethDebugBuiltInTracerConfig ===
|
||||
|
||||
impl GethDebugBuiltInTracerConfig {
|
||||
/// Returns true if the config matches the given tracer
|
||||
pub fn matches_tracer(&self, tracer: &GethDebugBuiltInTracerType) -> bool {
|
||||
matches!(
|
||||
(self, tracer),
|
||||
(GethDebugBuiltInTracerConfig::CallTracer(_), GethDebugBuiltInTracerType::CallTracer,) |
|
||||
(
|
||||
GethDebugBuiltInTracerConfig::PreStateTracer(_),
|
||||
GethDebugBuiltInTracerType::PreStateTracer,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Available tracers
|
||||
///
|
||||
/// See <https://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers> and <https://geth.ethereum.org/docs/developers/evm-tracing/custom-tracer>
|
||||
@ -174,30 +206,97 @@ pub enum GethDebugTracerConfig {
|
||||
JsTracer(serde_json::Value),
|
||||
}
|
||||
|
||||
// === impl GethDebugTracerConfig ===
|
||||
|
||||
impl GethDebugTracerConfig {
|
||||
/// Returns the [CallConfig] if it is a call config.
|
||||
pub fn into_call_config(self) -> Option<CallConfig> {
|
||||
match self {
|
||||
GethDebugTracerConfig::BuiltInTracer(GethDebugBuiltInTracerConfig::CallTracer(cfg)) => {
|
||||
Some(cfg)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the [PreStateConfig] if it is a call config.
|
||||
pub fn into_pre_state_config(self) -> Option<PreStateConfig> {
|
||||
match self {
|
||||
GethDebugTracerConfig::BuiltInTracer(GethDebugBuiltInTracerConfig::PreStateTracer(
|
||||
cfg,
|
||||
)) => Some(cfg),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the config matches the given tracer
|
||||
pub fn matches_tracer(&self, tracer: &GethDebugTracerType) -> bool {
|
||||
match (self, tracer) {
|
||||
(_, GethDebugTracerType::BuiltInTracer(tracer)) => self.matches_builtin_tracer(tracer),
|
||||
(GethDebugTracerConfig::JsTracer(_), GethDebugTracerType::JsTracer(_)) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the config matches the given tracer
|
||||
pub fn matches_builtin_tracer(&self, tracer: &GethDebugBuiltInTracerType) -> bool {
|
||||
match (self, tracer) {
|
||||
(GethDebugTracerConfig::BuiltInTracer(config), tracer) => config.matches_tracer(tracer),
|
||||
(GethDebugTracerConfig::JsTracer(_), _) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Bindings for additional `debug_traceTransaction` options
|
||||
///
|
||||
/// See <https://geth.ethereum.org/docs/rpc/ns-debug#debug_tracetransaction>
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GethDebugTracingOptions {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub disable_storage: Option<bool>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub disable_stack: Option<bool>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub enable_memory: Option<bool>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub enable_return_data: Option<bool>,
|
||||
#[serde(default, flatten)]
|
||||
pub config: GethDefaultTracingOptions,
|
||||
/// The custom tracer to use.
|
||||
///
|
||||
/// If `None` then the default structlog tracer is used.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub tracer: Option<GethDebugTracerType>,
|
||||
/// tracerConfig is slated for Geth v1.11.0
|
||||
/// See <https://github.com/ethereum/go-ethereum/issues/26513>
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub tracer_config: Option<GethDebugTracerConfig>,
|
||||
/// A string of decimal integers that overrides the JavaScript-based tracing calls default
|
||||
/// timeout of 5 seconds.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub timeout: Option<String>,
|
||||
}
|
||||
|
||||
/// Default tracing options for the struct looger
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GethDefaultTracingOptions {
|
||||
/// enable memory capture
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub enable_memory: Option<bool>,
|
||||
/// disable stack capture
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub disable_stack: Option<bool>,
|
||||
/// disable storage capture
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub disable_storage: Option<bool>,
|
||||
/// enable return data capture
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub enable_return_data: Option<bool>,
|
||||
/// print output during capture end
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub debug: Option<bool>,
|
||||
/// maximum length of output, but zero means unlimited
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub limit: Option<u64>,
|
||||
/// Chain overrides, can be used to execute a trace using future fork rules
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub overrides: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
/// Bindings for additional `debug_traceCall` options
|
||||
///
|
||||
/// See <https://geth.ethereum.org/docs/rpc/ns-debug#debug_tracecall>
|
||||
|
||||
@ -59,7 +59,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_serialize_pre_state_trace() {
|
||||
let mut opts = GethDebugTracingCallOptions::default();
|
||||
opts.tracing_options.disable_storage = Some(false);
|
||||
opts.tracing_options.config.disable_storage = Some(false);
|
||||
opts.tracing_options.tracer =
|
||||
Some(GethDebugTracerType::BuiltInTracer(GethDebugBuiltInTracerType::PreStateTracer));
|
||||
opts.tracing_options.tracer_config = Some(GethDebugTracerConfig::BuiltInTracer(
|
||||
|
||||
@ -1,12 +1,29 @@
|
||||
use crate::{result::internal_rpc_err, EthApiSpec};
|
||||
use crate::{
|
||||
eth::{
|
||||
error::{EthApiError, EthResult},
|
||||
revm_utils::inspect,
|
||||
EthTransactions,
|
||||
},
|
||||
result::internal_rpc_err,
|
||||
EthApiSpec,
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use jsonrpsee::core::RpcResult;
|
||||
use reth_primitives::{BlockId, BlockNumberOrTag, Bytes, H256};
|
||||
use reth_primitives::{BlockId, BlockNumberOrTag, Bytes, H256, U256};
|
||||
use reth_revm::{
|
||||
database::{State, SubState},
|
||||
env::tx_env_with_recovered,
|
||||
tracing::{TracingInspector, TracingInspectorConfig},
|
||||
};
|
||||
use reth_rpc_api::DebugApiServer;
|
||||
use reth_rpc_types::{
|
||||
trace::geth::{BlockTraceResult, GethDebugTracingOptions, GethTraceFrame, TraceResult},
|
||||
trace::geth::{
|
||||
BlockTraceResult, GethDebugBuiltInTracerType, GethDebugTracerType, GethDebugTracingOptions,
|
||||
GethTraceFrame, NoopFrame, TraceResult,
|
||||
},
|
||||
CallRequest, RichBlock,
|
||||
};
|
||||
use revm::primitives::Env;
|
||||
|
||||
/// `debug` API implementation.
|
||||
///
|
||||
@ -14,7 +31,7 @@ use reth_rpc_types::{
|
||||
#[non_exhaustive]
|
||||
pub struct DebugApi<Eth> {
|
||||
/// The implementation of `eth` API
|
||||
eth: Eth,
|
||||
eth_api: Eth,
|
||||
}
|
||||
|
||||
// === impl DebugApi ===
|
||||
@ -22,7 +39,81 @@ pub struct DebugApi<Eth> {
|
||||
impl<Eth> DebugApi<Eth> {
|
||||
/// Create a new instance of the [DebugApi]
|
||||
pub fn new(eth: Eth) -> Self {
|
||||
Self { eth }
|
||||
Self { eth_api: eth }
|
||||
}
|
||||
}
|
||||
|
||||
// === impl DebugApi ===
|
||||
|
||||
impl<Eth> DebugApi<Eth>
|
||||
where
|
||||
Eth: EthTransactions + 'static,
|
||||
{
|
||||
/// Trace the transaction according to the provided options.
|
||||
///
|
||||
/// Ref: <https://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers>
|
||||
pub async fn debug_trace_transaction(
|
||||
&self,
|
||||
tx_hash: H256,
|
||||
opts: GethDebugTracingOptions,
|
||||
) -> EthResult<GethTraceFrame> {
|
||||
let (transaction, at) = match self.eth_api.transaction_by_hash_at(tx_hash).await? {
|
||||
None => return Err(EthApiError::TransactionNotFound),
|
||||
Some(res) => res,
|
||||
};
|
||||
|
||||
let (cfg, block, at) = self.eth_api.evm_env_at(at).await?;
|
||||
|
||||
let tx = transaction.into_recovered();
|
||||
|
||||
self.eth_api.with_state_at(at, |state| {
|
||||
let tx = tx_env_with_recovered(&tx);
|
||||
let env = Env { cfg, block, tx };
|
||||
let db = SubState::new(State::new(state));
|
||||
|
||||
let GethDebugTracingOptions { config, tracer, tracer_config, .. } = opts;
|
||||
if let Some(tracer) = tracer {
|
||||
// valid matching config
|
||||
if let Some(ref config) = tracer_config {
|
||||
if !config.matches_tracer(&tracer) {
|
||||
return Err(EthApiError::InvalidTracerConfig)
|
||||
}
|
||||
}
|
||||
|
||||
return match tracer {
|
||||
GethDebugTracerType::BuiltInTracer(tracer) => match tracer {
|
||||
GethDebugBuiltInTracerType::FourByteTracer => {
|
||||
todo!()
|
||||
}
|
||||
GethDebugBuiltInTracerType::CallTracer => {
|
||||
todo!()
|
||||
}
|
||||
GethDebugBuiltInTracerType::PreStateTracer => {
|
||||
todo!()
|
||||
}
|
||||
GethDebugBuiltInTracerType::NoopTracer => Ok(NoopFrame::default().into()),
|
||||
},
|
||||
GethDebugTracerType::JsTracer(_) => {
|
||||
Err(EthApiError::Unsupported("javascript tracers are unsupported."))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// default structlog tracer
|
||||
let inspector_config = TracingInspectorConfig::default_geth()
|
||||
.set_memory_snapshots(config.enable_memory.unwrap_or_default())
|
||||
.set_stack_snapshots(!config.disable_stack.unwrap_or_default())
|
||||
.set_state_diffs(!config.disable_storage.unwrap_or_default());
|
||||
|
||||
let mut inspector = TracingInspector::new(inspector_config);
|
||||
|
||||
let (res, _) = inspect(db, env, &mut inspector)?;
|
||||
let gas_used = res.result.gas_used();
|
||||
|
||||
let frame = inspector.into_geth_builder().geth_traces(U256::from(gas_used), config);
|
||||
|
||||
Ok(frame.into())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,10 +187,10 @@ where
|
||||
/// Handler for `debug_traceTransaction`
|
||||
async fn debug_trace_transaction(
|
||||
&self,
|
||||
_tx_hash: H256,
|
||||
_opts: GethDebugTracingOptions,
|
||||
tx_hash: H256,
|
||||
opts: GethDebugTracingOptions,
|
||||
) -> RpcResult<GethTraceFrame> {
|
||||
Err(internal_rpc_err("unimplemented"))
|
||||
Ok(DebugApi::debug_trace_transaction(self, tx_hash, opts).await?)
|
||||
}
|
||||
|
||||
/// Handler for `debug_traceCall`
|
||||
|
||||
@ -446,7 +446,7 @@ mod tests {
|
||||
let hash = H256::random();
|
||||
let gas_limit: u64 = random();
|
||||
let gas_used: u64 = random();
|
||||
let base_fee_per_gas: Option<u64> = random::<bool>().then(|| random());
|
||||
let base_fee_per_gas: Option<u64> = random::<bool>().then(random);
|
||||
|
||||
let header = Header {
|
||||
number: newest_block - i,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
//! Implementation specific Errors for the `eth_` namespace.
|
||||
|
||||
use crate::result::{internal_rpc_err, rpc_err};
|
||||
use jsonrpsee::{core::Error as RpcError, types::error::INVALID_PARAMS_CODE};
|
||||
use crate::result::{internal_rpc_err, invalid_params_rpc_err, rpc_err};
|
||||
use jsonrpsee::core::Error as RpcError;
|
||||
use reth_primitives::{constants::SELECTOR_LEN, Address, Bytes, U256};
|
||||
use reth_rpc_types::{error::EthRpcErrorCode, BlockError};
|
||||
use reth_transaction_pool::error::{InvalidPoolTransactionError, PoolError};
|
||||
@ -55,6 +55,15 @@ pub enum EthApiError {
|
||||
/// Error related to signing
|
||||
#[error(transparent)]
|
||||
Signing(#[from] SignError),
|
||||
/// Thrown when a transaction was requested but not matching transaction exists
|
||||
#[error("transaction not found")]
|
||||
TransactionNotFound,
|
||||
/// Some feature is unsupported
|
||||
#[error("unsupported")]
|
||||
Unsupported(&'static str),
|
||||
/// When tracer config does not match the tracer
|
||||
#[error("invalid tracer config")]
|
||||
InvalidTracerConfig,
|
||||
}
|
||||
|
||||
impl From<EthApiError> for RpcError {
|
||||
@ -69,14 +78,15 @@ impl From<EthApiError> for RpcError {
|
||||
EthApiError::ConflictingRequestGasPriceAndTipSet { .. } |
|
||||
EthApiError::RequestLegacyGasPriceAndTipSet { .. } |
|
||||
EthApiError::Signing(_) |
|
||||
EthApiError::BothStateAndStateDiffInOverride(_) => {
|
||||
rpc_err(INVALID_PARAMS_CODE, error.to_string(), None)
|
||||
}
|
||||
EthApiError::BothStateAndStateDiffInOverride(_) |
|
||||
EthApiError::InvalidTracerConfig => invalid_params_rpc_err(error.to_string()),
|
||||
EthApiError::InvalidTransaction(err) => err.into(),
|
||||
EthApiError::PoolError(_) |
|
||||
EthApiError::PrevrandaoNotSet |
|
||||
EthApiError::InvalidBlockData(_) |
|
||||
EthApiError::Internal(_) => internal_rpc_err(error.to_string()),
|
||||
EthApiError::Internal(_) |
|
||||
EthApiError::TransactionNotFound => internal_rpc_err(error.to_string()),
|
||||
EthApiError::Unsupported(msg) => internal_rpc_err(msg),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,6 +125,11 @@ impl ToRpcResultExt for RethResult<Option<Block>> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs an invalid params JSON-RPC error.
|
||||
pub(crate) fn invalid_params_rpc_err(msg: impl Into<String>) -> jsonrpsee::core::Error {
|
||||
rpc_err(jsonrpsee::types::error::INVALID_PARAMS_CODE, msg, None)
|
||||
}
|
||||
|
||||
/// Constructs an internal JSON-RPC error.
|
||||
pub(crate) fn internal_rpc_err(msg: impl Into<String>) -> jsonrpsee::core::Error {
|
||||
rpc_err(jsonrpsee::types::error::INTERNAL_ERROR_CODE, msg, None)
|
||||
|
||||
@ -9,7 +9,7 @@ use reth_provider::{BlockProvider, EvmEnvProvider, StateProviderFactory};
|
||||
use reth_revm::{
|
||||
database::{State, SubState},
|
||||
env::tx_env_with_recovered,
|
||||
tracing::{TraceInspectorConfig, TracingInspector},
|
||||
tracing::{TracingInspector, TracingInspectorConfig},
|
||||
};
|
||||
use reth_rpc_api::TraceApiServer;
|
||||
use reth_rpc_types::{
|
||||
@ -82,7 +82,7 @@ where
|
||||
let tx = tx_env_with_recovered(&tx);
|
||||
let env = Env { cfg, block, tx };
|
||||
let db = SubState::new(State::new(state));
|
||||
let mut inspector = TracingInspector::new(TraceInspectorConfig::default_parity());
|
||||
let mut inspector = TracingInspector::new(TracingInspectorConfig::default_parity());
|
||||
|
||||
inspect(db, env, &mut inspector)?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user