mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(rpc): add missing geth trace calls (#1700)
This commit is contained in:
@ -1,6 +1,9 @@
|
||||
use jsonrpsee::{core::RpcResult as Result, proc_macros::rpc};
|
||||
use reth_primitives::{BlockId, Bytes, H256};
|
||||
use reth_rpc_types::RichBlock;
|
||||
use reth_primitives::{BlockId, BlockNumberOrTag, Bytes, H256};
|
||||
use reth_rpc_types::{
|
||||
trace::geth::{BlockTraceResult, GethDebugTracingOptions, GethTraceFrame, TraceResult},
|
||||
CallRequest, RichBlock,
|
||||
};
|
||||
|
||||
/// Debug rpc interface.
|
||||
#[cfg_attr(not(feature = "client"), rpc(server))]
|
||||
@ -25,4 +28,75 @@ pub trait DebugApi {
|
||||
/// Returns an array of recent bad blocks that the client has seen on the network.
|
||||
#[method(name = "debug_getBadBlocks")]
|
||||
async fn bad_blocks(&self) -> Result<Vec<RichBlock>>;
|
||||
|
||||
/// Returns the structured logs created during the execution of EVM between two blocks
|
||||
/// (excluding start) as a JSON object.
|
||||
#[method(name = "debug_traceChain")]
|
||||
async fn debug_trace_chain(
|
||||
&self,
|
||||
start_exclusive: BlockNumberOrTag,
|
||||
end_inclusive: BlockNumberOrTag,
|
||||
) -> Result<Vec<BlockTraceResult>>;
|
||||
|
||||
/// The `debug_traceBlock` method will return a full stack trace of all invoked opcodes of all
|
||||
/// transaction that were included in this block.
|
||||
///
|
||||
/// This expects an rlp encoded block
|
||||
///
|
||||
/// Note, the parent of this block must be present, or it will fail. For the second parameter
|
||||
/// see [GethDebugTracingOptions] reference.
|
||||
#[method(name = "debug_traceBlock")]
|
||||
async fn debug_trace_block(
|
||||
&self,
|
||||
rlp_block: Bytes,
|
||||
opts: GethDebugTracingOptions,
|
||||
) -> Result<Vec<TraceResult>>;
|
||||
|
||||
/// Similar to `debug_traceBlock`, `debug_traceBlockByHash` accepts a block hash and will replay
|
||||
/// the block that is already present in the database. For the second parameter see
|
||||
/// [GethDebugTracingOptions].
|
||||
#[method(name = "debug_traceBlockByHash")]
|
||||
async fn debug_trace_block_by_hash(
|
||||
&self,
|
||||
block: H256,
|
||||
opts: GethDebugTracingOptions,
|
||||
) -> Result<Vec<TraceResult>>;
|
||||
|
||||
/// Similar to `debug_traceBlockByNumber`, `debug_traceBlockByHash` accepts a block number
|
||||
/// [BlockNumberOrTag] and will replay the block that is already present in the database.
|
||||
/// For the second parameter see [GethDebugTracingOptions].
|
||||
#[method(name = "debug_traceBlockByNumber")]
|
||||
async fn debug_trace_block_by_number(
|
||||
&self,
|
||||
block: BlockNumberOrTag,
|
||||
opts: GethDebugTracingOptions,
|
||||
) -> Result<Vec<TraceResult>>;
|
||||
|
||||
/// The `debug_traceTransaction` debugging method will attempt to run the transaction in the
|
||||
/// exact same manner as it was executed on the network. It will replay any transaction that
|
||||
/// may have been executed prior to this one before it will finally attempt to execute the
|
||||
/// transaction that corresponds to the given hash.
|
||||
#[method(name = "debug_traceTransaction")]
|
||||
async fn debug_trace_transaction(
|
||||
&self,
|
||||
tx_hash: H256,
|
||||
opts: GethDebugTracingOptions,
|
||||
) -> Result<GethTraceFrame>;
|
||||
|
||||
/// The debug_traceCall method lets you run an `eth_call` within the context of the given block
|
||||
/// execution using the final state of parent block as the base.
|
||||
///
|
||||
/// The first argument (just as in`eth_call`) is a transaction request.
|
||||
/// The block can be specified either by hash or by number as
|
||||
/// the second argument.
|
||||
/// The trace can be configured similar to `debug_traceTransaction`,
|
||||
/// see [GethDebugTracingOptions]. The method returns the same output as
|
||||
/// `debug_traceTransaction`.
|
||||
#[method(name = "debug_traceCall")]
|
||||
async fn debug_trace_call(
|
||||
&self,
|
||||
request: CallRequest,
|
||||
block_number: Option<BlockId>,
|
||||
opts: GethDebugTracingOptions,
|
||||
) -> Result<GethTraceFrame>;
|
||||
}
|
||||
|
||||
14
crates/rpc/rpc-types/src/eth/trace/common.rs
Normal file
14
crates/rpc/rpc-types/src/eth/trace/common.rs
Normal file
@ -0,0 +1,14 @@
|
||||
//! Types used by tracing backends
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// The result of a single transaction trace.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum TraceResult<Ok, Err> {
|
||||
/// Untagged success variant
|
||||
Success { result: Ok },
|
||||
/// Untagged error variant
|
||||
Error { error: Err },
|
||||
}
|
||||
59
crates/rpc/rpc-types/src/eth/trace/geth.rs
Normal file
59
crates/rpc/rpc-types/src/eth/trace/geth.rs
Normal file
@ -0,0 +1,59 @@
|
||||
#![allow(missing_docs)]
|
||||
/// Geth tracing types
|
||||
use reth_primitives::{Bytes, JsonU256, H256, U256};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
// re-exported for geth tracing types
|
||||
pub use ethers_core::types::{GethDebugTracingOptions, GethTraceFrame};
|
||||
|
||||
/// Result type for geth style transaction trace
|
||||
pub type TraceResult = crate::trace::common::TraceResult<serde_json::Value, String>;
|
||||
|
||||
/// blockTraceResult represents the results of tracing a single block when an entire chain is being
|
||||
/// traced. ref <https://github.com/ethereum/go-ethereum/blob/ee530c0d5aa70d2c00ab5691a89ab431b73f8165/eth/tracers/api.go#L218-L222>
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct BlockTraceResult {
|
||||
/// Block number corresponding to the trace task
|
||||
pub block: U256,
|
||||
/// Block hash corresponding to the trace task
|
||||
pub hash: H256,
|
||||
/// Trace results produced by the trace task
|
||||
pub traces: Vec<TraceResult>,
|
||||
}
|
||||
|
||||
/// Geth Default trace frame
|
||||
///
|
||||
/// <https://github.com/ethereum/go-ethereum/blob/a9ef135e2dd53682d106c6a2aede9187026cc1de/eth/tracers/logger/logger.go#L406-L411>
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DefaultFrame {
|
||||
pub failed: bool,
|
||||
pub gas: JsonU256,
|
||||
pub return_value: Bytes,
|
||||
pub struct_logs: Vec<StructLog>,
|
||||
}
|
||||
|
||||
/// Represents a struct log entry in a trace
|
||||
///
|
||||
/// <https://github.com/ethereum/go-ethereum/blob/366d2169fbc0e0f803b68c042b77b6b480836dbc/eth/tracers/logger/logger.go#L413-L426>
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct StructLog {
|
||||
pub depth: u64,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub error: Option<String>,
|
||||
pub gas: u64,
|
||||
#[serde(rename = "gasCost")]
|
||||
pub gas_cost: u64,
|
||||
/// ref <https://github.com/ethereum/go-ethereum/blob/366d2169fbc0e0f803b68c042b77b6b480836dbc/eth/tracers/logger/logger.go#L450-L452>
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub memory: Option<Vec<String>>,
|
||||
pub op: String,
|
||||
pub pc: u64,
|
||||
#[serde(default, rename = "refund", skip_serializing_if = "Option::is_none")]
|
||||
pub refund_counter: Option<u64>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub stack: Option<Vec<U256>>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub storage: Option<BTreeMap<H256, H256>>,
|
||||
}
|
||||
@ -1,52 +1,6 @@
|
||||
//! Types for tracing
|
||||
|
||||
pub mod common;
|
||||
pub mod filter;
|
||||
pub mod geth;
|
||||
pub mod parity;
|
||||
|
||||
/// Geth tracing types
|
||||
pub mod geth {
|
||||
#![allow(missing_docs)]
|
||||
|
||||
use reth_primitives::{Bytes, JsonU256, H256, U256};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
// re-exported for geth tracing types
|
||||
pub use ethers_core::types::GethDebugTracingOptions;
|
||||
|
||||
/// Geth Default trace frame
|
||||
///
|
||||
/// <https://github.com/ethereum/go-ethereum/blob/a9ef135e2dd53682d106c6a2aede9187026cc1de/eth/tracers/logger/logger.go#L406-L411>
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DefaultFrame {
|
||||
pub failed: bool,
|
||||
pub gas: JsonU256,
|
||||
pub return_value: Bytes,
|
||||
pub struct_logs: Vec<StructLog>,
|
||||
}
|
||||
|
||||
/// Represents a struct log entry in a trace
|
||||
///
|
||||
/// <https://github.com/ethereum/go-ethereum/blob/366d2169fbc0e0f803b68c042b77b6b480836dbc/eth/tracers/logger/logger.go#L413-L426>
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct StructLog {
|
||||
pub depth: u64,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub error: Option<String>,
|
||||
pub gas: u64,
|
||||
#[serde(rename = "gasCost")]
|
||||
pub gas_cost: u64,
|
||||
/// ref <https://github.com/ethereum/go-ethereum/blob/366d2169fbc0e0f803b68c042b77b6b480836dbc/eth/tracers/logger/logger.go#L450-L452>
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub memory: Option<Vec<String>>,
|
||||
pub op: String,
|
||||
pub pc: u64,
|
||||
#[serde(default, rename = "refund", skip_serializing_if = "Option::is_none")]
|
||||
pub refund_counter: Option<u64>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub stack: Option<Vec<U256>>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub storage: Option<BTreeMap<H256, H256>>,
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,9 @@ use reth_primitives::{Address, Bytes, H256, U256, U64};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
/// Result type for parity style transaction trace
|
||||
pub type TraceResult = crate::trace::common::TraceResult<TraceOutput, String>;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum TraceType {
|
||||
@ -171,13 +174,6 @@ pub enum TraceOutput {
|
||||
Create(CreateOutput),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum TraceResult {
|
||||
Success { result: TraceOutput },
|
||||
Error { error: String },
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TransactionTrace {
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
use crate::{result::internal_rpc_err, EthApiSpec};
|
||||
use async_trait::async_trait;
|
||||
use jsonrpsee::core::RpcResult as Result;
|
||||
use reth_primitives::{BlockId, Bytes, H256};
|
||||
use jsonrpsee::core::RpcResult;
|
||||
use reth_primitives::{BlockId, BlockNumberOrTag, Bytes, H256};
|
||||
use reth_rpc_api::DebugApiServer;
|
||||
use reth_rpc_types::RichBlock;
|
||||
use reth_rpc_types::{
|
||||
trace::geth::{BlockTraceResult, GethDebugTracingOptions, GethTraceFrame, TraceResult},
|
||||
CallRequest, RichBlock,
|
||||
};
|
||||
|
||||
/// `debug` API implementation.
|
||||
///
|
||||
@ -28,24 +31,79 @@ impl<Eth> DebugApiServer for DebugApi<Eth>
|
||||
where
|
||||
Eth: EthApiSpec + 'static,
|
||||
{
|
||||
async fn raw_header(&self, _block_id: BlockId) -> Result<Bytes> {
|
||||
async fn raw_header(&self, _block_id: BlockId) -> RpcResult<Bytes> {
|
||||
Err(internal_rpc_err("unimplemented"))
|
||||
}
|
||||
|
||||
async fn raw_block(&self, _block_id: BlockId) -> Result<Bytes> {
|
||||
async fn raw_block(&self, _block_id: BlockId) -> RpcResult<Bytes> {
|
||||
Err(internal_rpc_err("unimplemented"))
|
||||
}
|
||||
|
||||
/// Returns the bytes of the transaction for the given hash.
|
||||
async fn raw_transaction(&self, _hash: H256) -> Result<Bytes> {
|
||||
async fn raw_transaction(&self, _hash: H256) -> RpcResult<Bytes> {
|
||||
Err(internal_rpc_err("unimplemented"))
|
||||
}
|
||||
|
||||
async fn raw_receipts(&self, _block_id: BlockId) -> Result<Vec<Bytes>> {
|
||||
async fn raw_receipts(&self, _block_id: BlockId) -> RpcResult<Vec<Bytes>> {
|
||||
Err(internal_rpc_err("unimplemented"))
|
||||
}
|
||||
|
||||
async fn bad_blocks(&self) -> Result<Vec<RichBlock>> {
|
||||
async fn bad_blocks(&self) -> RpcResult<Vec<RichBlock>> {
|
||||
Err(internal_rpc_err("unimplemented"))
|
||||
}
|
||||
|
||||
/// Handler for `debug_traceChain`
|
||||
async fn debug_trace_chain(
|
||||
&self,
|
||||
_start_exclusive: BlockNumberOrTag,
|
||||
_end_inclusive: BlockNumberOrTag,
|
||||
) -> RpcResult<Vec<BlockTraceResult>> {
|
||||
Err(internal_rpc_err("unimplemented"))
|
||||
}
|
||||
|
||||
/// Handler for `debug_traceBlock`
|
||||
async fn debug_trace_block(
|
||||
&self,
|
||||
_rlp_block: Bytes,
|
||||
_opts: GethDebugTracingOptions,
|
||||
) -> RpcResult<Vec<TraceResult>> {
|
||||
Err(internal_rpc_err("unimplemented"))
|
||||
}
|
||||
|
||||
/// Handler for `debug_traceBlockByHash`
|
||||
async fn debug_trace_block_by_hash(
|
||||
&self,
|
||||
_block: H256,
|
||||
_opts: GethDebugTracingOptions,
|
||||
) -> RpcResult<Vec<TraceResult>> {
|
||||
Err(internal_rpc_err("unimplemented"))
|
||||
}
|
||||
|
||||
/// Handler for `debug_traceBlockByNumber`
|
||||
async fn debug_trace_block_by_number(
|
||||
&self,
|
||||
_block: BlockNumberOrTag,
|
||||
_opts: GethDebugTracingOptions,
|
||||
) -> RpcResult<Vec<TraceResult>> {
|
||||
Err(internal_rpc_err("unimplemented"))
|
||||
}
|
||||
|
||||
/// Handler for `debug_traceTransaction`
|
||||
async fn debug_trace_transaction(
|
||||
&self,
|
||||
_tx_hash: H256,
|
||||
_opts: GethDebugTracingOptions,
|
||||
) -> RpcResult<GethTraceFrame> {
|
||||
Err(internal_rpc_err("unimplemented"))
|
||||
}
|
||||
|
||||
/// Handler for `debug_traceCall`
|
||||
async fn debug_trace_call(
|
||||
&self,
|
||||
_request: CallRequest,
|
||||
_block_number: Option<BlockId>,
|
||||
_opts: GethDebugTracingOptions,
|
||||
) -> RpcResult<GethTraceFrame> {
|
||||
Err(internal_rpc_err("unimplemented"))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user