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

fix: Geth trace inconsistence with self-destruct #173

Conversation

ZzPoLariszZ
Copy link
Contributor

Problem

The inconsistent problem in getting the Geth Debug trace result of a transaction
which includes a suicide / selfdestruct call type.

Reproducible Example

With the latest version reth v1.0.3, using debug_traceTransaction() and callTracer to trace
the transaction 0x47e9962fec372e5c34e650cbd094e396fe6278cd7b0ee5d34bccfe2739809e9c

curl http://localhost:8545 \
-X POST \
-H "Content-Type: application/json" \
--data '{"method":"debug_traceTransaction","params":["0x47e9962fec372e5c34e650cbd094e396fe6278cd7b0ee5d34bccfe2739809e9c", {"tracer": "callTracer"}], "id":1,"jsonrpc":"2.0"}'

From Reth

which is a two-layer nested structure, and
the from field of SELFDESTRUCT call is 0x322237f0f8d0cf75c413d76fbbbb658cd2edf7c1

{'calls': [{'from': '0x322237f0f8d0cf75c413d76fbbbb658cd2edf7c1',
            'gas': '0x4df8',
            'gasUsed': '0x1e85',
            'input': '0x608060405260405160593803806059833981016040819052601e91602a565b806001600160a01b0316ff5b600060208284031215603b57600080fd5b81516001600160a01b0381168114605157600080fd5b939250505056fe000000000000000000000000487294db79b9b0b66666627e21d1b56277b627c4',
            'to': '0x480641f98eaeb20a12e7c7fa29e4dc7649245cfb',
            'type': 'CREATE',
            'value': '0x4b1c80ab7791a50'},
           {'from': '0x322237f0f8d0cf75c413d76fbbbb658cd2edf7c1',
            'gas': '0x0',
            'gasUsed': '0x0',
            'input': '0x',
            'to': '0x487294db79b9b0b66666627e21d1b56277b627c4',
            'type': 'SELFDESTRUCT',
            'value': '0x4b1c80ab7791a50'}],
 'from': '0x98707bb9d75a98e1ee05446e7acaf864f5a09fdf',
 'gas': '0x12134',
 'gasUsed': '0xf0b3',
 'input': '0x687528fa000000000000000000000000487294db79b9b0b66666627e21d1b56277b627c4',
 'to': '0x322237f0f8d0cf75c413d76fbbbb658cd2edf7c1',
 'type': 'CALL',
 'value': '0x4b1c80ab7791a50'}

From Etherscan and QuickNode

which is a three-layer nested structure, and
the from field of SELFDESTRUCT call is 0x480641f98eaeb20a12e7c7fa29e4dc7649245cfb

{'calls': [{'calls': [{'from': '0x480641f98eaeb20a12e7c7fa29e4dc7649245cfb',
                       'gas': '0x0',
                       'gasUsed': '0x0',
                       'input': '0x',
                       'to': '0x487294db79b9b0b66666627e21d1b56277b627c4',
                       'type': 'SELFDESTRUCT',
                       'value': '0x4b1c80ab7791a50'}],
            'from': '0x322237f0f8d0cf75c413d76fbbbb658cd2edf7c1',
            'gas': '0x4df8',
            'gasUsed': '0x1e85',
            'input': '0x608060405260405160593803806059833981016040819052601e91602a565b806001600160a01b0316ff5b600060208284031215603b57600080fd5b81516001600160a01b0381168114605157600080fd5b939250505056fe000000000000000000000000487294db79b9b0b66666627e21d1b56277b627c4',
            'to': '0x480641f98eaeb20a12e7c7fa29e4dc7649245cfb',
            'type': 'CREATE',
            'value': '0x4b1c80ab7791a50'}],
 'from': '0x98707bb9d75a98e1ee05446e7acaf864f5a09fdf',
 'gas': '0x12134',
 'gasUsed': '0xf0b3',
 'input': '0x687528fa000000000000000000000000487294db79b9b0b66666627e21d1b56277b627c4',
 'to': '0x322237f0f8d0cf75c413d76fbbbb658cd2edf7c1',
 'type': 'CALL',
 'value': '0x4b1c80ab7791a50'}

More Examples

  • 0xc71cea6fa00d11e98f6733ee8740f239cb37b11dec29e7cf85d7a4077977fa65
  • 0x9610e6727b31f207d169013c470c3a7b2964ff67b3f0f169c272e99a6c0694ce
  • 0x1cc935268fe1a77d130574a44abe2f44d427c3f9bb3e035dd6438dd8a898b67a

Solution

  1. The selfdestruct call trace should not be added as an additional CallFrame object to the parent of the call trace where it is derived from, such that it is in the same level of the call trace where it is derived from.

    It should be added as the first child of the call trace where it is derived from.

  2. The from field in its CallFrame object should be self.trace.address rather than self.trace.caller

Copy link
Contributor

@mattsse mattsse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

amazing, tysm for all of these!

@@ -313,7 +313,7 @@ impl CallTraceNode {
if self.is_selfdestruct() {
Some(CallFrame {
typ: "SELFDESTRUCT".to_string(),
from: self.trace.caller,
from: self.trace.address,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah this makes sense

Comment on lines +150 to +151
// the call trace and are added as additional `CallFrame` objects
// becoming the first child of the derived call
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah I see, this adds the call frame first and then adds the sefldestruct to that callframe that we just added as a child call

@mattsse mattsse merged commit 318c121 into paradigmxyz:main Aug 1, 2024
11 checks passed
@ZzPoLariszZ ZzPoLariszZ changed the title fix: geth trace inconsistence with selfdestruct fix: Geth trace inconsistence with self-destruct Aug 1, 2024
@ZzPoLariszZ ZzPoLariszZ deleted the fix-geth-trace-inconsistence-with-selfdestruct branch August 1, 2024 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants