Skip to content

Commit

Permalink
evm: add blobgasfee eip 7516 (#3035)
Browse files Browse the repository at this point in the history
* evm: add blobgasfee eip 7516

* Update packages/evm/src/interpreter.ts

Co-authored-by: acolytec3 <17355484+acolytec3@users.noreply.github.com>

* Update packages/common/src/hardforks.ts

Co-authored-by: Scorbajio <indigophi@protonmail.com>

* update min hardfork

* add to supported eips

* update minimum hf to cancun

* update min hf to paris same as 4844

---------

Co-authored-by: acolytec3 <17355484+acolytec3@users.noreply.github.com>
Co-authored-by: Scorbajio <indigophi@protonmail.com>
  • Loading branch information
3 people authored Sep 19, 2023
1 parent bd70544 commit b6eb329
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 4 deletions.
13 changes: 13 additions & 0 deletions packages/common/src/eips.ts
Original file line number Diff line number Diff line change
Expand Up @@ -471,4 +471,17 @@ export const EIPs: EIPsDict = {
minimumHardfork: Hardfork.London,
requiredEIPs: [],
},
7516: {
comment: 'BLOBBASEFEE opcode',
url: 'https://eips.ethereum.org/EIPS/eip-7516',
status: Status.Draft,
minimumHardfork: Hardfork.Paris,
requiredEIPs: [4844],
gasPrices: {
blobbasefee: {
v: 2,
d: 'Gas cost of the BLOBBASEFEE opcode',
},
},
},
}
4 changes: 2 additions & 2 deletions packages/common/src/hardforks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -834,9 +834,9 @@ export const hardforks: HardforksDict = {
cancun: {
name: 'cancun',
comment:
'Next feature hardfork after the shanghai having proto-danksharding EIP 4844 blobs (still WIP hence not for production use), transient storage opcodes, parent beacon block root availability in EVM and selfdestruct only in same transaction',
'Next feature hardfork after shanghai, includes proto-danksharding EIP 4844 blobs (still WIP hence not for production use), transient storage opcodes, parent beacon block root availability in EVM, selfdestruct only in same transaction, and blob base fee opcode',
url: 'https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md',
status: Status.Final,
eips: [1153, 4844, 4788, 5656, 6780],
eips: [1153, 4844, 4788, 5656, 6780, 7516],
},
}
5 changes: 3 additions & 2 deletions packages/evm/src/evm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export class EVM implements EVMInterface {
// Supported EIPs
const supportedEIPs = [
1153, 1559, 2315, 2565, 2718, 2929, 2930, 3074, 3198, 3529, 3540, 3541, 3607, 3651, 3670,
3855, 3860, 4399, 4895, 4788, 4844, 5133, 5656, 6780,
3855, 3860, 4399, 4895, 4788, 4844, 5133, 5656, 6780, 7516,
]

for (const eip of this.common.eips()) {
Expand Down Expand Up @@ -966,7 +966,7 @@ export function EvmErrorResult(error: EvmError, gasUsed: bigint): ExecResult {
}
}

function defaultBlock(): Block {
export function defaultBlock(): Block {
return {
header: {
number: BigInt(0),
Expand All @@ -977,6 +977,7 @@ function defaultBlock(): Block {
prevRandao: zeros(32),
gasLimit: BigInt(0),
baseFeePerGas: undefined,
getBlobGasPrice: () => undefined,
},
}
}
12 changes: 12 additions & 0 deletions packages/evm/src/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,18 @@ export class Interpreter {
return baseFee
}

/**
* Returns the Blob Base Fee of the block as proposed in [EIP-7516](https;//eips.etheruem.org/EIPS/eip-7516)
*/
getBlobBaseFee(): bigint {
const blobBaseFee = this._env.block.header.getBlobGasPrice()
if (blobBaseFee === undefined) {
// Sanity check
throw new Error('Block has no Blob Base Fee')
}
return blobBaseFee
}

/**
* Returns the chain ID for current chain. Introduced for the
* CHAINID opcode proposed in [EIP-1344](https://eips.ethereum.org/EIPS/eip-1344).
Expand Down
6 changes: 6 additions & 0 deletions packages/evm/src/opcodes/codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,12 @@ const eipOpcodes: { eip: number; opcodes: OpcodeEntry }[] = [
0x5e: { name: 'MCOPY', isAsync: false, dynamicGas: true },
},
},
{
eip: 7516,
opcodes: {
0x4a: { name: 'BLOBBASEFEE', isAsync: false, dynamicGas: false },
},
},
]

/**
Expand Down
7 changes: 7 additions & 0 deletions packages/evm/src/opcodes/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,13 @@ export const handlers: Map<number, OpHandler> = new Map([
}
},
],
// 0x4a: BLOBBASEFEE
[
0x4a,
function (runState) {
runState.stack.push(runState.interpreter.getBlobBaseFee())
},
],
// 0x50 range - 'storage' and execution
// 0x50: POP
[
Expand Down
1 change: 1 addition & 0 deletions packages/evm/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ export type Block = {
prevRandao: Uint8Array
gasLimit: bigint
baseFeePerGas?: bigint
getBlobGasPrice(): bigint | undefined
}
}

Expand Down
38 changes: 38 additions & 0 deletions packages/evm/test/runCall.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
Account,
Address,
MAX_UINT64,
bytesToBigInt,
bytesToHex,
concatBytes,
hexToBytes,
Expand All @@ -13,6 +14,7 @@ import { keccak256 } from 'ethereum-cryptography/keccak.js'
import { assert, describe, it } from 'vitest'

import * as genesisJSON from '../../client/test/testdata/geth-genesis/eip4844.json'
import { defaultBlock } from '../src/evm.js'
import { ERROR } from '../src/exceptions.js'
import { EVM } from '../src/index.js'

Expand Down Expand Up @@ -602,6 +604,42 @@ describe('RunCall tests', () => {
)
})

it('runCall() => use BLOBBASEFEE opcode from EIP 7516', async () => {
// setup the evm
const common = Common.fromGethGenesis(genesisJSON, {
chain: 'custom',
hardfork: Hardfork.Cancun,
})
const evm = new EVM({
common,
})

const BLOBBASEFEE_OPCODE = 0x4a
assert.equal(
evm.getActiveOpcodes().get(BLOBBASEFEE_OPCODE)!.name,
'BLOBBASEFEE',
'Opcode 0x4a named BLOBBASEFEE'
)

const block = defaultBlock()
block.header.getBlobGasPrice = () => BigInt(119)

// setup the call arguments
const runCallArgs: EVMRunCallOpts = {
gasLimit: BigInt(0xffffffffff),
// calldata -- retrieves the blobgas and returns it from memory
data: hexToBytes('0x4a60005260206000F3'),
block,
}
const res = await evm.runCall(runCallArgs)
assert.equal(
bytesToBigInt(unpadBytes(res.execResult.returnValue)),
BigInt(119),
'retrieved correct gas fee'
)
assert.equal(res.execResult.executionGasUsed, BigInt(6417), 'correct blob gas fee (2) charged')
})

it('step event: ensure EVM memory and not internal memory gets reported', async () => {
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Berlin })
const evm = new EVM({
Expand Down

0 comments on commit b6eb329

Please sign in to comment.