From c6421e949e9f2318a1f6412d95503cf8646d3997 Mon Sep 17 00:00:00 2001 From: Zhang Guyu Date: Thu, 20 Jul 2023 11:54:19 +0800 Subject: [PATCH 1/5] doc: add `trace_transcation` doc --- docs/features/trace_transcation.md | 71 ++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 docs/features/trace_transcation.md diff --git a/docs/features/trace_transcation.md b/docs/features/trace_transcation.md new file mode 100644 index 0000000000..c25bf3a5d2 --- /dev/null +++ b/docs/features/trace_transcation.md @@ -0,0 +1,71 @@ +# EVM Transaction Tracing + +Ethereum has two different types of transactions: regular transfers and contract executions. A regular transfer simply moves Eth from one account to another. However, if the recipient of the transaction is a contract account with associated EVM (Ethereum Virtual Machine) bytecode, this bytecode will be executed as part of the transaction, in addition to transferring any Eth. + +We can check whether this execution was successful through the status code of the transaction receipt, but there's no way to see which data was modified halfway, nor which external contracts were called. To understand what a transaction has done, we need to trace the transaction. + +`trace_transaction` is an RPC method exposed by the Openethereum and Erigon Ethereum clients. You can get the EVM traces of a previously executed transaction using this method. This can be useful for debugging purposes, or for understanding how a transaction works. + +## Why + +The Tracer implemented by Geth/Erigon has relatively poor performance and cannot meet our business needs. The `debug_tracexx/trace_xx` functions of Geth/Erigon perform well for tracing recent transactions (within 128 blocks). However, for tracing historical transactions, the RPC usually takes more than 1 second to return. The fundamental reason is that their trace needs to first backtrack to a specific block and replay all transactions prior to the transaction to be traced in that block, which leads to inefficiency. + +`trace_transaction` implemented in this repository is generated as an add-on during transaction execution and stored in a designated database. The `trace_transaction` only requires a single read to obtain the trace, and the RPC response time is at the millisecond level. + +Moreover, most non-Ethereum public chains are forked from Go-Ethereum, so there is a strong demand for a high-performance tracer in Go version for subsequent business. + +## Design +### Parameters +This method only takes one parameter which is the transaction hash of the transaction whose traces you wish to get: + +- Hash - Transaction hash + +``` json +params: ["0x17104ac9d3312d8c136b7f44d4b8b47852618065ebfa534bd2d3b5ef218ca1f3"] +``` + +Returns +- Array - Traces of given transaction + +### Example +Request +```bash +curl --data '{"method":"trace_transaction","params":["0x17104ac9d3312d8c136b7f44d4b8b47852618065ebfa534bd2d3b5ef218ca1f3"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545 +``` +Response +``` +{ + "id": 1, + "jsonrpc": "2.0", + "result": [ + { + "action": { + "callType": "call", + "from": "0x1c39ba39e4735cb65978d4db400ddd70a72dc750", + "gas": "0x13e99", + "input": "0x16c72721", + "to": "0x2bd2326c993dfaef84f696526064ff22eba5b362", + "value": "0x0" + }, + "blockHash": "0x7eb25504e4c202cf3d62fd585d3e238f592c780cca82dacb2ed3cb5b38883add", + "blockNumber": 3068185, + "result": { + "gasUsed": "0x183", + "output": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + "subtraces": 0, + "traceAddress": [ + 0 + ], + "transactionHash": "0x17104ac9d3312d8c136b7f44d4b8b47852618065ebfa534bd2d3b5ef218ca1f3", + "transactionPosition": 2, + "type": "call" + }, + ... + ] +} +``` + +## Reference +- EVM Tracing +- Parity Trace Module From 9159832f981ec6d0a882bdc9a262daaecc0af2b6 Mon Sep 17 00:00:00 2001 From: Zhang Guyu Date: Thu, 20 Jul 2023 11:56:14 +0800 Subject: [PATCH 2/5] fix link --- docs/features/trace_transcation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/features/trace_transcation.md b/docs/features/trace_transcation.md index c25bf3a5d2..f8dc21134c 100644 --- a/docs/features/trace_transcation.md +++ b/docs/features/trace_transcation.md @@ -67,5 +67,5 @@ Response ``` ## Reference -- EVM Tracing -- Parity Trace Module +- [EVM Tracin](https://geth.ethereum.org/docs/developers/evm-tracing) +- [Parity Trace Module](https://openethereum.github.io/JSONRPC-trace-module) From 5d70bf9f071ff93ac57d21522b2957cd206dda6d Mon Sep 17 00:00:00 2001 From: Zhang Guyu Date: Thu, 20 Jul 2023 14:44:41 +0800 Subject: [PATCH 3/5] add `mutlcall` doc --- ...nscation.md => EVM Transaction Tracing.md} | 0 docs/features/Multicall.md | 129 ++++++++++++++++++ 2 files changed, 129 insertions(+) rename docs/features/{trace_transcation.md => EVM Transaction Tracing.md} (100%) create mode 100644 docs/features/Multicall.md diff --git a/docs/features/trace_transcation.md b/docs/features/EVM Transaction Tracing.md similarity index 100% rename from docs/features/trace_transcation.md rename to docs/features/EVM Transaction Tracing.md diff --git a/docs/features/Multicall.md b/docs/features/Multicall.md new file mode 100644 index 0000000000..c767b72ff2 --- /dev/null +++ b/docs/features/Multicall.md @@ -0,0 +1,129 @@ +# Multicall + +Similar to the multicall provided by [multicall contract](https://github.com/mds1/multicall). The `eth_multiCall` implemented in this repository has two main use cases: +* Aggregate results from multiple contract reads into a single JSON-RPC request. +* Execute multiple state-changing calls in a single transaction. + +## Why +The newly added `eth_multiCall` will solve the following problems existing in the multicall contract: +* Multicall contract is not applicable to old blocks before the deployment of the multicall contract. +* Multicall contract aggregates multiple parameters together and executes them as a whole in the EVM, which is not conducive to implementing computational layer caching. +For example, if this time the calls are [A, B, C, D], and the next call is [B, A, C, D] or [A, E, C, D], then the results of A, C, D cached the first time cannot make the next request hit. +* Multicall contract is executed in series in the EVM. Having too many calls in the multicall contract can easily lead to cumulative time consumption. + +## Design +### Parameters + +- calls - List[TransactionArgs] Transaction call object list +- blockNrOrHash - Block number or the string latest or pending +- pfastFail - bool, if true, Any single call fails the entire multicall return directly when a failure occurs. +- puseParallel - bool, if true, Calls are executed concurrently, not sequentially one after another. +- pdisableCache - bool, if true, Disable caching of call results. + +Returns +- result - List[Result], Call result list +- stats - Stats, The status information of this request +- err + +### Example +Request +``` json +{ + "jsonrpc":"2.0", + "method":"eth_multiCall", + "params":[ + [ + { + "to":"0xf824717e5e7cefd7aa78112fb7e62dd9422488d3", + "data":"0x3fc1cc26000000000000000000000000ac7a698a85102f7b1dc7345e7f17ebca74e5a9e7000000000000000000000000000000000000000000000000000000000000041f000000000000000000000000000000000000000000000000000000000000000100000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b75000000000000000000000000000000000000000000000000000000001dcd650000000000000000000000000000000000000000000000000000000000636b1b8d" + }, + { + "to":"0x8166994d9ebBe5829EC86Bd81258149B87faCFd3", + "data":"0x93f1a40b00000000000000000000000000000000000000000000000000000000000000370000000000000000000000004f2769e87c7d96ed9ca72084845ee05e7de5dda2" + }, + { + "to":"0xf824717e5e7cefd7aa78112fb7e62dd9422488d3", + "data":"0x3fc1cc26000000000000000000000000ac7a698a85102f7b1dc7345e7f17ebca74e5a9e7000000000000000000000000000000000000000000000000000000000000041f000000000000000000000000000000000000000000000000000000000000000100000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b75000000000000000000000000000000000000000000000000000000001dcd650000000000000000000000000000000000000000000000000000000000636b1b8d" + }, + { + "to":"0x49894fCC07233957c35462cfC3418Ef0CC26129f", + "data":"0x70a08231000000000000000000000000205b993bb19930c80fb10ddf4f4c423e49c4caac" + }, + { + "to":"0xffb02c56bb2843b794016ddc08ab11a8be7d73ca", + "data":"0xa799234e0000000000000000000000007e75ce11a7ea2969ea1c0e5b3a9ed4c45ec8363b0000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000000000002490181a000000000000000000000000d34ec5fda2e2f1098cd8ba4b883993cc0b9ec8c3000000000000000000000000f6f67f5639caf9bf36e7e32992cb7fa2d7d9df3500000000000000000000000000000000000000000000000000000000000026de00000000000000000000000000000000000000000000000000000000636b1c99" + }, + { + "to":"0x3776b8c349bc9af202e4d98af163d59ca56d2fc5", + "data":"0x8343d129" + } + ], + "0x87e31644c43654708bfc0de50ba8ae3a3d6ecf99eacda6041072ea526c7aec16", + false, + true, + true + ], + "id":2 +} +``` +Response +```json +{ + "jsonrpc":"2.0", + "id":2, + "result":{ + "results":[ + { + "err":"execution reverted", + "fromCache":false, + "result":"0x", + "gasUsed":0, + "timeCost":0.003416628 + }, + { + "err":"", + "fromCache":false, + "result":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasUsed":23794, + "timeCost":0.002786535 + }, + { + "err":"execution reverted", + "fromCache":false, + "result":"0x", + "gasUsed":0, + "timeCost":0.003377504 + }, + { + "err":"", + "fromCache":false, + "result":"0x0000000000000000000000000000000000000000000000000000000000000000", + "gasUsed":22718, + "timeCost":0.002273802 + }, + { + "err":"", + "fromCache":false, + "result":"0x", + "gasUsed":22884, + "timeCost":0.001404123 + }, + { + "err":"", + "fromCache":false, + "result":"0x", + "gasUsed":21064, + "timeCost":0.001325271 + } + ], + "stats":{ + "blockNum": "0x87e31644c43654708bfc0de50ba8ae3a3d6ecf99eacda6041072ea526c7aec16", + "blockTime":1648512415, + "success":true, + "timeCost":0.003840274, + "gasUsed":90460, + "usedParallel":true + } + } +} +``` \ No newline at end of file From 77af6bf3ca251ec0011a9f482dc3dffe91d5d77e Mon Sep 17 00:00:00 2001 From: Zhang Guyu Date: Thu, 20 Jul 2023 15:14:45 +0800 Subject: [PATCH 4/5] add `pre_traceMany` doc --- docs/features/EVM Pre Execution.md | 132 +++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 docs/features/EVM Pre Execution.md diff --git a/docs/features/EVM Pre Execution.md b/docs/features/EVM Pre Execution.md new file mode 100644 index 0000000000..a97aa09ea4 --- /dev/null +++ b/docs/features/EVM Pre Execution.md @@ -0,0 +1,132 @@ +# EVM Pre Execution +Interacting with contracts is not as straightforward as EOA (Externally Owned Account) transfers. Users need to know how their assets change after submitting transactions to avoid potential risks to the greatest extent. Pre-execution executes related transactions on the latest block and collects state changes, event logs, and the call and create call stack during EVM execution. + +## Why +In JSON-RPC, there already exist `eth_call` and `eth_estimateGas` for simulating the result and gas usage of user transactions. This is sufficient for ordinary transfer requests, but for contract calls, we also need to know which data has been modified halfway, which external contracts have been called, and the Event Log during contract execution. + +The `pre_traceMany` enhances the tracing capabilities of our API, allowing users to trace multiple transactions in a single call. This can be particularly useful for debugging complex interactions between multiple transactions. + +The defining feature of `pre_traceMany` is its sequential execution of transactions, where each transaction is executed based on the final state of the preceding one, thereby creating a cumulative effect on the state. + +The primary use case for this feature is pre-execution checks in wallets. When a user wants to understand the potential asset changes from interacting with an unauthorized contract, debug_traceCall requires the user to approve the contract before it can estimate the user's asset changes, which introduces potential risks. However, with debug_traceCallMany, there's no need for the user to approve the contract to make an estimate (the user's contract approval just needs to be passed in as a preceding transaction). In fact, the pre-transaction balance change feature in Rabby Wallet is based on this method. + +## Design +### Parameters + +- calls - List[TransactionArgs] Transaction call object list + +Returns +- List[PreResult] + +PreResult +- trace - List[TraceResult], trace result list +- Logs - List[Log], contract log event, +- StateDiff - state change +- Error - error message +- GasUsed - gas used of the transaction + +### Example +Request +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "pre_traceMany", + "params": [ + [ + { + "chainId": 1, + "data": "0x5ae401dc0000000000000000000000000000000000000000000000000000000063735a2b00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000124b858183f00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000494010000000000000000000000000000000000000000000000000000ab48ad714c000000000000000000000000000000000000000000000000000000000000000042dac17f958d2ee523a2206206994597c13d831ec70001f46b175474e89094c44da98b954eedeac495271d0f0001f4c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004449404b7c0000000000000000000000000000000000000000000000000000ab48ad714c000000000000000000000000005853ed4f26a3fcea565b3fbc698bb19cdf6deb8500000000000000000000000000000000000000000000000000000000", + "from": "0x5853ed4f26a3fcea565b3fbc698bb19cdf6deb85", + "to": "0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45", + "gas_price": "0x0", + "nonce": "0xD36", + "value": "0x0" + } + ] + ] +} +``` +Response +```json +{ + "jsonrpc": "2.0", + "id": 1, + "result": [ + { + "trace": [ + ... + { + "action": { + "callType": "call", + "from": "0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45", + "to": "0x5853ed4f26a3fcea565b3fbc698bb19cdf6deb85", + "value": "0xd65434b5d543", + "gas": "0x7c07fffffffc7756", + "input": "0x" + }, + "blockHash": "0x5fd7ab63f50e1847a61a29dc0e0fa2f04b92854a3bc517ca8e6aac6a2ab8ff16", + "blockNumber": 15974376, + "result": { + "gasUsed": "0x0", + "output": "0x" + }, + "subtraces": 0, + "traceAddress": [ + 1, + 2 + ], + "transactionHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "transactionPosition": 0, + "type": "call" + } + ], + "logs": [ + ... + { + "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", + "topics": [ + "0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65", + "0x00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45" + ], + "data": "0x0000000000000000000000000000000000000000000000000000d65434b5d543", + "blockNumber": "0xf3bfe8", + "transactionHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "transactionIndex": "0x0", + "blockHash": "0x5fd7ab63f50e1847a61a29dc0e0fa2f04b92854a3bc517ca8e6aac6a2ab8ff16", + "logIndex": "0x6", + "removed": false + } + ], + "stateDiff": { + ... + "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2": { + "0xdc51a0a44317b550a6b5ddb34687ce2bd40e4750eec27343e32b23e686739208": { + "before": "0x0000000000000000000000000000000000000000000000000000000000000000", + "after": "0x0000000000000000000000000000000000000000000000000000d65434b5d543" + }, + "0xf762dfe765e313d39f5dd6e34e29a9ef0af51578e67f7f482bb4f8efd984976b": { + "before": "0x0000000000000000000000000000000000000000000000774b2e49fbce11d66a", + "after": "0x0000000000000000000000000000000000000000000000774b2d73a7995c0127" + } + }, + "0xdac17f958d2ee523a2206206994597c13d831ec7": { + "0x7319dbd3df87dc649aecf2c43364f3729a895a26487ee485b7813b28cddd22fe": { + "before": "0x000000000000000000000000000000000000000000000000000000dc6b650f79", + "after": "0x000000000000000000000000000000000000000000000000000000dc6b69a37a" + }, + "0xaa92b417b47961809296951f3d875b19705bd9dea1aa082bb9fed9fdc898f2af": { + "before": "0x0000000000000000000000000000000000000000000000000000000000049401", + "after": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + } + }, + "error": { + "code": 0, + "msg": "" + }, + "gasUsed": 195350 + } + ] +} +``` \ No newline at end of file From 921f30f655369188161e62d53019c48364beeea8 Mon Sep 17 00:00:00 2001 From: Zhang Guyu Date: Thu, 20 Jul 2023 15:30:22 +0800 Subject: [PATCH 5/5] add doc for Ancient Pruner --- docs/features/Ancient Pruner.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 docs/features/Ancient Pruner.md diff --git a/docs/features/Ancient Pruner.md b/docs/features/Ancient Pruner.md new file mode 100644 index 0000000000..9ba31215e2 --- /dev/null +++ b/docs/features/Ancient Pruner.md @@ -0,0 +1,7 @@ +# Ancient Pruner + +## Why +The chain freezer improves efficiency by moving the ancient chain items into their own flat files. This allows us to split the database into an active set, which requires a fast SSD disk, and an immutable freezer set, for which a slower HDD disk is sufficient. + +However, for Geth running as a state node, ancient data is not needed and it's more beneficial to delete it directly. If the user enables "ancient.prune", the system will completely discard the ancient blocks instead of writing them to the freezer database. +