Skip to content

Commit

Permalink
vm: removed chain, hardfork options from the constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
holgerd77 committed Sep 7, 2020
1 parent 14bc686 commit c1bf90e
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 59 deletions.
16 changes: 12 additions & 4 deletions packages/vm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Please update your library references accordingly or install with:
npm i @ethereumjs/vm
```

### Support for all current Hardforks
### Support for all current Hardforks / HF API Changes

This is the first release of the VM which supports all hardforks
currently applied on mainnet starting with the support of the
Expand All @@ -40,13 +40,21 @@ The following HFs have been added:
PR [#828](https://github.com/ethereumjs/ethereumjs-vm/pull/828)

A VM with the specific HF rules (on the chain provided) can be instantiated
by passing in a `Common` instance or by setting HF and chain directly with:
by passing in a `Common` instance:

```typescript
import VM from 'ethereumjs-vm'
const vm = new VM({ chain: 'mainnet', hardfork: 'spuriousDragon' })
import VM from '@ethereumjs/vm'
import Common from '@ethereumjs/common'

const common = new Common({ chain: 'mainnet', hardfork: 'spuriousDragon' })
const vm = new VM({ common })
```

**Breaking**: Please note that the options to directly pass in
`chain` and `hardfork` strings have been removed to simpify the API.
Providing a `Common` instance is now the only way to change
the chain setup, see PR [#863](https://github.com/ethereumjs/ethereumjs-vm/pull/863)

### Berlin HF Support / HF-independent EIPs

This releases adds support for subroutines (`EIP-2315`) which gets
Expand Down
50 changes: 24 additions & 26 deletions packages/vm/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@ const promisify = require('util.promisify')
*/
export interface VMOpts {
/**
* The chain the VM operates on
*/
chain?: string
/**
* Hardfork rules to be used
* Use a [common](https://github.com/ethereumjs/ethereumjs-vm/packages/common) instance
* if you want to change the network setup
*
* If no common instance is provided the VM defaults to the following chain setup:
*
* Chain: `mainnet`
* Hardfork: `petersburg`
*
* Hardfork rules are implemented up to the 'muirGlacier' hardfork.
*/
hardfork?: string
common?: Common
/**
* A [[StateManager]] instance to use as the state store (Beta API)
*/
Expand All @@ -49,17 +53,17 @@ export interface VMOpts {
*
* Setting this to true has the effect of precompiled contracts' gas costs matching mainnet's from
* the very first call, which is intended for testing networks.
*
* Default: `false`
*/
activatePrecompiles?: boolean
/**
* Allows unlimited contract sizes while debugging. By setting this to `true`, the check for contract size limit of 24KB (see [EIP-170](https://git.io/vxZkK)) is bypassed
* Allows unlimited contract sizes while debugging. By setting this to `true`, the check for
* contract size limit of 24KB (see [EIP-170](https://git.io/vxZkK)) is bypassed.
*
* Default: `false` [ONLY set to `true` during debugging]
*/
allowUnlimitedContractSize?: boolean
/**
* Use a [common](https://github.com/ethereumjs/ethereumjs-vm/packages/common) instance or a combination
* on the `chain` and `hardfork` options if you want to change the network setup
*/
common?: Common
/**
* Selected EIPs which can be activated on the VM, please use an array for instantiation
* (e.g. `eips: [ 'EIP2537', ])
Expand Down Expand Up @@ -102,28 +106,18 @@ export default class VM extends AsyncEventEmitter {

/**
* Instantiates a new [[VM]] Object.
* @param opts - Default values for the options are:
* - `chain`: 'mainnet'
* - `hardfork`: 'petersburg' [supported: 'byzantium', 'constantinople', 'petersburg', 'istanbul' (DRAFT) (will throw on unsupported)]
* - `activatePrecompiles`: false
* - `allowUnlimitedContractSize`: false [ONLY set to `true` during debugging]
* @param opts
*/
constructor(opts: VMOpts = {}) {
super()

this.opts = opts

if (opts.common) {
if (opts.chain || opts.hardfork) {
throw new Error(
'You can only instantiate the VM class with one of: opts.common, or opts.chain and opts.hardfork',
)
}

this._common = opts.common
} else {
const chain = opts.chain ? opts.chain : 'mainnet'
const hardfork = opts.hardfork ? opts.hardfork : 'petersburg'
const DEFAULT_CHAIN = 'mainnet'
const DEFAULT_HARDFORK = 'petersburg'
const supportedHardforks = [
'chainstart',
'homestead',
Expand All @@ -138,7 +132,11 @@ export default class VM extends AsyncEventEmitter {
'berlin',
]

this._common = new Common({ chain, hardfork, supportedHardforks })
this._common = new Common({
chain: DEFAULT_CHAIN,
hardfork: DEFAULT_HARDFORK,
supportedHardforks,
})
}

// EIPs
Expand Down
4 changes: 3 additions & 1 deletion packages/vm/tests/GeneralStateTestsRunner.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const { setupPreConditions, makeTx, makeBlockFromEnv } = require('./util')
const Trie = require('merkle-patricia-tree').SecureTrie
const { BN } = require('ethereumjs-util')
const { default: Common } = require('@ethereumjs/common')
const Account = require('@ethereumjs/account').default

function parseTestCases(forkConfigTestSuite, testData, data, gasLimit, value) {
Expand Down Expand Up @@ -49,9 +50,10 @@ async function runTestCase(options, testData, t) {
} else {
VM = require('../lib/index').default
}
const common = new Common({ chain: 'mainnet', hardfork: options.forkConfigVM })
vm = new VM({
state,
hardfork: options.forkConfigVM,
common: common,
})

await setupPreConditions(vm.stateManager._trie, testData)
Expand Down
16 changes: 4 additions & 12 deletions packages/vm/tests/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,6 @@ tape('VM with default blockchain', (t) => {
st.end()
})

t.test('should only accept common or chain and fork', (st) => {
const common = new Common({ chain: 'mainnet' })

st.throws(() => new VM({ chain: 'a', common }))
st.throws(() => new VM({ hardfork: 'a', common }))
st.throws(() => new VM({ chain: 'a', hardfork: 'a', common }))

st.end()
})

t.test('should accept a common object as option', async (st) => {
const common = new Common({ chain: 'mainnet', hardfork: 'istanbul' })

Expand All @@ -60,12 +50,14 @@ tape('VM with default blockchain', (t) => {
})

t.test('should only accept valid chain and fork', async (st) => {
let vm = new VM({ chain: 'ropsten', hardfork: 'byzantium' })
let common = new Common({ chain: 'ropsten', hardfork: 'byzantium' })
let vm = new VM({ common })
await vm.init()
st.equal(vm.stateManager._common.param('gasPrices', 'ecAdd'), 500)

try {
vm = new VM({ chain: 'mainchain', hardfork: 'homestead' })
common = new Common({ chain: 'mainchain', hardfork: 'homestead' })
vm = new VM({ common })
st.fail('should have failed for invalid chain')
} catch (e) {
st.ok(e.message.includes('not supported'))
Expand Down
12 changes: 0 additions & 12 deletions packages/vm/tests/api/istanbul/index.js

This file was deleted.

3 changes: 2 additions & 1 deletion packages/vm/tests/api/muirGlacier/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
const tape = require('tape')
const util = require('ethereumjs-util')
const { default: Common } = require('@ethereumjs/common')
const VM = require('../../../dist/index').default

tape('General MuirGlacier VM tests', (t) => {
t.test('should accept muirGlacier harfork option for supported chains', (st) => {
let vm = new VM({ hardfork: 'muirGlacier' })
let vm = new VM(new Common({ chain: 'mainnet', hardfork: 'muirGlacier' }))
st.ok(vm.stateManager)
st.deepEqual(vm.stateManager._trie.root, util.KECCAK256_RLP, 'it has default trie')
st.end()
Expand Down
7 changes: 4 additions & 3 deletions packages/vm/tests/api/runCall.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ tape('Constantinople: EIP-1014 CREATE2 creates the right contract address', asyn
const caller = Buffer.from('00000000000000000000000000000000000000ee', 'hex') // caller addres
const contractAddress = Buffer.from('00000000000000000000000000000000000000ff', 'hex') // contract address
// setup the vm
const vm = new VM({ chain: 'mainnet', hardfork: 'constantinople'})
const common = new Common({ chain: 'mainnet', hardfork: 'constantinople'})
const vm = new VM({ common })
const code = "3460008080F560005260206000F3"
/*
code: remarks: (top of the stack is at the zero index)
Expand Down Expand Up @@ -83,8 +84,8 @@ tape('Byzantium cannot access Constantinople opcodes', async (t) => {
const caller = Buffer.from('00000000000000000000000000000000000000ee', 'hex') // caller addres
const contractAddress = Buffer.from('00000000000000000000000000000000000000ff', 'hex') // contract address
// setup the vm
const vmByzantium = new VM({ chain: 'mainnet', hardfork: 'byzantium'})
const vmConstantinople = new VM({ chain: 'mainnet', hardfork: 'constantinople'})
const vmByzantium = new VM(new Common({ chain: 'mainnet', hardfork: 'byzantium'}))
const vmConstantinople = new VM(new Common({ chain: 'mainnet', hardfork: 'constantinople'}))
const code = "600160011B00"
/*
code: remarks: (top of the stack is at the zero index)
Expand Down

0 comments on commit c1bf90e

Please sign in to comment.