Skip to content

Commit

Permalink
vm/evm: ensure exp dynamic gas calculated in gas.ts not functions.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
jochem-brouwer committed May 27, 2022
1 parent 5c95b1b commit 51e5582
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 13 deletions.
2 changes: 1 addition & 1 deletion packages/vm/src/evm/evm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export interface ExecResult {
/**
* Amount of gas the code used to run
*/
gasUsed: bigint
gasUsed: bigint //TODO misleading; does not cover upfront cost (does it cover callvalue?)
/**
* Return value from the contract
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/vm/src/evm/opcodes/codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const opcodes: OpcodeEntry = {
0x07: { name: 'SMOD', isAsync: false, dynamicGas: false },
0x08: { name: 'ADDMOD', isAsync: false, dynamicGas: false },
0x09: { name: 'MULMOD', isAsync: false, dynamicGas: false },
0x0a: { name: 'EXP', isAsync: false, dynamicGas: false },
0x0a: { name: 'EXP', isAsync: false, dynamicGas: true },
0x0b: { name: 'SIGNEXTEND', isAsync: false, dynamicGas: false },

// 0x10 range - bit ops
Expand Down
12 changes: 1 addition & 11 deletions packages/vm/src/evm/opcodes/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,22 +164,12 @@ export const handlers: Map<number, OpHandler> = new Map([
// 0x0a: EXP
[
0x0a,
function (runState, common) {
function (runState) {
const [base, exponent] = runState.stack.popN(2)
if (exponent === BigInt(0)) {
runState.stack.push(BigInt(1))
return
}
let byteLength = exponent.toString(2).length / 8
if (byteLength > Math.trunc(byteLength)) {
byteLength = Math.trunc(byteLength) + 1
}
if (byteLength < 1 || byteLength > 32) {
trap(ERROR.OUT_OF_RANGE)
}
const gasPrice = common.param('gasPrices', 'expByte')
const amount = BigInt(byteLength) * gasPrice
runState.interpreter.useGas(amount, 'EXP opcode') // TODO Why is this not in gas.ts??

if (base === BigInt(0)) {
runState.stack.push(base)
Expand Down
20 changes: 20 additions & 0 deletions packages/vm/src/evm/opcodes/gas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,26 @@ export interface SyncDynamicGasHandler {

export const dynamicGasHandlers: Map<number, AsyncDynamicGasHandler | SyncDynamicGasHandler> =
new Map<number, AsyncDynamicGasHandler>([
[
/* EXP */
0x0a,
async function (runState, gas, common): Promise<bigint> {
const [_base, exponent] = runState.stack.peek(2)
if (exponent === BigInt(0)) {
return gas
}
let byteLength = exponent.toString(2).length / 8
if (byteLength > Math.trunc(byteLength)) {
byteLength = Math.trunc(byteLength) + 1
}
if (byteLength < 1 || byteLength > 32) {
trap(ERROR.OUT_OF_RANGE)
}
const expPricePerByte = common.param('gasPrices', 'expByte')
gas += BigInt(byteLength) * expPricePerByte
return gas
},
],
[
/* SHA3 */
0x20,
Expand Down

0 comments on commit 51e5582

Please sign in to comment.