Skip to content

Commit

Permalink
Add evm call script tests
Browse files Browse the repository at this point in the history
  • Loading branch information
izqui committed Oct 23, 2017
1 parent 240af20 commit dac3013
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 3 deletions.
68 changes: 68 additions & 0 deletions test/evm_call_script.js
@@ -0,0 +1,68 @@
const { assertInvalidOpcode } = require('./helpers/assertThrow')
const { encodeScript } = require('./helpers/evmScript')
const ExecutionTarget = artifacts.require('ExecutionTarget')
const Executor = artifacts.require('Executor')

contract('EVM call script', accounts => {
let executor, executionTarget = {}

before(async () => {
executor = await Executor.new()
})

beforeEach(async () => {
executionTarget = await ExecutionTarget.new()
})

it('executes single action script', async () => {
const action = { to: executionTarget.address, calldata: executionTarget.contract.execute.getData() }
const script = encodeScript([action])

await executor.execute(script)

assert.equal(await executionTarget.counter(), 1, 'should have executed action')
})

it('executes multi action script', async () => {
const action = { to: executionTarget.address, calldata: executionTarget.contract.execute.getData() }
const script = encodeScript([action, action, action, action])

await executor.execute(script)

assert.equal(await executionTarget.counter(), 4, 'should have executed action')
})

it('executes multi action script to multiple addresses', async () => {
const executionTarget2 = await ExecutionTarget.new()

const action = { to: executionTarget.address, calldata: executionTarget.contract.execute.getData() }
const action2 = { to: executionTarget2.address, calldata: executionTarget2.contract.execute.getData() }

const script = encodeScript([action2, action, action2, action, action2])

await executor.execute(script)

assert.equal(await executionTarget.counter(), 2, 'should have executed action')
assert.equal(await executionTarget2.counter(), 3, 'should have executed action')
})

it('executes with parameters', async () => {
const action = { to: executionTarget.address, calldata: executionTarget.contract.setCounter.getData(101) }
const script = encodeScript([action])

await executor.execute(script)

assert.equal(await executionTarget.counter(), 101, 'should have set counter')
})

it('execution fails if one call fails', async () => {
const action1 = { to: executionTarget.address, calldata: executionTarget.contract.setCounter.getData(101) }
const action2 = { to: executionTarget.address, calldata: executionTarget.contract.failExecute.getData() }

const script = encodeScript([action1, action2])

return assertInvalidOpcode(async () => {
await executor.execute(script)
})
})
})
15 changes: 15 additions & 0 deletions test/helpers/evmScript.js
@@ -0,0 +1,15 @@
const abi = require('ethereumjs-abi')

module.exports = {
// Encodes an array of actions ({ to: address, calldata: bytes}) into the EVM script format
// Concatenates [ 20 bytes (address) ] + [ 4 bytes (uint32: calldata length) ] + [ calldataLength bytes (payload) ]
encodeScript: actions => {
return actions.reduce((script, { to, calldata }) => {
const addr = abi.rawEncode(['address'], [to]).toString('hex')
const length = abi.rawEncode(['uint256'], [(calldata.length - 2) / 2]).toString('hex')

// Remove 12 first 0s of padding for addr and 28 0s for uint32
return script + addr.slice(24) + length.slice(56) + calldata.slice(2)
}, '0x')
}
}
3 changes: 0 additions & 3 deletions test/kernel_upgrade.js
Expand Up @@ -2,9 +2,6 @@ const { assertInvalidOpcode } = require('./helpers/assertThrow')
const Kernel = artifacts.require('Kernel')
const KernelProxy = artifacts.require('KernelProxy')
const UpgradedKernel = artifacts.require('UpgradedKernel')
const { getBlockNumber } = require('./helpers/web3')

const getSig = x => web3.sha3(x).slice(0, 10)

contract('Kernel Upgrade', accounts => {
let kernel = {}
Expand Down
20 changes: 20 additions & 0 deletions test/mocks/ExecutionTarget.sol
@@ -0,0 +1,20 @@
pragma solidity 0.4.15;

contract ExecutionTarget {
uint public counter;

function execute() {
counter += 1;
Executed(counter);
}

function failExecute() {
revert();
}

function setCounter(uint x) {
counter = x;
}

event Executed(uint x);
}
17 changes: 17 additions & 0 deletions test/mocks/Executor.sol
@@ -0,0 +1,17 @@
pragma solidity 0.4.15;

import "../../contracts/common/EVMCallScript.sol";

contract Executor is EVMCallScriptRunner, EVMCallScriptDecoder {
function execute(bytes script) {
runScript(script);
}

function getActionsCount(bytes script) constant returns (uint256) {
return getScriptActionsCount(script);
}

function getAction(bytes script, uint256 i) constant returns (address, bytes) {
return getScriptAction(script, i);
}
}

0 comments on commit dac3013

Please sign in to comment.