Implement EIP-7516: BLOBBASEFEE opcode (#1791)

* Implement EIP-7516: BLOBBASEFEE opcode
This commit is contained in:
andri lim 2023-10-01 14:24:15 +07:00 committed by GitHub
parent e2bf6e153b
commit b7365085ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 138 additions and 101 deletions

View File

@ -107,25 +107,31 @@ template getOrigin*(c: Computation): EthAddress =
when evmc_enabled: when evmc_enabled:
c.host.getTxContext().tx_origin c.host.getTxContext().tx_origin
else: else:
c.vmState.txOrigin c.vmState.txCtx.origin
template getGasPrice*(c: Computation): GasInt = template getGasPrice*(c: Computation): GasInt =
when evmc_enabled: when evmc_enabled:
UInt256.fromEvmc(c.host.getTxContext().tx_gas_price).truncate(GasInt) UInt256.fromEvmc(c.host.getTxContext().tx_gas_price).truncate(GasInt)
else: else:
c.vmState.txGasPrice c.vmState.txCtx.gasPrice
template getVersionedHash*(c: Computation, index: int): VersionedHash = template getVersionedHash*(c: Computation, index: int): VersionedHash =
when evmc_enabled: when evmc_enabled:
cast[ptr UncheckedArray[VersionedHash]](c.host.getTxContext().blob_hashes)[index] cast[ptr UncheckedArray[VersionedHash]](c.host.getTxContext().blob_hashes)[index]
else: else:
c.vmState.txVersionedHashes[index] c.vmState.txCtx.versionedHashes[index]
template getVersionedHashesLen*(c: Computation): int = template getVersionedHashesLen*(c: Computation): int =
when evmc_enabled: when evmc_enabled:
c.host.getTxContext().blob_hashes_count.int c.host.getTxContext().blob_hashes_count.int
else: else:
c.vmState.txVersionedHashes.len c.vmState.txCtx.versionedHashes.len
template getBlobBaseFee*(c: Computation): UInt256 =
when evmc_enabled:
UInt256.fromEvmc c.host.getTxContext().blob_base_fee
else:
c.vmState.txCtx.blobBaseFee
proc getBlockHash*(c: Computation, number: UInt256): Hash256 proc getBlockHash*(c: Computation, number: UInt256): Hash256
{.gcsafe, raises: [CatchableError].} = {.gcsafe, raises: [CatchableError].} =

View File

@ -30,6 +30,7 @@ type
block_base_fee* : evmc_uint256be # The block base fee. block_base_fee* : evmc_uint256be # The block base fee.
blob_hashes* : ptr evmc_bytes32 # The array of blob hashes (EIP-4844). blob_hashes* : ptr evmc_bytes32 # The array of blob hashes (EIP-4844).
blob_hashes_count*: csize_t # The number of blob hashes (EIP-4844). blob_hashes_count*: csize_t # The number of blob hashes (EIP-4844).
blob_base_fee* : evmc_uint256be # The blob base fee (EIP-7516).
nimbus_message* = object nimbus_message* = object
kind* : evmc_call_kind kind* : evmc_call_kind

View File

@ -620,6 +620,7 @@ template gasCosts(fork: EVMFork, prefix, ResultGasCostsName: untyped) =
SelfBalance: fixed GasLow, SelfBalance: fixed GasLow,
BaseFee: fixed GasBase, BaseFee: fixed GasBase,
BlobHash: fixed GasVeryLow, BlobHash: fixed GasVeryLow,
BlobBaseFee: fixed GasBase,
# 50s: Stack, Memory, Storage and Flow Operations # 50s: Stack, Memory, Storage and Flow Operations
Pop: fixed GasBase, Pop: fixed GasBase,

View File

@ -105,8 +105,9 @@ type
SelfBalance = 0x47, ## Get current contract's balance. SelfBalance = 0x47, ## Get current contract's balance.
BaseFee = 0x48, ## Get blocks base fee. EIP-3198 BaseFee = 0x48, ## Get blocks base fee. EIP-3198
BlobHash = 0x49, ## Get transaction's versionedHash. EIP-4844 BlobHash = 0x49, ## Get transaction's versionedHash. EIP-4844
BlobBaseFee = 0x4A, ## Returns the current data-blob base-fee
Nop0x4A, Nop0x4B, Nop0x4C, Nop0x4D, Nop0x4B, Nop0x4C, Nop0x4D,
Nop0x4E, Nop0x4F, ## .. Nop0x4E, Nop0x4F, ## ..
# 50s: Stack, Memory, Storage and Flow Operations # 50s: Stack, Memory, Storage and Flow Operations

View File

@ -93,6 +93,12 @@ const
k.cpt.stack.push: k.cpt.stack.push:
0 0
blobBaseFeeOp: Vm2OpFn = proc (k: var Vm2Ctx) =
## 0x4a, Get the block's base fee.
k.cpt.stack.push:
k.cpt.getBlobBaseFee
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Public, op exec table entries # Public, op exec table entries
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -178,6 +184,14 @@ const
info: "Get current transaction's EIP-4844 versioned hash", info: "Get current transaction's EIP-4844 versioned hash",
exec: (prep: vm2OpIgnore, exec: (prep: vm2OpIgnore,
run: blobHashOp, run: blobHashOp,
post: vm2OpIgnore)),
(opCode: BlobBaseFee, ## 0x4a, EIP-7516 Returns the current data-blob base-fee
forks: Vm2OpCancunAndLater,
name: "blobBaseFee",
info: "Returns the current data-blob base-fee",
exec: (prep: vm2OpIgnore,
run: blobBaseFeeOp,
post: vm2OpIgnore))] post: vm2OpIgnore))]
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@ -24,21 +24,17 @@ import
{.push raises: [].} {.push raises: [].}
proc setupTxContext*(vmState: BaseVMState, proc setupTxContext*(vmState: BaseVMState,
origin: EthAddress, txCtx: sink TxContext,
gasPrice: GasInt,
versionedHashes: openArray[VersionedHash],
forkOverride=none(EVMFork)) = forkOverride=none(EVMFork)) =
## this proc will be called each time a new transaction ## this proc will be called each time a new transaction
## is going to be executed ## is going to be executed
vmState.txOrigin = origin vmState.txCtx = system.move(txCtx)
vmState.txGasPrice = gasPrice
vmState.fork = vmState.fork =
if forkOverride.isSome: if forkOverride.isSome:
forkOverride.get forkOverride.get
else: else:
vmState.determineFork vmState.determineFork
vmState.gasCosts = vmState.fork.forkToSchedule vmState.gasCosts = vmState.fork.forkToSchedule
vmState.txVersionedHashes = @versionedHashes
# FIXME-awkwardFactoring: the factoring out of the pre and # FIXME-awkwardFactoring: the factoring out of the pre and
# post parts feels awkward to me, but for now I'd really like # post parts feels awkward to me, but for now I'd really like

View File

@ -51,21 +51,25 @@ type
coinbase* : EthAddress coinbase* : EthAddress
excessBlobGas* : uint64 excessBlobGas* : uint64
TxContext* = object
origin* : EthAddress
gasPrice* : GasInt
versionedHashes*: VersionedHashes
blobBaseFee* : UInt256
BaseVMState* = ref object of RootObj BaseVMState* = ref object of RootObj
com* : CommonRef com* : CommonRef
stateDB* : AccountsCache
gasPool* : GasInt gasPool* : GasInt
parent* : BlockHeader parent* : BlockHeader
blockCtx* : BlockContext blockCtx* : BlockContext
txCtx* : TxContext
flags* : set[VMFlag] flags* : set[VMFlag]
fork* : EVMFork
tracer* : TracerRef tracer* : TracerRef
receipts* : seq[Receipt] receipts* : seq[Receipt]
stateDB* : AccountsCache
cumulativeGasUsed*: GasInt cumulativeGasUsed*: GasInt
txOrigin* : EthAddress
txGasPrice* : GasInt
txVersionedHashes*: VersionedHashes
gasCosts* : GasCosts gasCosts* : GasCosts
fork* : EVMFork
asyncFactory* : AsyncOperationFactory asyncFactory* : AsyncOperationFactory
Computation* = ref object Computation* = ref object

View File

@ -127,9 +127,12 @@ proc initialAccessListEIP2929(call: CallParams) =
proc setupHost(call: CallParams): TransactionHost = proc setupHost(call: CallParams): TransactionHost =
let vmState = call.vmState let vmState = call.vmState
vmState.setupTxContext( vmState.setupTxContext(
origin = call.origin.get(call.sender), TxContext(
gasPrice = call.gasPrice, origin : call.origin.get(call.sender),
versionedHashes = call.versionedHashes, gasPrice : call.gasPrice,
versionedHashes: call.versionedHashes,
blobBaseFee : getBlobGasprice(vmState.blockCtx.excessBlobGas),
),
forkOverride = call.forkOverride forkOverride = call.forkOverride
) )

View File

@ -154,8 +154,8 @@ proc evmcExecComputation*(host: TransactionHost): EvmcResult
host.showCallReturn(result) host.showCallReturn(result)
# This code assumes fields, methods and types of ABI version 10, and must be # This code assumes fields, methods and types of ABI version 11, and must be
# checked for compatibility if the `import evmc/evmc` major version is updated. # checked for compatibility if the `import evmc/evmc` major version is updated.
when EVMC_ABI_VERSION != 10: when EVMC_ABI_VERSION != 11:
{.error: ("This code assumes EVMC_ABI_VERSION 10;" & {.error: ("This code assumes EVMC_ABI_VERSION 11;" &
" update the code to use EVMC_ABI_VERSION " & $EVMC_ABI_VERSION).} " update the code to use EVMC_ABI_VERSION " & $EVMC_ABI_VERSION).}

View File

@ -101,8 +101,8 @@ proc evmc_create_nimbus_evm(): ptr evmc_vm {.cdecl, exportc.} =
GC_ref(vm) GC_ref(vm)
return cast[ptr evmc_vm](vm) return cast[ptr evmc_vm](vm)
# This code assumes fields, methods and types of ABI version 10, and must be # This code assumes fields, methods and types of ABI version 11, and must be
# checked for compatibility if the `import evmc/evmc` major version is updated. # checked for compatibility if the `import evmc/evmc` major version is updated.
when EVMC_ABI_VERSION != 10: when EVMC_ABI_VERSION != 11:
{.error: ("This code assumes EVMC_ABI_VERSION 10;" & {.error: ("This code assumes EVMC_ABI_VERSION 11;" &
" update the code to use EVMC_ABI_VERSION " & $EVMC_ABI_VERSION).} " update the code to use EVMC_ABI_VERSION " & $EVMC_ABI_VERSION).}

View File

@ -50,8 +50,8 @@ proc setupTxContext(host: TransactionHost) =
# values over much of the 256-bit range. # values over much of the 256-bit range.
let vmState = host.vmState let vmState = host.vmState
host.txContext.tx_gas_price = vmState.txGasPrice.u256.toEvmc host.txContext.tx_gas_price = vmState.txCtx.gasPrice.u256.toEvmc
host.txContext.tx_origin = vmState.txOrigin.toEvmc host.txContext.tx_origin = vmState.txCtx.origin.toEvmc
# vmState.coinbase now unused # vmState.coinbase now unused
host.txContext.block_coinbase = vmState.blockCtx.coinbase.toEvmc host.txContext.block_coinbase = vmState.blockCtx.coinbase.toEvmc
# vmState.blockNumber now unused # vmState.blockNumber now unused
@ -65,20 +65,22 @@ proc setupTxContext(host: TransactionHost) =
host.txContext.chain_id = vmState.com.chainId.uint.u256.toEvmc host.txContext.chain_id = vmState.com.chainId.uint.u256.toEvmc
host.txContext.block_base_fee = vmState.blockCtx.fee.get(0.u256).toEvmc host.txContext.block_base_fee = vmState.blockCtx.fee.get(0.u256).toEvmc
if vmState.txVersionedHashes.len > 0: if vmState.txCtx.versionedHashes.len > 0:
type type
BlobHashPtr = typeof host.txContext.blob_hashes BlobHashPtr = typeof host.txContext.blob_hashes
host.txContext.blob_hashes = cast[BlobHashPtr](vmState.txVersionedHashes[0].addr) host.txContext.blob_hashes = cast[BlobHashPtr](vmState.txCtx.versionedHashes[0].addr)
else: else:
host.txContext.blob_hashes = nil host.txContext.blob_hashes = nil
host.txContext.blob_hashes_count= vmState.txVersionedHashes.len.csize_t host.txContext.blob_hashes_count= vmState.txCtx.versionedHashes.len.csize_t
host.txContext.blob_base_fee = vmState.txCtx.blobBaseFee.toEvmc
# Most host functions do `flip256` in `evmc_host_glue`, but due to this # Most host functions do `flip256` in `evmc_host_glue`, but due to this
# result being cached, it's better to do `flip256` when filling the cache. # result being cached, it's better to do `flip256` when filling the cache.
host.txContext.tx_gas_price = flip256(host.txContext.tx_gas_price) host.txContext.tx_gas_price = flip256(host.txContext.tx_gas_price)
host.txContext.chain_id = flip256(host.txContext.chain_id) host.txContext.chain_id = flip256(host.txContext.chain_id)
host.txContext.block_base_fee = flip256(host.txContext.block_base_fee) host.txContext.block_base_fee = flip256(host.txContext.block_base_fee)
host.txContext.blob_base_fee = flip256(host.txContext.blob_base_fee)
# EIP-4399 # EIP-4399
# Transfer block randomness to difficulty OPCODE # Transfer block randomness to difficulty OPCODE

View File

@ -108,8 +108,10 @@ proc debug*(vms: BaseVMState): string =
result.add "receipts.len : " & $vms.receipts.len & "\n" result.add "receipts.len : " & $vms.receipts.len & "\n"
result.add "stateDB.root : " & $vms.stateDB.rootHash & "\n" result.add "stateDB.root : " & $vms.stateDB.rootHash & "\n"
result.add "cumulativeGasUsed: " & $vms.cumulativeGasUsed & "\n" result.add "cumulativeGasUsed: " & $vms.cumulativeGasUsed & "\n"
result.add "txOrigin : " & $vms.txOrigin & "\n" result.add "tx.origin : " & $vms.txCtx.origin & "\n"
result.add "txGasPrice : " & $vms.txGasPrice & "\n" result.add "tx.gasPrice : " & $vms.txCtx.gasPrice & "\n"
result.add "tx.blobHash.len : " & $vms.txCtx.versionedHashes.len & "\n"
result.add "tx.blobBaseFee : " & $vms.txCtx.blobBaseFee & "\n"
result.add "fork : " & $vms.fork & "\n" result.add "fork : " & $vms.fork & "\n"
proc `$`(x: ChainId): string = proc `$`(x: ChainId): string =

View File

@ -22,7 +22,8 @@ export
vmt.TracerFlags, vmt.TracerFlags,
vmt.TracerRef, vmt.TracerRef,
vmt.VMFlag, vmt.VMFlag,
vmt.BlockContext vmt.BlockContext,
vmt.TxContext
when defined(evmc_enabled): when defined(evmc_enabled):
import import

View File

@ -374,79 +374,85 @@ proc opEnvMain*() =
"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
fork: Merge fork: Merge
# from here onward, versionedHashes is taken from assembler:
# tx.versionedHashes = @[EMPTY_UNCLE_HASH, EMPTY_SHA3] title: "EIP-4844: BlobHash 1"
# preset in macro_assembler: createSignedTx code:
when not defined(evmc_enabled): PUSH1 "0x01"
assembler: BlobHash
title: "EIP-4844: BlobHash 1" STOP
code: stack:
PUSH1 "0x01" "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
BlobHash fork: Cancun
STOP
stack:
"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
fork: Cancun
assembler: assembler:
title: "EIP-4844: BlobHash 0" title: "EIP-4844: BlobHash 0"
code: code:
PUSH1 "0x00" PUSH1 "0x00"
BlobHash BlobHash
STOP STOP
stack: stack:
"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
fork: Cancun fork: Cancun
assembler: assembler:
title: "EIP-4844: BlobHash 2" title: "EIP-4844: BlobHash 2"
code: code:
PUSH1 "0x02" PUSH1 "0x02"
BlobHash BlobHash
STOP STOP
stack: stack:
"0x0000000000000000000000000000000000000000000000000000000000000000" "0x0000000000000000000000000000000000000000000000000000000000000000"
fork: Cancun fork: Cancun
assembler: assembler:
title: "EIP-4844: BlobHash 32 Bit high" title: "EIP-4844: BlobHash 32 Bit high"
code: code:
PUSH4 "0xffffffff" PUSH4 "0xffffffff"
BlobHash BlobHash
STOP STOP
stack: stack:
"0x0000000000000000000000000000000000000000000000000000000000000000" "0x0000000000000000000000000000000000000000000000000000000000000000"
fork: Cancun fork: Cancun
assembler: assembler:
title: "EIP-4844: BlobHash 64 Bit high" title: "EIP-4844: BlobHash 64 Bit high"
code: code:
PUSH8 "0xffffffffffffffff" PUSH8 "0xffffffffffffffff"
BlobHash BlobHash
STOP STOP
stack: stack:
"0x0000000000000000000000000000000000000000000000000000000000000000" "0x0000000000000000000000000000000000000000000000000000000000000000"
fork: Cancun fork: Cancun
assembler: assembler:
title: "EIP-4844: BlobHash 128 Bit high" title: "EIP-4844: BlobHash 128 Bit high"
code: code:
PUSH16 "0xffffffffffffffffffffffffffffffff" PUSH16 "0xffffffffffffffffffffffffffffffff"
BlobHash BlobHash
STOP STOP
stack: stack:
"0x0000000000000000000000000000000000000000000000000000000000000000" "0x0000000000000000000000000000000000000000000000000000000000000000"
fork: Cancun fork: Cancun
assembler: assembler:
title: "EIP-4844: BlobHash 256 Bit high" title: "EIP-4844: BlobHash 256 Bit high"
code: code:
PUSH32 "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" PUSH32 "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
BlobHash BlobHash
STOP STOP
stack: stack:
"0x0000000000000000000000000000000000000000000000000000000000000000" "0x0000000000000000000000000000000000000000000000000000000000000000"
fork: Cancun fork: Cancun
assembler:
title: "EIP-7516: BlobBaseFee"
code:
BlobBaseFee
STOP
stack:
"0x0000000000000000000000000000000000000000000000000000000000000001"
gasused: 2
fork: Cancun
when isMainModule: when isMainModule:
opEnvMain() opEnvMain()

2
vendor/nim-evmc vendored

@ -1 +1 @@
Subproject commit 51bdaa5ddb488f874477afa0f4bd23b5111a3806 Subproject commit 42cde520d383c7f4613bf710144727d40e9ae4b5