From 26a0ef22e7e986df3235e6610e5df8394256bd01 Mon Sep 17 00:00:00 2001 From: holgerd77 Date: Wed, 20 Jun 2018 12:58:17 +0200 Subject: [PATCH 1/3] Added ethereumjs-common dependency, updated VM API with chain and hardfork options --- lib/index.js | 11 ++++++++++- lib/stateManager.js | 14 +++++++++++--- package.json | 2 +- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/lib/index.js b/lib/index.js index 573ac53335..3f2fed3f31 100644 --- a/lib/index.js +++ b/lib/index.js @@ -2,6 +2,7 @@ const Buffer = require('safe-buffer').Buffer const util = require('util') const ethUtil = require('ethereumjs-util') const StateManager = require('./stateManager.js') +const Common = require('ethereumjs-common') const Account = require('ethereumjs-account') const AsyncEventEmitter = require('async-eventemitter') const BN = ethUtil.BN @@ -31,18 +32,26 @@ VM.deps = { * @param {StateManager} [opts.stateManager] A state manager instance (EXPERIMENTAL - unstable API) * @param {Trie} [opts.state] A merkle-patricia-tree instance for the state tree (ignored if stateManager is passed) * @param {Blockchain} [opts.blockchain] A blockchain object for storing/retrieving blocks (ignored if stateManager is passed) + * @param {String|Number} opts.chain The chain the VM operates on [default: 'mainnet'] + * @param {String} opts.hardfork Hardfork rules to be used [default: 'byzantium', supported: 'byzantium'] * @param {Boolean} [opts.activatePrecompiles] Create entries in the state tree for the precompiled contracts * @param {Boolean} [opts.allowUnlimitedContractSize] Allows unlimited contract sizes while debugging (default: false; ONLY use during debugging) */ function VM (opts = {}) { this.opts = opts + let chain = opts.chain ? opts.chain : 'mainnet' + let hardfork = opts.hardfork ? opts.hardfork : 'byzantium' + let supportedHardforks = [ 'byzantium' ] + this._common = new Common(chain, hardfork, supportedHardforks) + if (opts.stateManager) { this.stateManager = opts.stateManager } else { this.stateManager = new StateManager({ trie: opts.state, - blockchain: opts.blockchain + blockchain: opts.blockchain, + common: this._common }) } diff --git a/lib/stateManager.js b/lib/stateManager.js index cc4acb095d..c7f7c3ed7c 100644 --- a/lib/stateManager.js +++ b/lib/stateManager.js @@ -1,6 +1,7 @@ const Buffer = require('safe-buffer').Buffer const Trie = require('merkle-patricia-tree/secure.js') -const common = require('ethereum-common') +const Common = require('ethereumjs-common') +const genesisStates = require('ethereumjs-common/genesisStates') const async = require('async') const Account = require('ethereumjs-account') const fakeBlockchain = require('./fakeBlockChain.js') @@ -16,6 +17,13 @@ function StateManager (opts = {}) { self.blockchain = opts.blockchain || fakeBlockchain self.trie = opts.trie || new Trie() + + var common = opts.common + if (!common) { + common = new Common('mainnet', 'byzantium') + } + self._common = common + self._storageTries = {} // the storage trie cache self.cache = new Cache(self.trie) self._touched = new Set() @@ -297,7 +305,7 @@ proto.dumpStorage = function (address, cb) { } proto.hasGenesisState = function (cb) { - const root = common.genesisStateRoot.v + const root = this._common.genesis().stateRoot this.trie.checkRoot(root, cb) } @@ -306,7 +314,7 @@ proto.generateCanonicalGenesis = function (cb) { this.hasGenesisState(function (err, genesis) { if (!genesis && !err) { - self.generateGenesis(common.genesisState, cb) + self.generateGenesis(genesisStates[self._common.chainName()], cb) } else { cb(err) } diff --git a/package.json b/package.json index dc38818563..ee88f1f921 100644 --- a/package.json +++ b/package.json @@ -33,9 +33,9 @@ "dependencies": { "async": "^2.1.2", "async-eventemitter": "^0.2.2", - "ethereum-common": "0.2.0", "ethereumjs-account": "^2.0.3", "ethereumjs-block": "~1.7.0", + "ethereumjs-common": "~0.4.0", "ethereumjs-util": "^5.1.3", "fake-merkle-patricia-tree": "^1.0.1", "functional-red-black-tree": "^1.0.1", From 55959c3bedc1157140d1f67e1640fb255a1f96c9 Mon Sep 17 00:00:00 2001 From: holgerd77 Date: Wed, 20 Jun 2018 12:59:10 +0200 Subject: [PATCH 2/3] Read all fee and config params from new common library --- lib/opFns.js | 49 ++++++++++++++++----------------- lib/precompiled/01-ecrecover.js | 3 +- lib/precompiled/02-sha256.js | 5 ++-- lib/precompiled/03-ripemd160.js | 5 ++-- lib/precompiled/04-identity.js | 5 ++-- lib/precompiled/05-modexp.js | 4 +-- lib/precompiled/06-ecadd.js | 3 +- lib/precompiled/07-ecmul.js | 3 +- lib/precompiled/08-ecpairing.js | 3 +- lib/runBlock.js | 5 ++-- lib/runCall.js | 3 +- lib/runCode.js | 1 + lib/runJit.js | 1 + 13 files changed, 40 insertions(+), 50 deletions(-) diff --git a/lib/opFns.js b/lib/opFns.js index 570e339e82..8d0c95fc67 100644 --- a/lib/opFns.js +++ b/lib/opFns.js @@ -1,6 +1,5 @@ const Buffer = require('safe-buffer').Buffer const async = require('async') -const fees = require('ethereum-common') const utils = require('ethereumjs-util') const BN = utils.BN const exceptions = require('./exceptions.js') @@ -95,7 +94,7 @@ module.exports = { if (!exponent.isZero()) { var bytes = 1 + logTable(exponent) - subGas(runState, new BN(bytes).muln(fees.expByteGas.v)) + subGas(runState, new BN(bytes).muln(runState._common.param('gasPrices', 'expByte'))) return base.redPow(exponent) } else { return new BN(1) @@ -162,7 +161,7 @@ module.exports = { SHA3: function (offset, length, runState) { var data = memLoad(runState, offset, length) // copy fee - subGas(runState, new BN(fees.sha3WordGas.v).imul(length.divCeil(new BN(32)))) + subGas(runState, new BN(runState._common.param('gasPrices', 'sha3Word')).imul(length.divCeil(new BN(32)))) return new BN(utils.sha3(data)) }, // 0x30 range - closure state @@ -217,7 +216,7 @@ module.exports = { CALLDATACOPY: function (memOffset, dataOffset, dataLength, runState) { memStore(runState, memOffset, runState.callData, dataOffset, dataLength) // sub the COPY fee - subGas(runState, new BN(fees.copyGas.v).imul(dataLength.divCeil(new BN(32)))) + subGas(runState, new BN(runState._common.param('gasPrices', 'copy')).imul(dataLength.divCeil(new BN(32)))) }, CODESIZE: function (runState) { return new BN(runState.code.length) @@ -225,7 +224,7 @@ module.exports = { CODECOPY: function (memOffset, codeOffset, length, runState) { memStore(runState, memOffset, runState.code, codeOffset, length) // sub the COPY fee - subGas(runState, new BN(fees.copyGas.v).imul(length.divCeil(new BN(32)))) + subGas(runState, new BN(runState._common.param('gasPrices', 'copy')).imul(length.divCeil(new BN(32)))) }, EXTCODESIZE: function (address, runState, cb) { var stateManager = runState.stateManager @@ -242,7 +241,7 @@ module.exports = { // FIXME: for some reason this must come before subGas subMemUsage(runState, memOffset, length) // copy fee - subGas(runState, new BN(fees.copyGas.v).imul(length.divCeil(new BN(32)))) + subGas(runState, new BN(runState._common.param('gasPrices', 'copy')).imul(length.divCeil(new BN(32)))) stateManager.getContractCode(address, function (err, code) { if (err) return cb(err) @@ -260,7 +259,7 @@ module.exports = { memStore(runState, memOffset, utils.toBuffer(runState.lastReturned), returnDataOffset, length, false) // sub the COPY fee - subGas(runState, new BN(fees.copyGas.v).mul(length.divCeil(new BN(32)))) + subGas(runState, new BN(runState._common.param('gasPrices', 'copy')).mul(length.divCeil(new BN(32)))) }, GASPRICE: function (runState) { return new BN(runState.gasPrice) @@ -339,14 +338,14 @@ module.exports = { if (err) return cb(err) try { if (value.length === 0 && !found.length) { - subGas(runState, new BN(fees.sstoreResetGas.v)) + subGas(runState, new BN(runState._common.param('gasPrices', 'sstoreReset'))) } else if (value.length === 0 && found.length) { - subGas(runState, new BN(fees.sstoreResetGas.v)) - runState.gasRefund.iaddn(fees.sstoreRefundGas.v) + subGas(runState, new BN(runState._common.param('gasPrices', 'sstoreReset'))) + runState.gasRefund.iaddn(runState._common.param('gasPrices', 'sstoreRefund')) } else if (value.length !== 0 && !found.length) { - subGas(runState, new BN(fees.sstoreSetGas.v)) + subGas(runState, new BN(runState._common.param('gasPrices', 'sstoreSet'))) } else if (value.length !== 0 && found.length) { - subGas(runState, new BN(fees.sstoreResetGas.v)) + subGas(runState, new BN(runState._common.param('gasPrices', 'sstoreReset'))) } } catch (e) { cb(e.error) @@ -445,7 +444,7 @@ module.exports = { const numOfTopics = runState.opCode - 0xa0 const mem = memLoad(runState, memOffset, memLength) - subGas(runState, new BN(fees.logTopicGas.v).imuln(numOfTopics).iadd(memLength.muln(fees.logDataGas.v))) + subGas(runState, new BN(runState._common.param('gasPrices', 'logTopic')).imuln(numOfTopics).iadd(memLength.muln(runState._common.param('gasPrices', 'logData')))) // add address var log = [runState.address] @@ -507,7 +506,7 @@ module.exports = { } if (!value.isZero()) { - subGas(runState, new BN(fees.callValueTransferGas.v)) + subGas(runState, new BN(runState._common.param('gasPrices', 'callValueTransfer'))) } stateManager.exists(toAddress, function (err, exists) { @@ -525,7 +524,7 @@ module.exports = { if (!exists || empty) { if (!value.isZero()) { try { - subGas(runState, new BN(fees.callNewAccountGas.v)) + subGas(runState, new BN(runState._common.param('gasPrices', 'callNewAccount'))) } catch (e) { done(e.error) return @@ -542,8 +541,8 @@ module.exports = { } if (!value.isZero()) { - runState.gasLeft.iaddn(fees.callStipend.v) - options.gasLimit.iaddn(fees.callStipend.v) + runState.gasLeft.iaddn(runState._common.param('gasPrices', 'callStipend')) + options.gasLimit.iaddn(runState._common.param('gasPrices', 'callStipend')) } makeCall(runState, options, localOpts, done) @@ -572,15 +571,15 @@ module.exports = { } if (!value.isZero()) { - subGas(runState, new BN(fees.callValueTransferGas.v)) + subGas(runState, new BN(runState._common.param('gasPrices', 'callValueTransfer'))) } checkCallMemCost(runState, options, localOpts) checkOutOfGas(runState, options) if (!value.isZero()) { - runState.gasLeft.iaddn(fees.callStipend.v) - options.gasLimit.iaddn(fees.callStipend.v) + runState.gasLeft.iaddn(runState._common.param('gasPrices', 'callStipend')) + options.gasLimit.iaddn(runState._common.param('gasPrices', 'callStipend')) } // load the code @@ -724,7 +723,7 @@ module.exports = { if ((new BN(contract.balance)).gtn(0)) { if (!toAccount.exists || empty) { try { - subGas(runState, new BN(fees.callNewAccountGas.v)) + subGas(runState, new BN(runState._common.param('gasPrices', 'callNewAccount'))) } catch (e) { cb(e.error) return @@ -734,7 +733,7 @@ module.exports = { // only add to refund if this is the first selfdestruct for the address if (!runState.selfdestruct[contractAddress.toString('hex')]) { - runState.gasRefund = runState.gasRefund.addn(fees.suicideRefundGas.v) + runState.gasRefund = runState.gasRefund.addn(runState._common.param('gasPrices', 'selfdestructRefund')) } runState.selfdestruct[contractAddress.toString('hex')] = selfdestructToAddress runState.stopped = true @@ -786,8 +785,8 @@ function subMemUsage (runState, offset, length) { if (newMemoryWordCount.lte(runState.memoryWordCount)) return const words = newMemoryWordCount - const fee = new BN(fees.memoryGas.v) - const quadCoeff = new BN(fees.quadCoeffDiv.v) + const fee = new BN(runState._common.param('gasPrices', 'memory')) + const quadCoeff = new BN(runState._common.param('gasPrices', 'quadCoeffDiv')) // words * 3 + words ^2 / 512 const cost = words.mul(fee).add(words.mul(words).div(quadCoeff)) @@ -927,7 +926,7 @@ function makeCall (runState, callOptions, localOpts, cb) { // check if account has enough ether // Note: in the case of delegatecall, the value is persisted and doesn't need to be deducted again - if (runState.depth >= fees.stackLimit.v || (callOptions.delegatecall !== true && new BN(runState.contract.balance).lt(callOptions.value))) { + if (runState.depth >= runState._common.param('vm', 'stackLimit') || (callOptions.delegatecall !== true && new BN(runState.contract.balance).lt(callOptions.value))) { cb(null, new BN(0)) } else { // if creating a new contract then increament the nonce diff --git a/lib/precompiled/01-ecrecover.js b/lib/precompiled/01-ecrecover.js index 444c39ed15..d0dc586487 100644 --- a/lib/precompiled/01-ecrecover.js +++ b/lib/precompiled/01-ecrecover.js @@ -1,7 +1,6 @@ const utils = require('ethereumjs-util') const BN = utils.BN const error = require('../exceptions.js').ERROR -const fees = require('ethereum-common') const assert = require('assert') module.exports = function (opts) { @@ -9,7 +8,7 @@ module.exports = function (opts) { var results = {} - results.gasUsed = new BN(fees.ecrecoverGas.v) + results.gasUsed = new BN(opts._common.param('gasPrices', 'ecRecover')) if (opts.gasLimit.lt(results.gasUsed)) { results.gasUsed = opts.gasLimit diff --git a/lib/precompiled/02-sha256.js b/lib/precompiled/02-sha256.js index ac060f93c5..96a3af97e2 100644 --- a/lib/precompiled/02-sha256.js +++ b/lib/precompiled/02-sha256.js @@ -1,7 +1,6 @@ const utils = require('ethereumjs-util') const BN = utils.BN const error = require('../exceptions.js').ERROR -const fees = require('ethereum-common') const assert = require('assert') module.exports = function (opts) { @@ -10,8 +9,8 @@ module.exports = function (opts) { var results = {} var data = opts.data - results.gasUsed = new BN(fees.sha256Gas.v) - results.gasUsed.iadd(new BN(fees.sha256WordGas.v).imuln(Math.ceil(data.length / 32))) + results.gasUsed = new BN(opts._common.param('gasPrices', 'sha256')) + results.gasUsed.iadd(new BN(opts._common.param('gasPrices', 'sha256Word')).imuln(Math.ceil(data.length / 32))) if (opts.gasLimit.lt(results.gasUsed)) { results.gasUsed = opts.gasLimit diff --git a/lib/precompiled/03-ripemd160.js b/lib/precompiled/03-ripemd160.js index 03554cedf5..46ea8ba5d6 100644 --- a/lib/precompiled/03-ripemd160.js +++ b/lib/precompiled/03-ripemd160.js @@ -1,7 +1,6 @@ const utils = require('ethereumjs-util') const BN = utils.BN const error = require('../exceptions.js').ERROR -const fees = require('ethereum-common') const assert = require('assert') module.exports = function (opts) { @@ -10,8 +9,8 @@ module.exports = function (opts) { var results = {} var data = opts.data - results.gasUsed = new BN(fees.ripemd160Gas.v) - results.gasUsed.iadd(new BN(fees.ripemd160WordGas.v).imuln(Math.ceil(data.length / 32))) + results.gasUsed = new BN(opts._common.param('gasPrices', 'ripemd160')) + results.gasUsed.iadd(new BN(opts._common.param('gasPrices', 'ripemd160Word')).imuln(Math.ceil(data.length / 32))) if (opts.gasLimit.lt(results.gasUsed)) { results.gasUsed = opts.gasLimit diff --git a/lib/precompiled/04-identity.js b/lib/precompiled/04-identity.js index 9328a48b93..5fef9c1dd2 100644 --- a/lib/precompiled/04-identity.js +++ b/lib/precompiled/04-identity.js @@ -1,6 +1,5 @@ const utils = require('ethereumjs-util') const BN = utils.BN -const fees = require('ethereum-common') const error = require('../exceptions.js').ERROR const assert = require('assert') @@ -10,8 +9,8 @@ module.exports = function (opts) { var results = {} var data = opts.data - results.gasUsed = new BN(fees.identityGas.v) - results.gasUsed.iadd(new BN(fees.identityWordGas.v).imuln(Math.ceil(data.length / 32))) + results.gasUsed = new BN(opts._common.param('gasPrices', 'identity')) + results.gasUsed.iadd(new BN(opts._common.param('gasPrices', 'identityWord')).imuln(Math.ceil(data.length / 32))) if (opts.gasLimit.lt(results.gasUsed)) { results.gasUsed = opts.gasLimit diff --git a/lib/precompiled/05-modexp.js b/lib/precompiled/05-modexp.js index 8dbff8a2b3..9040dee238 100644 --- a/lib/precompiled/05-modexp.js +++ b/lib/precompiled/05-modexp.js @@ -1,11 +1,8 @@ const utils = require('ethereumjs-util') const BN = utils.BN const error = require('../exceptions.js').ERROR -const fees = require('ethereum-common') const assert = require('assert') -const Gquaddivisor = fees.modexpGquaddivisor.v - function multComplexity (x) { var fac1 = new BN(0) var fac2 = new BN(0) @@ -95,6 +92,7 @@ module.exports = function (opts) { if (maxLen.lt(mLen)) { maxLen = mLen } + const Gquaddivisor = opts._common.param('gasPrices', 'modexpGquaddivisor') var gasUsed = adjustedELen.mul(multComplexity(maxLen)).divn(Gquaddivisor) if (opts.gasLimit.lt(gasUsed)) { diff --git a/lib/precompiled/06-ecadd.js b/lib/precompiled/06-ecadd.js index c1d2034797..8b7659d012 100644 --- a/lib/precompiled/06-ecadd.js +++ b/lib/precompiled/06-ecadd.js @@ -1,7 +1,6 @@ const utils = require('ethereumjs-util') const BN = utils.BN const error = require('../exceptions.js').ERROR -const fees = require('ethereum-common') const assert = require('assert') const bn128Module = require('rustbn.js') @@ -14,7 +13,7 @@ module.exports = function (opts) { let data = opts.data let inputHexStr = data.toString('hex') - results.gasUsed = new BN(fees.ecAddGas.v) + results.gasUsed = new BN(opts._common.param('gasPrices', 'ecAdd')) if (opts.gasLimit.lt(results.gasUsed)) { results.return = Buffer.alloc(0) results.exception = 0 diff --git a/lib/precompiled/07-ecmul.js b/lib/precompiled/07-ecmul.js index ad0cb7b234..357cd7037c 100644 --- a/lib/precompiled/07-ecmul.js +++ b/lib/precompiled/07-ecmul.js @@ -1,7 +1,6 @@ const utils = require('ethereumjs-util') const ERROR = require('../exceptions.js').ERROR const BN = utils.BN -const fees = require('ethereum-common') const assert = require('assert') const bn128Module = require('rustbn.js') @@ -14,7 +13,7 @@ module.exports = function (opts) { let data = opts.data let inputHexStr = data.toString('hex') - results.gasUsed = new BN(fees.ecMulGas.v) + results.gasUsed = new BN(opts._common.param('gasPrices', 'ecMul')) if (opts.gasLimit.lt(results.gasUsed)) { results.return = Buffer.alloc(0) diff --git a/lib/precompiled/08-ecpairing.js b/lib/precompiled/08-ecpairing.js index 38c7d3ac49..c4ebc402d2 100644 --- a/lib/precompiled/08-ecpairing.js +++ b/lib/precompiled/08-ecpairing.js @@ -1,7 +1,6 @@ const utils = require('ethereumjs-util') const BN = utils.BN const error = require('../exceptions.js').ERROR -const fees = require('ethereum-common') const assert = require('assert') const bn128Module = require('rustbn.js') @@ -17,7 +16,7 @@ module.exports = function (opts) { let inputData = Buffer.from(inputHexStr, 'hex') let inputDataSize = Math.floor(inputData.length / 192) - const gascost = fees.ecPairingGas.v + (inputDataSize * fees.ecPairingWordGas.v) + const gascost = opts._common.param('gasPrices', 'ecPairing') + (inputDataSize * opts._common.param('gasPrices', 'ecPairingWord')) results.gasUsed = new BN(gascost) if (opts.gasLimit.ltn(gascost)) { diff --git a/lib/runBlock.js b/lib/runBlock.js index ebc5a75b81..80d081e65a 100644 --- a/lib/runBlock.js +++ b/lib/runBlock.js @@ -2,13 +2,10 @@ const Buffer = require('safe-buffer').Buffer const async = require('async') const ethUtil = require('ethereumjs-util') const Bloom = require('./bloom.js') -const common = require('ethereum-common') const rlp = ethUtil.rlp const Trie = require('merkle-patricia-tree') const BN = ethUtil.BN -const minerReward = new BN(common.minerReward.v) - /** * process the transaction in a block and pays the miners * @param opts @@ -189,6 +186,7 @@ module.exports = function (opts, cb) { ommers.forEach(rewardOmmer) // calculate nibling reward + var minerReward = new BN(self._common.param('pow', 'minerReward')) var niblingReward = minerReward.divn(32) var totalNiblingReward = niblingReward.muln(ommers.length) minerAccount = self.stateManager.cache.get(block.header.coinbase) @@ -202,6 +200,7 @@ module.exports = function (opts, cb) { // credit ommer function rewardOmmer (ommer) { // calculate reward + var minerReward = new BN(self._common.param('pow', 'minerReward')) var heightDiff = new BN(block.header.number).sub(new BN(ommer.number)) var reward = ((new BN(8)).sub(heightDiff)).mul(minerReward.divn(8)) diff --git a/lib/runCall.js b/lib/runCall.js index 1b77f78145..57662d2728 100644 --- a/lib/runCall.js +++ b/lib/runCall.js @@ -2,7 +2,6 @@ const Buffer = require('safe-buffer').Buffer const async = require('async') const ethUtil = require('ethereumjs-util') const BN = ethUtil.BN -const fees = require('ethereum-common') const exceptions = require('./exceptions.js') const ERROR = exceptions.ERROR @@ -182,7 +181,7 @@ module.exports = function (opts, cb) { // fee for size of the return value var totalGas = results.gasUsed if (!results.runState.vmError) { - var returnFee = new BN(results.return.length * fees.createDataGas.v) + var returnFee = new BN(results.return.length * self._common.param('gasPrices', 'createData')) totalGas = totalGas.add(returnFee) } diff --git a/lib/runCode.js b/lib/runCode.js index ab8f0bea63..7dace81894 100644 --- a/lib/runCode.js +++ b/lib/runCode.js @@ -79,6 +79,7 @@ module.exports = function (opts, cb) { } // temporary - to be factored out + runState._common = self._common runState._precompiled = self._precompiled runState._vm = self diff --git a/lib/runJit.js b/lib/runJit.js index 43ea06d51a..73dcd332dc 100644 --- a/lib/runJit.js +++ b/lib/runJit.js @@ -2,6 +2,7 @@ module.exports = function (opts, cb) { // for precompiled var results if (typeof opts.code === 'function') { + opts._common = this._common results = opts.code(opts) results.account = opts.account if (results.exception === undefined) { From 0b3c5d186277187eddab302633fb04a63256f716 Mon Sep 17 00:00:00 2001 From: holgerd77 Date: Fri, 22 Jun 2018 11:16:49 +0200 Subject: [PATCH 3/3] Pass fork parameter to the VM in test runner, updated API in README --- README.md | 2 ++ lib/index.js | 2 +- tests/BlockchainTestsRunner.js | 3 ++- tests/GeneralStateTestsRunner.js | 3 ++- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8679781623..d0364cda2a 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,8 @@ Creates a new VM object - `stateManager` - A state manager instance (**EXPERIMENTAL** - unstable API) - `state` - A merkle-patricia-tree instance for the state tree (ignored if `stateManager` is passed) - `blockchain` - A blockchain object for storing/retrieving blocks (ignored if `stateManager` is passed) + - `chain` - The chain the VM operates on [default: 'mainnet'] + - `hardfork` - Hardfork rules to be used [default: 'byzantium', supported: 'byzantium' (will throw on unsupported)] - `activatePrecompiles` - Create entries in the state tree for the precompiled contracts - `allowUnlimitedContractSize` - Allows unlimited contract sizes while debugging. By setting this to `true`, the check for contract size limit of 2KB (see [EIP-170](https://git.io/vxZkK)) is bypassed. (default: `false`; **ONLY** set to `true` during debugging). diff --git a/lib/index.js b/lib/index.js index 3f2fed3f31..c4936b70b1 100644 --- a/lib/index.js +++ b/lib/index.js @@ -33,7 +33,7 @@ VM.deps = { * @param {Trie} [opts.state] A merkle-patricia-tree instance for the state tree (ignored if stateManager is passed) * @param {Blockchain} [opts.blockchain] A blockchain object for storing/retrieving blocks (ignored if stateManager is passed) * @param {String|Number} opts.chain The chain the VM operates on [default: 'mainnet'] - * @param {String} opts.hardfork Hardfork rules to be used [default: 'byzantium', supported: 'byzantium'] + * @param {String} opts.hardfork Hardfork rules to be used [default: 'byzantium', supported: 'byzantium' (will throw on unsupported)] * @param {Boolean} [opts.activatePrecompiles] Create entries in the state tree for the precompiled contracts * @param {Boolean} [opts.allowUnlimitedContractSize] Allows unlimited contract sizes while debugging (default: false; ONLY use during debugging) */ diff --git a/tests/BlockchainTestsRunner.js b/tests/BlockchainTestsRunner.js index 2de3bb4a8d..defa431845 100644 --- a/tests/BlockchainTestsRunner.js +++ b/tests/BlockchainTestsRunner.js @@ -23,7 +23,8 @@ module.exports = function runBlockchainTest (options, testData, t, cb) { } var vm = new VM({ state: state, - blockchain: blockchain + blockchain: blockchain, + hardfork: options.forkConfig.toLowerCase() }) var genesisBlock = new Block() diff --git a/tests/GeneralStateTestsRunner.js b/tests/GeneralStateTestsRunner.js index 96a251d7e9..24d80d522a 100644 --- a/tests/GeneralStateTestsRunner.js +++ b/tests/GeneralStateTestsRunner.js @@ -54,7 +54,8 @@ function runTestCase (options, testData, t, cb) { VM = require('../lib/index.js') } vm = new VM({ - state: state + state: state, + hardfork: options.forkConfig.toLowerCase() }) testUtil.setupPreConditions(state, testData, done) },