Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP150 - Part II #129

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9a99da0
Remove unused _homestead flag
axic Oct 24, 2016
20237e0
Add homesteadReprice option
axic Oct 24, 2016
b7555d9
Implement EIP150.1c (suicide new account cost)
axic Oct 24, 2016
4bedff2
Implement EIP150.1b (all but 64th rule)
axic Oct 26, 2016
abf9a4b
Increase gas baseCosts for EIP150
sdtsui Jun 25, 2017
3ebd670
Improve comments in runTx
sdtsui Jun 25, 2017
3ea2dab
Change gas baseCost to finalized EIP150 spec, 700 instead of 4000
sdtsui Jun 25, 2017
716b6a9
Add gasLimit to CREATE and CALL opFns
sdtsui Jun 25, 2017
70c5c6a
Merge ethereumjs/master
sdtsui Jun 29, 2017
f6aaf58
Resolve conflicts, bump FORK_CONFIG, bump ethereumjs-testing version
sdtsui Jun 29, 2017
a6aa776
Merge branch 'master' of github.com:ethereumjs/ethereumjs-vm into wip…
sdtsui Jun 30, 2017
78b71fc
Remove unnecessary saved testOutput file
sdtsui Jun 30, 2017
05d950a
Separate OOG from checkCallMemCost, so EIP150 limit can be applied
sdtsui Jul 3, 2017
f75537f
Cleanup repo, remove support for flags in calcCallLimit
sdtsui Jul 3, 2017
c89d971
Merge branch 'master' of github.com:ethereumjs/ethereumjs-vm into wip…
sdtsui Jul 3, 2017
bfc8547
Fix application of stipend in CALL
sdtsui Jul 4, 2017
15bb68c
Fix from @inclu-media for checkOutOfGas - 335 failing tests
sdtsui Jul 4, 2017
f6480d3
Fix callcall_00_OOGE test with @cdetrio
sdtsui Jul 5, 2017
8d88af4
Cleanup, remove commented code
sdtsui Jul 5, 2017
7348526
Add @inclu-media\'s use of BN in checkOutofGas
sdtsui Jul 5, 2017
cada821
Fixed last commit (code parts left)
Jul 5, 2017
631bcdf
fix some initializations, validate results return length
hugo-dc Jul 6, 2017
5b91938
Removed double-run of checkCallMemCost/checkOutOfGas in CREATE opcode…
Jul 7, 2017
1b6b709
fixed refund handling in SUICIDE
inclu-media Jul 9, 2017
8c8d7ad
subGas in CALLCODE, unnecessary stateManager call removed
inclu-media Jul 9, 2017
be256cb
Fix lint errors in opFns, runCode, and test hooks
sdtsui Jul 10, 2017
e2820a9
Removed unintentionally added package-lock.json file, added package-l…
Jul 10, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,6 @@ build/Release
# Dependency directory
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
node_modules
package-lock.json


1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
79 changes: 48 additions & 31 deletions lib/opFns.js
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ module.exports = {
}

checkCallMemCost(runState, options, localOpts)
checkOutOfGas(runState, options)
makeCall(runState, options, localOpts, done)
},
CALL: function (gasLimit, toAddress, value, inOffset, inLength, outOffset, outLength, runState, done) {
Expand All @@ -539,11 +540,8 @@ module.exports = {
outLength: outLength
}

// add stipend
if (!value.isZero()) {
runState.gasLeft.iadd(new BN(fees.callStipend.v))
subGas(runState, new BN(fees.callValueTransferGas.v))
options.gasLimit.iadd(new BN(fees.callStipend.v))
}

stateManager.exists(toAddress, function (err, exists) {
Expand All @@ -563,11 +561,17 @@ module.exports = {

try {
checkCallMemCost(runState, options, localOpts)
checkOutOfGas(runState, options)
} catch (e) {
done(e.error)
return
}

if (!value.isZero()) {
runState.gasLeft.iadd(new BN(fees.callStipend.v))
options.gasLimit.iadd(new BN(fees.callStipend.v))
}

makeCall(runState, options, localOpts, done)
})
},
Expand All @@ -594,30 +598,30 @@ module.exports = {
outLength: outLength
}

// add stipend
if (!value.isZero()) {
runState.gasLeft.isub(new BN(fees.callValueTransferGas.v)).iadd(new BN(fees.callStipend.v))
options.gasLimit.iadd(new BN(fees.callStipend.v))
subGas(runState, new BN(fees.callValueTransferGas.v))
}

checkCallMemCost(runState, options, localOpts)
checkOutOfGas(runState, options)

// load the code
stateManager.getAccount(toAddress, function (err, account) {
if (err) return done(err)
if (utils.isPrecompiled(toAddress)) {
options.compiled = true
options.code = runState._precompiled[toAddress.toString('hex')]
if (!value.isZero()) {
runState.gasLeft.iadd(new BN(fees.callStipend.v))
options.gasLimit.iadd(new BN(fees.callStipend.v))
}

if (utils.isPrecompiled(toAddress)) {
options.compiled = true
options.code = runState._precompiled[toAddress.toString('hex')]
makeCall(runState, options, localOpts, done)
} else {
stateManager.getContractCode(toAddress, function (err, code, compiled) {
if (err) return done(err)
options.code = code
options.compiled = compiled
makeCall(runState, options, localOpts, done)
} else {
stateManager.getContractCode(toAddress, function (err, code, compiled) {
if (err) return done(err)
options.code = code
options.compiled = compiled
makeCall(runState, options, localOpts, done)
})
}
})
})
}
},
DELEGATECALL: function (gas, toAddress, inOffset, inLength, outOffset, outLength, runState, done) {
var stateManager = runState.stateManager
Expand Down Expand Up @@ -645,6 +649,7 @@ module.exports = {
}

checkCallMemCost(runState, options, localOpts)
checkOutOfGas(runState, options)

// load the code
stateManager.getAccount(toAddress, function (err, account) {
Expand Down Expand Up @@ -675,20 +680,29 @@ module.exports = {
var contractAddress = runState.address
suicideToAddress = utils.setLengthLeft(suicideToAddress, 20)

// only add to refund if this is the first suicide for the address
if (!runState.suicides[contractAddress.toString('hex')]) {
runState.gasRefund = runState.gasRefund.add(new BN(fees.suicideRefundGas.v))
}

runState.suicides[contractAddress.toString('hex')] = suicideToAddress
runState.stopped = true

stateManager.getAccount(suicideToAddress, function (err, toAccount) {
// update balances
if (err) {
cb(err)
return
}

if (!toAccount.exists) {
try {
subGas(runState, new BN(fees.callNewAccountGas.v))
} catch (e) {
cb(e.error)
return
}
}

// only add to refund if this is the first suicide for the address
if (!runState.suicides[contractAddress.toString('hex')]) {
runState.gasRefund = runState.gasRefund.add(new BN(fees.suicideRefundGas.v))
}
runState.suicides[contractAddress.toString('hex')] = suicideToAddress
runState.stopped = true

var newBalance = new Buffer(new BN(contract.balance).add(new BN(toAccount.balance)).toArray())
async.series([
stateManager.putAccountBalance.bind(stateManager, suicideToAddress, newBalance),
Expand Down Expand Up @@ -813,9 +827,12 @@ function checkCallMemCost (runState, callOptions, localOpts) {
if (!callOptions.gasLimit) {
callOptions.gasLimit = runState.gasLeft
}
}

if (runState.gasLeft.cmp(callOptions.gasLimit) === -1) {
trap(ERROR.OUT_OF_GAS)
function checkOutOfGas (runState, callOptions) {
const gasAllowed = runState.gasLeft.sub(runState.gasLeft.div(new BN(64)))
if (callOptions.gasLimit.gt(gasAllowed)) {
callOptions.gasLimit = gasAllowed
}
}

Expand Down
16 changes: 8 additions & 8 deletions lib/opcodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const codes = {

// 0x30 range - closure state
0x30: ['ADDRESS', 2, 0, 1, true],
0x31: ['BALANCE', 20, 1, 1, true],
0x31: ['BALANCE', 400, 1, 1, true],
0x32: ['ORIGIN', 2, 0, 1, true],
0x33: ['CALLER', 2, 0, 1, true],
0x34: ['CALLVALUE', 2, 0, 1, true],
Expand All @@ -42,8 +42,8 @@ const codes = {
0x38: ['CODESIZE', 2, 0, 1, false],
0x39: ['CODECOPY', 3, 3, 0, false],
0x3a: ['GASPRICE', 2, 0, 1, false],
0x3b: ['EXTCODESIZE', 20, 1, 1, true],
0x3c: ['EXTCODECOPY', 20, 4, 0, true],
0x3b: ['EXTCODESIZE', 700, 1, 1, true],
0x3c: ['EXTCODECOPY', 700, 4, 0, true],

// '0x40' range - block operations
0x40: ['BLOCKHASH', 20, 1, 1, true],
Expand All @@ -58,7 +58,7 @@ const codes = {
0x51: ['MLOAD', 3, 1, 1, false],
0x52: ['MSTORE', 3, 2, 0, false],
0x53: ['MSTORE8', 3, 2, 0, false],
0x54: ['SLOAD', 50, 1, 1, true],
0x54: ['SLOAD', 200, 1, 1, true],
0x55: ['SSTORE', 0, 2, 0, true],
0x56: ['JUMP', 8, 1, 0, false],
0x57: ['JUMPI', 10, 2, 0, false],
Expand Down Expand Up @@ -143,13 +143,13 @@ const codes = {

// '0xf0' range - closures
0xf0: ['CREATE', 32000, 3, 1, true],
0xf1: ['CALL', 40, 7, 1, true],
0xf2: ['CALLCODE', 40, 7, 1, true],
0xf1: ['CALL', 700, 7, 1, true],
0xf2: ['CALLCODE', 700, 7, 1, true],
0xf3: ['RETURN', 0, 2, 0, false],
0xf4: ['DELEGATECALL', 40, 6, 1, true],
0xf4: ['DELEGATECALL', 700, 6, 1, true],

// '0x70', range - other
0xff: ['SUICIDE', 0, 1, 0, false]
0xff: ['SUICIDE', 5000, 1, 0, false]
}

module.exports = function (op, full) {
Expand Down
2 changes: 1 addition & 1 deletion lib/runCall.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ module.exports = function (opts, cb) {
var returnFee = results.return.length * fees.createDataGas.v
var totalGas = results.gasUsed.addn(returnFee)
// if not enough gas
if (totalGas.cmp(gasLimit) <= 0) {
if (totalGas.cmp(gasLimit) <= 0 && results.return.length <= 24576) {
results.gasUsed = totalGas
} else {
results.return = new Buffer([])
Expand Down
3 changes: 2 additions & 1 deletion lib/runCode.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ module.exports = function (opts, cb) {
callData: opts.data || new Buffer([0]),
code: opts.code,
populateCache: opts.populateCache === undefined ? true : opts.populateCache,
enableHomestead: this.opts.enableHomestead === undefined ? block.isHomestead() : this.opts.enableHomestead // this == vm
enableHomestead: this.opts.enableHomestead === undefined ? block.isHomestead() : this.opts.enableHomestead
}

// temporary - to be factored out
Expand Down Expand Up @@ -105,6 +105,7 @@ module.exports = function (opts, cb) {

function vmIsActive () {
var notAtEnd = runState.programCounter < runState.code.length

return !runState.stopped && notAtEnd && !runState.vmError && !runState.returnValue
}

Expand Down
19 changes: 7 additions & 12 deletions lib/runTx.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const Bloom = require('./bloom.js')
const Block = require('ethereumjs-block')

/**
* Process a transaction. Run the vm. Transfers eth. checks balaces
* Process a transaction. Run the vm. Transfers eth. Checks balances.
* @method processTx
* @param opts
* @param opts.tx {Transaction} - a transaction
Expand All @@ -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
Expand Down Expand Up @@ -70,7 +66,7 @@ module.exports = function (opts, cb) {
}

/**
* populates the cache with the two and from of the tx
* populates the cache with the 'to' and 'from' of the tx
*/
function populateCache (cb) {
var accounts = new Set()
Expand All @@ -85,10 +81,9 @@ module.exports = function (opts, cb) {
self.stateManager.warmCache(accounts, cb)
}

// sets up the envorment and runs a `call`
// sets up the environment and runs a `call`
function runCall (cb) {
// check to the sender's account to make sure it has enought wei and the
// correct nonce
// check to the sender's account to make sure it has enough wei and the correct nonce
var fromAccount = self.stateManager.cache.get(tx.from)
var message

Expand Down Expand Up @@ -141,10 +136,10 @@ module.exports = function (opts, cb) {
results.bloom = txLogsBloom(results.vm.logs)
fromAccount = self.stateManager.cache.get(tx.from)

// caculate the totall gas used
// caculate the total gas used
results.gasUsed = results.gasUsed.add(basefee)

// refund the accoun.stateManagert
// process any gas refund
var gasRefund = results.vm.gasRefund
if (gasRefund) {
if (gasRefund.cmp(results.gasUsed.divn(2)) === -1) {
Expand All @@ -155,7 +150,7 @@ module.exports = function (opts, cb) {
}

results.amountSpent = results.gasUsed.mul(new BN(tx.gasPrice))
// refund the left over gas amount
// refund the leftover gas amount
fromAccount.balance = new BN(tx.gasLimit).sub(results.gasUsed)
.mul(new BN(tx.gasPrice))
.add(new BN(fromAccount.balance))
Expand Down
10 changes: 4 additions & 6 deletions tests/GeneralStateTestsRunner.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,10 @@ function runTestCase (testData, t, cb) {
function (done) {
var tx = testUtil.makeTx(testData.transaction)
block = testUtil.makeBlockFromEnv(testData.env)
if (!block.isHomestead() && !testData.homestead) {
tx._homestead = false
} else {
block.isHomestead = function () {
return true
}
tx._homestead = true
tx.enableHomestead = true
block.isHomestead = function () {
return true
}

if (tx.validate()) {
Expand Down
3 changes: 2 additions & 1 deletion tests/hooked.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ tape('hooked-vm', function (test) {
}

var vm = createHookedVm({
enableHomestead: true
enableHomestead: true,
enableHomsteadReprice: true
}, hooksForBlockchainState(blockchainState))

// vm.on('step', function(stepData){
Expand Down
2 changes: 1 addition & 1 deletion tests/tester.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const argv = require('minimist')(process.argv.slice(2))
const async = require('async')
const tape = require('tape')
const testing = require('ethereumjs-testing')
const FORK_CONFIG = 'Homestead'
const FORK_CONFIG = 'EIP150'
const skip = [
'CreateHashCollision', // impossible hash collision on generating address
'SuicidesMixingCoinbase', // sucides to the coinbase, since we run a blockLevel we create coinbase account.
Expand Down