Skip to content

Commit

Permalink
Add EIP-1884 support for Istanbul
Browse files Browse the repository at this point in the history
  • Loading branch information
s1na committed Aug 29, 2019
1 parent edffcde commit 56350e1
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 0 deletions.
7 changes: 7 additions & 0 deletions lib/evm/eei.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@ export default class EEI {
return new BN(account.balance)
}

/**
* Returns balance of self.
*/
getSelfBalance(): BN {
return new BN(this._env.contract.balance)
}

/**
* Returns caller address. This is the address of the account
* that is directly responsible for this execution.
Expand Down
7 changes: 7 additions & 0 deletions lib/evm/opFns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,13 @@ export const handlers: { [k: string]: OpHandler } = {

runState.stack.push(runState.eei.getChainId())
},
SELFBALANCE: function(runState: RunState) {
if (!runState._common.gteHardfork('istanbul')) {
trap(ERROR.INVALID_OPCODE)
}

runState.stack.push(runState.eei.getSelfBalance())
},
// 0x50 range - 'storage' and execution
POP: function(runState: RunState) {
runState.stack.pop()
Expand Down
4 changes: 4 additions & 0 deletions lib/evm/opcodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,11 @@ let codes: any = {
}

const istanbulOpcodes: any = {
0x31: ['BALANCE', 700, true],
0x3f: ['EXTCODEHASH', 700, true],
0x46: ['CHAINID', 2, false],
0x47: ['SELFBALANCE', 5, false],
0x54: ['SLOAD', 800, true],
}

export function setOpcodes(hf: string) {
Expand Down
44 changes: 44 additions & 0 deletions tests/api/istanbul/eip-1884.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const tape = require('tape')
const BN = require('bn.js')
const Common = require('ethereumjs-common').default
const VM = require('../../../dist/index').default
const PStateManager = require('../../../dist/state/promisified').default
const { ERROR } = require('../../../dist/exceptions')
const { createAccount } = require('../utils')

const testCases = [
{ chain: 'mainnet', hardfork: 'istanbul', selfbalance: '0xf1' },
{ chain: 'mainnet', hardfork: 'constantinople', err: ERROR.INVALID_OPCODE }
]

// SELFBALANCE PUSH8 0x00 MSTORE8 PUSH8 0x01 PUSH8 0x00 RETURN
const code = ['47', '60', '00', '53', '60', '01', '60', '00', 'f3']
tape('Istanbul: EIP-1884: SELFBALANCE', async (t) => {
const addr = Buffer.from('00000000000000000000000000000000000000ff', 'hex')
const runCodeArgs = {
code: Buffer.from(code.join(''), 'hex'),
gasLimit: new BN(0xffff),
address: addr
}

for (const testCase of testCases) {
const common = new Common(testCase.chain, testCase.hardfork)
const vm = new VM({ common })
const state = new PStateManager(vm.stateManager)
const account = createAccount('00', testCase.selfbalance)
await state.putAccount(addr, account)
try {
const res = await vm.runCode(runCodeArgs)
if (testCase.err) {
t.equal(res.exceptionError.error, testCase.err)
} else {
t.assert(res.exceptionError === undefined)
t.assert(new BN(Buffer.from(testCase.selfbalance.slice(2), 'hex')).eq(new BN(res.returnValue)))
}
} catch (e) {
t.fail(e.message)
}
}

t.end()
})

0 comments on commit 56350e1

Please sign in to comment.