Skip to content

Commit 287f960

Browse files
gabrocheleauacolytec3jochem-brouwer
authored
common: refactor verkleCrypto into customCrypto from common (#3790)
* common: refactor verkleCrypto into customCrypto from common * vm: type issue * remove obsolete `await loadVerkleCrypto` references * fix code stem and code chunk suffix generation * fix suffix counts * fix tests * Update packages/statemanager/src/statelessVerkleStateManager.ts Co-authored-by: Jochem Brouwer <[email protected]> --------- Co-authored-by: acolytec3 <[email protected]> Co-authored-by: Jochem Brouwer <[email protected]>
1 parent 253e271 commit 287f960

22 files changed

+174
-198
lines changed

packages/client/src/execution/vmexecution.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import {
2626
import { createVM, runBlock, runTx } from '@ethereumjs/vm'
2727
import { writeFileSync } from 'fs'
2828
import * as mcl from 'mcl-wasm'
29-
import * as verkle from 'micro-eth-signer/verkle'
3029
import { initRustBN } from 'rustbn-wasm'
3130

3231
import { Event } from '../types.js'
@@ -42,7 +41,6 @@ import type { ExecutionOptions } from './execution.js'
4241
import type { Block } from '@ethereumjs/block'
4342
import type { PrefixedHexString } from '@ethereumjs/util'
4443
import type { RunBlockOpts, TxReceipt, VM } from '@ethereumjs/vm'
45-
const loadVerkleCrypto = () => Promise.resolve(verkle)
4644

4745
export enum ExecStatus {
4846
VALID = 'VALID',
@@ -202,9 +200,8 @@ export class VMExecution extends Execution {
202200
return
203201
}
204202
this.config.logger.info(`Setting up verkleVM`)
205-
const verkleCrypto = await loadVerkleCrypto()
206203
const stateManager = new StatelessVerkleStateManager({
207-
verkleCrypto,
204+
common: this.config.execCommon,
208205
})
209206
await mcl.init(mcl.BLS12_381)
210207
const rustBN = await initRustBN()

packages/client/test/rpc/engine/kaustinen6.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
} from '@ethereumjs/block'
77
import { hexToBytes } from '@ethereumjs/util'
88
import { readFileSync } from 'fs'
9+
import * as verkle from 'micro-eth-signer'
910
import * as td from 'testdouble'
1011
import { assert, describe, it } from 'vitest'
1112

@@ -80,6 +81,7 @@ describe(`valid verkle network setup`, async () => {
8081
const { server, chain, common } = await setupChain(kaustinen6Data, 'post-merge', {
8182
engine: true,
8283
genesisStateRoot: genesisVerkleStateRoot,
84+
customCrypto: { verkleCrypto: verkle },
8385
})
8486
const rpc = getRPCClient(server)
8587
it('genesis should be correctly setup', async () => {

packages/common/src/types.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import type { ConsensusAlgorithm, ConsensusType, Hardfork } from './enums.js'
2-
import type { BigIntLike, ECDSASignature, KZG, PrefixedHexString } from '@ethereumjs/util'
2+
import type {
3+
BigIntLike,
4+
ECDSASignature,
5+
KZG,
6+
PrefixedHexString,
7+
VerkleCrypto,
8+
} from '@ethereumjs/util'
39

410
export interface ChainName {
511
[chainId: string]: string
@@ -89,6 +95,7 @@ export interface CustomCrypto {
8995
ecdsaSign?: (msg: Uint8Array, pk: Uint8Array) => { signature: Uint8Array; recid: number }
9096
ecdsaRecover?: (sig: Uint8Array, recId: number, hash: Uint8Array) => Uint8Array
9197
kzg?: KZG
98+
verkleCrypto?: VerkleCrypto
9299
}
93100

94101
export interface BaseOpts {

packages/evm/test/verkle.spec.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,29 @@ import {
99
} from '@ethereumjs/util'
1010
import { createVerkleTree } from '@ethereumjs/verkle'
1111
import * as verkle from 'micro-eth-signer/verkle'
12-
import { assert, beforeAll, describe, it } from 'vitest'
12+
import { assert, describe, it } from 'vitest'
1313

1414
import { VerkleAccessWitness, createEVM } from '../src/index.js'
1515

16-
import type { VerkleCrypto } from '@ethereumjs/util'
17-
const loadVerkleCrypto = () => Promise.resolve(verkle)
18-
1916
describe('verkle tests', () => {
20-
let verkleCrypto: VerkleCrypto
21-
beforeAll(async () => {
22-
verkleCrypto = await loadVerkleCrypto()
23-
})
2417
it('should execute bytecode and update the state', async () => {
2518
// This tests executes some very simple bytecode that stores the value 1 in slot 2
26-
const common = new Common({ chain: Mainnet, eips: [6800], hardfork: Hardfork.Cancun })
19+
const common = new Common({
20+
chain: Mainnet,
21+
customCrypto: { verkleCrypto: verkle },
22+
eips: [6800],
23+
hardfork: Hardfork.Cancun,
24+
})
2725
const trie = await createVerkleTree()
28-
const sm = new StatefulVerkleStateManager({ trie, verkleCrypto })
26+
const sm = new StatefulVerkleStateManager({ common, trie })
2927
const address = createAddressFromString('0x9e5ef720fa2cdfa5291eb7e711cfd2e62196f4b3')
3028
const account = createAccount({ nonce: 3n, balance: 0xffffffffn })
3129
await sm.putAccount(address, account)
3230
const evm = await createEVM({ common, stateManager: sm })
3331
// Initialize verkleAccess Witness manually (in real context, it is done by the VM, but we are bypassing that here)
34-
evm.verkleAccessWitness = new VerkleAccessWitness({ verkleCrypto })
32+
evm.verkleAccessWitness = new VerkleAccessWitness({
33+
verkleCrypto: verkle,
34+
})
3535
const code = hexToBytes('0x6001600255') // PUSH1 01 PUSH1 02 SSTORE
3636
const res = await evm.runCall({
3737
code,

packages/statemanager/src/statefulVerkleStateManager.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Common, Mainnet, VerkleAccessedStateType } from '@ethereumjs/common'
1+
import { VerkleAccessedStateType } from '@ethereumjs/common'
22
import { RLP } from '@ethereumjs/rlp'
33
import {
44
Account,
@@ -41,6 +41,7 @@ import type { Caches } from './cache/caches.js'
4141
import type { StatefulVerkleStateManagerOpts, VerkleState } from './types.js'
4242
import type {
4343
AccountFields,
44+
Common,
4445
StateManagerInterface,
4546
StorageDump,
4647
StorageRange,
@@ -80,7 +81,6 @@ export class StatefulVerkleStateManager implements StateManagerInterface {
8081
protected readonly DEBUG: boolean = false
8182

8283
private keccakFunction: Function
83-
8484
constructor(opts: StatefulVerkleStateManagerOpts) {
8585
// Skip DEBUG calls unless 'ethjs' included in environmental DEBUG variables
8686
// Additional window check is to prevent vite browser bundling (and potentially other) to break
@@ -89,23 +89,28 @@ export class StatefulVerkleStateManager implements StateManagerInterface {
8989

9090
this._checkpointCount = 0
9191

92-
if (opts.common?.isActivatedEIP(6800) === false)
92+
if (opts.common.isActivatedEIP(6800) === false) {
9393
throw new Error('EIP-6800 required for verkle state management')
94+
}
95+
96+
if (opts.common.customCrypto.verkleCrypto === undefined) {
97+
throw new Error('verkle crypto required')
98+
}
9499

95-
this.common = opts.common ?? new Common({ chain: Mainnet, eips: [6800] })
100+
this.common = opts.common
96101
this._trie =
97102
opts.trie ??
98103
new VerkleTree({
99-
verkleCrypto: opts.verkleCrypto,
104+
verkleCrypto: opts.common.customCrypto.verkleCrypto,
100105
db: new MapDB<Uint8Array, Uint8Array>(),
101106
useRootPersistence: false,
102107
cacheSize: 0,
103108
})
104109
this._debug = debugDefault('statemanager:verkle:stateful')
105110
this.originalStorageCache = new OriginalStorageCache(this.getStorage.bind(this))
106111
this._caches = opts.caches
107-
this.keccakFunction = opts.common?.customCrypto.keccak256 ?? keccak256
108-
this.verkleCrypto = opts.verkleCrypto
112+
this.keccakFunction = opts.common.customCrypto.keccak256 ?? keccak256
113+
this.verkleCrypto = opts.common.customCrypto.verkleCrypto
109114
}
110115

111116
/**

packages/statemanager/src/statelessVerkleStateManager.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import type { StatelessVerkleStateManagerOpts, VerkleState } from './index.js'
3333
import type { MerkleStateManager } from './merkleStateManager.js'
3434
import type {
3535
AccountFields,
36+
Common,
3637
StateManagerInterface,
3738
VerkleAccessWitnessInterface,
3839
VerkleAccessedStateWithAddress,
@@ -76,6 +77,8 @@ export class StatelessVerkleStateManager implements StateManagerInterface {
7677

7778
protected _debug: Debugger
7879

80+
public readonly common: Common
81+
7982
/**
8083
* StateManager is run in DEBUG mode (default: false)
8184
* Taken from DEBUG environment variable
@@ -112,14 +115,19 @@ export class StatelessVerkleStateManager implements StateManagerInterface {
112115

113116
this._caches = opts.caches
114117

115-
this.keccakFunction = opts.common?.customCrypto.keccak256 ?? keccak256
116-
117-
this._debug = debugDefault('statemanager:verkle:stateless')
118+
if (opts.common.isActivatedEIP(6800) === false) {
119+
throw new Error('EIP-6800 required for stateless verkle state management')
120+
}
118121

119-
if (opts.verkleCrypto === undefined) {
122+
if (opts.common.customCrypto.verkleCrypto === undefined) {
120123
throw new Error('verkle crypto required')
121124
}
122-
this.verkleCrypto = opts.verkleCrypto
125+
126+
this.common = opts.common
127+
this.keccakFunction = opts.common.customCrypto.keccak256 ?? keccak256
128+
this.verkleCrypto = opts.common.customCrypto.verkleCrypto
129+
130+
this._debug = debugDefault('statemanager:verkle:stateless')
123131

124132
// Skip DEBUG calls unless 'ethjs' included in environmental DEBUG variables
125133
// Additional window check is to prevent vite browser bundling (and potentially other) to break
@@ -211,7 +219,7 @@ export class StatelessVerkleStateManager implements StateManagerInterface {
211219
shallowCopy(downlevelCaches = true): StatelessVerkleStateManager {
212220
const stateManager = new StatelessVerkleStateManager({
213221
caches: this._caches?.shallowCopy(downlevelCaches),
214-
verkleCrypto: this.verkleCrypto,
222+
common: this.common,
215223
})
216224
return stateManager
217225
}

packages/statemanager/src/types.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { type PrefixedHexString } from '@ethereumjs/util'
33
import type { Caches } from './index.js'
44
import type { Common } from '@ethereumjs/common'
55
import type { MerklePatriciaTrie } from '@ethereumjs/mpt'
6-
import type { VerkleCrypto } from '@ethereumjs/util'
76
import type { VerkleTree } from '@ethereumjs/verkle'
87
/**
98
* Basic state manager options (not to be used directly)
@@ -69,12 +68,12 @@ export interface MerkleStateManagerOpts extends BaseStateManagerOpts {
6968
* Options dictionary.
7069
*/
7170
export interface StatelessVerkleStateManagerOpts extends BaseStateManagerOpts {
72-
verkleCrypto: VerkleCrypto
71+
common: Common // Common required since it provides verkleCrypto through customCrypto
7372
caches?: Caches
7473
}
7574

7675
export interface StatefulVerkleStateManagerOpts extends BaseStateManagerOpts {
77-
verkleCrypto: VerkleCrypto
76+
common: Common // Common required since it provides verkleCrypto through customCrypto
7877
trie?: VerkleTree
7978
caches?: Caches
8079
}

packages/statemanager/test/statefulVerkleStateManager.spec.ts

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Common, Mainnet } from '@ethereumjs/common'
12
import {
23
Account,
34
VerkleLeafType,
@@ -11,22 +12,22 @@ import {
1112
} from '@ethereumjs/util'
1213
import { createVerkleTree } from '@ethereumjs/verkle'
1314
import * as verkle from 'micro-eth-signer/verkle'
14-
import { assert, beforeAll, describe, it } from 'vitest'
15+
import { assert, describe, it } from 'vitest'
1516

1617
import { Caches } from '../src/index.js'
1718
import { StatefulVerkleStateManager } from '../src/statefulVerkleStateManager.js'
1819

19-
import type { PrefixedHexString, VerkleCrypto } from '@ethereumjs/util'
20-
const loadVerkleCrypto = () => Promise.resolve(verkle)
20+
import type { PrefixedHexString } from '@ethereumjs/util'
2121

2222
describe('Verkle Tree API tests', () => {
23-
let verkleCrypto: VerkleCrypto
24-
beforeAll(async () => {
25-
verkleCrypto = await loadVerkleCrypto()
26-
})
2723
it('should put/get/delete an account (with no storage/code from the trie)', async () => {
2824
const trie = await createVerkleTree()
29-
const sm = new StatefulVerkleStateManager({ trie, verkleCrypto })
25+
const common = new Common({
26+
chain: Mainnet,
27+
eips: [6800],
28+
customCrypto: { verkleCrypto: verkle },
29+
})
30+
const sm = new StatefulVerkleStateManager({ common, trie })
3031
const address = createAddressFromString('0x9e5ef720fa2cdfa5291eb7e711cfd2e62196f4b3')
3132
const account = createAccount({ nonce: 3n, balance: 0xfffn })
3233
await sm.putAccount(address, account)
@@ -40,7 +41,12 @@ describe('Verkle Tree API tests', () => {
4041

4142
it('should return same stateRoot when putting and then deleting account', async () => {
4243
const trie = await createVerkleTree()
43-
const sm = new StatefulVerkleStateManager({ trie, verkleCrypto })
44+
const common = new Common({
45+
chain: Mainnet,
46+
eips: [6800],
47+
customCrypto: { verkleCrypto: verkle },
48+
})
49+
const sm = new StatefulVerkleStateManager({ common, trie })
4450

4551
const address1 = createAddressFromString('0x9e5ef720fa2cdfa5291eb7e711cfd2e62196f4b3')
4652
const account1 = createAccount({ nonce: 3n, balance: 0xfffn })
@@ -61,7 +67,12 @@ describe('Verkle Tree API tests', () => {
6167

6268
it('should put and get code', async () => {
6369
const trie = await createVerkleTree()
64-
const sm = new StatefulVerkleStateManager({ trie, verkleCrypto })
70+
const common = new Common({
71+
chain: Mainnet,
72+
eips: [6800],
73+
customCrypto: { verkleCrypto: verkle },
74+
})
75+
const sm = new StatefulVerkleStateManager({ common, trie })
6576
const address = createAddressFromString('0x9e5ef720fa2cdfa5291eb7e711cfd2e62196f4b3')
6677
const code = hexToBytes('0x6001') // PUSH 01
6778
await sm.putCode(address, code)
@@ -90,7 +101,12 @@ describe('Verkle Tree API tests', () => {
90101
const zeroSlot = setLengthLeft(bigIntToBytes(0n), 32)
91102
const zeroSlotValue = hexToBytes('0x1')
92103
const trie = await createVerkleTree()
93-
const sm = new StatefulVerkleStateManager({ trie, verkleCrypto })
104+
const common = new Common({
105+
chain: Mainnet,
106+
eips: [6800],
107+
customCrypto: { verkleCrypto: verkle },
108+
})
109+
const sm = new StatefulVerkleStateManager({ common, trie })
94110
const address = createAddressFromString('0x9e5ef720fa2cdfa5291eb7e711cfd2e62196f4b3')
95111
await sm.putAccount(address, new Account(0n, 1n))
96112
await sm.putStorage(address, zeroSlot, zeroSlotValue)
@@ -100,19 +116,20 @@ describe('Verkle Tree API tests', () => {
100116
})
101117

102118
describe('caching functionality works', () => {
103-
let verkleCrypto: VerkleCrypto
104-
beforeAll(async () => {
105-
verkleCrypto = await loadVerkleCrypto()
106-
})
107119
it('should cache accounts and then write to trie', async () => {
108120
const trie = await createVerkleTree()
109-
const sm = new StatefulVerkleStateManager({ trie, verkleCrypto, caches: new Caches() })
121+
const common = new Common({
122+
chain: Mainnet,
123+
eips: [6800],
124+
customCrypto: { verkleCrypto: verkle },
125+
})
126+
const sm = new StatefulVerkleStateManager({ common, trie, caches: new Caches() })
110127
const address = createAddressFromString('0x9e5ef720fa2cdfa5291eb7e711cfd2e62196f4b3')
111128
const account = createAccount({ nonce: 3n, balance: 0xfffn })
112129
await sm.putAccount(address, account)
113130

114131
// Confirm account doesn't exist in trie
115-
const stem = getVerkleStem(verkleCrypto, address, 0)
132+
const stem = getVerkleStem(verkle, address, 0)
116133
const accountData = await sm['_trie'].get(stem, [
117134
VerkleLeafType.BasicData,
118135
VerkleLeafType.CodeHash,

0 commit comments

Comments
 (0)