diff --git a/lib/hooked.js b/lib/hooked.js index dc3882a4d5..a665e00f22 100644 --- a/lib/hooked.js +++ b/lib/hooked.js @@ -17,6 +17,7 @@ module.exports.fromWeb3Provider = fromWeb3Provider ```js var vm = createHookedVm({ enableHomestead: true, + enableHomesteadReprice: true }, { fetchAccountBalance: function(addressHex, cb){ ... }, fetchAccountNonce: function(addressHex, cb){ ... }, diff --git a/lib/index.js b/lib/index.js index c2321edebc..3e0d57fd31 100644 --- a/lib/index.js +++ b/lib/index.js @@ -25,6 +25,7 @@ VM.deps = { * @param {Blockchain} [opts.blockchain] A blockchain object for storing/retrieving blocks * @param {Boolean} [opts.activatePrecompiles] Create entries in the state tree for the precompiled contracts * @param {Boolean} [opts.enableHomestead] Force enable Homestead irrelevant to block number + * @param {Boolean} [opts.enableHomesteadReprice] Force enable Homestead Reprice (EIP150) irrevelant to block number */ function VM (opts = {}) { this.stateManager = new StateManager({ diff --git a/lib/opFns.js b/lib/opFns.js index 9ca3ba7e3c..b60d46ccd7 100644 --- a/lib/opFns.js +++ b/lib/opFns.js @@ -549,6 +549,8 @@ module.exports = { checkCallMemCost(runState, options, localOpts) + gasLimit = calcCallLimit(runState, gasLimit) + stateManager.exists(toAddress, function (err, exists) { if (err) { done(err) @@ -679,6 +681,12 @@ module.exports = { cb(err) return } + + if (runState.enableHomsteadReprice && !toAccount.exists) { + // can't wrap because we are in a callback + runState.gasLeft.isub(new BN(fees.callNewAccountGas.v)) + } + var newBalance = new Buffer(new BN(contract.balance).add(new BN(toAccount.balance)).toArray()) async.series([ stateManager.putAccountBalance.bind(stateManager, suicideToAddress, newBalance), @@ -877,3 +885,14 @@ function makeCall (runState, callOptions, localOpts, cb) { } } } + +function calcCallLimit (runState, gas) { + if (!runState.enableHomesteadReprice) { + return gas + } + + // div should round down + const max = runState.gasLimit.sub(runState.gasLimit.div(64)) + + return BN.min(gas, max) +} diff --git a/lib/runCall.js b/lib/runCall.js index fe891d953e..31f9cca45c 100644 --- a/lib/runCall.js +++ b/lib/runCall.js @@ -43,6 +43,7 @@ module.exports = function (opts, cb) { var depth = opts.depth var suicides = opts.suicides var enableHomestead = this.opts.enableHomestead === undefined ? block.isHomestead() : this.opts.enableHomestead + var enableHomesteadReprice = this.opts.enableHomesteadReprice === undefined ? block.isHomesteadReprice() : this.opts.enableHomesteadReprice txValue = new BN(txValue) diff --git a/lib/runCode.js b/lib/runCode.js index 0821baeab2..568bd3538b 100644 --- a/lib/runCode.js +++ b/lib/runCode.js @@ -73,6 +73,7 @@ module.exports = function (opts, cb) { code: opts.code, populateCache: opts.populateCache === undefined ? true : opts.populateCache, enableHomestead: this.opts.enableHomestead === undefined ? block.isHomestead() : this.opts.enableHomestead // this == vm + enableHomesteadReprice: this.opts.enableHomesteadReprice === undefined ? block.isHomesteadReprice() : this.opts.enableHomesteadReprice // this == vm } // temporary - to be factored out diff --git a/lib/runTx.js b/lib/runTx.js index 659e54e992..6955beea2e 100644 --- a/lib/runTx.js +++ b/lib/runTx.js @@ -27,10 +27,6 @@ module.exports = function (opts, cb) { block = new Block() } - if (this.opts.enableHomestead) { - tx._homestead = true - } - if (new BN(block.header.gasLimit).cmp(new BN(tx.gasLimit)) === -1) { cb(new Error('tx has a higher gas limit than the block')) return