Skip to content

Commit

Permalink
Merge branch 'master' into add-kurtosis-to-ci-workflows
Browse files Browse the repository at this point in the history
  • Loading branch information
scorbajio authored Jul 2, 2024
2 parents be3f166 + 436bcc9 commit 7ef0076
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 18 deletions.
2 changes: 1 addition & 1 deletion packages/ethereum-tests
5 changes: 4 additions & 1 deletion packages/evm/src/evm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
BIGINT_0,
BIGINT_1,
KECCAK256_NULL,
KECCAK256_RLP,
MAX_INTEGER,
bigIntToBytes,
bytesToUnprefixedHex,
Expand Down Expand Up @@ -490,7 +491,9 @@ export class EVM implements EVMInterface {
// Check for collision
if (
(toAccount.nonce && toAccount.nonce > BIGINT_0) ||
!(equalsBytes(toAccount.codeHash, KECCAK256_NULL) === true)
!(equalsBytes(toAccount.codeHash, KECCAK256_NULL) === true) ||
// See EIP 7610 and the discussion `https://ethereum-magicians.org/t/eip-7610-revert-creation-in-case-of-non-empty-storage`
!(equalsBytes(toAccount.storageRoot, KECCAK256_RLP) === true)
) {
if (this.DEBUG) {
debug(`Returning on address collision`)
Expand Down
10 changes: 9 additions & 1 deletion packages/vm/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Bloom } from './bloom/index.js'
import type { Block, BlockOptions, HeaderData } from '@ethereumjs/block'
import type { BlockchainInterface } from '@ethereumjs/blockchain'
import type { Common, EVMStateManagerInterface } from '@ethereumjs/common'
import type { EVMInterface, EVMResult, Log } from '@ethereumjs/evm'
import type { EVMInterface, EVMOpts, EVMResult, Log } from '@ethereumjs/evm'
import type { AccessList, TypedTransaction } from '@ethereumjs/tx'
import type {
BigIntLike,
Expand Down Expand Up @@ -159,6 +159,14 @@ export interface VMOpts {
*/
evm?: EVMInterface

/**
* Often there is no need to provide a full custom EVM but only a few options need to be
* adopted. This option allows to provide a custom set of EVM options to be passed.
*
* Note: This option will throw if used in conjunction with a full custom EVM passed.
*/
evmOpts?: EVMOpts

profilerOpts?: VMProfilerOpts
}

Expand Down
12 changes: 9 additions & 3 deletions packages/vm/src/vm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ export class VM {
}
}

if (opts.evm !== undefined && opts.evmOpts !== undefined) {
throw new Error('the evm and evmOpts options cannot be used in conjunction')
}

if (opts.evm === undefined) {
let enableProfiler = false
if (
Expand All @@ -117,13 +121,15 @@ export class VM {
) {
enableProfiler = true
}
const evmOpts = opts.evmOpts ?? {}
opts.evm = await EVM.create({
common: opts.common,
stateManager: opts.stateManager,
blockchain: opts.blockchain,
profiler: {
enabled: enableProfiler,
},
...evmOpts,
})
}

Expand Down Expand Up @@ -241,9 +247,9 @@ export class VM {
const stateManager = this.stateManager.shallowCopy(downlevelCaches)
const evmOpts = {
...(this.evm as any)._optsCached,
common,
blockchain,
stateManager,
common: this._opts.evmOpts?.common?.copy() ?? common,
blockchain: this._opts.evmOpts?.blockchain?.shallowCopy() ?? blockchain,
stateManager: this._opts.evmOpts?.stateManager?.shallowCopy(downlevelCaches) ?? stateManager,
}
const evmCopy = await EVM.create(evmOpts) // TODO fixme (should copy the EVMInterface, not default EVM)
return VM.create({
Expand Down
52 changes: 52 additions & 0 deletions packages/vm/test/api/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,58 @@ describe('VM -> basic instantiation / boolean switches', () => {
})
})

describe('VM -> Default EVM / Custom EVM Opts', () => {
it('Default EVM should have correct default EVM opts', async () => {
const vm = await VM.create()
assert.isFalse((vm.evm as EVM).allowUnlimitedContractSize, 'allowUnlimitedContractSize=false')
})

it('should throw if evm and evmOpts are both used', async () => {
try {
await VM.create({ evmOpts: {}, evm: await EVM.create() })
assert.fail('should throw')
} catch (e: any) {
assert.ok('correctly thrown')
}
})

it('Default EVM should use custom EVM opts', async () => {
const vm = await VM.create({ evmOpts: { allowUnlimitedContractSize: true } })
assert.isTrue((vm.evm as EVM).allowUnlimitedContractSize, 'allowUnlimitedContractSize=true')
const copiedVM = await vm.shallowCopy()
assert.isTrue(
(copiedVM.evm as EVM).allowUnlimitedContractSize,
'allowUnlimitedContractSize=true (for shallowCopied VM)'
)
})

it('Default EVM should use VM common', async () => {
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Byzantium })
const vm = await VM.create({ common })
assert.equal((vm.evm as EVM).common.hardfork(), 'byzantium', 'use modfied HF from VM common')

const copiedVM = await vm.shallowCopy()
assert.equal(
(copiedVM.evm as EVM).common.hardfork(),
'byzantium',
'use modfied HF from VM common (for shallowCopied VM)'
)
})

it('Default EVM should prefer common from evmOpts if provided (same logic for blockchain, statemanager)', async () => {
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Byzantium })
const vm = await VM.create({ evmOpts: { common } })
assert.equal((vm.evm as EVM).common.hardfork(), 'byzantium', 'use modfied HF from evmOpts')

const copiedVM = await vm.shallowCopy()
assert.equal(
(copiedVM.evm as EVM).common.hardfork(),
'byzantium',
'use modfied HF from evmOpts (for shallowCopied VM)'
)
})
})

describe('VM -> supportedHardforks', () => {
it('should throw when common is set to an unsupported hardfork', async () => {
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Shanghai })
Expand Down
33 changes: 21 additions & 12 deletions packages/vm/test/tester/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ export const SKIP_BROKEN = [
'blockChainFrontierWithLargerTDvsHomesteadBlockchain2_FrontierToHomesteadAt5',
'blockChainFrontierWithLargerTDvsHomesteadBlockchain_FrontierToHomesteadAt5',
'HomesteadOverrideFrontier_FrontierToHomesteadAt5',

// Test skipped in ethereum-tests v14, this is an internal test for retesteth to throw an error if the test self is wrong
// This test is thus not supposed to pass
// TODO: remove me once this test is removed from the releases
'filling_unexpectedException',
]

/**
Expand Down Expand Up @@ -165,17 +170,18 @@ const testLegacy = {
byzantium: true,
constantinople: true,
petersburg: true,
istanbul: false,
muirGlacier: false,
berlin: false,
london: false,
paris: false,
ByzantiumToConstantinopleFixAt5: false,
EIP158ToByzantiumAt5: false,
FrontierToHomesteadAt5: false,
HomesteadToDaoAt5: false,
HomesteadToEIP150At5: false,
BerlinToLondonAt5: false,
istanbul: true,
muirGlacier: true,
berlin: true,
london: true,
paris: true,
shanghai: true,
ByzantiumToConstantinopleFixAt5: true,
EIP158ToByzantiumAt5: true,
FrontierToHomesteadAt5: true,
HomesteadToDaoAt5: true,
HomesteadToEIP150At5: true,
BerlinToLondonAt5: true,
}

/**
Expand All @@ -190,9 +196,12 @@ export function getTestDirs(network: string, testType: string) {
key.toLowerCase() === network.toLowerCase() &&
testLegacy[key as keyof typeof testLegacy] === true
) {
// Tests for HFs before Istanbul have been moved under `LegacyTests/Constantinople`:
// Tests snapshots have moved in `LegacyTests/Constantinople`:
// https://github.com/ethereum/tests/releases/tag/v7.0.0-beta.1
// Also tests have moved in `LegacyTests/Cancun`:
// https://github.com/ethereum/tests/releases/tag/v14.0
testDirs.push('LegacyTests/Constantinople/' + testType)
testDirs.push('LegacyTests/Cancun/' + testType)
break
}
}
Expand Down

0 comments on commit 7ef0076

Please sign in to comment.