Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support debug_traceTransaction #1737

Closed
BlinkyStitt opened this issue May 26, 2022 · 14 comments
Closed

Support debug_traceTransaction #1737

BlinkyStitt opened this issue May 26, 2022 · 14 comments
Assignees
Labels
C-anvil Command: anvil T-feature Type: feature

Comments

@BlinkyStitt
Copy link

Component

Anvil

Describe the feature you would like

I am currently working on adding support for anvil to Brownie. (eth-brownie/brownie#1541). Brownie makes heavy use of eth_debugTraceTransaction

It looks like anvil already has a stub for the rpc call that returns Not implemented:

foundry/anvil/src/eth/api.rs

Lines 1140 to 1147 in b8733d4

pub async fn debug_trace_transaction(
&self,
_tx_hash: H256,
_opts: GethDebugTracingOptions,
) -> Result<Vec<Trace>> {
node_info!("debug_traceTransaction");
Err(BlockchainError::RpcUnimplemented)
}

@gakonst said in telegram: "I think we should already should be able to support geth style traces. Maybe we dont expose over rpc?"

Additional context

Brownie currently checks for response["error"]["code"] != -32601, so changing anvil to do that in the mean time would be helpful.

https://github.com/eth-brownie/brownie/blob/master/brownie/network/web3.py#L119-L131

@drawnwren
Copy link
Contributor

Any progress on this? I'm happy to try and pick it up over the weekend if it's stalled.

@mattsse
Copy link
Member

mattsse commented Jul 8, 2022

this requires some effort,

first, ethers-rs does not have support for geth tracing either,

gakonst/ethers-rs#558 contains (some of) the first work package, which is bindings for geth's trace types.

once we have that we need proper conversions from revm tracing to geth trace types

the current revm tracing to parity tracing conversion is handled here https://github.com/foundry-rs/foundry/blob/master/evm/src/trace/node.rs we'd need the same for geth tracing types

so to summarize

  1. add geth tracing type bindings to ethers-rs
  2. add tracing conversion in https://github.com/foundry-rs/foundry/blob/master/evm/src/trace/node.rs
  3. convert on geth tracing RPC request, same as for parity, ref
    pub fn parity_traces(&self) -> Vec<Trace> {

@drawnwren
Copy link
Contributor

drawnwren commented Jul 8, 2022

  1. Submitted a PR gakonst/ethers-rs#1469
  2. (and 3) wip.

@onbjerg onbjerg assigned drawnwren and unassigned mattsse Jul 10, 2022
@onbjerg onbjerg moved this from Todo to In Progress in Foundry Jul 10, 2022
@drawnwren
Copy link
Contributor

drawnwren commented Jul 12, 2022

So, this ends up being hairier than expected.

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>,
}

The tracer option is a string which is evaluated as JS of the form:

tracer = function(tx) {
   return debug.traceTransaction(tx, {tracer:
      '{' +
         'retVal: [],' +
         'step: function(log,db) {this.retVal.push(log.getPC() + ":" + log.op.toString())},' +
         'fault: function(log,db) {this.retVal.push("FAULT: " + JSON.stringify(log))},' +
         'result: function(ctx,db) {return this.retVal}' +
      '}'
   }) // return debug.traceTransaction ...
}   // tracer = function ...

It requires writing some JS built-ins on top of evaluating the JS. Do you have any preference for the JS evaluation piece? it looks like there's a library, js_sys that does JS evaluation but I'll still have to think on the built-ins.

@mattsse
Copy link
Member

mattsse commented Jul 12, 2022

It requires writing some JS built-ins on top of evaluating the JS. Do you have any preference for the JS evaluation piece? it looks like there's a library, js_sys that does JS evaluation but I'll still have to think on the built-ins.

sorry, hard time understanding this, why would we need to evaluate JS?

I don't know where this snippet is from.

GethDebugTracingOptions are the possible options the endpoint accepts.

so next step would be to convert revm traces to the new geth tracing types, right? once we have those conversions, we can deal wth the GethDebugTracingOptions

we implemented conversions for parity traces here https://github.com/foundry-rs/foundry/blob/master/evm/src/trace/node.rs

lmk what's unclear

@drawnwren
Copy link
Contributor

Sorry, the JS snippet is from here: https://geth.ethereum.org/docs/dapp/custom-tracer#custom-javascript-tracing

Essentially, debug_traceTransaction(tx_hash, options) where options optionally includes a JS "tracer"

@Natanela
Copy link

Natanela commented Aug 17, 2022

+1 on this one

This could very helpful for us as for now we are not able to deeply analyze transactions that were executed on Anvil and we are forced to work side-by-side with hardhat (and re-execute the transactions)

@mattsse
Copy link
Member

mattsse commented Aug 17, 2022

bumping this

@onbjerg onbjerg removed this from the v1.0.0 milestone Aug 23, 2022
@haowang0402
Copy link

@mattsse we need javascript support because Geth takes a javascript tracer code snippet to process the tracing results. Also, it seems that this issue is not active anymore. I would also love to see this feature, and I am down to work on this. Could you guys also assign me to this issue? Thank you!

@gakonst
Copy link
Member

gakonst commented Aug 30, 2022

I don't feel super hot about allowing the geth-style JS tracer here FWIW. Geth itself has switched to native tracers I believe for performance reasons?

@haowang0402
Copy link

haowang0402 commented Aug 30, 2022

I agree that JS tracer is slower than native tracer but it's easier to integrate with existing tracer implementations out there. However, I don't have strong preferences between JS-style tracers and native tracers. We probably need to support the native tracers (mostly callTracer and prestateTracer) that geth supports.

@yhayun
Copy link

yhayun commented Aug 31, 2022

+1 on this request.
having this supported is needed for parsing internal transactions on Blocker Explorers.

@gakonst
Copy link
Member

gakonst commented Sep 4, 2022

having this supported is needed for parsing internal transactions on Blocker Explorers.

got some example code?

@mattsse
Copy link
Member

mattsse commented Sep 12, 2022

closing as debug_traceTransaction landed with #2868

@mattsse mattsse closed this as completed Sep 12, 2022
Repository owner moved this from In Progress to Done in Foundry Sep 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-anvil Command: anvil T-feature Type: feature
Projects
Archived in project
Development

No branches or pull requests

8 participants