-
Notifications
You must be signed in to change notification settings - Fork 188
feat: Implement Forest.EthTraceCall
#6412
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
Merged
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
4a99dc2
Start impl of EthTrace call API (wip)
elmattic 2425477
refactor the eth trace call impl [skip ci]
akaladarshi 442052f
add deep trace into the tracer contract
akaladarshi fca5536
add stateDiff support in trace call API
akaladarshi aa3e558
add trace call api integration test script [skip ci]
akaladarshi f36d8c3
add support for the evm storage slot in the state diff
akaladarshi 47b7aa3
include storage slot diff in the trace call test script
akaladarshi c3b0eb5
fix ci linter issue
akaladarshi 770f359
remove the unused script and refactor the trace test script
akaladarshi 9f68a52
add trace call api testing guide
akaladarshi 0460a9e
address comments about docs and scripts
akaladarshi 2371d26
address comments about adding unit tests and small cleanup
akaladarshi cbd672a
fix linter issue
akaladarshi 641aad6
allow the state tree flush in call_with_gas based on bool
akaladarshi 1a3f0d8
refactor integration test to assert value checks and add more tests
akaladarshi 57ad705
fix linter issue and make blockparam optional in the API
akaladarshi 81cb3c5
Merge branch 'main' into akaladarshi/eth-trace-call
akaladarshi 812e5e2
update open rpc doc to add trace call and only support trace_call in …
akaladarshi 324f78f
fix linter issue
akaladarshi 74a2ab8
Merge branch 'main' into akaladarshi/eth-trace-call
akaladarshi 49d9a94
address comments
akaladarshi 002c584
address stack safe comment
akaladarshi 342b02f
use enum instead of bool for flushing the vm
akaladarshi 6eeac35
Merge branch 'main' into akaladarshi/eth-trace-call
akaladarshi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
LesnyRumcajs marked this conversation as resolved.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,177 @@ | ||
| # trace_call Developer Guide | ||
|
|
||
| This guide covers testing and development workflows for Forest's `trace_call` implementation. For API documentation and user-facing usage, see the [trace_call API guide](/knowledge_base/rpc/trace_call). | ||
|
|
||
| ## Tracer Contract | ||
|
|
||
| The [`Tracer.sol`](https://github.com/ChainSafe/forest/blob/963237708137e9c7388c57eba39a2f8bf12ace74/src/tool/subcommands/api_cmd/contracts/tracer/Tracer.sol) contract provides various functions to test different tracing scenarios. | ||
|
|
||
| ### Storage Layout | ||
|
|
||
| | Slot | Variable | Description | | ||
| | ---- | -------------- | ---------------------------- | | ||
| | 0 | `x` | Initialized to 42 | | ||
| | 1 | `balances` | Mapping base slot | | ||
| | 2 | `storageTestA` | Starts empty (for add tests) | | ||
| | 3 | `storageTestB` | Starts empty | | ||
| | 4 | `storageTestC` | Starts empty | | ||
| | 5 | `dynamicArray` | Array length slot | | ||
|
|
||
| ### Function Reference | ||
|
|
||
| #### Basic Operations | ||
|
|
||
| | Function | Selector | Description | | ||
| | ------------------- | ------------ | --------------------------- | | ||
| | `setX(uint256)` | `0x4018d9aa` | Write to slot 0 | | ||
| | `deposit()` | `0xd0e30db0` | Receive ETH, update mapping | | ||
| | `withdraw(uint256)` | `0x2e1a7d4d` | Send ETH from contract | | ||
| | `doRevert()` | `0xafc874d2` | Always reverts | | ||
|
|
||
| #### Call Tracing | ||
|
|
||
| | Function | Selector | Description | | ||
| | ----------------------- | ------------ | ---------------------- | | ||
| | `callSelf(uint256)` | `0xa1a88595` | Single nested CALL | | ||
| | `delegateSelf(uint256)` | `0x8f5e07b8` | `DELEGATECALL` trace | | ||
| | `complexTrace()` | `0x6659ab96` | Multiple nested calls | | ||
| | `deepTrace(uint256)` | `0x0f3a17b8` | Recursive N-level deep | | ||
|
|
||
| #### Storage Diff Testing | ||
|
|
||
| | Function | Selector | Description | | ||
| | ------------------------------------------ | ------------ | -------------------- | | ||
| | `storageAdd(uint256)` | `0x55cb64b4` | Add to empty slot 2 | | ||
| | `storageChange(uint256)` | `0x7c8f6e57` | Modify existing slot | | ||
| | `storageDelete()` | `0xd92846a3` | Set slot to zero | | ||
| | `storageMultiple(uint256,uint256,uint256)` | `0x310af204` | Change slots 2,3,4 | | ||
|
|
||
| ### Generating Function Selectors | ||
|
|
||
| Use `cast` from Foundry to generate function selectors: | ||
|
|
||
| ```bash | ||
| # Get selector for a function | ||
| cast sig "setX(uint256)" | ||
| # Output: 0x4018d9aa | ||
|
|
||
| # Encode full calldata | ||
| cast calldata "setX(uint256)" 123 | ||
| # Output: 0x4018d9aa000000000000000000000000000000000000000000000000000000000000007b | ||
| ``` | ||
|
|
||
| ### Deployed Contracts | ||
|
|
||
| Pre-deployed Tracer contracts for quick testing: | ||
|
|
||
| | Network | Contract Address | | ||
| | -------- | ------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | Calibnet | [`0x73a43475aa2ccb14246613708b399f4b2ba546c7`](https://calibration.filfox.info/en/address/0x73a43475aa2ccb14246613708b399f4b2ba546c7) | | ||
| | Mainnet | [`0x9BB686Ba6a50D1CF670a98f522a59555d4977fb2`](https://filecoin.blockscout.com/address/0x9BB686Ba6a50D1CF670a98f522a59555d4977fb2) | | ||
|
|
||
| ## Comparison Testing with Anvil | ||
|
|
||
| Anvil uses **Geth style** tracing (`debug_traceCall` with `prestateTracer`), while Forest uses **Parity style** tracing (`trace_call` with `stateDiff`). This makes Anvil useful for comparison testing — verifying that Forest produces semantically equivalent results in a different format. | ||
|
|
||
|
LesnyRumcajs marked this conversation as resolved.
|
||
| ### Prerequisites | ||
|
|
||
| - [Foundry](https://book.getfoundry.sh/getting-started/installation) installed (`forge`, `cast` commands) | ||
| - A running [Forest node](https://docs.forest.chainsafe.io/getting_started/syncing) and Anvil instance | ||
|
|
||
| ### What is Anvil? | ||
|
|
||
| [Anvil](https://getfoundry.sh/anvil/reference/) is a local Ethereum development node included with Foundry. It provides: | ||
|
|
||
| - Instant block mining | ||
| - Pre-funded test accounts (10 accounts with 10,000 ETH each) | ||
| - Support for `debug_traceCall` with various tracers | ||
| - No real tokens required | ||
|
|
||
| ### Starting Anvil | ||
|
|
||
| ```bash | ||
| # Start Anvil with tracer to allow debug_traceCall API's | ||
| anvil --tracing | ||
| ``` | ||
|
|
||
| Anvil RPC endpoint: `http://localhost:8545` | ||
|
|
||
| ### Deploying Contract on Anvil | ||
|
|
||
| ```bash | ||
| forge create src/tool/subcommands/api_cmd/contracts/tracer/Tracer.sol:Tracer \ | ||
| --rpc-url http://localhost:8545 \ | ||
| --broadcast \ | ||
| --private-key <ANVIL_OUTPUT_PRIVATE_KEY> | ||
|
|
||
| # Output: | ||
| # Deployer: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 | ||
| # Deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 | ||
| # Transaction hash: 0x... | ||
| ``` | ||
|
|
||
| ### Comparing Forest vs Anvil Responses | ||
|
|
||
| The same contract call can be tested against both nodes. The request data payloads are identical; only the method name and parameter ordering differ. | ||
|
|
||
| **Forest (Parity-style `trace_call`):** | ||
|
|
||
| ```bash | ||
| curl -s -X POST "http://localhost:2345/rpc/v1" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{ | ||
| "jsonrpc": "2.0", | ||
| "id": 1, | ||
| "method": "trace_call", | ||
| "params": [ | ||
| {"from": "0x...", "to": "0x...", "data": "0x4018d9aa..."}, | ||
| ["stateDiff"], | ||
| "latest" | ||
| ] | ||
| }' | ||
| ``` | ||
|
|
||
| **Anvil (Geth style `debug_traceCall`):** | ||
|
|
||
| ```bash | ||
| curl -s -X POST "http://localhost:8545" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{ | ||
| "jsonrpc": "2.0", | ||
| "id": 1, | ||
| "method": "debug_traceCall", | ||
| "params": [ | ||
| {"from": "0x...", "to": "0x...", "data": "0x4018d9aa..."}, | ||
| "latest", | ||
| {"tracer": "prestateTracer", "tracerConfig": {"diffMode": true}} | ||
| ] | ||
| }' | ||
| ``` | ||
|
|
||
| ## Integration Test Script | ||
|
|
||
| An automated test script is available to compare Forest's `trace_call` with Anvil's `debug_traceCall`: | ||
|
|
||
| ```bash | ||
| # Run the test (requires Forest and Anvil running) | ||
| ./scripts/tests/trace_call_integration_test.sh | ||
|
|
||
| or | ||
|
|
||
| # Deploy contract on Anvil first, forest and anvil node should already be running | ||
| ./scripts/tests/trace_call_integration_test.sh --deploy | ||
| ``` | ||
|
|
||
| ### Test Categories | ||
|
|
||
| 1. **Trace Tests**: Call hierarchy, subcalls, reverts, deep traces | ||
| 2. **Balance Diff Tests**: ETH transfers, deposits | ||
| 3. **Storage Diff Tests**: Single slot, multiple slots, value comparison | ||
|
|
||
| ## Official Resources | ||
|
|
||
| - [OpenEthereum trace module](https://openethereum.github.io/JSONRPC-trace-module) | ||
| - [Geth Built-in Tracers](https://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers) | ||
| - [Alchemy: `trace_call` vs `debug_traceCall`](https://www.alchemy.com/docs/reference/trace_call-vs-debug_tracecall) | ||
| - [Reth trace Namespace](https://reth.rs/jsonrpc/trace) | ||
| - [Foundry Book - Anvil](https://book.getfoundry.sh/reference/anvil/) | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.