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

vm: adjust test runner with verkle state management #3716

Closed
wants to merge 102 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
34a5f08
vm: verkle testing wip
gabrocheleau Sep 29, 2024
ac621b7
Add missing getStateRoot method
acolytec3 Sep 30, 2024
618074c
vm: add option for state manager
gabrocheleau Sep 30, 2024
a932790
Add expanded logging
acolytec3 Oct 1, 2024
a6bd723
fix account creation in preconditions step
acolytec3 Oct 1, 2024
eff3d6f
Add statemanager arg to runner args
acolytec3 Oct 1, 2024
8459c6c
add setStateRoot to verkleStateful
acolytec3 Oct 1, 2024
f971e70
vm: fix test runner
gabrocheleau Oct 1, 2024
b29c56a
vm: update generalStateTestRunner with verkle stateManager option
gabrocheleau Oct 2, 2024
bf7b152
Add verkle specific common setup
acolytec3 Oct 3, 2024
9694e21
Merge remote-tracking branch 'origin/master' into vm/verkle-testing
acolytec3 Oct 8, 2024
f83a1c5
lint
acolytec3 Oct 8, 2024
635648d
Merge remote-tracking branch 'origin/master' into vm/verkle-testing
acolytec3 Oct 24, 2024
b6e0ac7
Add fixes to allow verkle blocks to run
acolytec3 Oct 28, 2024
f7f8f73
Add comments on block constructor
acolytec3 Oct 28, 2024
f07055c
Merge remote-tracking branch 'origin/master' into vm/verkle-testing
acolytec3 Oct 28, 2024
91d3dd3
initialize witness
acolytec3 Oct 28, 2024
0e9f438
fix typo in postState verification check
acolytec3 Oct 28, 2024
c61cf3d
Reorganize verkle checks
acolytec3 Oct 28, 2024
3d86e4f
fix code chunking size calculation
acolytec3 Oct 28, 2024
4fe493f
clean up
acolytec3 Oct 28, 2024
5543970
Merge remote-tracking branch 'origin/master' into vm/verkle-testing
acolytec3 Oct 29, 2024
f29f458
Add trie walking helper
acolytec3 Oct 29, 2024
e0adfb6
remove rlp encoding of storage values
acolytec3 Oct 29, 2024
e3a614a
Merge branch 'master' into vm/verkle-testing
gabrocheleau Oct 30, 2024
0ab7ba2
cspell fix
gabrocheleau Oct 30, 2024
c5433d1
typo
acolytec3 Oct 30, 2024
b137c41
update logger
acolytec3 Oct 30, 2024
e05d41e
logic bugs
acolytec3 Oct 30, 2024
72f3bfd
Merge branch 'vm/verkle-testing' of https://github.com/ethereumjs/eth…
gabrocheleau Oct 31, 2024
66d9f04
Move verkle crypto loading out of run function
acolytec3 Oct 31, 2024
549d21b
Merge branch 'vm/verkle-testing' of https://github.com/ethereumjs/eth…
gabrocheleau Nov 1, 2024
22098c1
Merge branch 'master' into vm/verkle-testing
gabrocheleau Nov 1, 2024
063c873
Merge branch 'vm/verkle-testing' of https://github.com/ethereumjs/eth…
gabrocheleau Nov 1, 2024
e6dcdad
vm: re add validation logic for stateful verkle
gabrocheleau Nov 1, 2024
2d93031
Merge branch 'master' into vm/verkle-testing
gabrocheleau Nov 2, 2024
da060f8
verkle:improve type of createDefaultLeafVerkleValues
gabrocheleau Nov 3, 2024
a0c3536
Add new util method for dumping node hashes
acolytec3 Nov 4, 2024
d074be6
Partial fix for null child nodes
acolytec3 Nov 4, 2024
2f76957
Collapse internal nodes when deleting values
acolytec3 Nov 5, 2024
5d6b85d
Merge remote-tracking branch 'origin/master' into vm/verkle-testing
acolytec3 Nov 5, 2024
1178633
update packages
acolytec3 Nov 6, 2024
a444162
Merge remote-tracking branch 'origin/master' into vm/verkle-testing
acolytec3 Nov 6, 2024
344979e
fix code stem and code chunk suffix generation
acolytec3 Nov 7, 2024
f6e0656
Merge branch 'master' into vm/verkle-testing
gabrocheleau Nov 7, 2024
d922a8d
vm: update test runners with updated verkle crypto
gabrocheleau Nov 7, 2024
8def8a5
vm: update package lock
gabrocheleau Nov 7, 2024
c218c8e
fix suffix counts
acolytec3 Nov 7, 2024
760b3f8
Merge remote-tracking branch 'origin/master' into vm/verkle-testing
acolytec3 Nov 8, 2024
5ccea5f
Merge branch 'master' into vm/verkle-testing
gabrocheleau Nov 11, 2024
0545b03
fix verkle setup
acolytec3 Nov 14, 2024
6594acf
Let the robots rewrite chunkifyCode
acolytec3 Nov 15, 2024
519f5d2
Merge remote-tracking branch 'origin/master' into vm/verkle-testing
acolytec3 Nov 15, 2024
6302863
Merge branch 'master' into vm/verkle-testing
gabrocheleau Nov 17, 2024
1157db0
vm: fix test setup
gabrocheleau Nov 17, 2024
690eb32
vm: use common instead of verklecrypto
gabrocheleau Nov 20, 2024
52e4359
merge: fix merge conflicts
gabrocheleau Nov 21, 2024
2bb30bc
vm: fix historyAddress
gabrocheleau Nov 21, 2024
17ce748
vm: add 2935
gabrocheleau Nov 21, 2024
6d2ff2e
vm: some improvements for 2935 handling
gabrocheleau Nov 24, 2024
fa157ca
statemanageR: clarify post state error messages
gabrocheleau Nov 26, 2024
6ff4943
evm: access witness methods renaming, addition of system verkle acces…
gabrocheleau Nov 27, 2024
27615b3
evm: minor verkle testnet related adjustments
gabrocheleau Dec 3, 2024
3ece78d
evm: remove unused clear method2
gabrocheleau Dec 4, 2024
4ec2a97
evm: typo
gabrocheleau Dec 7, 2024
74647c6
Add simple cache to access witness (#3810)
acolytec3 Dec 9, 2024
2e8015b
evm: debug verkle access witness cost helper
gabrocheleau Dec 17, 2024
8854f6c
Fix step logging so dynamic gas doesn't include state accesses
acolytec3 Dec 19, 2024
50d7a99
merge with master
gabrocheleau Dec 20, 2024
d93016e
statemanager: fix getCode logic for last chunk
gabrocheleau Dec 21, 2024
2d3a02f
evm: access witness withdrawals handling
gabrocheleau Dec 21, 2024
98bd9c6
Merge branch 'master' into vm/verkle-testing
gabrocheleau Dec 21, 2024
216650b
vm: don't include access witness if miner value is 0
gabrocheleau Dec 23, 2024
b2dd43d
Merge branch 'vm/verkle-testing' of https://github.com/ethereumjs/eth…
gabrocheleau Dec 23, 2024
6449b5e
evm: fix witness skipping for precompiles and system contracts
gabrocheleau Dec 23, 2024
ec286f9
Add miner basic data and codehash to system access witness
acolytec3 Dec 24, 2024
cc351fd
evm: minor fixes
gabrocheleau Dec 24, 2024
ee00f50
fix rewardAccount to write account into trie
acolytec3 Dec 24, 2024
92ff519
Merge branch 'vm/verkle-testing' of https://github.com/ethereumjs/eth…
gabrocheleau Dec 24, 2024
e2d2cb7
evm/verkle: fix charging base gas for address accessing opcodes
jochem-brouwer Dec 26, 2024
a1e1c4b
Properly await putAccount
acolytec3 Dec 31, 2024
2761918
chore: merge with master
gabrocheleau Jan 8, 2025
c8834e3
evm: fix codehash handling in verkle access witness
gabrocheleau Jan 11, 2025
e86cfee
chore: merge
gabrocheleau Jan 13, 2025
4775048
vm: uncomment runblock logic
gabrocheleau Jan 20, 2025
84ed414
monorepo: merge with master
gabrocheleau Jan 20, 2025
6241920
chore: merge with master
gabrocheleau Jan 21, 2025
44c2aa0
client: remove console log
gabrocheleau Jan 21, 2025
3343475
vm: adjust 2935 contract addres
gabrocheleau Jan 21, 2025
bb25475
vm: remove console log
gabrocheleau Jan 21, 2025
c322c3d
evm: undo history storage addres update
gabrocheleau Jan 21, 2025
765827a
client: minor fixes
gabrocheleau Jan 22, 2025
fca73cc
vm: simplify blockchain test runner
gabrocheleau Jan 22, 2025
338408a
vm: attempt to fix testloader
gabrocheleau Jan 22, 2025
27ec60f
vm: attempt to fix blockchain test runner
gabrocheleau Jan 22, 2025
d764f6d
vm: simplify getCommon verkle
gabrocheleau Jan 22, 2025
8aa2a97
Merge branch 'master' into vm/verkle-testing
gabrocheleau Jan 22, 2025
449e0c2
vm: minor fix attempts
gabrocheleau Jan 22, 2025
3232c06
Merge branch 'master' into vm/verkle-testing
gabrocheleau Jan 22, 2025
7694a49
Merge branch 'master' into vm/verkle-testing
gabrocheleau Jan 24, 2025
3a3cf47
vm: attempt alternative way of building block in blockchain test runner
gabrocheleau Jan 24, 2025
2b3fa08
Merge branch 'vm/verkle-testing' of https://github.com/ethereumjs/eth…
gabrocheleau Jan 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/client/src/util/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ function checkHeaderAuth(req: any, jwtSecret: Uint8Array): void {
const token = header.trim().split(' ')[1]
if (!token) throw Error(`Missing jwt token`)
const claims = decode(token.trim(), jwtSecret as never as string, false, algorithm)
const drift = Math.abs(new Date().getTime() - claims.iat * 1000 ?? 0)
const drift = Math.abs(new Date().getTime() - claims.iat * 1000)
if (drift > ALLOWED_DRIFT) {
throw Error(`Stale jwt token drift=${drift}, allowed=${ALLOWED_DRIFT}`)
}
Expand Down
10 changes: 5 additions & 5 deletions packages/client/test/cli/cli.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('[CLI]', () => {
}
}
await clientRunHelper(cliArgs, onData)
}, 5000)
}, 15000)
it('should successfully start client with custom inputs for PoA network', async () => {
const cliArgs = [
'--rpc',
Expand Down Expand Up @@ -117,7 +117,7 @@ describe('[CLI]', () => {
resolve(undefined)
}
await clientRunHelper(cliArgs, onData, true)
}, 5000)
}, 15000)
it('should throw error if the same port is assigned to multiple RPC servers', async () => {
const cliArgs = ['--ws', '--rpc', '--rpcPort=8546']
const onData = async (
Expand Down Expand Up @@ -792,7 +792,7 @@ describe('[CLI]', () => {
resolve(undefined)
}
await clientRunHelper(cliArgs, onData, true)
}, 5000)
}, 15000)
it('should not start client with conflicting parameters', async () => {
const cliArgs = ['--chainId', '--gethGenesis']
const onData = async (
Expand All @@ -807,7 +807,7 @@ describe('[CLI]', () => {
resolve(undefined)
}
await clientRunHelper(cliArgs, onData, true)
}, 5000)
}, 15000)
it('should not start client with conflicting parameters', async () => {
const cliArgs = ['--chainId', '--gethGenesis']
const onData = async (
Expand All @@ -822,7 +822,7 @@ describe('[CLI]', () => {
resolve(undefined)
}
await clientRunHelper(cliArgs, onData, true)
}, 5000)
}, 15000)
}, 180000)

describe('verkle execution', () => {
Expand Down
4 changes: 4 additions & 0 deletions packages/common/src/chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ export const Mainnet: ChainConfig = {
name: 'osaka',
block: null,
},
{
name: 'verkle',
block: null,
},
],
bootstrapNodes: [
{
Expand Down
1 change: 1 addition & 0 deletions packages/vm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"devDependencies": {
"@ethereumjs/blockchain": "^8.0.0-alpha.1",
"@ethereumjs/ethash": "^4.0.0-alpha.1",
"@ethereumjs/verkle": "^0.2.0-alpha.1",
"@paulmillr/trusted-setups": "^0.1.2",
"@types/benchmark": "^1.0.33",
"@types/core-js": "^2.5.0",
Expand Down
71 changes: 70 additions & 1 deletion packages/vm/test/tester/config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Common, Hardfork, Mainnet, createCustomCommon } from '@ethereumjs/common'
import { type KZG } from '@ethereumjs/util'
import * as verkle from 'micro-eth-signer/verkle'
import * as path from 'path'

import type { HardforkTransitionConfig } from '@ethereumjs/common'
import type { KZG } from '@ethereumjs/util'

/**
* Default tests path (git submodule: ethereum-tests)
Expand Down Expand Up @@ -109,6 +110,7 @@ const normalHardforks = [
'cancun',
'prague',
'osaka',
'verkle',
]

const transitionNetworks = {
Expand Down Expand Up @@ -278,6 +280,69 @@ function setupCommonWithNetworks(network: string, ttd?: number, timestamp?: numb
return common
}

/**
* Returns a common instance configured for verkle
* @param network Network target (this can include EIPs, such as Byzantium+2537+2929)
* @param ttd If set: total terminal difficulty to switch to merge
* @returns
*/
function setupCommonForVerkle(network: string, timestamp?: number, kzg?: KZG) {
let ttd
// hard fork that verkle tests are filled on
const hfName = 'shanghai'
const mainnetCommon = new Common({ chain: Mainnet, hardfork: hfName })
const hardforks = mainnetCommon.hardforks().slice(0, 17) // skip hardforks after Shanghai
const testHardforks: HardforkTransitionConfig[] = []
for (const hf of hardforks) {
// check if we enable this hf
// disable dao hf by default (if enabled at block 0 forces the first 10 blocks to have dao-hard-fork in extraData of block header)
if (mainnetCommon.gteHardfork(hf.name) && hf.name !== Hardfork.Dao) {
// this hardfork should be activated at block 0
testHardforks.push({
name: hf.name,
// Current type definition Partial<Chain> in Common is currently not allowing to pass in forkHash
// forkHash: hf.forkHash,
block: 0,
})
} else {
// disable hardforks newer than the test hardfork (but do add "support" for it, it just never gets activated)
if (
(ttd === undefined && timestamp === undefined) ||
(hf.name === 'paris' && ttd !== undefined)
) {
testHardforks.push({
name: hf.name,
block: null,
})
}
if (timestamp !== undefined && hf.name !== Hardfork.Dao) {
testHardforks.push({
name: hf.name,
block: null,
timestamp,
})
}
}
}

testHardforks.push({ name: 'verkle', block: 1 })
const common = createCustomCommon(
{
hardforks: testHardforks,
defaultHardfork: 'verkle',
},
Mainnet,
{ eips: [2935, 3607], customCrypto: { kzg, verkle } },
)

// Activate EIPs
const eips = network.match(/(?<=\+)(.\d+)/g)
if (eips) {
common.setEIPs(eips.map((e: string) => parseInt(e)))
}
return common
}

/**
* Returns a Common for the given network (a test parameter)
* @param network - the network field of a test.
Expand All @@ -292,6 +357,10 @@ export function getCommon(network: string, kzg?: KZG): Common {
network = retestethAlias[network as keyof typeof retestethAlias]
}
let networkLowercase = network.toLowerCase()
// Special handler for verkle tests
if (networkLowercase.includes('verkle')) {
return setupCommonForVerkle(network, undefined, kzg)
}
if (network.includes('+')) {
const index = network.indexOf('+')
networkLowercase = network.slice(0, index).toLowerCase()
Expand Down
2 changes: 2 additions & 0 deletions packages/vm/test/tester/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ async function runTests() {
profile: boolean
bls: EVMBLSInterface
bn254: EVMBN254Interface
stateManager: string
} = {
forkConfigVM: FORK_CONFIG_VM,
forkConfigTestSuite: FORK_CONFIG_TEST_SUITE,
Expand All @@ -156,6 +157,7 @@ async function runTests() {
bls,
profile: RUN_PROFILER,
bn254,
stateManager: argv.stateManager,
}

/**
Expand Down
91 changes: 53 additions & 38 deletions packages/vm/test/tester/runners/BlockchainTestsRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,26 @@ import { EthashConsensus, createBlockchain } from '@ethereumjs/blockchain'
import { ConsensusAlgorithm } from '@ethereumjs/common'
import { Ethash } from '@ethereumjs/ethash'
import { MerklePatriciaTrie } from '@ethereumjs/mpt'
import { RLP } from '@ethereumjs/rlp'
import { Caches, MerkleStateManager } from '@ethereumjs/statemanager'
import { Caches, MerkleStateManager, StatefulVerkleStateManager } from '@ethereumjs/statemanager'
import { createTxFromRLP } from '@ethereumjs/tx'
import {
MapDB,
bytesToBigInt,
bytesToHex,
hexToBytes,
isHexString,
stripHexPrefix,
toBytes,
} from '@ethereumjs/util'
import { createVerkleTree } from '@ethereumjs/verkle'

import { buildBlock, createVM, runBlock } from '../../../src/index.js'
import { setupPreConditions, verifyPostConditions } from '../../util.js'

import type { Block } from '@ethereumjs/block'
import type { Blockchain, ConsensusDict } from '@ethereumjs/blockchain'
import type { Common } from '@ethereumjs/common'
import type { Common, StateManagerInterface } from '@ethereumjs/common'
import type { PrefixedHexString } from '@ethereumjs/util'
import type { VerkleTree } from '@ethereumjs/verkle'
import type * as tape from 'tape'

function formatBlockHeader(data: any) {
Expand All @@ -46,13 +46,25 @@ export async function runBlockchainTest(options: any, testData: any, t: tape.Tes
let common = options.common.copy() as Common
common.setHardforkBy({ blockNumber: 0 })

let stateTree: MerklePatriciaTrie | VerkleTree
let stateManager: StateManagerInterface

if (options.stateManager === 'verkle') {
stateTree = await createVerkleTree()
stateManager = new StatefulVerkleStateManager({
trie: stateTree,
common: options.common,
})
} else {
stateTree = new MerklePatriciaTrie({ useKeyHashing: true, common })
stateManager = new MerkleStateManager({
caches: new Caches(),
trie: stateTree,
common,
})
}

let cacheDB = new MapDB()
let state = new MerklePatriciaTrie({ useKeyHashing: true, common })
let stateManager = new MerkleStateManager({
caches: new Caches(),
trie: state,
common,
})

let validatePow = false
// Only run with block validation when sealEngine present in test file
Expand Down Expand Up @@ -86,7 +98,7 @@ export async function runBlockchainTest(options: any, testData: any, t: tape.Tes
})

if (validatePow) {
;(blockchain.consensus as EthashConsensus)._ethash!.cacheDB = cacheDB as any
;(blockchain.consensus as EthashConsensus)._ethash!.cacheDB = cacheDB
}

const begin = Date.now()
Expand Down Expand Up @@ -134,29 +146,13 @@ export async function runBlockchainTest(options: any, testData: any, t: tape.Tes
raw[paramAll1] ??
raw[paramAll2] ??
raw.blockHeader === undefined) as PrefixedHexString | boolean

// Here we decode the rlp to extract the block number
// The block library cannot be used, as this throws on certain EIP1559 blocks when trying to convert
try {
const blockRlp = hexToBytes(raw.rlp as PrefixedHexString)
const decodedRLP: any = RLP.decode(Uint8Array.from(blockRlp))
currentBlock = bytesToBigInt(decodedRLP[0][8])
} catch (e: any) {
await handleError(e, expectException)
continue
}

try {
const blockRlp = hexToBytes(raw.rlp as PrefixedHexString)
// Update common HF
let timestamp: bigint | undefined = undefined
try {
const decoded: any = RLP.decode(blockRlp)
timestamp = bytesToBigInt(decoded[0][11])
// eslint-disable-next-line no-empty
} catch (e) {}

common.setHardforkBy({ blockNumber: currentBlock, timestamp })
// The block library cannot be used, as this throws on certain EIP1559 blocks when trying to convert
currentBlock = BigInt(raw.blockHeader.number)
common.setHardforkBy({
blockNumber: currentBlock,
timestamp: BigInt(raw.blockHeader.timestamp),
})

// transactionSequence is provided when txs are expected to be rejected.
// To run this field we try to import them on the current state.
Expand Down Expand Up @@ -190,7 +186,27 @@ export async function runBlockchainTest(options: any, testData: any, t: tape.Tes
await blockBuilder.revert() // will only revert if checkpointed
}

const block = createBlockFromRLP(blockRlp, { common, setHardfork: true })
let block: Block
if (options.stateManager === 'verkle') {
// Create the block from the JSON block data since the RLP doesn't include the execution witness
block = createBlock(
{
header: raw.blockHeader,
transactions: raw.transactions,
uncleHeaders: raw.uncleHeaders,
withdrawals: raw.withdrawals,
executionWitness: raw.witness,
},
{
common,
setHardfork: true,
},
)
} else {
const blockRLP = hexToBytes(raw.rlp as PrefixedHexString)
block = createBlockFromRLP(blockRLP, { common, setHardfork: true })
}

await blockchain.putBlock(block)

// This is a trick to avoid generating the canonical genesis
Expand Down Expand Up @@ -224,7 +240,7 @@ export async function runBlockchainTest(options: any, testData: any, t: tape.Tes
const headBlock = await (vm.blockchain as Blockchain).getIteratorHead()
await vm.stateManager.setStateRoot(headBlock.header.stateRoot)
} else {
await verifyPostConditions(state, testData.postState, t)
await verifyPostConditions(stateTree, testData.postState, t)
}

throw e
Expand All @@ -242,7 +258,7 @@ export async function runBlockchainTest(options: any, testData: any, t: tape.Tes
}

t.equal(
bytesToHex((blockchain as any)._headHeaderHash),
bytesToHex(blockchain['_headHeaderHash']),
'0x' + testData.lastblockhash,
'correct last header block',
)
Expand All @@ -251,6 +267,5 @@ export async function runBlockchainTest(options: any, testData: any, t: tape.Tes
const timeSpent = `${(end - begin) / 1000} secs`
t.comment(`Time: ${timeSpent}`)

// @ts-ignore Explicitly delete objects for memory optimization (early GC)
common = blockchain = state = stateManager = vm = cacheDB = null // eslint-disable-line
common = blockchain = stateTree = stateManager = vm = cacheDB = null as any
}
Loading
Loading