Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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: 1 addition & 1 deletion packages/vm/lib/evm/stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,6 @@ export default class Stack {
}

const i = this._store.length - position
this.push(this._store[i])
this.push(this._store[i].clone())
}
}
48 changes: 48 additions & 0 deletions packages/vm/tests/api/evm/stack.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const tape = require('tape')
const BN = require('bn.js')
const Stack = require('../../../dist/evm/stack').default
const VM = require('../../../dist/index').default
const { createAccount } = require('../utils')

tape('Stack', t => {
t.test('should be empty initially', st => {
Expand Down Expand Up @@ -111,4 +113,50 @@ tape('Stack', t => {
st.throws(() => s.push(max.addn(1)))
st.end()
})

t.test('stack items should not change if they are DUPed', async st => {
const caller = Buffer.from('00000000000000000000000000000000000000ee', 'hex')
const addr = Buffer.from('00000000000000000000000000000000000000ff', 'hex')
const key = new BN(0).toArrayLike(Buffer, 'be', 32)
const vm = new VM()
const account = createAccount('0x00', '0x00')
const code = "60008080808060013382F15060005260206000F3"
const expectedReturnValue = new BN(0).toArrayLike(Buffer, 'be', 32)
/*
code: remarks: (top of the stack is at the zero index)
PUSH1 0x00
DUP1
DUP1
DUP1
DUP1
PUSH1 0x01
CALLER
DUP3
CALL stack: [0, CALLER, 1, 0, 0, 0, 0, 0]
POP pop the call result (1)
PUSH1 0x00
MSTORE we now expect that the stack (prior to MSTORE) is [0, 0]
PUSH1 0x20
PUSH1 0x00
RETURN stack: [0, 0x20] (we thus return the stack item which was originally pushed as 0, and then DUPed)
*/
await vm.stateManager.putAccount(addr, account)
await vm.stateManager.putContractCode(addr, Buffer.from(code, 'hex'))
const runCallArgs = {
caller: caller,
gasLimit: new BN(0xffffffffff),
to: addr,
value: new BN(1)
}
try {
const res = await vm.runCall(runCallArgs)
const executionReturnValue = res.execResult.returnValue
st.assert(executionReturnValue.equals(expectedReturnValue))
st.end()
} catch(e) {
st.fail(e.message)
}
})


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that's great! 😄

Ah, yeah, I see what you mean ("a bit out of place"), lol 😜, but anyhow, doesn't hurt or blow things up either, at least would be my stance here on this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really see how to make it much compacter either. For now, it seems like only this gas stipend thing messes up the stack as I don't see any other potentially stack-editing operations in opFns via BN.js i* arithmetic when glancing over the file.

})