feat(debug_traceTransaction): initial commit (#1469)
* feat(debug_traceTransaction): initial commit * chore(changelog): updated changelog * feat(debug_traceTransaction): type adjusments * feat(debug_traceTransaction): type adjusments * Update ethers-providers/src/provider.rs Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de> * Update ethers-providers/src/provider.rs Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de> * chore(format): cargo +nightly fmt Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de> Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
This commit is contained in:
parent
d22fb2bd0b
commit
cb7e586645
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
### Unreleased
|
### Unreleased
|
||||||
|
|
||||||
|
- Add support for Geth `debug_traceTransaction` [#1469](https://github.com/gakonst/ethers-rs/pull/1469)
|
||||||
- Use correct, new transaction type for `typool_content` RPC endpoint [#1501](https://github.com/gakonst/ethers-rs/pull/1501)
|
- Use correct, new transaction type for `typool_content` RPC endpoint [#1501](https://github.com/gakonst/ethers-rs/pull/1501)
|
||||||
- Fix the default config for generated `BuildInfo` [#1458](https://github.com/gakonst/ethers-rs/pull/1458)
|
- Fix the default config for generated `BuildInfo` [#1458](https://github.com/gakonst/ethers-rs/pull/1458)
|
||||||
- Allow configuration of the output directory of the generated `BuildInfo` [#1433](https://github.com/gakonst/ethers-rs/pull/1433)
|
- Allow configuration of the output directory of the generated `BuildInfo` [#1433](https://github.com/gakonst/ethers-rs/pull/1433)
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
use crate::types::{Bytes, H256, U256};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GethTrace {
|
||||||
|
failed: bool,
|
||||||
|
gas: u64,
|
||||||
|
#[serde(rename = "returnValue")]
|
||||||
|
return_value: Bytes,
|
||||||
|
#[serde(rename = "structLogs")]
|
||||||
|
struct_logs: Vec<StructLog>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct StructLog {
|
||||||
|
depth: u64,
|
||||||
|
error: Option<String>,
|
||||||
|
gas: u64,
|
||||||
|
#[serde(rename = "gasCost")]
|
||||||
|
gas_cost: u64,
|
||||||
|
memory: Option<Vec<String>>,
|
||||||
|
op: String,
|
||||||
|
pc: U256,
|
||||||
|
stack: Vec<String>,
|
||||||
|
storage: BTreeMap<H256, H256>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub tracer: Option<String>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub timeout: Option<String>,
|
||||||
|
}
|
|
@ -8,6 +8,9 @@ use std::collections::BTreeMap;
|
||||||
mod filter;
|
mod filter;
|
||||||
pub use filter::*;
|
pub use filter::*;
|
||||||
|
|
||||||
|
mod geth;
|
||||||
|
pub use geth::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
/// Description of the type of trace to make
|
/// Description of the type of trace to make
|
||||||
pub enum TraceType {
|
pub enum TraceType {
|
||||||
|
|
|
@ -510,6 +510,17 @@ pub trait Middleware: Sync + Send + Debug {
|
||||||
self.inner().txpool_status().await.map_err(FromErr::from)
|
self.inner().txpool_status().await.map_err(FromErr::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Geth `trace` support
|
||||||
|
/// After replaying any previous transactions in the same block,
|
||||||
|
/// Replays a transaction, returning the traces configured with passed options
|
||||||
|
async fn debug_trace_transaction(
|
||||||
|
&self,
|
||||||
|
tx_hash: TxHash,
|
||||||
|
trace_options: GethDebugTracingOptions,
|
||||||
|
) -> Result<GethTrace, ProviderError> {
|
||||||
|
self.inner().debug_trace_transaction(tx_hash, trace_options).await.map_err(FromErr::from)
|
||||||
|
}
|
||||||
|
|
||||||
// Parity `trace` support
|
// Parity `trace` support
|
||||||
|
|
||||||
/// Executes the given call and returns a number of possible traces for it
|
/// Executes the given call and returns a number of possible traces for it
|
||||||
|
|
|
@ -22,9 +22,9 @@ use ethers_core::{
|
||||||
types::{
|
types::{
|
||||||
transaction::{eip2718::TypedTransaction, eip2930::AccessListWithGasUsed},
|
transaction::{eip2718::TypedTransaction, eip2930::AccessListWithGasUsed},
|
||||||
Address, Block, BlockId, BlockNumber, BlockTrace, Bytes, EIP1186ProofResponse, FeeHistory,
|
Address, Block, BlockId, BlockNumber, BlockTrace, Bytes, EIP1186ProofResponse, FeeHistory,
|
||||||
Filter, FilterBlockOption, Log, NameOrAddress, Selector, Signature, Trace, TraceFilter,
|
Filter, FilterBlockOption, GethDebugTracingOptions, GethTrace, Log, NameOrAddress,
|
||||||
TraceType, Transaction, TransactionReceipt, TransactionRequest, TxHash, TxpoolContent,
|
Selector, Signature, Trace, TraceFilter, TraceType, Transaction, TransactionReceipt,
|
||||||
TxpoolInspect, TxpoolStatus, H256, U256, U64,
|
TransactionRequest, TxHash, TxpoolContent, TxpoolInspect, TxpoolStatus, H256, U256, U64,
|
||||||
},
|
},
|
||||||
utils,
|
utils,
|
||||||
};
|
};
|
||||||
|
@ -1021,6 +1021,17 @@ impl<P: JsonRpcClient> Middleware for Provider<P> {
|
||||||
self.request("txpool_status", ()).await
|
self.request("txpool_status", ()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Executes the given call and returns a number of possible traces for it
|
||||||
|
async fn debug_trace_transaction(
|
||||||
|
&self,
|
||||||
|
tx_hash: TxHash,
|
||||||
|
trace_options: GethDebugTracingOptions,
|
||||||
|
) -> Result<GethTrace, ProviderError> {
|
||||||
|
let tx_hash = utils::serialize(&tx_hash);
|
||||||
|
let trace_options = utils::serialize(&trace_options);
|
||||||
|
self.request("debug_traceTransaction", [tx_hash, trace_options]).await
|
||||||
|
}
|
||||||
|
|
||||||
/// Executes the given call and returns a number of possible traces for it
|
/// Executes the given call and returns a number of possible traces for it
|
||||||
async fn trace_call<T: Into<TypedTransaction> + Send + Sync>(
|
async fn trace_call<T: Into<TypedTransaction> + Send + Sync>(
|
||||||
&self,
|
&self,
|
||||||
|
@ -1243,12 +1254,12 @@ impl<P: JsonRpcClient> Provider<P> {
|
||||||
|
|
||||||
// otherwise, decode_bytes panics
|
// otherwise, decode_bytes panics
|
||||||
if data.0.is_empty() {
|
if data.0.is_empty() {
|
||||||
return Err(ProviderError::EnsError(ens_name.to_owned()))
|
return Err(ProviderError::EnsError(ens_name.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
let resolver_address: Address = decode_bytes(ParamType::Address, data);
|
let resolver_address: Address = decode_bytes(ParamType::Address, data);
|
||||||
if resolver_address == Address::zero() {
|
if resolver_address == Address::zero() {
|
||||||
return Err(ProviderError::EnsError(ens_name.to_owned()))
|
return Err(ProviderError::EnsError(ens_name.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve
|
// resolve
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
use ethers::prelude::*;
|
||||||
|
use eyre::Result;
|
||||||
|
use std::{env, str::FromStr};
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<()> {
|
||||||
|
let rpc_url: String = env::var("RPC_URL")?;
|
||||||
|
let client = Provider::<Http>::try_from(rpc_url)?;
|
||||||
|
let tx_hash = "0x97a02abf405d36939e5b232a5d4ef5206980c5a6661845436058f30600c52df7";
|
||||||
|
let h: H256 = H256::from_str(tx_hash)?;
|
||||||
|
let options: GethDebugTracingOptions = GethDebugTracingOptions::default();
|
||||||
|
let traces = client.debug_trace_transaction(h, options).await?;
|
||||||
|
println!("{:?}", traces);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in New Issue