Skip to content

Commit

Permalink
vm: add other opcodes to gas map
Browse files Browse the repository at this point in the history
vm: change step event fee type from number to BN

vm: deduct dynamic gas

vm: fix stack peek
vm: do not add gasLimit to gas cost for CREATE
  • Loading branch information
jochem-brouwer committed Jul 19, 2021
1 parent cb9169e commit ce50052
Show file tree
Hide file tree
Showing 7 changed files with 293 additions and 265 deletions.
9 changes: 5 additions & 4 deletions packages/vm/src/evm/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface RunState {
_common: Common
stateManager: StateManager
eei: EEI
messageGasLimit?: BN // Cache value from `gas.ts` to save gas limit for a message call
}

export interface InterpreterResult {
Expand All @@ -47,7 +48,7 @@ export interface InterpreterStep {
memoryWordCount: BN
opcode: {
name: string
fee: number
fee: BN
isAsync: boolean
}
account: Account
Expand Down Expand Up @@ -145,7 +146,7 @@ export default class Interpreter {

if (opInfo.dynamicGas) {
const dynamicGasHandler = dynamicGasHandlers.get(this._runState.opCode)!
gas.iadd(dynamicGasHandler(this._runState))
gas.iadd(await dynamicGasHandler(this._runState))
}

// TODO: figure out if we should try/catch this (in case step event throws)
Expand All @@ -157,7 +158,7 @@ export default class Interpreter {
}

// Reduce opcode's base fee
this._eei.useGas(new BN(opInfo.fee), `${opInfo.name} (base fee)`)
this._eei.useGas(gas, `${opInfo.name} fee`)
// Advance program counter
this._runState.programCounter++

Expand Down Expand Up @@ -193,7 +194,7 @@ export default class Interpreter {
gasRefund: this._eei._evm._refund,
opcode: {
name: opcode.fullName,
fee: fee.toNumber(),
fee: fee,
isAsync: opcode.isAsync,
},
stack: this._runState.stack._store,
Expand Down
23 changes: 5 additions & 18 deletions packages/vm/src/evm/opcodes/EIP1283.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,18 @@ import { RunState } from './../interpreter'
* @param {any} found
* @param {Buffer} value
*/
export function updateSstoreGasEIP1283(runState: RunState, found: any, value: Buffer) {
export function updateSstoreGasEIP1283(runState: RunState, found: any, value: Buffer): BN {
const { original, current } = found
if (current.equals(value)) {
// If current value equals new value (this is a no-op), 200 gas is deducted.
runState.eei.useGas(
new BN(runState._common.param('gasPrices', 'netSstoreNoopGas')),
'EIP-1283 -> netSstoreNoopGas'
)
return
return new BN(runState._common.param('gasPrices', 'netSstoreNoopGas'))
}
// If current value does not equal new value
if (original.equals(current)) {
// If original value equals current value (this storage slot has not been changed by the current execution context)
if (original.length === 0) {
// If original value is 0, 20000 gas is deducted.
return runState.eei.useGas(
new BN(runState._common.param('gasPrices', 'netSstoreInitGas')),
'EIP-1283 -> netSstoreInitGas'
)
return new BN(runState._common.param('gasPrices', 'netSstoreInitGas'))
}
if (value.length === 0) {
// If new value is 0, add 15000 gas to refund counter.
Expand All @@ -36,10 +29,7 @@ export function updateSstoreGasEIP1283(runState: RunState, found: any, value: Bu
)
}
// Otherwise, 5000 gas is deducted.
return runState.eei.useGas(
new BN(runState._common.param('gasPrices', 'netSstoreCleanGas')),
'EIP-1283 -> netSstoreCleanGas'
)
return new BN(runState._common.param('gasPrices', 'netSstoreCleanGas'))
}
// If original value does not equal current value (this storage slot is dirty), 200 gas is deducted. Apply both of the following clauses.
if (original.length !== 0) {
Expand Down Expand Up @@ -74,8 +64,5 @@ export function updateSstoreGasEIP1283(runState: RunState, found: any, value: Bu
)
}
}
return runState.eei.useGas(
new BN(runState._common.param('gasPrices', 'netSstoreDirtyGas')),
'EIP-1283 -> netSstoreDirtyGas'
)
return new BN(runState._common.param('gasPrices', 'netSstoreDirtyGas'))
}
27 changes: 10 additions & 17 deletions packages/vm/src/evm/opcodes/EIP2200.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ import { trap } from './util'
* @param {any} found
* @param {Buffer} value
*/
export function updateSstoreGasEIP2200(runState: RunState, found: any, value: Buffer, key: Buffer) {
export function updateSstoreGasEIP2200(
runState: RunState,
found: any,
value: Buffer,
key: Buffer
): BN {
const { original, current } = found
// Fail if not enough gas is left
if (
Expand All @@ -23,18 +28,12 @@ export function updateSstoreGasEIP2200(runState: RunState, found: any, value: Bu
// Noop
if (current.equals(value)) {
const sstoreNoopCost = runState._common.param('gasPrices', 'sstoreNoopGasEIP2200')
return runState.eei.useGas(
adjustSstoreGasEIP2929(runState, key, sstoreNoopCost, 'noop'),
'EIP-2200 -> sstoreNoopGasEIP2200'
)
return adjustSstoreGasEIP2929(runState, key, sstoreNoopCost, 'noop')
}
if (original.equals(current)) {
// Create slot
if (original.length === 0) {
return runState.eei.useGas(
new BN(runState._common.param('gasPrices', 'sstoreInitGasEIP2200')),
'EIP-2200 -> sstoreInitGasEIP2200'
)
return new BN(runState._common.param('gasPrices', 'sstoreInitGasEIP2200'))
}
// Delete slot
if (value.length === 0) {
Expand All @@ -44,10 +43,7 @@ export function updateSstoreGasEIP2200(runState: RunState, found: any, value: Bu
)
}
// Write existing slot
return runState.eei.useGas(
new BN(runState._common.param('gasPrices', 'sstoreCleanGasEIP2200')),
'EIP-2200 -> sstoreCleanGasEIP2200'
)
return new BN(runState._common.param('gasPrices', 'sstoreCleanGasEIP2200'))
}
if (original.length > 0) {
if (current.length === 0) {
Expand Down Expand Up @@ -82,8 +78,5 @@ export function updateSstoreGasEIP2200(runState: RunState, found: any, value: Bu
}
}
// Dirty update
return runState.eei.useGas(
new BN(runState._common.param('gasPrices', 'sstoreDirtyGasEIP2200')),
'EIP-2200 -> sstoreDirtyGasEIP2200'
)
return new BN(runState._common.param('gasPrices', 'sstoreDirtyGasEIP2200'))
}
Loading

0 comments on commit ce50052

Please sign in to comment.