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

Remove EEI from EVM v2 #2649

Merged
merged 28 commits into from
May 11, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0f1f14a
statemanager/common: extract state manager interface to common
jochem-brouwer Mar 27, 2023
12753d4
evm/tx/common/statemanager: move EEI logic into statemanager
jochem-brouwer Apr 22, 2023
8b23ce7
evm: fix test runner
jochem-brouwer Apr 22, 2023
a48b144
statemanager/vm: fix test runners [no ci]
jochem-brouwer Apr 22, 2023
a5f3ff6
vm: fix bugs regarding touched accounts
jochem-brouwer Apr 23, 2023
c011785
vm: fix api tests, update interface
jochem-brouwer Apr 23, 2023
ffdb95c
evm: ensure accounts are touched
jochem-brouwer Apr 23, 2023
9a9cedd
Merge branch 'develop-v7' into remove-eei-rebase-v2
jochem-brouwer Apr 23, 2023
5943700
Merge branch 'remove-eei-rebase-v2' of github.com:ethereumjs/ethereum…
jochem-brouwer Apr 23, 2023
fc5172b
client: fix build
jochem-brouwer Apr 23, 2023
6111529
vm: move cleanup touched accounts check inside vm
jochem-brouwer Apr 24, 2023
12d1ffe
Merge branch 'develop-v7' into remove-eei-rebase-v2
jochem-brouwer Apr 24, 2023
96f46da
vm: fix state test
jochem-brouwer Apr 24, 2023
d887b65
vm: fix retesteth
jochem-brouwer Apr 24, 2023
adace69
vm: fix benchmarks
jochem-brouwer Apr 24, 2023
569de81
evm: fix test
jochem-brouwer Apr 24, 2023
2ba20d7
util: lint
jochem-brouwer Apr 24, 2023
1675ff5
client: fix tests
jochem-brouwer Apr 24, 2023
f8797dc
evm/statemanager: remove unused methods + mark methods as private
jochem-brouwer Apr 25, 2023
71805d6
evm/vm/state/common: extract statemanagerinterface
jochem-brouwer Apr 27, 2023
e9e55c1
common: update interfaces
jochem-brouwer Apr 28, 2023
7dffd58
evm: remove enableDefaultBlockchain
jochem-brouwer Apr 29, 2023
fa24e13
Merge branch 'develop-v7' into remove-eei-rebase-v2
jochem-brouwer Apr 29, 2023
9ea1a28
vm: fix retesteth
jochem-brouwer Apr 30, 2023
2b6cd1c
Merge remote-tracking branch 'origin/develop-v7' into remove-eei-reba…
acolytec3 May 9, 2023
a329d6f
Merge branch 'develop-v7' into remove-eei-rebase-v2
jochem-brouwer May 11, 2023
9da6ed6
ethersStateManager: disable tests
jochem-brouwer May 11, 2023
e9b6939
empty commit
jochem-brouwer May 11, 2023
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/lib/execution/vmexecution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export class VMExecution extends Execution {
if (typeof this.vm.blockchain.genesisState !== 'function') {
throw new Error('cannot get iterator head: blockchain has no genesisState function')
}
await this.vm.eei.generateCanonicalGenesis(this.vm.blockchain.genesisState())
await this.vm.stateManager.generateCanonicalGenesis(this.vm.blockchain.genesisState())
}
await super.open()
// TODO: Should a run be started to execute any left over blocks?
Expand Down
2 changes: 1 addition & 1 deletion packages/client/lib/miner/miner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ export class Miner {

// Set the state root to ensure the resulting state
// is based on the parent block's state
await vmCopy.eei.setStateRoot(parentBlock.header.stateRoot)
await vmCopy.stateManager.setStateRoot(parentBlock.header.stateRoot)

let difficulty
let cliqueSigner
Expand Down
2 changes: 1 addition & 1 deletion packages/client/lib/miner/pendingBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export class PendingBlock {

// Set the state root to ensure the resulting state
// is based on the parent block's state
await vm.eei.setStateRoot(parentBlock.header.stateRoot)
await vm.stateManager.setStateRoot(parentBlock.header.stateRoot)

const builder = await vm.buildBlock({
parentBlock,
Expand Down
2 changes: 1 addition & 1 deletion packages/client/lib/service/txpool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ export class TxPool {
.map((obj) => obj.tx)
.sort((a, b) => Number(a.nonce - b.nonce))
// Check if the account nonce matches the lowest known tx nonce
let account = await vm.eei.getAccount(new Address(hexStringToBytes(address)))
let account = await vm.stateManager.getAccount(new Address(hexStringToBytes(address)))
if (account === undefined) {
account = new Account()
}
Expand Down
12 changes: 3 additions & 9 deletions packages/client/test/miner/miner.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Common, Chain as CommonChain, Hardfork } from '@ethereumjs/common'
import { DefaultStateManager } from '@ethereumjs/statemanager'
import { FeeMarketEIP1559Transaction, Transaction } from '@ethereumjs/tx'
import { Address, equalsBytes, hexStringToBytes } from '@ethereumjs/util'
import { VmState } from '@ethereumjs/vm/dist/eei/vmState'
import { AbstractLevel } from 'abstract-level'
import { keccak256 } from 'ethereum-cryptography/keccak'
import * as tape from 'tape'
Expand Down Expand Up @@ -31,20 +30,16 @@ const B = {
}

const setBalance = async (vm: VM, address: Address, balance: bigint) => {
await vm.eei.checkpoint()
await vm.eei.modifyAccountFields(address, { balance })
await vm.eei.commit()
await vm.stateManager.checkpoint()
await vm.stateManager.modifyAccountFields(address, { balance })
await vm.stateManager.commit()
}

tape('[Miner]', async (t) => {
const originalValidate = BlockHeader.prototype._consensusFormatValidation
BlockHeader.prototype._consensusFormatValidation = td.func<any>()
td.replace('@ethereumjs/block', { BlockHeader })

const originalSetStateRoot = VmState.prototype.setStateRoot
VmState.prototype.setStateRoot = td.func<any>()
td.replace('@ethereumjs/vm/dist/vmState', { VmState })

// Stub out setStateRoot so txPool.validate checks will pass since correct state root
// doesn't exist in fakeChain state anyway
const ogStateManagerSetStateRoot = DefaultStateManager.prototype.setStateRoot
Expand Down Expand Up @@ -620,7 +615,6 @@ tape('[Miner]', async (t) => {
// mocking indirect dependencies is not properly supported, but it works for us in this file,
// so we will replace the original functions to avoid issues in other tests that come after
BlockHeader.prototype._consensusFormatValidation = originalValidate
VmState.prototype.setStateRoot = originalSetStateRoot
DefaultStateManager.prototype.setStateRoot = ogStateManagerSetStateRoot
t.end()
})
Expand Down
9 changes: 4 additions & 5 deletions packages/client/test/miner/pendingBlock.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Block, BlockHeader } from '@ethereumjs/block'
import { Common, Chain as CommonChain, Hardfork } from '@ethereumjs/common'
import { DefaultStateManager } from '@ethereumjs/statemanager'
import { BlobEIP4844Transaction, FeeMarketEIP1559Transaction, Transaction } from '@ethereumjs/tx'
import {
Account,
Expand All @@ -16,7 +17,6 @@ import {
randomBytes,
} from '@ethereumjs/util'
import { VM } from '@ethereumjs/vm'
import { VmState } from '@ethereumjs/vm/dist/eei/vmState'
import * as kzg from 'c-kzg'
import * as tape from 'tape'
import * as td from 'testdouble'
Expand Down Expand Up @@ -83,9 +83,8 @@ tape('[PendingBlock]', async (t) => {
BlockHeader.prototype._consensusFormatValidation = td.func<any>()
td.replace('@ethereumjs/block', { BlockHeader })

const originalSetStateRoot = VmState.prototype.setStateRoot
VmState.prototype.setStateRoot = td.func<any>()
td.replace('@ethereumjs/vm/dist/vmState', { VmState })
const originalSetStateRoot = DefaultStateManager.prototype.setStateRoot
DefaultStateManager.prototype.setStateRoot = td.func<any>()

const createTx = (
from = A,
Expand Down Expand Up @@ -344,7 +343,7 @@ tape('[PendingBlock]', async (t) => {
// mocking indirect dependencies is not properly supported, but it works for us in this file,
// so we will replace the original functions to avoid issues in other tests that come after
BlockHeader.prototype._consensusFormatValidation = originalValidate
VmState.prototype.setStateRoot = originalSetStateRoot
DefaultStateManager.prototype.setStateRoot = originalSetStateRoot

st.end()
})
Expand Down
2 changes: 1 addition & 1 deletion packages/client/test/rpc/eth/estimateGas.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ tape(`${method}: call with valid arguments`, async (t) => {
const { execution } = client.services.find((s) => s.name === 'eth') as FullEthereumService
t.notEqual(execution, undefined, 'should have valid execution')
const { vm } = execution
await vm.eei.generateCanonicalGenesis(blockchain.genesisState())
await vm.stateManager.generateCanonicalGenesis(blockchain.genesisState())

// genesis address with balance
const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997')
Expand Down
2 changes: 1 addition & 1 deletion packages/client/test/rpc/eth/getBalance.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ tape(`${method}: ensure balance deducts after a tx`, async (t) => {

// since synchronizer.run() is not executed in the mock setup,
// manually run stateManager.generateCanonicalGenesis()
await vm.eei.generateCanonicalGenesis(blockchain.genesisState())
await vm.stateManager.generateCanonicalGenesis(blockchain.genesisState())

// genesis address with balance
const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ tape(`${method}: call with valid arguments`, async (t) => {
t.notEqual(execution, undefined, 'should have valid execution')
const { vm } = execution

await vm.eei.generateCanonicalGenesis(blockchain.genesisState())
await vm.stateManager.generateCanonicalGenesis(blockchain.genesisState())

const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997')

Expand Down Expand Up @@ -81,7 +81,7 @@ tape(`${method}: call with valid arguments (multiple transactions)`, async (t) =
t.notEqual(execution, undefined, 'should have valid execution')
const { vm } = execution

await vm.eei.generateCanonicalGenesis(blockchain.genesisState())
await vm.stateManager.generateCanonicalGenesis(blockchain.genesisState())

const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997')

Expand Down
2 changes: 1 addition & 1 deletion packages/client/test/rpc/eth/getCode.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ tape(`${method}: call with valid arguments`, async (t) => {
const { execution } = client.services.find((s) => s.name === 'eth') as FullEthereumService
t.notEqual(execution, undefined, 'should have valid execution')
const { vm } = execution
await vm.eei.generateCanonicalGenesis(blockchain.genesisState())
await vm.stateManager.generateCanonicalGenesis(blockchain.genesisState())

// genesis address
const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997')
Expand Down
2 changes: 1 addition & 1 deletion packages/client/test/rpc/eth/getTransactionCount.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ tape(`${method}: call with valid arguments`, async (t) => {

// since synchronizer.run() is not executed in the mock setup,
// manually run stateManager.generateCanonicalGenesis()
await vm.eei.generateCanonicalGenesis(blockchain.genesisState())
await vm.stateManager.generateCanonicalGenesis(blockchain.genesisState())

// a genesis address
const address = Address.fromString('0xccfd725760a68823ff1e062f4cc97e1360e8d997')
Expand Down
2 changes: 1 addition & 1 deletion packages/client/test/rpc/txpool/content.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ tape(`${method}: call with valid arguments`, async (t) => {
const { execution } = client.services.find((s) => s.name === 'eth') as FullEthereumService
t.notEqual(execution, undefined, 'should have valid execution')
const { vm } = execution
await vm.eei.generateCanonicalGenesis(blockchain.genesisState())
await vm.stateManager.generateCanonicalGenesis(blockchain.genesisState())
const gasLimit = 2000000
const parent = await blockchain.getCanonicalHeadHeader()
const block = Block.fromBlockData(
Expand Down
4 changes: 1 addition & 3 deletions packages/client/test/sync/txpool.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ import { getLogger } from '../../lib/logging'
import { PeerPool } from '../../lib/net/peerpool'
import { TxPool } from '../../lib/service/txpool'

import type { StateManager } from '@ethereumjs/statemanager'

const setup = () => {
const config = new Config({
transports: [],
Expand Down Expand Up @@ -50,7 +48,7 @@ const config = new Config({ transports: [], accountCache: 10000, storageCache: 1
const handleTxs = async (
txs: any[],
failMessage: string,
stateManager?: StateManager,
stateManager?: DefaultStateManager,
pool?: TxPool
) => {
if (pool === undefined) {
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './common'
export * from './enums'
export * from './interfaces'
export * from './types'
export * from './utils'
94 changes: 94 additions & 0 deletions packages/common/src/interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import type { Account, Address, PrefixedHexString } from '@ethereumjs/util'

export interface StorageDump {
[key: string]: string
}

export type AccountFields = Partial<Pick<Account, 'nonce' | 'balance' | 'storageRoot' | 'codeHash'>>

export type StorageProof = {
key: PrefixedHexString
proof: PrefixedHexString[]
value: PrefixedHexString
}

export type Proof = {
address: PrefixedHexString
balance: PrefixedHexString
codeHash: PrefixedHexString
nonce: PrefixedHexString
storageHash: PrefixedHexString
accountProof: PrefixedHexString[]
storageProof: StorageProof[]
}

/*
* Access List types
*/

export type AccessListItem = {
address: PrefixedHexString
storageKeys: PrefixedHexString[]
}

/*
* An Access List as a tuple of [address: Uint8Array, storageKeys: Uint8Array[]]
*/
export type AccessListBytesItem = [Uint8Array, Uint8Array[]]
export type AccessListBytes = AccessListBytesItem[]
export type AccessList = AccessListItem[]

export interface StateManagerInterface {
accountExists(address: Address): Promise<boolean>
getAccount(address: Address): Promise<Account | undefined>
putAccount(address: Address, account: Account): Promise<void>
deleteAccount(address: Address): Promise<void>
modifyAccountFields(address: Address, accountFields: AccountFields): Promise<void>
putContractCode(address: Address, value: Uint8Array): Promise<void>
getContractCode(address: Address): Promise<Uint8Array>
getContractStorage(address: Address, key: Uint8Array): Promise<Uint8Array>
putContractStorage(address: Address, key: Uint8Array, value: Uint8Array): Promise<void>
clearContractStorage(address: Address): Promise<void>
checkpoint(): Promise<void>
commit(): Promise<void>
revert(): Promise<void>
getStateRoot(): Promise<Uint8Array>
setStateRoot(stateRoot: Uint8Array, clearCache?: boolean): Promise<void>
getProof?(address: Address, storageSlots: Uint8Array[]): Promise<Proof>
hasStateRoot(root: Uint8Array): Promise<boolean> // only used in client
copy(): StateManagerInterface
}

export interface EVMStateManagerInterface extends StateManagerInterface {
// TODO check if all these `touch?` interfaces can be moved into StateManagerInterface
putAccount(address: Address, account: Account, touch?: boolean): Promise<void>
deleteAccount(address: Address, touch?: boolean): Promise<void>
accountIsEmptyOrNonExistent(address: Address): Promise<boolean>

getOriginalContractStorage(address: Address, key: Uint8Array): Promise<Uint8Array>

dumpStorage(address: Address): Promise<StorageDump> // only used in client
putContractStorage(
address: Address,
key: Uint8Array,
value: Uint8Array,
touch?: boolean
): Promise<void>

clearContractStorage(address: Address, touch?: boolean): Promise<void>

clearWarmedAccounts(): void
cleanupTouchedAccounts(): Promise<void>
clearOriginalStorageCache(): void

addWarmedAddress(address: Uint8Array): void
isWarmedAddress(address: Uint8Array): boolean
addWarmedStorage(address: Uint8Array, slot: Uint8Array): void
isWarmedStorage(address: Uint8Array, slot: Uint8Array): boolean

generateCanonicalGenesis(initState: any): Promise<void> // TODO make input more typesafe
generateAccessList(addressesRemoved: Address[], addressesOnlyStorage: Address[]): AccessList
getProof(address: Address, storageSlots?: Uint8Array[]): Promise<Proof>

copy(): EVMStateManagerInterface
}
5 changes: 2 additions & 3 deletions packages/evm/examples/runCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,17 @@ import { Blockchain } from '@ethereumjs/blockchain'
import { Chain, Common, Hardfork } from '@ethereumjs/common'
import { EVM } from '@ethereumjs/evm'
import { DefaultStateManager } from '@ethereumjs/statemanager'
import { EEI } from '@ethereumjs/vm'
import { bytesToHex, hexToBytes } from 'ethereum-cryptography/utils'

const main = async () => {
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London })
const stateManager = new DefaultStateManager()
const blockchain = await Blockchain.create()
const eei = new EEI(stateManager, common, blockchain)

const evm = new EVM({
common,
eei,
stateManager,
blockchain,
})

const STOP = '00'
Expand Down
2 changes: 1 addition & 1 deletion packages/evm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"tsc": "../../config/cli/ts-compile.sh"
},
"dependencies": {
"@ethereumjs/statemanager": "^1.0.4",
"@ethereumjs/common": "^3.1.1",
"@ethereumjs/util": "^8.0.5",
"@ethersproject/providers": "^5.7.1",
Expand All @@ -56,7 +57,6 @@
"rustbn.js": "~0.2.0"
},
"devDependencies": {
"@ethereumjs/statemanager": "^1.0.4",
"@ethersproject/abi": "^5.0.12",
"@types/benchmark": "^1.0.33",
"@types/core-js": "^2.5.0",
Expand Down
Loading
Loading