Skip to content

Commit c186e33

Browse files
committed
vm -> EIP2929: updated accessAddressEIP2929 to use Address type, test fixes
1 parent 20e845d commit c186e33

File tree

4 files changed

+26
-30
lines changed

4 files changed

+26
-30
lines changed

packages/vm/lib/evm/interpreter.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,11 @@ export default class Interpreter {
243243
// all the precompiles. (EIP 2929)
244244
_initAccessedAddresses() {
245245
this._runState.accessedAddresses.clear()
246-
this._runState.accessedAddresses.add(this._eei._env.origin.toString('hex'))
247-
this._runState.accessedAddresses.add(this._eei.getAddress().toString('hex'))
246+
this._runState.accessedAddresses.add(this._eei._env.origin.toString())
247+
this._runState.accessedAddresses.add(this._eei.getAddress().toString())
248248

249249
for (let address of Object.keys(precompiles)) {
250-
this._runState.accessedAddresses.add(address)
250+
this._runState.accessedAddresses.add(`0x${address}`)
251251
}
252252
}
253253
}

packages/vm/lib/evm/opcodes/EIP2929.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import BN = require('bn.js')
2+
import { Address } from 'ethereumjs-util'
23
import { RunState } from './../interpreter'
34
import { addressToBuffer } from './util'
45

@@ -9,10 +10,10 @@ import { addressToBuffer } from './util'
910
* @param {RunState} runState
1011
* @param {BN} address
1112
*/
12-
export function accessAddressEIP2929(runState: RunState, address: BN | Buffer, baseFee?: number) {
13+
export function accessAddressEIP2929(runState: RunState, address: Address, baseFee?: number) {
1314
if (!runState._common.eips().includes(2929)) return
1415

15-
const addressStr = addressToBuffer(address).toString('hex')
16+
const addressStr = address.toString()
1617

1718
// Cold
1819
if (!runState.accessedAddresses.has(addressStr)) {
@@ -43,7 +44,7 @@ export function accessStorageEIP2929(runState: RunState, key: Buffer, isSstore:
4344

4445
const keyStr = key.toString('hex')
4546
const baseFee = !isSstore ? runState._common.param('gasPrices', 'sload') : 0
46-
const address = runState.eei.getAddress().toString('hex')
47+
const address = runState.eei.getAddress().toString()
4748
const keysAtAddress = runState.accessedStorage.get(address)
4849

4950
// Cold (SLOAD and SSTORE)
@@ -79,7 +80,7 @@ export function adjustSstoreGasEIP2929(
7980
if (!runState._common.eips().includes(2929)) return defaultCost
8081

8182
const keyStr = key.toString('hex')
82-
const address = runState.eei.getAddress().toString('hex')
83+
const address = runState.eei.getAddress().toString()
8384
const warmRead = runState._common.param('gasPrices', 'warmstorageread')
8485
const coldSload = runState._common.param('gasPrices', 'coldsload')
8586

packages/vm/lib/evm/opcodes/functions.ts

+13-19
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ export const handlers: Map<number, OpHandler> = new Map([
410410
async function (runState: RunState) {
411411
const addressBN = runState.stack.pop()
412412
const address = new Address(addressToBuffer(addressBN))
413-
accessAddressEIP2929(runState, address.buf, runState._common.param('gasPrices', 'balance'))
413+
accessAddressEIP2929(runState, address, runState._common.param('gasPrices', 'balance'))
414414
const balance = await runState.eei.getExternalBalance(address)
415415
runState.stack.push(balance)
416416
},
@@ -509,27 +509,29 @@ export const handlers: Map<number, OpHandler> = new Map([
509509
[
510510
0x3b,
511511
async function (runState: RunState) {
512-
const address = runState.stack.pop()
512+
const addressBN = runState.stack.pop()
513+
const address = new Address(addressToBuffer(addressBN))
513514
accessAddressEIP2929(runState, address, runState._common.param('gasPrices', 'extcodesize'))
514-
const size = await runState.eei.getExternalCodeSize(address)
515+
const size = await runState.eei.getExternalCodeSize(addressBN)
515516
runState.stack.push(size)
516517
},
517518
],
518519
// 0x3c: EXTCODECOPY
519520
[
520521
0x3c,
521522
async function (runState: RunState) {
522-
const [address, memOffset, codeOffset, length] = runState.stack.popN(4)
523+
const [addressBN, memOffset, codeOffset, length] = runState.stack.popN(4)
523524

524525
// FIXME: for some reason this must come before subGas
525526
subMemUsage(runState, memOffset, length)
527+
const address = new Address(addressToBuffer(addressBN))
526528
accessAddressEIP2929(runState, address, runState._common.param('gasPrices', 'extcodecopy'))
527529
// copy fee
528530
runState.eei.useGas(
529531
new BN(runState._common.param('gasPrices', 'copy')).imul(divCeil(length, new BN(32)))
530532
)
531533

532-
const code = await runState.eei.getExternalCode(address)
534+
const code = await runState.eei.getExternalCode(addressBN)
533535

534536
const data = getDataSlice(code, codeOffset, length)
535537
const memOffsetNum = memOffset.toNumber()
@@ -544,7 +546,7 @@ export const handlers: Map<number, OpHandler> = new Map([
544546
async function (runState: RunState) {
545547
const addressBN = runState.stack.pop()
546548
const address = new Address(addressToBuffer(addressBN))
547-
accessAddressEIP2929(runState, address.buf, runState._common.param('gasPrices', 'extcodehash'))
549+
accessAddressEIP2929(runState, address, runState._common.param('gasPrices', 'extcodehash'))
548550
const empty = await runState.eei.isAccountEmpty(address)
549551
if (empty) {
550552
runState.stack.push(new BN(0))
@@ -986,7 +988,7 @@ export const handlers: Map<number, OpHandler> = new Map([
986988
}
987989
subMemUsage(runState, inOffset, inLength)
988990
subMemUsage(runState, outOffset, outLength)
989-
accessAddressEIP2929(runState, toAddressBuf, runState._common.param('gasPrices', 'call'))
991+
accessAddressEIP2929(runState, toAddress, runState._common.param('gasPrices', 'call'))
990992

991993
if (!value.isZero()) {
992994
runState.eei.useGas(new BN(runState._common.param('gasPrices', 'callValueTransfer')))
@@ -1038,7 +1040,7 @@ export const handlers: Map<number, OpHandler> = new Map([
10381040

10391041
subMemUsage(runState, inOffset, inLength)
10401042
subMemUsage(runState, outOffset, outLength)
1041-
accessAddressEIP2929(runState, toAddressBuf, runState._common.param('gasPrices', 'callcode'))
1043+
accessAddressEIP2929(runState, toAddress, runState._common.param('gasPrices', 'callcode'))
10421044

10431045
if (!value.isZero()) {
10441046
runState.eei.useGas(new BN(runState._common.param('gasPrices', 'callValueTransfer')))
@@ -1075,11 +1077,7 @@ export const handlers: Map<number, OpHandler> = new Map([
10751077

10761078
subMemUsage(runState, inOffset, inLength)
10771079
subMemUsage(runState, outOffset, outLength)
1078-
accessAddressEIP2929(
1079-
runState,
1080-
toAddressBuf,
1081-
runState._common.param('gasPrices', 'delegatecall')
1082-
)
1080+
accessAddressEIP2929(runState, toAddress, runState._common.param('gasPrices', 'delegatecall'))
10831081

10841082
gasLimit = maxCallGas(gasLimit, runState.eei.getGasLeft(), runState)
10851083
// note that TangerineWhistle or later this cannot happen (it could have ran out of gas prior to getting here though)
@@ -1108,11 +1106,7 @@ export const handlers: Map<number, OpHandler> = new Map([
11081106

11091107
subMemUsage(runState, inOffset, inLength)
11101108
subMemUsage(runState, outOffset, outLength)
1111-
accessAddressEIP2929(
1112-
runState,
1113-
toAddressBuf,
1114-
runState._common.param('gasPrices', 'staticcall')
1115-
)
1109+
accessAddressEIP2929(runState, toAddress, runState._common.param('gasPrices', 'staticcall'))
11161110
gasLimit = maxCallGas(gasLimit, runState.eei.getGasLeft(), runState) // we set TangerineWhistle or later to true here, as STATICCALL was available from Byzantium (which is after TangerineWhistle)
11171111

11181112
let data = Buffer.alloc(0)
@@ -1187,7 +1181,7 @@ export const handlers: Map<number, OpHandler> = new Map([
11871181
runState.eei.useGas(new BN(runState._common.param('gasPrices', 'callNewAccount')))
11881182
}
11891183

1190-
accessAddressEIP2929(runState, selfdestructToAddress.buf, 0)
1184+
accessAddressEIP2929(runState, selfdestructToAddress, 0)
11911185
return runState.eei.selfDestruct(selfdestructToAddress)
11921186
},
11931187
],

packages/vm/tests/api/EIPs/eip-2929.spec.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import tape from 'tape'
2-
import { BN } from 'ethereumjs-util'
2+
import { Address, BN } from 'ethereumjs-util'
33
import VM from '../../../lib'
44
import Common from '@ethereumjs/common'
55
import { inspect } from 'util'
66

77
// Test cases source: https://gist.github.com/holiman/174548cad102096858583c6fbbb0649a
88
tape('EIP 2929: gas cost tests', (t) => {
99
const initialGas = new BN(0xffffffffff)
10-
const address = Buffer.from('000000000000000000000000636F6E7472616374', 'hex')
10+
const address = new Address(Buffer.from('000000000000000000000000636F6E7472616374', 'hex'))
1111
const common = new Common({ chain: 'mainnet', hardfork: 'berlin', eips: [2929] })
1212

1313
const runTest = async function (test: any, st: tape.Test) {
@@ -20,14 +20,15 @@ tape('EIP 2929: gas cost tests', (t) => {
2020
currentGas = step.gasLeft
2121

2222
if (test.steps.length) {
23-
st.equal(step.opcode.name, test.steps[i].expectedOpcode)
23+
st.equal(step.opcode.name, test.steps[i].expectedOpcode, `Expected Opcode: ${test.steps[i].expectedOpcode}`)
2424

2525
// Validates the gas consumption of the (i - 1)th opcode
2626
// b/c the step event fires before gas is debited.
2727
// The first opcode of every test should be +/- irrelevant
2828
// (ex: PUSH) and the last opcode is always STOP
2929
if (i > 0) {
30-
st.equal(true, gasUsed.eq(new BN(test.steps[i - 1].expectedGasUsed)))
30+
const expectedGasUsed = new BN(test.steps[i - 1].expectedGasUsed)
31+
st.equal(true, gasUsed.eq(expectedGasUsed), `Opcode: ${test.steps[i - 1].expectedOpcode}, Gase Used: ${gasUsed}, Expected: ${expectedGasUsed}`)
3132
}
3233
}
3334
i++

0 commit comments

Comments
 (0)