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
|
||||
|
||||
- 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)
|
||||
- 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)
|
||||
|
|
|
@ -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;
|
||||
pub use filter::*;
|
||||
|
||||
mod geth;
|
||||
pub use geth::*;
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
/// Description of the type of trace to make
|
||||
pub enum TraceType {
|
||||
|
|
|
@ -510,6 +510,17 @@ pub trait Middleware: Sync + Send + Debug {
|
|||
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
|
||||
|
||||
/// Executes the given call and returns a number of possible traces for it
|
||||
|
|
|
@ -22,9 +22,9 @@ use ethers_core::{
|
|||
types::{
|
||||
transaction::{eip2718::TypedTransaction, eip2930::AccessListWithGasUsed},
|
||||
Address, Block, BlockId, BlockNumber, BlockTrace, Bytes, EIP1186ProofResponse, FeeHistory,
|
||||
Filter, FilterBlockOption, Log, NameOrAddress, Selector, Signature, Trace, TraceFilter,
|
||||
TraceType, Transaction, TransactionReceipt, TransactionRequest, TxHash, TxpoolContent,
|
||||
TxpoolInspect, TxpoolStatus, H256, U256, U64,
|
||||
Filter, FilterBlockOption, GethDebugTracingOptions, GethTrace, Log, NameOrAddress,
|
||||
Selector, Signature, Trace, TraceFilter, TraceType, Transaction, TransactionReceipt,
|
||||
TransactionRequest, TxHash, TxpoolContent, TxpoolInspect, TxpoolStatus, H256, U256, U64,
|
||||
},
|
||||
utils,
|
||||
};
|
||||
|
@ -1021,6 +1021,17 @@ impl<P: JsonRpcClient> Middleware for Provider<P> {
|
|||
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
|
||||
async fn trace_call<T: Into<TypedTransaction> + Send + Sync>(
|
||||
&self,
|
||||
|
@ -1243,12 +1254,12 @@ impl<P: JsonRpcClient> Provider<P> {
|
|||
|
||||
// otherwise, decode_bytes panics
|
||||
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);
|
||||
if resolver_address == Address::zero() {
|
||||
return Err(ProviderError::EnsError(ens_name.to_owned()))
|
||||
return Err(ProviderError::EnsError(ens_name.to_string()))
|
||||
}
|
||||
|
||||
// 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