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:
c.host.getTxContext().tx_origin
else:
c.vmState.txOrigin
c.vmState.txCtx.origin
template getGasPrice*(c: Computation): GasInt =
when evmc_enabled:
UInt256.fromEvmc(c.host.getTxContext().tx_gas_price).truncate(GasInt)
else:
c.vmState.txGasPrice
c.vmState.txCtx.gasPrice
template getVersionedHash*(c: Computation, index: int): VersionedHash =
when evmc_enabled:
cast[ptr UncheckedArray[VersionedHash]](c.host.getTxContext().blob_hashes)[index]
else:
c.vmState.txVersionedHashes[index]
c.vmState.txCtx.versionedHashes[index]
template getVersionedHashesLen*(c: Computation): int =
when evmc_enabled:
c.host.getTxContext().blob_hashes_count.int
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
{.gcsafe, raises: [CatchableError].} =

View File

@ -30,6 +30,7 @@ type
block_base_fee* : evmc_uint256be # The block base fee.
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_base_fee* : evmc_uint256be # The blob base fee (EIP-7516).
nimbus_message* = object
kind* : evmc_call_kind

View File

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

View File

@ -105,8 +105,9 @@ type
SelfBalance = 0x47, ## Get current contract's balance.
BaseFee = 0x48, ## Get blocks base fee. EIP-3198
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, ## ..
# 50s: Stack, Memory, Storage and Flow Operations

View File

@ -93,6 +93,12 @@ const
k.cpt.stack.push:
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
# ------------------------------------------------------------------------------
@ -178,6 +184,14 @@ const
info: "Get current transaction's EIP-4844 versioned hash",
exec: (prep: vm2OpIgnore,
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))]
# ------------------------------------------------------------------------------

View File

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

View File

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

View File

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

View File

@ -154,8 +154,8 @@ proc evmcExecComputation*(host: TransactionHost): EvmcResult
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.
when EVMC_ABI_VERSION != 10:
{.error: ("This code assumes EVMC_ABI_VERSION 10;" &
when EVMC_ABI_VERSION != 11:
{.error: ("This code assumes EVMC_ABI_VERSION 11;" &
" 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)
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.
when EVMC_ABI_VERSION != 10:
{.error: ("This code assumes EVMC_ABI_VERSION 10;" &
when EVMC_ABI_VERSION != 11:
{.error: ("This code assumes EVMC_ABI_VERSION 11;" &
" 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.
let vmState = host.vmState
host.txContext.tx_gas_price = vmState.txGasPrice.u256.toEvmc
host.txContext.tx_origin = vmState.txOrigin.toEvmc
host.txContext.tx_gas_price = vmState.txCtx.gasPrice.u256.toEvmc
host.txContext.tx_origin = vmState.txCtx.origin.toEvmc
# vmState.coinbase now unused
host.txContext.block_coinbase = vmState.blockCtx.coinbase.toEvmc
# vmState.blockNumber now unused
@ -65,20 +65,22 @@ proc setupTxContext(host: TransactionHost) =
host.txContext.chain_id = vmState.com.chainId.uint.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
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:
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
# 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.chain_id = flip256(host.txContext.chain_id)
host.txContext.block_base_fee = flip256(host.txContext.block_base_fee)
host.txContext.blob_base_fee = flip256(host.txContext.blob_base_fee)
# EIP-4399
# 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 "stateDB.root : " & $vms.stateDB.rootHash & "\n"
result.add "cumulativeGasUsed: " & $vms.cumulativeGasUsed & "\n"
result.add "txOrigin : " & $vms.txOrigin & "\n"
result.add "txGasPrice : " & $vms.txGasPrice & "\n"
result.add "tx.origin : " & $vms.txCtx.origin & "\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"
proc `$`(x: ChainId): string =

View File

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

View File

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

2
vendor/nim-evmc vendored

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