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

Client: Add debugCode CLI option to generate Block execution script #1091

Merged
merged 1 commit into from
Feb 11, 2021

Conversation

holgerd77
Copy link
Member

@holgerd77 holgerd77 commented Feb 11, 2021

Fixing #1090

I will actually not start working on new consensus bugs without adding a new meaningful debug tool. 😂

This one from this first commit 8d0afb7 is actually super-handy: it adds a new CLI option (mainly for internal usage, but of course also can be leveraged by consumers) debugCode which generates a dynamic script on a VM block execution failure.

So this can be run with:

npm run client:start -- --network=rinkeby --debugCode

Script looks something like this and will be logged out to the console:

/**
 * Script for locally executing a block in the EthereumJS VM,
 * meant to be used from packages/vm directory within the
 * https://github.com/ethereumjs/ethereumjs-monorepo repository.
 *
 * Block: 14182
 * Hardfork: spuriousDragon
 *
 * Run with: DEBUG=vm:*:*,vm:*,-vm:ops:* ts-node [SCRIPT_NAME].ts
 *
 */

const level = require('level')
import Common from '@ethereumjs/common'
import { Block } from '@ethereumjs/block'
import VM from './lib'
import { SecureTrie as Trie } from '@ethereumjs/trie'
import { DefaultStateManager } from './lib/state'
import Blockchain from '@ethereumjs/blockchain'

const main = async () => {
  const common = new Common({ chain: 'rinkeby', hardfork: 'spuriousDragon' })
  const block = Block.fromRLPSerializedBlock(Buffer.from('f91692f9025ba0b477241819c2222f...', 'hex'), { common })

  const stateDB = level('/Ethereum/ethereumjs/rinkeby/state')
  const trie = new Trie(stateDB)
  const stateManager = new DefaultStateManager({ trie, common })
  // Ensure we run on the right root
  stateManager.setStateRoot(Buffer.from('135fae6d4909a072d77707a797769afc72f6239a72173e0f411c7700af66ac26', 'hex'))


  const chainDB = level('/Ethereum/ethereumjs/rinkeby/chain')
  const blockchain = await Blockchain.create({
    db: chainDB,
    common,
    validateBlocks: true,
    validateConsensus: false,
  })
  const vm = new VM({ stateManager, blockchain, common })

  await vm.runBlock({ block })
}

main()

The script works out of the box, has all the correct values filled in (HFs, directories, block RLP) and can directly be copied over into the VM folder and then executed to reliably reproduce the error locally. 😄

…utable script to locally reproduce a VM block execution error
@codecov
Copy link

codecov bot commented Feb 11, 2021

Codecov Report

Merging #1091 (0d83ea9) into master (6822c08) will decrease coverage by 4.20%.
The diff coverage is n/a.

Impacted file tree graph

Flag Coverage Δ
block 79.02% <ø> (-2.24%) ⬇️
blockchain ?
client ?
common ?
ethash ?
tx ?
vm 82.32% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

@jochem-brouwer
Copy link
Member

Hi @holgerd77, please check this PR #1093. I wanted to fetch the Geth JSON trace from an archive node, but sadly the eth dev ops node seems to be down.

I am currently spinning up a Rinkeby archive node to get the trace. I'll upload it to the PR, so you can directly compare traces and see exactly at which point the two transactions diverge 😄

@holgerd77
Copy link
Member Author

@jochem-brouwer great 👍

@jochem-brouwer
Copy link
Member

Will merge the debug stuff here (you can remove these debug files later when ready for review) so we can compare stack traces.

@holgerd77
Copy link
Member Author

@jochem-brouwer Ok. 😄

The CI got stuck at some point, I will merge this in by admin merge so that we can continue.

@holgerd77 holgerd77 merged commit 7c4c5b9 into master Feb 11, 2021
@holgerd77 holgerd77 deleted the fix-rinkeby-block-14182-consensus-bug branch February 11, 2021 11:21
@holgerd77 holgerd77 changed the title Client, VM -> Rinkeby: Fix consensus error on block 14182 (invalid receipt trie) Client: Add debugCode CLI option to generate Block execution script Feb 11, 2021
@jochem-brouwer
Copy link
Member

debug.ts is not a valid script?

@holgerd77
Copy link
Member Author

No, not yet. You need to run the client with the new option npm run client:start -- --network=rinkeby --debugCode the final script will then printed out to the console on VM block execution error with the correct values filled in.

@holgerd77
Copy link
Member Author

(so this will work for all future debugging cases)

const stateManager = new DefaultStateManager({ trie, common })
// Ensure we run on the right root
stateManager.setStateRoot(Buffer.from('${(
await execution.vm.stateManager.getStateRoot(true)
Copy link
Member

Choose a reason for hiding this comment

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

Ah yes, I should have spotted this earlier. You should get the state root of the previous block, and set the state managers' root to the root of that block. (Can probably just get it from vm's blockchain)

* Block: ${block.header.number}
* Hardfork: ${execution.hardfork}
*
* Run with: DEBUG=vm:*:*,vm:*,-vm:ops:* ts-node [SCRIPT_NAME].ts
Copy link
Member

Choose a reason for hiding this comment

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

Should be export DEBUG. If I don't use export then debug is not triggered.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, no, export should not be needed. Your are likely putting an && in between the commands?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants