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 26, 2019
1 parent c3d7a57 commit 800920c
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 3 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
7 changes: 4 additions & 3 deletions lib/evm/opcodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const codes: any = {

// 0x30 range - closure state
0x30: ['ADDRESS', 2, true],
0x31: ['BALANCE', 400, true, true],
0x31: ['BALANCE', 700, true, true],
0x32: ['ORIGIN', 2, true],
0x33: ['CALLER', 2, true],
0x34: ['CALLVALUE', 2, true],
Expand All @@ -57,7 +57,7 @@ const codes: any = {
0x3c: ['EXTCODECOPY', 700, true, true],
0x3d: ['RETURNDATASIZE', 2, true],
0x3e: ['RETURNDATACOPY', 3, true],
0x3f: ['EXTCODEHASH', 400, true, true],
0x3f: ['EXTCODEHASH', 700, true, true],

// '0x40' range - block operations
0x40: ['BLOCKHASH', 20, true, true],
Expand All @@ -67,13 +67,14 @@ const codes: any = {
0x44: ['DIFFICULTY', 2, true],
0x45: ['GASLIMIT', 2, true],
0x46: ['CHAINID', 2, false],
0x47: ['SELFBALANCE', 5, false],

// 0x50 range - 'storage' and execution
0x50: ['POP', 2, false],
0x51: ['MLOAD', 3, false],
0x52: ['MSTORE', 3, false],
0x53: ['MSTORE8', 3, false],
0x54: ['SLOAD', 200, true, true],
0x54: ['SLOAD', 800, true, true],
0x55: ['SSTORE', 0, true, true],
0x56: ['JUMP', 8, false],
0x57: ['JUMPI', 10, false],
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 800920c

Please sign in to comment.