From 83e42d85cefa06e93ac6197349fa6c94c3d4355c Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Tue, 5 Nov 2019 13:54:03 +0100 Subject: [PATCH 01/15] Add state tests for Istanbul --- .circleci/config.yml | 18 ++++++++++++++++++ package.json | 6 ++++-- tests/tester.js | 7 ++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 07f2f2ffae..26f514bb8e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -82,6 +82,15 @@ jobs: - run: name: testStatePetersburg command: npm run testStatePetersburg + test_state_istanbul: + <<: *defaults + steps: + - attach_workspace: + at: ~/project + - *restore_node_modules + - run: + name: testStateIstanbul + command: npm run testStateIstanbul test_blockchain: <<: *defaults steps: @@ -91,6 +100,15 @@ jobs: - run: name: testBlockchain command: npm run testBlockchain + test_blockchain_petersburg: + <<: *defaults + steps: + - attach_workspace: + at: ~/project + - *restore_node_modules + - run: + name: testBlockchainPetersburg + command: npm run testBlockchainPetersburg coveralls: <<: *defaults steps: diff --git a/package.json b/package.json index 4a99f86df2..e7ec6c62d1 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,10 @@ "testStateByzantium": "npm run build:dist && node ./tests/tester -s --fork='Byzantium' --dist", "testStateConstantinople": "npm run build:dist && node ./tests/tester -s --fork='Constantinople' --dist", "testStatePetersburg": "npm run build:dist && node ./tests/tester -s --fork='Petersburg' --dist", + "testStateIstanbul": "npm run build:dist && node ./tests/tester -s --fork='Istanbul' --dist", "testBuildIntegrity": "npm run build:dist && node ./tests/tester -s --dist --test='stackOverflow'", - "testBlockchain": "npm run build:dist && node --stack-size=1500 ./tests/tester -b --fork='Petersburg' --dist --excludeDir='GeneralStateTests'", + "testBlockchain": "npm run build:dist && node --stack-size=1500 ./tests/tester -b --fork='Istanbul' --dist --excludeDir='GeneralStateTests'", + "testBlockchainPetersburg": "npm run build:dist && node --stack-size=1500 ./tests/tester -b --fork='Petersburg' --dist --excludeDir='GeneralStateTests'", "testBlockchainGeneralStateTests": "npm run build:dist && node --stack-size=1500 ./tests/tester -b --dist --dir='GeneralStateTests'", "testAPI": "npm run build:dist && tape './tests/api/**/*.js'", "testAPI:browser": "npm run build:dist && karma start karma.conf.js", @@ -74,7 +76,7 @@ "@types/node": "^11.13.4", "browserify": "^16.2.3", "coveralls": "^3.0.0", - "ethereumjs-testing": "git+https://github.com/ethereumjs/ethereumjs-testing.git#v1.2.7", + "ethereumjs-testing": "git+https://github.com/ethereumjs/ethereumjs-testing.git#istanbul-tests", "husky": "^2.1.0", "karma": "^4.0.1", "karma-browserify": "^6.0.0", diff --git a/tests/tester.js b/tests/tester.js index 207acbc5e5..8f7c5cbf06 100755 --- a/tests/tester.js +++ b/tests/tester.js @@ -3,7 +3,7 @@ const argv = require('minimist')(process.argv.slice(2)) const tape = require('tape') const testing = require('ethereumjs-testing') -const FORK_CONFIG = argv.fork || 'Petersburg' +const FORK_CONFIG = argv.fork || 'Istanbul' const { getRequiredForkConfigAlias } = require('./util') @@ -212,6 +212,11 @@ function runTests (name, runnerArgs, cb) { } else { tape(name, t => { const runner = require(`./${name}Runner.js`) + // Tests for HFs before Istanbul have been moved under `LegacyTests/Constantinople`: + // https://github.com/ethereum/tests/releases/tag/v7.0.0-beta.1 + if (runnerArgs.forkConfig !== 'Istanbul') { + name = 'LegacyTests/Constantinople/'.concat(name) + } testing.getTestsFromArgs(name, (fileName, testName, test) => { return new Promise((resolve, reject) => { if (name === 'VMTests') { From 63c90321c4c99848c2a7929e9112238aab4531ba Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Tue, 5 Nov 2019 13:59:30 +0100 Subject: [PATCH 02/15] Fix circleci config for istanbul tests --- .circleci/config.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 26f514bb8e..ca6feedb92 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -141,9 +141,15 @@ workflows: - test_state_petersburg: requires: - install + - test_state_istanbul: + requires: + - install - test_blockchain: requires: - install + - test_blockchain_petersburg: + requires: + - install - coveralls: requires: - install From d91f2464a53d051514d4b1c5d8860f91e0acc14f Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Tue, 5 Nov 2019 16:43:40 +0100 Subject: [PATCH 03/15] Fix transaction's hardfork option for istanbul tests --- tests/GeneralStateTestsRunner.js | 2 +- tests/util.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/GeneralStateTestsRunner.js b/tests/GeneralStateTestsRunner.js index fc9a0a5e33..ff964327c8 100644 --- a/tests/GeneralStateTestsRunner.js +++ b/tests/GeneralStateTestsRunner.js @@ -62,7 +62,7 @@ function runTestCase (options, testData, t, cb) { testUtil.setupPreConditions(state, testData, done) }, function (done) { - var tx = testUtil.makeTx(testData.transaction) + var tx = testUtil.makeTx(testData.transaction, options.forkConfig.toLowerCase()) block = testUtil.makeBlockFromEnv(testData.env) tx._homestead = true tx.enableHomestead = true diff --git a/tests/util.js b/tests/util.js index 62a062baca..f7039f5002 100644 --- a/tests/util.js +++ b/tests/util.js @@ -94,8 +94,8 @@ var format = exports.format = function (a, toZero, isHex) { * @param {[type]} txData the transaction object from tests repo * @returns {Object} object that will be passed to VM.runTx function */ -exports.makeTx = function (txData) { - var tx = new Transaction() +exports.makeTx = function (txData, hf) { + var tx = new Transaction({}, { hardfork: hf }) tx.nonce = format(txData.nonce) tx.gasPrice = format(txData.gasPrice) tx.gasLimit = format(txData.gasLimit) From 3f15631940dd51e937dae8ddefa373a786d6419a Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi <1591639+s1na@users.noreply.github.com> Date: Mon, 11 Nov 2019 14:20:04 +0100 Subject: [PATCH 04/15] Store refund counter in EVM (#612) * Store refund counter in EVM * Fix linting error --- lib/evm/eei.ts | 24 +++++------------------- lib/evm/evm.ts | 13 ++++++++----- lib/evm/opFns.ts | 4 +--- lib/runTx.ts | 8 ++++---- 4 files changed, 18 insertions(+), 31 deletions(-) diff --git a/lib/evm/eei.ts b/lib/evm/eei.ts index f2d429626d..aea15fa3d3 100644 --- a/lib/evm/eei.ts +++ b/lib/evm/eei.ts @@ -33,7 +33,6 @@ export interface Env { export interface RunResult { logs: any // TODO: define type for Log (each log: [Buffer(address), [Buffer(topic0), ...]]) returnValue?: Buffer - gasRefund: BN /** * A map from the accounts that have self-destructed to the addresses to send their funds to */ @@ -67,7 +66,6 @@ export default class EEI { this._result = { logs: [], returnValue: undefined, - gasRefund: new BN(0), selfdestruct: {}, } } @@ -90,7 +88,7 @@ export default class EEI { * @param amount - Amount of gas refunded */ refundGas(amount: BN): void { - this._result.gasRefund.iadd(amount) + this._evm._refund.iadd(amount) } /** @@ -98,9 +96,9 @@ export default class EEI { * @param amount - Amount to subtract from gas refunds */ subRefund(amount: BN): void { - this._result.gasRefund.isub(amount) - if (this._result.gasRefund.ltn(0)) { - this._result.gasRefund = new BN(0) + this._evm._refund.isub(amount) + if (this._evm._refund.ltn(0)) { + this._evm._refund = new BN(0) trap(ERROR.REFUND_EXHAUSTED) } } @@ -354,9 +352,7 @@ export default class EEI { async _selfDestruct(toAddress: Buffer): Promise { // only add to refund if this is the first selfdestruct for the address if (!this._result.selfdestruct[this._env.address.toString('hex')]) { - this._result.gasRefund = this._result.gasRefund.addn( - this._common.param('gasPrices', 'selfdestructRefund'), - ) + this.refundGas(new BN(this._common.param('gasPrices', 'selfdestructRefund'))) } this._result.selfdestruct[this._env.address.toString('hex')] = toAddress @@ -491,11 +487,6 @@ export default class EEI { this._result.logs = this._result.logs.concat(results.execResult.logs) } - // add gasRefund - if (results.execResult.gasRefund) { - this._result.gasRefund = this._result.gasRefund.add(results.execResult.gasRefund) - } - // this should always be safe this.useGas(results.gasUsed) @@ -553,11 +544,6 @@ export default class EEI { this._result.logs = this._result.logs.concat(results.execResult.logs) } - // add gasRefund - if (results.execResult.gasRefund) { - this._result.gasRefund = this._result.gasRefund.add(results.execResult.gasRefund) - } - // this should always be safe this.useGas(results.gasUsed) diff --git a/lib/evm/evm.ts b/lib/evm/evm.ts index 80a1a6490c..d7811d9eec 100644 --- a/lib/evm/evm.ts +++ b/lib/evm/evm.ts @@ -61,10 +61,6 @@ export interface ExecResult { * Array of logs that the contract emitted */ logs?: any[] - /** - * Amount of gas to refund from deleting storage values - */ - gasRefund?: BN /** * A map from the accounts that have self-destructed to the addresses to send their funds to */ @@ -96,12 +92,17 @@ export default class EVM { _state: PStateManager _tx: TxContext _block: any + /** + * Amount of gas to refund from deleting storage values + */ + _refund: BN constructor(vm: any, txContext: TxContext, block: any) { this._vm = vm this._state = this._vm.pStateManager this._tx = txContext this._block = block + this._refund = new BN(0) } /** @@ -289,6 +290,7 @@ export default class EVM { eei._result.selfdestruct = message.selfdestruct } + const oldRefund = this._refund.clone() const interpreter = new Interpreter(this._vm, eei) const interpreterRes = await interpreter.run(message.code as Buffer, opts) @@ -303,9 +305,10 @@ export default class EVM { result = { ...result, logs: [], - gasRefund: new BN(0), selfdestruct: {}, } + // Revert gas refund if message failed + this._refund = oldRefund } return { diff --git a/lib/evm/opFns.ts b/lib/evm/opFns.ts index 5bdb839b0c..2458d4d9c3 100644 --- a/lib/evm/opFns.ts +++ b/lib/evm/opFns.ts @@ -959,9 +959,7 @@ function updateSstoreGas(runState: RunState, found: any, value: Buffer) { // If original value is not 0 if (current.length === 0) { // If current value is 0 (also means that new value is not 0), remove 15000 gas from refund counter. We can prove that refund counter will never go below 0. - runState.eei._result.gasRefund.isub( - new BN(runState._common.param('gasPrices', 'netSstoreClearRefund')), - ) + runState.eei.subRefund(new BN(runState._common.param('gasPrices', 'netSstoreClearRefund'))) } else if (value.length === 0) { // If new value is 0 (also means that current value is not 0), add 15000 gas to refund counter. runState.eei.refundGas(new BN(runState._common.param('gasPrices', 'netSstoreClearRefund'))) diff --git a/lib/runTx.ts b/lib/runTx.ts index cdf432983e..87d56ea97f 100644 --- a/lib/runTx.ts +++ b/lib/runTx.ts @@ -154,10 +154,10 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { // Caculate the total gas used results.gasUsed = results.gasUsed.add(basefee) // Process any gas refund - results.gasRefund = results.execResult.gasRefund - if (results.gasRefund) { - if (results.gasRefund.lt(results.gasUsed.divn(2))) { - results.gasUsed.isub(results.gasRefund) + const gasRefund = evm._refund + if (gasRefund) { + if (gasRefund.lt(results.gasUsed.divn(2))) { + results.gasUsed.isub(gasRefund) } else { results.gasUsed.isub(results.gasUsed.divn(2)) } From b0d71f0fd2e359083271b6918e6451d6daf3f574 Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Mon, 11 Nov 2019 14:21:51 +0100 Subject: [PATCH 05/15] Skip zero storage slots read from state tests --- tests/util.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/util.js b/tests/util.js index f7039f5002..09ca228a37 100644 --- a/tests/util.js +++ b/tests/util.js @@ -370,8 +370,11 @@ exports.setupPreConditions = function (state, testData, done) { var keys = Object.keys(acctData.storage) async.forEachSeries(keys, function (key, cb3) { - var val = acctData.storage[key] - val = rlp.encode(Buffer.from(val.slice(2), 'hex')) + const valBN = new BN(acctData.storage[key].slice(2), 16) + if (valBN.isZero()) { + return cb3() + } + let val = rlp.encode(valBN.toArrayLike(Buffer, 'be')) key = utils.setLength(Buffer.from(key.slice(2), 'hex'), 32) storageTrie.put(key, val, cb3) From 29f14fb3c92311c0033379da1f728a2dcce55736 Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Mon, 11 Nov 2019 15:43:53 +0100 Subject: [PATCH 06/15] Clone refund counter in EVMResult, fix eip-2200 api tests --- lib/evm/evm.ts | 5 +++++ tests/api/istanbul/eip-2200.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/evm/evm.ts b/lib/evm/evm.ts index d7811d9eec..421c6284f6 100644 --- a/lib/evm/evm.ts +++ b/lib/evm/evm.ts @@ -34,6 +34,10 @@ export interface EVMResult { * Contains the results from running the code, if any, as described in [[runCode]] */ execResult: ExecResult + /** + * Amount of gas to refund from deleting storage values + */ + gasRefund?: BN } /** @@ -121,6 +125,7 @@ export default class EVM { } else { result = await this._executeCreate(message) } + result.gasRefund = this._refund.clone() const err = result.execResult.exceptionError if (err) { diff --git a/tests/api/istanbul/eip-2200.js b/tests/api/istanbul/eip-2200.js index 840c3bf1a6..f72a88c590 100644 --- a/tests/api/istanbul/eip-2200.js +++ b/tests/api/istanbul/eip-2200.js @@ -58,7 +58,7 @@ tape('Istanbul: EIP-2200: net-metering SSTORE', async (t) => { t.assert(res.execResult.exceptionError === undefined) } t.assert(new BN(testCase.used).eq(res.gasUsed)) - t.assert(new BN(testCase.refund).eq(res.execResult.gasRefund)) + t.assert(new BN(testCase.refund).eq(res.gasRefund)) } catch (e) { t.fail(e.message) } From 1b5538e22f0776f15dfb1de4d89a80cc1c22ff86 Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Mon, 11 Nov 2019 17:18:18 +0100 Subject: [PATCH 07/15] Fix blake2f precompile for rounds > 0x4000000 --- lib/evm/precompiles/09-blake2f.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/evm/precompiles/09-blake2f.ts b/lib/evm/precompiles/09-blake2f.ts index d502cddea1..5b87233d5b 100644 --- a/lib/evm/precompiles/09-blake2f.ts +++ b/lib/evm/precompiles/09-blake2f.ts @@ -404,7 +404,7 @@ export default function(opts: PrecompileInput): ExecResult { const f = lastByte === 1 const gasUsed = new BN(opts._common.param('gasPrices', 'blake2Round')) - gasUsed.imuln(rounds) + gasUsed.imul(new BN(rounds)) if (opts.gasLimit.lt(gasUsed)) { return OOGResult(opts.gasLimit) } From 7776c0638645b6a871d46cf6be0fc47a87026eea Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Mon, 11 Nov 2019 17:19:17 +0100 Subject: [PATCH 08/15] Mark CALLBlake2f_MaxRounds as a slow test --- tests/tester.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/tester.js b/tests/tester.js index 8f7c5cbf06..83393bae0f 100755 --- a/tests/tester.js +++ b/tests/tester.js @@ -51,7 +51,8 @@ const skipSlow = [ 'static_Callcode50000', // slow 'static_Return50000', // slow 'static_Return50000_2', // slow - 'QuadraticComplexitySolidity_CallDataCopy' + 'QuadraticComplexitySolidity_CallDataCopy', + 'CALLBlake2f_MaxRounds' ] /* From c3e1ccfbbfc82124b81a758fef0d6a3929e0fd93 Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Wed, 13 Nov 2019 16:00:25 +0100 Subject: [PATCH 09/15] Fix issues causing RevertPrecompiled* test failures --- lib/evm/eei.ts | 4 ---- lib/evm/evm.ts | 11 +---------- lib/evm/precompiles/index.ts | 5 +++-- lib/state/stateManager.ts | 23 +++++++++++++++++++++-- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/lib/evm/eei.ts b/lib/evm/eei.ts index aea15fa3d3..ac42280f29 100644 --- a/lib/evm/eei.ts +++ b/lib/evm/eei.ts @@ -161,10 +161,6 @@ export default class EEI { * input data passed with the message call instruction or transaction. */ getCallDataSize(): BN { - if (this._env.callData.length === 1 && this._env.callData[0] === 0) { - return new BN(0) - } - return new BN(this._env.callData.length) } diff --git a/lib/evm/evm.ts b/lib/evm/evm.ts index 421c6284f6..bb0b40ab7b 100644 --- a/lib/evm/evm.ts +++ b/lib/evm/evm.ts @@ -10,7 +10,7 @@ import { import Account from 'ethereumjs-account' import { ERROR, VmError } from '../exceptions' import PStateManager from '../state/promisified' -import { getPrecompile, PrecompileFunc } from './precompiles' +import { getPrecompile, PrecompileFunc, ripemdPrecompileAddress } from './precompiles' import TxContext from './txContext' import Message from './message' import EEI from './eei' @@ -131,15 +131,6 @@ export default class EVM { if (err) { result.execResult.logs = [] await this._state.revert() - if (message.isCompiled) { - // Empty precompiled contracts need to be deleted even in case of OOG - // because the bug in both Geth and Parity led to deleting RIPEMD precompiled in this case - // see https://github.com/ethereum/go-ethereum/pull/3341/files#diff-2433aa143ee4772026454b8abd76b9dd - // We mark the account as touched here, so that is can be removed among other touched empty accounts (after tx finalization) - if (err.error === ERROR.OUT_OF_GAS) { - await this._touchAccount(message.to) - } - } } else { await this._state.commit() } diff --git a/lib/evm/precompiles/index.ts b/lib/evm/precompiles/index.ts index 4a3588f41e..1e95c6b613 100644 --- a/lib/evm/precompiles/index.ts +++ b/lib/evm/precompiles/index.ts @@ -13,10 +13,11 @@ interface Precompiles { [key: string]: PrecompileFunc } +const ripemdPrecompileAddress = '0000000000000000000000000000000000000003' const precompiles: Precompiles = { '0000000000000000000000000000000000000001': p1, '0000000000000000000000000000000000000002': p2, - '0000000000000000000000000000000000000003': p3, + [ripemdPrecompileAddress]: p3, '0000000000000000000000000000000000000004': p4, '0000000000000000000000000000000000000005': p5, '0000000000000000000000000000000000000006': p6, @@ -29,4 +30,4 @@ function getPrecompile(address: string): PrecompileFunc { return precompiles[address] } -export { precompiles, getPrecompile, PrecompileFunc, PrecompileInput } +export { precompiles, getPrecompile, PrecompileFunc, PrecompileInput, ripemdPrecompileAddress } diff --git a/lib/state/stateManager.ts b/lib/state/stateManager.ts index bc742f5c37..8b68dcc09f 100644 --- a/lib/state/stateManager.ts +++ b/lib/state/stateManager.ts @@ -8,6 +8,7 @@ import Common from 'ethereumjs-common' import { genesisStateByName } from 'ethereumjs-common/dist/genesisStates' import Account from 'ethereumjs-account' import Cache from './cache' +import { ripemdPrecompileAddress } from '../evm/precompiles' /** * Storage values of an account @@ -102,11 +103,22 @@ export default class StateManager { // if (toAccount.balance.toString('hex') === '00') { // if they have money or a non-zero nonce or code, then write to tree this._cache.put(address, account) - this._touched.add(address.toString('hex')) + this.touchAccount(address) // self._trie.put(addressHex, account.serialize(), cb) cb() } + /** + * Marks an account as touched, according to the definition + * in [EIP-158](https://github.com/ethereum/EIPs/issues/158). + * This happens when the account is triggered for a state-changing + * event. Touched accounts that are empty will be cleared + * at the end of the tx. + */ + touchAccount(address: Buffer): void { + this._touched.add(address.toString('hex')) + } + /** * Adds `value` to the state trie as code, and sets `codeHash` on the account * corresponding to `address` to reference this. @@ -275,7 +287,7 @@ export default class StateManager { const contract = this._cache.get(address) contract.stateRoot = storageTrie.root this.putAccount(address, contract, cb) - this._touched.add(address.toString('hex')) + this.touchAccount(address) }) }) } @@ -372,6 +384,13 @@ export default class StateManager { if (!touched) { throw new Error('Reverting to invalid state checkpoint failed') } + // Exceptional case due to consensus issue in Geth and Parity. + // See [EIP-716](https://github.com/ethereum/EIPs/issues/716) for context. + // The RIPEMD precompile has to remain *touched* even when the call reverts, + // and be considered for deletion. + if (this._touched.has(ripemdPrecompileAddress)) { + touched.add(ripemdPrecompileAddress) + } this._touched = touched this._checkpointCount-- From b26f15cd8dc9eba5eac618f34df7c6987d9a599b Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Fri, 15 Nov 2019 10:51:44 +0100 Subject: [PATCH 10/15] Update ethereumjs-block to v2.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e7ec6c62d1..ae9366c624 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "async-eventemitter": "^0.2.2", "core-js-pure": "^3.0.1", "ethereumjs-account": "^3.0.0", - "ethereumjs-block": "~2.2.0", + "ethereumjs-block": "^2.2.1", "ethereumjs-blockchain": "^4.0.1", "ethereumjs-common": "^1.3.2", "ethereumjs-tx": "^2.1.1", From b9ebe69f54f34e1e509bb2870d83e1dcca072ecc Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Fri, 15 Nov 2019 11:15:07 +0100 Subject: [PATCH 11/15] Mark randomStatetest94_Istanbul as slow --- tests/tester.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/tester.js b/tests/tester.js index 83393bae0f..f920cb22ff 100755 --- a/tests/tester.js +++ b/tests/tester.js @@ -52,7 +52,8 @@ const skipSlow = [ 'static_Return50000', // slow 'static_Return50000_2', // slow 'QuadraticComplexitySolidity_CallDataCopy', - 'CALLBlake2f_MaxRounds' + 'CALLBlake2f_MaxRounds', + 'randomStatetest94_Istanbul' ] /* From a29de25b6210da80cabf583db1c2f6f5c1b4068c Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Fri, 15 Nov 2019 11:28:38 +0100 Subject: [PATCH 12/15] Point ethereumjs-testing dependency to v1.3.0 tag --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ae9366c624..e8c4ed49d0 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "@types/node": "^11.13.4", "browserify": "^16.2.3", "coveralls": "^3.0.0", - "ethereumjs-testing": "git+https://github.com/ethereumjs/ethereumjs-testing.git#istanbul-tests", + "ethereumjs-testing": "git+https://github.com/ethereumjs/ethereumjs-testing.git#v1.3.0", "husky": "^2.1.0", "karma": "^4.0.1", "karma-browserify": "^6.0.0", From 18b34f93ee33f386ef2107373629c063d07d865d Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Fri, 15 Nov 2019 15:16:21 +0100 Subject: [PATCH 13/15] Limit ethereumjs-util to ~6.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e8c4ed49d0..590bac0631 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "ethereumjs-blockchain": "^4.0.1", "ethereumjs-common": "^1.3.2", "ethereumjs-tx": "^2.1.1", - "ethereumjs-util": "^6.1.0", + "ethereumjs-util": "~6.1.0", "fake-merkle-patricia-tree": "^1.0.1", "functional-red-black-tree": "^1.0.1", "merkle-patricia-tree": "^2.3.2", From 57d7483fade4c75f710bf5084f98a4b85552ec74 Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Mon, 18 Nov 2019 11:24:56 +0100 Subject: [PATCH 14/15] Fix common mismatch in VM api tests --- package.json | 2 +- tests/api/index.js | 8 ++++---- tests/api/utils.js | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 590bac0631..fa1f278fb3 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "core-js-pure": "^3.0.1", "ethereumjs-account": "^3.0.0", "ethereumjs-block": "^2.2.1", - "ethereumjs-blockchain": "^4.0.1", + "ethereumjs-blockchain": "^4.0.2", "ethereumjs-common": "^1.3.2", "ethereumjs-tx": "^2.1.1", "ethereumjs-util": "~6.1.0", diff --git a/tests/api/index.js b/tests/api/index.js index 767784ad1e..252977e747 100644 --- a/tests/api/index.js +++ b/tests/api/index.js @@ -87,8 +87,8 @@ tape('VM with blockchain', (t) => { t.test('should run blockchain with mocked runBlock', async (st) => { const vm = setupVM({ chain: 'goerli' }) - const genesis = new Block(Buffer.from(testData.genesisRLP.slice(2), 'hex')) - const block = new Block(Buffer.from(testData.blocks[0].rlp.slice(2), 'hex')) + const genesis = new Block(Buffer.from(testData.genesisRLP.slice(2), 'hex'), { common: vm._common }) + const block = new Block(Buffer.from(testData.blocks[0].rlp.slice(2), 'hex'), { common: vm._common }) await putGenesisP(vm.blockchain, genesis) st.equal(vm.blockchain.meta.genesis.toString('hex'), testData.genesisBlockHeader.hash.slice(2)) @@ -114,8 +114,8 @@ tape('VM with blockchain', (t) => { t.test('should run blockchain with blocks', async (st) => { const vm = setupVM({ chain: 'goerli' }) - const genesis = new Block(Buffer.from(testData.genesisRLP.slice(2), 'hex')) - const block = new Block(Buffer.from(testData.blocks[0].rlp.slice(2), 'hex')) + const genesis = new Block(Buffer.from(testData.genesisRLP.slice(2), 'hex'), { common: vm._common }) + const block = new Block(Buffer.from(testData.blocks[0].rlp.slice(2), 'hex'), { common: vm._common }) await putGenesisP(vm.blockchain, genesis) st.equal(vm.blockchain.meta.genesis.toString('hex'), testData.genesisBlockHeader.hash.slice(2)) diff --git a/tests/api/utils.js b/tests/api/utils.js index 64717f2a19..9499130918 100644 --- a/tests/api/utils.js +++ b/tests/api/utils.js @@ -25,6 +25,8 @@ function setupVM (opts = {}) { const db = level() opts.blockchain = opts.blockchain ? opts.blockchain : new Blockchain({ db, validate: false }) const vm = new VM(opts) + vm.blockchain._common = vm._common + vm.blockchain.dbManager._common = vm._common return vm } From 970ddbfe082a74ef397083f62de177eb2fd84a78 Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Mon, 18 Nov 2019 13:11:34 +0100 Subject: [PATCH 15/15] Re-add gasRefund to ExecResult for backwards-compatibility --- lib/evm/evm.ts | 12 +++++++----- tests/api/istanbul/eip-2200.js | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/evm/evm.ts b/lib/evm/evm.ts index bb0b40ab7b..5c7eca392e 100644 --- a/lib/evm/evm.ts +++ b/lib/evm/evm.ts @@ -34,10 +34,6 @@ export interface EVMResult { * Contains the results from running the code, if any, as described in [[runCode]] */ execResult: ExecResult - /** - * Amount of gas to refund from deleting storage values - */ - gasRefund?: BN } /** @@ -69,6 +65,10 @@ export interface ExecResult { * A map from the accounts that have self-destructed to the addresses to send their funds to */ selfdestruct?: { [k: string]: Buffer } + /** + * Total amount of gas to be refunded from all nested calls. + */ + gasRefund?: BN } export interface NewContractEvent { @@ -125,7 +125,9 @@ export default class EVM { } else { result = await this._executeCreate(message) } - result.gasRefund = this._refund.clone() + // TODO: Move `gasRefund` to a tx-level result object + // instead of `ExecResult`. + result.execResult.gasRefund = this._refund.clone() const err = result.execResult.exceptionError if (err) { diff --git a/tests/api/istanbul/eip-2200.js b/tests/api/istanbul/eip-2200.js index f72a88c590..840c3bf1a6 100644 --- a/tests/api/istanbul/eip-2200.js +++ b/tests/api/istanbul/eip-2200.js @@ -58,7 +58,7 @@ tape('Istanbul: EIP-2200: net-metering SSTORE', async (t) => { t.assert(res.execResult.exceptionError === undefined) } t.assert(new BN(testCase.used).eq(res.gasUsed)) - t.assert(new BN(testCase.refund).eq(res.gasRefund)) + t.assert(new BN(testCase.refund).eq(res.execResult.gasRefund)) } catch (e) { t.fail(e.message) }