ethereumjs / ethereumjs-monorepo

Monorepo for the Ethereum VM TypeScript Implementation
2.6k stars 760 forks source link

Verkle Kaustinen Testnet Sync Meta Issue #3389

Open holgerd77 opened 7 months ago

holgerd77 commented 7 months ago

This is a meta issue to collect and update Kaustinen sync instructions as well as other additional docs and some references, so that these get a bit better accessible and do not always "get lost" again with some PRs merged (latest the Kaustinen6 instructions from #3355.

Instructions

Adopted instructions from #3355 and #3179

EthereumJS Client (Execution)

Verified: 2024-05-02

  1. Install and build EthereumJS as described here (master branch)

  2. Run EthereumJS with:

(rm -Rf datadir/kaustinen6 && )npm run client:start:ts -- --ignoreStatelessInvalidExecs --dataDir=./datadir --network kaustinen6 --rpcEngine --rpcEngineAuth false

If you want to reduce noice during sync additionally set --logLevel warn.

Lodestar (lodestar-quickstart)

Verified: -

Clean the lodestar-quickstart datadir's lodestar folder (here k6data/lodestar and run the following:

/setup.sh --dataDir k6data --network kaustinen6 --justCL

to start lodestar.

Lodestar (manual)

Verified: 2024-05-02

  1. Install Lodestar from source as described here (g11tech/verge branch)

  2. Clone the EthPandaOps specs/config repo for Verkle: git clone https://github.com/ethpandaops/verkle-devnets.git (assumed to be on the same directory level as the lodestar repo for further relative folder path references)

  3. Optional but recommended to copy or symlink the current testnet config folder to the lodestar repo for easier/shorter path references: cd lodestart && cp -Rf ../verkle-devnets/network-configs/gen-devnet-6 kaustinen-testnet

  4. Start Lodestar with:

(rm -Rf kaustinen && )./lodestar beacon --paramsFile kaustinen-testnet/config.yaml --genesisStateFile kaustinen-testnet/genesis.ssz --eth1.depositContractDeployBlock 0 --bootnodesFile kaustinen-testnet/boot_enr.yaml --dataDir=kaustinen

Debugging

Ignore Invalid Executions

The --ignoreStatelessInvalidExecs option for the EL client (EthereumJS) gives the possibility to ignore invalid executions and just continue with the stateless sync.

Invalid blocks are then saved as json into a directory invalidblocks within the data directory and can be used for debugging.

Executing a Single Block

To execute and debug a single block the EL client can be started with the --startExecutionFrom flag. The targeted block needs to have been synced before to be available for execution. There is currently no comfortable functionality to stop execution. This can be hacked in by adding something like if (block.header.number >= 26) { return } before the VM.runBlock() call in the client VMExecution. class (link above).

Understanding Execution Flow

For understanding and debugging the execution flow the build in debug logging functionality of the vm, evm and statemanager packages can be used and combined, see e.g. this docs for some introduction.

Different loggers can be prepended to the client start command like this:

DEBUG=ethjs,vm:*,evm:*,statemanager:*,verkle:* npm run client:start:ts ...

Log output will the look like the following:

grafik

The vm:* logger (can also used in a more fine grained way like vm:block) give a high level view on the block execution flow, the evm:* logger can be used for EVM processing output and the statemanager:* logger shows pre and post state as well as state access and verification information.

Execution Flow

During a basic execution flow (so: a verkle block execution) roughly the following things happen:

  1. In the client a StatelessVerkleStateManager is instantiated in the FullEthereumService class by calling into setupVerkleVM()
  2. Execution is then later on triggered in the client within the VMExecution.run() method roughly around here
  3. VM.runBlock() calls into initVerkleExecutionWitness() from StatelessVerkleStateManager passing in block.executionWitness. This is extracting the pre and the post state from the execution witness within the state manager.
  4. During tx processing/EVM execution contract, code and storage accesses and writes are handled by the StatelessVerkleStateManager, accessing values provided by the pre state (or erroring out otherwise) and following a tree design and key schema (e.g. how to compose together an account nonce key) as described in EIP-6800.
  5. To account for the correct gas resembling the new verkle tree structure there is a new class AccessWitness within the statemanager package. An AccessWitness is initialized as part of the StatelessVerkleStateManager and then passed over along an EVM call in VM.runTx() and then calls into methods like message.accessWitness!.touchTxOriginAndComputeGas(fromAddress) within the EVM. The AccessWitness tracks stem and chunk reads as described in EIP-4762.
  6. At the end of the block execution verifyPostState() in the verkle state manager is called from within VM.runBlock() to compare the accesses tracked by the AccessWitness with the state included in both pre and post state.

Example Data

Verkle Block

An example for a verkle block with execution witness can be found here.

gabrocheleau commented 3 months ago

Adding this as a separate comment since Kaustinen6 could still be somewhat relevant.

Kaustinen 7 readiness

Before Kaustinen 7 launch, we should be able to run these test vectors https://hackmd.io/@jsign/verkle-testing#/4

Relevant repo with tests: https://github.com/ethereum/execution-spec-tests/tree/verkle/main/tests/verkle

Not directly related to Kaustinen7, but update on the state of verkle as of August 26th 2024: https://notes.ethereum.org/@gballet/verkle-and-binary#/