From d81a42c12776ce1739ba0521679fad1a3d9a01a6 Mon Sep 17 00:00:00 2001 From: Ake <10195782+akegaviar@users.noreply.github.com> Date: Fri, 24 Jul 2026 07:23:41 +0700 Subject: [PATCH] =?UTF-8?q?docs:=20Polygon=20Bor=20consistency=20=E2=80=94?= =?UTF-8?q?=20document=20flatCallTracer,=20drop=20stale=20Erigon=20claims?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follows #578. Now that Polygon runs fully on Bor with flatCallTracer enabled, propagate the change across the debug/trace references and fix leftover Erigon-era drift: - debug-and-trace-apis: Polygon Dedicated Nodes run Bor (debug_* only); dropped the stale Bor-or-Erigon choice, the trace_* claim, and the Erigon README link; point to the migration on Polygon methods. - polygon-getblockreceipts: dropped the false 'available on Erigon only' (eth_getBlockReceipts is served on Bor and is in the availability table). - debug/trace overview + the 4 debug_trace* reference pages: added flatCallTracer to the tracer catalog, parameter lists, response sections, and code comments. Response fields verified against a live flatCallTracer trace. callTracer examples kept as-is (still supported). --- docs/debug-and-trace-apis.mdx | 7 +------ reference/polygon-debug-trace-rpc-methods.mdx | 4 ++++ reference/polygon-getblockreceipts.mdx | 2 +- reference/polygon-traceblockbyhash.mdx | 17 ++++++++++++++--- reference/polygon-traceblockbynumber.mdx | 15 +++++++++++++-- reference/polygon-tracecall.mdx | 17 ++++++++++++++--- reference/polygon-tracetransaction.mdx | 15 +++++++++++++-- 7 files changed, 60 insertions(+), 17 deletions(-) diff --git a/docs/debug-and-trace-apis.mdx b/docs/debug-and-trace-apis.mdx index 2248e5ca..212ae5f6 100644 --- a/docs/debug-and-trace-apis.mdx +++ b/docs/debug-and-trace-apis.mdx @@ -43,12 +43,7 @@ To enable debug and trace APIs on your Polygon node, you must have a [paid plan] #### Dedicated Nodes -To enable debug and trace APIs on your dedicated Polygon node, you must have a [paid plan](https://chainstack.com/pricing/). Dedicated Nodes can be deployed either as the Bor or Erigon client implementation for the full and archive modes respectively, however, they slightly differ from each other: - -* With a node running on Bor, only `debug_*`namespace is exposed. -* With a node running on Erigon, both `debug_*` and `trace_*`namespaces are exposed. - -For the full list of the available debug and trace API methods, see: [Erigon: RPC implementation status](https://github.com/ledgerwatch/erigon/blob/stable/cmd/rpcdaemon/README.md#rpc-implementation-status) +To enable debug and trace APIs on your dedicated Polygon node, you must have a [paid plan](https://chainstack.com/pricing/). Dedicated Polygon nodes run the Bor client, which exposes the `debug_*` namespace. Bor does not implement the Erigon-only Parity `trace_*` namespace — see [Polygon methods](/docs/polygon-methods) for the `trace_*` → `debug_*` migration. ### BNB Smart Chain diff --git a/reference/polygon-debug-trace-rpc-methods.mdx b/reference/polygon-debug-trace-rpc-methods.mdx index 43de0ef5..b54126a4 100644 --- a/reference/polygon-debug-trace-rpc-methods.mdx +++ b/reference/polygon-debug-trace-rpc-methods.mdx @@ -40,6 +40,10 @@ This tracer looks for function signatures that are 4 bytes long during contract This tracer extracts information about all internal calls made by a transaction, providing visibility into how contracts interact with each other. +### `flatCallTracer` + +This tracer returns the same call data as `callTracer` but as a flat array in the Parity-style trace format, where each entry's `traceAddress` marks its position in the call tree. It is the drop-in replacement for the Erigon `trace_*` methods, which Bor does not implement. + ### `prestateTracer` This tracer returns sufficient information about an account to create a local execution of the transaction. This procedure runs the given transaction again and monitors every aspect of the state that is modified or accessed during execution. diff --git a/reference/polygon-getblockreceipts.mdx b/reference/polygon-getblockreceipts.mdx index 3b1ba368..220ab219 100644 --- a/reference/polygon-getblockreceipts.mdx +++ b/reference/polygon-getblockreceipts.mdx @@ -4,7 +4,7 @@ openapi: /openapi/polygon_node_api/transaction_info/eth_getBlockReceipts.json PO description: "Polygon API method that retrieves all transaction receipts for a given block. Reference for eth_getBlockReceipts on Polygon via Chainstack." --- -Polygon API method that retrieves all transaction receipts for a given block. Transaction receipts contain information about the execution status of a transaction and can be useful for monitoring the status of transfers or contract execution on the blockchain. This method is available on Erigon only. +Polygon API method that retrieves all transaction receipts for a given block. Transaction receipts contain information about the execution status of a transaction and can be useful for monitoring the status of transfers or contract execution on the blockchain. diff --git a/reference/polygon-traceblockbyhash.mdx b/reference/polygon-traceblockbyhash.mdx index 36fa507f..8833986c 100644 --- a/reference/polygon-traceblockbyhash.mdx +++ b/reference/polygon-traceblockbyhash.mdx @@ -28,6 +28,7 @@ You can sign up with your GitHub, X, Google, or Microsoft account. + `4byteTracer` — tracer that captures the function signatures and call data sizes for all functions executed during a transaction, creating a map that links each selector and size combination to the number of times it occurred. This provides valuable information about the frequency and usage of each function within the transaction. + `callTracer` — tracer that captures information on all call frames executed during a transaction. The resulting nested list of call frames is organized into a tree structure that reflects the way the Ethereum Virtual Machine works and can be used for debugging and analysis purposes. + `prestateTracer` — tracer with two modes: `prestate` and `diff`, where the former returns the accounts needed to execute a transaction, and the latter returns the differences between the pre and post-states of the transaction. The tracer operates by re-executing the transaction and tracking every state change made, resulting in an object with the account addresses as keys and the corresponding trie leaves as values. + + `flatCallTracer` — tracer that returns the transaction's calls as a flat array in the Parity-style trace format, with each entry's position given by its `traceAddress`. This is the drop-in replacement for the Erigon `trace_*` methods, which Bor does not implement. ## Response types @@ -49,6 +50,16 @@ You can sign up with your GitHub, X, Google, or Microsoft account. + `revertReason` — the reason why the transaction was reverted, returned by the smart contract if any. + `calls` — a list of sub-calls made by the contract during the call, each represented as a nested call frame object. +### `flatCallTracer` response + +* `array` — the block's calls as a flat list in the Parity trace format, one object per call: + + `action` — the call details: `from`, `to`, `value`, `gas`, `input`, and `callType` (for example, `call`, `delegatecall`, or `staticcall`). Contract creations and self-destructs carry the corresponding Parity `create` and `suicide` fields instead. + + `result` — the call outcome: `gasUsed` and `output`. Contract creations return the new contract `address` and its `code`. + + `subtraces` — the number of child calls made directly by this call. + + `traceAddress` — the position of this call in the call tree, as an array of child indices. + + `type` — the call type: `call`, `create`, or `suicide`. + + `error` — present only when the call failed, with the failure reason. + ### `prestateTracer` response * `object` — the `prestateTracer` traces object: @@ -68,7 +79,7 @@ const provider = new ethers.JsonRpcProvider(NODE_URL); const traceBlockByHash = async (blockHash) => { - // Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer + // Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer const tracer = { tracer: '4byteTracer' }; const traces = await provider.send("debug_traceBlockByHash", [blockHash, tracer]); console.log(traces); @@ -84,7 +95,7 @@ web3 = Web3.HTTPProvider(node_url) block_hash = "0x22507441629262af0d44bfadebe086470df5936827bc482300b5183b4b8ac8bd" -# Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer +# Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer tracer = { "tracer": '4byteTracer' } block_traces = web3.provider.make_request('debug_traceBlockByHash', [block_hash, tracer]) print(block_traces) @@ -107,7 +118,7 @@ const provider = new ethers.JsonRpcProvider(NODE_URL); async function traceTransferFunction(blockHash) { try { - // Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer + // Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer const tracer = { tracer: '4byteTracer' }; const response = await provider.send("debug_traceBlockByHash", [blockHash, tracer]); diff --git a/reference/polygon-traceblockbynumber.mdx b/reference/polygon-traceblockbynumber.mdx index deb0d3ef..ef3d3492 100644 --- a/reference/polygon-traceblockbynumber.mdx +++ b/reference/polygon-traceblockbynumber.mdx @@ -38,6 +38,7 @@ See the [default block parameter](https://ethereum.org/en/developers/docs/apis/j + `4byteTracer` — tracer that captures the function signatures and call data sizes for all functions executed during a transaction, creating a map that links each selector and size combination to the number of times it occurred. This provides valuable information about the frequency and usage of each function within the transaction. + `callTracer` — tracer that captures information on all call frames executed during a transaction. The resulting nested list of call frames is organized into a tree structure that reflects the way the Ethereum Virtual Machine works and can be used for debugging and analysis purposes. + `prestateTracer` — tracer with two modes: `prestate` and `diff`, where the former returns the accounts needed to execute a transaction, and the latter returns the differences between the pre and post-states of the transaction. The tracer operates by re-executing the transaction and tracking every state change made, resulting in an object with the account addresses as keys and the corresponding trie leaves as values. + + `flatCallTracer` — tracer that returns the transaction's calls as a flat array in the Parity-style trace format, with each entry's position given by its `traceAddress`. This is the drop-in replacement for the Erigon `trace_*` methods, which Bor does not implement. ## Response types @@ -59,6 +60,16 @@ See the [default block parameter](https://ethereum.org/en/developers/docs/apis/j + `revertReason` — the reason why the transaction was reverted, returned by the smart contract if any. + `calls` — a list of sub-calls made by the contract during the call, each represented as a nested call frame object. +### `flatCallTracer` response + +* `array` — the block's calls as a flat list in the Parity trace format, one object per call: + + `action` — the call details: `from`, `to`, `value`, `gas`, `input`, and `callType` (for example, `call`, `delegatecall`, or `staticcall`). Contract creations and self-destructs carry the corresponding Parity `create` and `suicide` fields instead. + + `result` — the call outcome: `gasUsed` and `output`. Contract creations return the new contract `address` and its `code`. + + `subtraces` — the number of child calls made directly by this call. + + `traceAddress` — the position of this call in the call tree, as an array of child indices. + + `type` — the call type: `call`, `create`, or `suicide`. + + `error` — present only when the call failed, with the failure reason. + ### `prestateTracer` response * `object` — the `prestateTracer` traces object: @@ -78,7 +89,7 @@ const provider = new ethers.JsonRpcProvider(NODE_URL); const traceBlockByNumber = async (block) => { - // Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer + // Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer const tracer = { tracer: 'callTracer' }; const traces = await provider.send("debug_traceBlockByNumber", [block, tracer]); console.log(traces); @@ -94,7 +105,7 @@ web3 = Web3.HTTPProvider(node_url) block = "latest" -# Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer +# Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer tracer = { "tracer": 'callTracer' } block_traces = web3.provider.make_request('debug_traceBlockByNumber', [block, tracer]) print(block_traces) diff --git a/reference/polygon-tracecall.mdx b/reference/polygon-tracecall.mdx index 4f5f1a9d..8973f4f3 100644 --- a/reference/polygon-tracecall.mdx +++ b/reference/polygon-tracecall.mdx @@ -46,6 +46,7 @@ See the [default block parameter](https://ethereum.org/en/developers/docs/apis/j + `4byteTracer` — tracer that captures the function signatures and call data sizes for all functions executed during a transaction, creating a map that links each selector and size combination to the number of times it occurred. This provides valuable information about the frequency and usage of each function within the transaction. + `callTracer` — tracer that captures information on all call frames executed during a transaction. The resulting nested list of call frames is organized into a tree structure that reflects the way the Ethereum Virtual Machine works and can be used for debugging and analysis purposes. + `prestateTracer` — tracer with two modes: `prestate` and `diff`, where the former returns the accounts needed to execute a transaction, and the latter returns the differences between the pre and post-states of the transaction. The tracer operates by re-executing the transaction and tracking every state change made, resulting in an object with the account addresses as keys and the corresponding trie leaves as values. + + `flatCallTracer` — tracer that returns the call's execution as a flat array in the Parity-style trace format, with each entry's position given by its `traceAddress`. This is the drop-in replacement for the Erigon `trace_*` methods, which Bor does not implement. Find a complete [list of available built-in tracers](/reference/polygon-debug-trace-rpc-methods#pre-built-native-tracers) in the debug and trace overview. @@ -97,6 +98,16 @@ When no built-in tracer is selected, the response defaults to the [Struct/opcode + `revertReason` — the reason why the transaction was reverted, returned by the smart contract, if any. + `calls` — a list of sub-calls made by the contract during the call, each represented as a nested call frame object. +### `flatCallTracer` response + +* `array` — the call's execution as a flat list in the Parity trace format, one object per call: + + `action` — the call details: `from`, `to`, `value`, `gas`, `input`, and `callType` (for example, `call`, `delegatecall`, or `staticcall`). Contract creations and self-destructs carry the corresponding Parity `create` and `suicide` fields instead. + + `result` — the call outcome: `gasUsed` and `output`. Contract creations return the new contract `address` and its `code`. + + `subtraces` — the number of child calls made directly by this call. + + `traceAddress` — the position of this call in the call tree, as an array of child indices. + + `type` — the call type: `call`, `create`, or `suicide`. + + `error` — present only when the call failed, with the failure reason. + ### `prestateTracer` response * `object` — the `prestateTracer` traces object: @@ -137,7 +148,7 @@ const traceCall = async () => { const block = 'latest' - // Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer. Leave empty {} for Struct/opcode logger. + // Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer. Leave empty {} for Struct/opcode logger. const tracer = {}; const traces = await provider.send("debug_traceCall", [call, block, tracer]); console.log(traces); @@ -161,7 +172,7 @@ call = { block = 'latest' -# Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer. Leave empty {} for Struct/opcode logger. +# Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer. Leave empty {} for Struct/opcode logger. tracer = { "tracer": 'prestateTracer' } tx_traces = web3.provider.make_request('debug_traceCall', [call, block, tracer]) print(tx_traces) @@ -187,7 +198,7 @@ const provider = new ethers.JsonRpcProvider(NODE_URL); async function traceCall(call, block) { try { - // Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer. + // Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer. // Leave empty {} for Struct/opcode logger. const tracer = { tracer: 'callTracer' }; diff --git a/reference/polygon-tracetransaction.mdx b/reference/polygon-tracetransaction.mdx index a0c062bb..9fc39eb3 100644 --- a/reference/polygon-tracetransaction.mdx +++ b/reference/polygon-tracetransaction.mdx @@ -28,6 +28,7 @@ You can sign up with your GitHub, X, Google, or Microsoft account. + `4byteTracer` — tracer that captures the function signatures and call data sizes for all functions executed during a transaction, creating a map that links each selector and size combination to the number of times it occurred. This provides valuable information about the frequency and usage of each function within the transaction. + `callTracer` — tracer that captures information on all call frames executed during a transaction. The resulting nested list of call frames is organized into a tree structure that reflects the way the Ethereum Virtual Machine works and can be used for debugging and analysis purposes. + `prestateTracer` — tracer with two modes: `prestate` and `diff`, where the former returns the accounts needed to execute a transaction, and the latter returns the differences between the pre and post-states of the transaction. The tracer operates by re-executing the transaction and tracking every state change made, resulting in an object with the account addresses as keys and the corresponding trie leaves as values. + + `flatCallTracer` — tracer that returns the transaction's calls as a flat array in the Parity-style trace format, with each entry's position given by its `traceAddress`. This is the drop-in replacement for the Erigon `trace_*` methods, which Bor does not implement. Find a complete [list of available built-in tracers](/reference/polygon-debug-trace-rpc-methods#pre-built-native-tracers) in the debug and trace overview. @@ -79,6 +80,16 @@ When no built-in tracer is selected, the response defaults to the [Struct/opcode + `revertReason` — the reason why the transaction was reverted, returned by the smart contract if any. + `calls` — a list of sub-calls made by the contract during the call, each represented as a nested call frame object. +### `flatCallTracer` response + +* `array` — the transaction's calls as a flat list in the Parity trace format, one object per call: + + `action` — the call details: `from`, `to`, `value`, `gas`, `input`, and `callType` (for example, `call`, `delegatecall`, or `staticcall`). Contract creations and self-destructs carry the corresponding Parity `create` and `suicide` fields instead. + + `result` — the call outcome: `gasUsed` and `output`. Contract creations return the new contract `address` and its `code`. + + `subtraces` — the number of child calls made directly by this call. + + `traceAddress` — the position of this call in the call tree, as an array of child indices. + + `type` — the call type: `call`, `create`, or `suicide`. + + `error` — present only when the call failed, with the failure reason. + ### `prestateTracer` response * `object` — the `prestateTracer` traces object: @@ -109,7 +120,7 @@ const provider = new ethers.JsonRpcProvider(NODE_URL); const traceTransaction = async (txhash) => { - // Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer. Leave empty {} for Struct/opcode logger. + // Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer. Leave empty {} for Struct/opcode logger. const tracer = {}; const traces = await provider.send("debug_traceTransaction", [txhash, tracer]); console.log(traces); @@ -125,7 +136,7 @@ web3 = Web3.HTTPProvider(node_url) tx_hash = "0x6be573c85c46d02cd2d47b997d2f153583fbc959541400bc41b9f140d1216772" -# Specify the type of tracer: 4byteTracer, callTracer, or prestateTracer. Leave empty {} for Struct/opcode logger. +# Specify the type of tracer: 4byteTracer, callTracer, flatCallTracer, or prestateTracer. Leave empty {} for Struct/opcode logger. tracer = { "tracer": '4byteTracer' } tx_traces = web3.provider.make_request('debug_traceTransaction', [tx_hash, tracer]) print(tx_traces)