Skip to content

Commit

Permalink
Merge pull request #406 from pinkiebell/pc
Browse files Browse the repository at this point in the history
runCode.js: add `pc` to opt args | initial API tests
  • Loading branch information
holgerd77 committed Feb 12, 2019
2 parents 994556a + 46bbc10 commit 57293c6
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ Runs EVM code
- `opts.gasLimit` **[Buffer][42]** the gas limit for the code
- `opts.origin` **[Buffer][42]** the address where the call originated from. The address should be a `Buffer` of 20bits. Defaults to `0`
- `opts.value` **[Buffer][42]** the value in ether that is being sent to `opt.address`. Defaults to `0`
- `opts.pc` **[Number][32]** the initial program counter. Defaults to `0`
- `cb` **[runCode~callback][44]** callback

## Event: beforeBlock
Expand Down
9 changes: 8 additions & 1 deletion lib/runCode.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const VmError = exceptions.VmError
* @param {Buffer} opts.gasLimit the gas limit for the code
* @param {Buffer} opts.origin the address where the call originated from. The address should be a `Buffer` of 20bits. Defaults to `0`
* @param {Buffer} opts.value the value in ether that is being sent to `opt.address`. Defaults to `0`
* @param {Number} opts.pc the initial program counter. Defaults to `0`
* @param {runCode~callback} cb callback
*/

Expand Down Expand Up @@ -69,7 +70,7 @@ module.exports = function (opts, cb) {
returnValue: false,
stopped: false,
vmError: false,
programCounter: 0,
programCounter: opts.pc | 0,
opCode: undefined,
opName: undefined,
gasLeft: new BN(opts.gasLimit),
Expand Down Expand Up @@ -108,6 +109,12 @@ module.exports = function (opts, cb) {

// iterate through the given ops until something breaks or we hit STOP
function runVm (err) {
// Check that the programCounter is in range. Does not overwrite the previous err, if any.
const pc = runState.programCounter
if (!err && pc !== 0 && (pc < 0 || pc >= runState.code.length)) {
err = new VmError(ERROR.INVALID_OPCODE)
}

if (err) {
return parseVmResults(err)
}
Expand Down
58 changes: 58 additions & 0 deletions tests/api/runCode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const tape = require('tape')
const async = require('async')
const VM = require('../../lib/index')

const STOP = '00'
const JUMP = '56'
const JUMPDEST = '5b'
const PUSH1 = '60'

const testCases = [
{ code: [STOP, JUMPDEST, PUSH1, '05', JUMP, JUMPDEST], pc: 1, resultPC: 6 },
{ code: [STOP, JUMPDEST, PUSH1, '05', JUMP, JUMPDEST], pc: -1, error: 'invalid opcode' },
{ code: [STOP], pc: 3, error: 'invalid opcode' },
{ code: [STOP], resultPC: 1 }
]

tape('VM.runcode: initial program counter', function (t) {
const vm = new VM()

testCases.forEach(function (testData, i) {
t.test('should start the execution at the specified pc or 0 #' + i, function (st) {
const runCodeArgs = {
code: Buffer.from(testData.code.join(''), 'hex'),
pc: testData.pc,
gasLimit: 0xffff
}
let result

async.series([
function (done) {
vm.runCode(runCodeArgs, function (err, res) {
if (res) {
result = res
}

done(err)
})
},
function (done) {
if (testData.resultPC !== undefined) {
t.equals(result.runState.programCounter, testData.resultPC, 'runstate.programCounter')
}

done()
}
], function (err) {
if (testData.error) {
err = err ? err.error : 'no error thrown'
t.equals(err, testData.error, 'error message should match')
err = false
}

t.assert(!err)
st.end()
})
})
})
})

0 comments on commit 57293c6

Please sign in to comment.