mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-03 15:55:47 +00:00
EIP-4844: Fix excessBlobGas handling (#1771)
* EIP-4844: Fix excessBlobGas handling * Change vmState.difficulty to vmState.difficultyOrPrevRandao
This commit is contained in:
parent
c405f79a84
commit
dc1dcfb206
@ -10,6 +10,7 @@
|
||||
|
||||
import
|
||||
std/[os, strutils],
|
||||
nimcrypto/sha2,
|
||||
kzg4844/kzg_ex as kzg,
|
||||
stew/results,
|
||||
stint,
|
||||
@ -39,7 +40,7 @@ const
|
||||
|
||||
# kzgToVersionedHash implements kzg_to_versioned_hash from EIP-4844
|
||||
proc kzgToVersionedHash(kzg: kzg.KZGCommitment): VersionedHash =
|
||||
result = keccakHash(kzg)
|
||||
result = sha256.digest(kzg)
|
||||
result.data[0] = VERSIONED_HASH_VERSION_KZG
|
||||
|
||||
# pointEvaluation implements point_evaluation_precompile from EIP-4844
|
||||
@ -50,7 +51,7 @@ proc pointEvaluation*(input: openArray[byte]): Result[void, string] =
|
||||
# Also verify that the provided commitment matches the provided versioned_hash.
|
||||
# The data is encoded as follows: versioned_hash | z | y | commitment | proof |
|
||||
|
||||
if input.len < PrecompileInputLength:
|
||||
if input.len != PrecompileInputLength:
|
||||
return err("invalid input length")
|
||||
|
||||
var
|
||||
@ -93,16 +94,16 @@ proc calcExcessBlobGas*(parent: BlockHeader): uint64 =
|
||||
|
||||
# fakeExponential approximates factor * e ** (num / denom) using a taylor expansion
|
||||
# as described in the EIP-4844 spec.
|
||||
func fakeExponential*(factor, numerator, denominator: uint64): uint64 =
|
||||
func fakeExponential*(factor, numerator, denominator: UInt256): UInt256 =
|
||||
var
|
||||
i = 1'u64
|
||||
output = 0'u64
|
||||
i = 1.u256
|
||||
output = 0.u256
|
||||
numeratorAccum = factor * denominator
|
||||
|
||||
while numeratorAccum > 0'u64:
|
||||
while numeratorAccum > 0.u256:
|
||||
output += numeratorAccum
|
||||
numeratorAccum = (numeratorAccum * numerator) div (denominator * i)
|
||||
i = i + 1'u64
|
||||
i = i + 1.u256
|
||||
|
||||
output div denominator
|
||||
|
||||
@ -113,22 +114,17 @@ proc getTotalBlobGas*(versionedHashesLen: int): uint64 =
|
||||
GAS_PER_BLOB * versionedHasheslen.uint64
|
||||
|
||||
# getBlobGasPrice implements get_data_gas_price from EIP-4844
|
||||
func getBlobGasprice*(parentExcessBlobGas: uint64): uint64 =
|
||||
func getBlobGasprice*(excessBlobGas: uint64): UInt256 =
|
||||
fakeExponential(
|
||||
MIN_BLOB_GASPRICE,
|
||||
parentExcessBlobGas,
|
||||
BLOB_GASPRICE_UPDATE_FRACTION
|
||||
MIN_BLOB_GASPRICE.u256,
|
||||
excessBlobGas.u256,
|
||||
BLOB_GASPRICE_UPDATE_FRACTION.u256
|
||||
)
|
||||
|
||||
proc calcDataFee*(tx: Transaction,
|
||||
parentExcessBlobGas: Option[uint64]): uint64 =
|
||||
tx.getTotalBlobGas *
|
||||
getBlobGasprice(parentExcessBlobGas.get(0'u64))
|
||||
|
||||
proc calcDataFee*(versionedHashesLen: int,
|
||||
parentExcessBlobGas: Option[uint64]): uint64 =
|
||||
getTotalBlobGas(versionedHashesLen) *
|
||||
getBlobGasprice(parentExcessBlobGas.get(0'u64))
|
||||
excessBlobGas: uint64): UInt256 =
|
||||
getTotalBlobGas(versionedHashesLen).u256 *
|
||||
getBlobGasprice(excessBlobGas)
|
||||
|
||||
func blobGasUsed(txs: openArray[Transaction]): uint64 =
|
||||
for tx in txs:
|
||||
|
@ -80,7 +80,7 @@ proc asyncProcessTransactionImpl(
|
||||
baseFee = baseFee256.truncate(GasInt)
|
||||
tx = eip1559TxNormalization(tx, baseFee)
|
||||
priorityFee = min(tx.maxPriorityFee, tx.maxFee - baseFee)
|
||||
excessBlobGas = vmState.parent.excessBlobGas.get(0'u64)
|
||||
excessBlobGas = header.excessBlobGas.get(0'u64)
|
||||
|
||||
# Return failure unless explicitely set `ok()`
|
||||
var res: Result[GasInt, string] = err("")
|
||||
|
@ -132,15 +132,19 @@ proc resetTxEnv(dh: TxChainRef; parent: BlockHeader; fee: Option[UInt256])
|
||||
|
||||
# we don't consider PoS difficulty here
|
||||
# because that is handled in vmState
|
||||
let blockCtx = BlockContext(
|
||||
timestamp : dh.prepHeader.timestamp,
|
||||
gasLimit : (if dh.maxMode: dh.limits.maxLimit else: dh.limits.trgLimit),
|
||||
fee : fee,
|
||||
prevRandao: dh.prepHeader.prevRandao,
|
||||
difficulty: dh.prepHeader.difficulty,
|
||||
coinbase : dh.feeRecipient,
|
||||
)
|
||||
|
||||
dh.txEnv.vmState = BaseVMState.new(
|
||||
parent = parent,
|
||||
timestamp = dh.prepHeader.timestamp,
|
||||
gasLimit = (if dh.maxMode: dh.limits.maxLimit else: dh.limits.trgLimit),
|
||||
fee = fee,
|
||||
prevRandao= dh.prepHeader.prevRandao,
|
||||
difficulty= dh.prepHeader.difficulty,
|
||||
miner = dh.feeRecipient,
|
||||
com = dh.com)
|
||||
parent = parent,
|
||||
blockCtx = blockCtx,
|
||||
com = dh.com)
|
||||
|
||||
dh.txEnv.txRoot = EMPTY_ROOT_HASH
|
||||
dh.txEnv.stateRoot = dh.txEnv.vmState.parent.stateRoot
|
||||
@ -217,13 +221,13 @@ proc getHeader*(dh: TxChainRef): BlockHeader
|
||||
bloom: dh.txEnv.receipts.createBloom,
|
||||
difficulty: dh.prepHeader.difficulty,
|
||||
blockNumber: dh.txEnv.vmState.blockNumber,
|
||||
gasLimit: dh.txEnv.vmState.gasLimit,
|
||||
gasLimit: dh.txEnv.vmState.blockCtx.gasLimit,
|
||||
gasUsed: gasUsed,
|
||||
timestamp: dh.prepHeader.timestamp,
|
||||
# extraData: Blob # signing data
|
||||
# mixDigest: Hash256 # mining hash for given difficulty
|
||||
# nonce: BlockNonce # mining free vaiable
|
||||
fee: dh.txEnv.vmState.fee,
|
||||
fee: dh.txEnv.vmState.blockCtx.fee,
|
||||
blobGasUsed: dh.txEnv.blobGasUsed,
|
||||
excessBlobGas: dh.txEnv.excessBlobGas)
|
||||
|
||||
@ -238,7 +242,7 @@ proc getHeader*(dh: TxChainRef): BlockHeader
|
||||
proc clearAccounts*(dh: TxChainRef)
|
||||
{.gcsafe,raises: [CatchableError].} =
|
||||
## Reset transaction environment, e.g. before packing a new block
|
||||
dh.resetTxEnv(dh.txEnv.vmState.parent, dh.txEnv.vmState.fee)
|
||||
dh.resetTxEnv(dh.txEnv.vmState.parent, dh.txEnv.vmState.blockCtx.fee)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Public functions, getters
|
||||
@ -274,15 +278,15 @@ proc feeRecipient*(dh: TxChainRef): EthAddress {.gcsafe.} =
|
||||
proc baseFee*(dh: TxChainRef): GasPrice =
|
||||
## Getter, baseFee for the next bock header. This value is auto-generated
|
||||
## when a new insertion point is set via `head=`.
|
||||
if dh.txEnv.vmState.fee.isSome:
|
||||
dh.txEnv.vmState.fee.get.truncate(uint64).GasPrice
|
||||
if dh.txEnv.vmState.blockCtx.fee.isSome:
|
||||
dh.txEnv.vmState.blockCtx.fee.get.truncate(uint64).GasPrice
|
||||
else:
|
||||
0.GasPrice
|
||||
|
||||
proc excessBlobGas*(dh: TxChainRef): uint64 =
|
||||
## Getter, baseFee for the next bock header. This value is auto-generated
|
||||
## when a new insertion point is set via `head=`.
|
||||
dh.txEnv.vmState.parent.excessBlobGas.get(0'u64)
|
||||
dh.txEnv.excessBlobGas.get(0'u64)
|
||||
|
||||
proc nextFork*(dh: TxChainRef): EVMFork =
|
||||
## Getter, fork of next block
|
||||
@ -330,9 +334,9 @@ proc `baseFee=`*(dh: TxChainRef; val: GasPrice) =
|
||||
## function would be called in exceptional cases only as this parameter is
|
||||
## determined by the `head=` update.
|
||||
if 0 < val or dh.com.isLondon(dh.txEnv.vmState.blockNumber):
|
||||
dh.txEnv.vmState.fee = some(val.uint64.u256)
|
||||
dh.txEnv.vmState.blockCtx.fee = some(val.uint64.u256)
|
||||
else:
|
||||
dh.txEnv.vmState.fee = UInt256.none()
|
||||
dh.txEnv.vmState.blockCtx.fee = UInt256.none()
|
||||
|
||||
proc `head=`*(dh: TxChainRef; val: BlockHeader)
|
||||
{.gcsafe,raises: [CatchableError].} =
|
||||
@ -348,20 +352,20 @@ proc `lhwm=`*(dh: TxChainRef; val: TxChainGasLimitsPc) =
|
||||
dh.lhwm = val
|
||||
let parent = dh.txEnv.vmState.parent
|
||||
dh.limits = dh.com.gasLimitsGet(parent, dh.limits.gasLimit, dh.lhwm)
|
||||
dh.txEnv.vmState.gasLimit = if dh.maxMode: dh.limits.maxLimit
|
||||
else: dh.limits.trgLimit
|
||||
dh.txEnv.vmState.blockCtx.gasLimit = if dh.maxMode: dh.limits.maxLimit
|
||||
else: dh.limits.trgLimit
|
||||
|
||||
proc `maxMode=`*(dh: TxChainRef; val: bool) =
|
||||
## Setter, the packing mode (maximal or target limit) for the next block
|
||||
## header
|
||||
dh.maxMode = val
|
||||
dh.txEnv.vmState.gasLimit = if dh.maxMode: dh.limits.maxLimit
|
||||
else: dh.limits.trgLimit
|
||||
dh.txEnv.vmState.blockCtx.gasLimit = if dh.maxMode: dh.limits.maxLimit
|
||||
else: dh.limits.trgLimit
|
||||
|
||||
proc `miner=`*(dh: TxChainRef; val: EthAddress) =
|
||||
## Setter
|
||||
dh.miner = val
|
||||
dh.txEnv.vmState.minerAddress = val
|
||||
dh.txEnv.vmState.blockCtx.coinbase = val
|
||||
|
||||
proc `profit=`*(dh: TxChainRef; val: UInt256) =
|
||||
## Setter
|
||||
|
@ -107,7 +107,7 @@ proc txFeesCovered(xp: TxPoolRef; item: TxItemRef): bool =
|
||||
let
|
||||
excessBlobGas = xp.chain.excessBlobGas
|
||||
blobGasPrice = getBlobGasPrice(excessBlobGas)
|
||||
if item.tx.maxFeePerBlobGas.uint64 < blobGasPrice:
|
||||
if item.tx.maxFeePerBlobGas < blobGasPrice:
|
||||
debug "invalid tx: maxFeePerBlobGas smaller than blobGasPrice",
|
||||
maxFeePerBlobGas=item.tx.maxFeePerBlobGas,
|
||||
blobGasPrice=blobGasPrice
|
||||
@ -222,7 +222,7 @@ proc classifyValidatePacked*(xp: TxPoolRef;
|
||||
else:
|
||||
xp.chain.limits.trgLimit
|
||||
tx = item.tx.eip1559TxNormalization(xp.chain.baseFee.GasInt)
|
||||
excessBlobGas = vmState.parent.excessBlobGas.get(0'u64)
|
||||
excessBlobGas = calcExcessBlobGas(vmState.parent)
|
||||
|
||||
roDB.validateTransaction(tx, item.sender, gasLimit, baseFee, excessBlobGas, fork).isOk
|
||||
|
||||
|
@ -380,7 +380,7 @@ proc validateTransaction*(
|
||||
if tx.txType >= TxEip4844:
|
||||
# ensure that the user was willing to at least pay the current data gasprice
|
||||
let blobGasPrice = getBlobGasPrice(excessBlobGas)
|
||||
if tx.maxFeePerBlobGas.uint64 < blobGasPrice:
|
||||
if tx.maxFeePerBlobGas < blobGasPrice:
|
||||
return err("invalid tx: maxFeePerBlobGas smaller than blobGasPrice. " &
|
||||
"maxFeePerBlobGas=$1, blobGasPrice=$2" % [$tx.maxFeePerBlobGas, $blobGasPrice])
|
||||
|
||||
|
@ -71,7 +71,7 @@ template getTimestamp*(c: Computation): int64 =
|
||||
when evmc_enabled:
|
||||
c.host.getTxContext().block_timestamp
|
||||
else:
|
||||
c.vmState.timestamp.toUnix
|
||||
c.vmState.blockCtx.timestamp.toUnix
|
||||
|
||||
template getBlockNumber*(c: Computation): UInt256 =
|
||||
when evmc_enabled:
|
||||
@ -83,19 +83,19 @@ template getDifficulty*(c: Computation): DifficultyInt =
|
||||
when evmc_enabled:
|
||||
UInt256.fromEvmc c.host.getTxContext().block_prev_randao
|
||||
else:
|
||||
c.vmState.difficulty
|
||||
c.vmState.difficultyOrPrevRandao
|
||||
|
||||
template getGasLimit*(c: Computation): GasInt =
|
||||
when evmc_enabled:
|
||||
c.host.getTxContext().block_gas_limit.GasInt
|
||||
else:
|
||||
c.vmState.gasLimit
|
||||
c.vmState.blockCtx.gasLimit
|
||||
|
||||
template getBaseFee*(c: Computation): UInt256 =
|
||||
when evmc_enabled:
|
||||
UInt256.fromEvmc c.host.getTxContext().block_base_fee
|
||||
else:
|
||||
c.vmState.baseFee
|
||||
c.vmState.blockCtx.fee.get(0.u256)
|
||||
|
||||
template getChainId*(c: Computation): uint =
|
||||
when evmc_enabled:
|
||||
|
@ -24,30 +24,32 @@ proc init(
|
||||
self: BaseVMState;
|
||||
ac: AccountsCache;
|
||||
parent: BlockHeader;
|
||||
timestamp: EthTime;
|
||||
gasLimit: GasInt;
|
||||
fee: Option[UInt256];
|
||||
prevRandao: Hash256;
|
||||
difficulty: UInt256;
|
||||
miner: EthAddress;
|
||||
blockCtx: BlockContext;
|
||||
com: CommonRef;
|
||||
tracer: TracerRef,
|
||||
asyncFactory: AsyncOperationFactory = AsyncOperationFactory(maybeDataSource: none[AsyncDataSource]()))
|
||||
{.gcsafe.} =
|
||||
## Initialisation helper
|
||||
self.parent = parent
|
||||
self.timestamp = timestamp
|
||||
self.gasLimit = gasLimit
|
||||
self.gasPool = gasLimit
|
||||
self.fee = fee
|
||||
self.prevRandao = prevRandao
|
||||
self.blockDifficulty = difficulty
|
||||
self.blockCtx = blockCtx
|
||||
self.gasPool = blockCtx.gasLimit
|
||||
self.com = com
|
||||
self.tracer = tracer
|
||||
self.stateDB = ac
|
||||
self.minerAddress = miner
|
||||
self.asyncFactory = asyncFactory
|
||||
|
||||
func blockCtx(com: CommonRef, header: BlockHeader):
|
||||
BlockContext {.gcsafe, raises: [CatchableError].} =
|
||||
BlockContext(
|
||||
timestamp : header.timestamp,
|
||||
gasLimit : header.gasLimit,
|
||||
fee : header.fee,
|
||||
prevRandao : header.prevRandao,
|
||||
difficulty : header.difficulty,
|
||||
coinbase : com.minerAddress(header),
|
||||
excessBlobGas: header.excessBlobGas.get(0'u64),
|
||||
)
|
||||
|
||||
# --------------
|
||||
|
||||
proc `$`*(vmState: BaseVMState): string
|
||||
@ -59,16 +61,11 @@ proc `$`*(vmState: BaseVMState): string
|
||||
&"\n blockNumber: {vmState.parent.blockNumber + 1}"
|
||||
|
||||
proc new*(
|
||||
T: type BaseVMState;
|
||||
parent: BlockHeader; ## parent header, account sync position
|
||||
timestamp: EthTime; ## tx env: time stamp
|
||||
gasLimit: GasInt; ## tx env: gas limit
|
||||
fee: Option[UInt256]; ## tx env: optional base fee
|
||||
prevRandao: Hash256; ## tx env: POS block randomness
|
||||
difficulty: UInt256, ## tx env: difficulty
|
||||
miner: EthAddress; ## tx env: coinbase(PoW) or signer(PoA)
|
||||
com: CommonRef; ## block chain config
|
||||
tracer: TracerRef = nil): T
|
||||
T: type BaseVMState;
|
||||
parent: BlockHeader; ## parent header, account sync position
|
||||
blockCtx: BlockContext;
|
||||
com: CommonRef; ## block chain config
|
||||
tracer: TracerRef = nil): T
|
||||
{.gcsafe.} =
|
||||
## Create a new `BaseVMState` descriptor from a parent block header. This
|
||||
## function internally constructs a new account state cache rooted at
|
||||
@ -79,25 +76,15 @@ proc new*(
|
||||
## with the `parent` block header.
|
||||
new result
|
||||
result.init(
|
||||
ac = AccountsCache.init(com.db, parent.stateRoot, com.pruneTrie),
|
||||
parent = parent,
|
||||
timestamp = timestamp,
|
||||
gasLimit = gasLimit,
|
||||
fee = fee,
|
||||
prevRandao = prevRandao,
|
||||
difficulty = difficulty,
|
||||
miner = miner,
|
||||
com = com,
|
||||
tracer = tracer)
|
||||
ac = AccountsCache.init(com.db, parent.stateRoot, com.pruneTrie),
|
||||
parent = parent,
|
||||
blockCtx = blockCtx,
|
||||
com = com,
|
||||
tracer = tracer)
|
||||
|
||||
proc reinit*(self: BaseVMState; ## Object descriptor
|
||||
parent: BlockHeader; ## parent header, account sync pos.
|
||||
timestamp: EthTime; ## tx env: time stamp
|
||||
gasLimit: GasInt; ## tx env: gas limit
|
||||
fee: Option[UInt256]; ## tx env: optional base fee
|
||||
prevRandao:Hash256; ## tx env: POS block randomness
|
||||
difficulty:UInt256, ## tx env: difficulty
|
||||
miner: EthAddress; ## tx env: coinbase(PoW) or signer(PoA)
|
||||
proc reinit*(self: BaseVMState; ## Object descriptor
|
||||
parent: BlockHeader; ## parent header, account sync pos.
|
||||
blockCtx: BlockContext
|
||||
): bool
|
||||
{.gcsafe.} =
|
||||
## Re-initialise state descriptor. The `AccountsCache` database is
|
||||
@ -117,22 +104,17 @@ proc reinit*(self: BaseVMState; ## Object descriptor
|
||||
else: AccountsCache.init(db, parent.stateRoot, com.pruneTrie)
|
||||
self[].reset
|
||||
self.init(
|
||||
ac = ac,
|
||||
parent = parent,
|
||||
timestamp = timestamp,
|
||||
gasLimit = gasLimit,
|
||||
fee = fee,
|
||||
prevRandao = prevRandao,
|
||||
difficulty = difficulty,
|
||||
miner = miner,
|
||||
com = com,
|
||||
tracer = tracer)
|
||||
ac = ac,
|
||||
parent = parent,
|
||||
blockCtx = blockCtx,
|
||||
com = com,
|
||||
tracer = tracer)
|
||||
return true
|
||||
# else: false
|
||||
|
||||
proc reinit*(self: BaseVMState; ## Object descriptor
|
||||
parent: BlockHeader; ## parent header, account sync pos.
|
||||
header: BlockHeader; ## header with tx environment data fields
|
||||
proc reinit*(self: BaseVMState; ## Object descriptor
|
||||
parent: BlockHeader; ## parent header, account sync pos.
|
||||
header: BlockHeader; ## header with tx environment data fields
|
||||
): bool
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
## Variant of `reinit()`. The `parent` argument is used to sync the accounts
|
||||
@ -142,13 +124,9 @@ proc reinit*(self: BaseVMState; ## Object descriptor
|
||||
## It requires the `header` argument properly initalised so that for PoA
|
||||
## networks, the miner address is retrievable via `ecRecover()`.
|
||||
result = self.reinit(
|
||||
parent = parent,
|
||||
timestamp = header.timestamp,
|
||||
gasLimit = header.gasLimit,
|
||||
fee = header.fee,
|
||||
prevRandao= header.prevRandao,
|
||||
difficulty= header.difficulty,
|
||||
miner = self.com.minerAddress(header))
|
||||
parent = parent,
|
||||
blockCtx = self.com.blockCtx(header),
|
||||
)
|
||||
|
||||
proc reinit*(self: BaseVMState; ## Object descriptor
|
||||
header: BlockHeader; ## header with tx environment data fields
|
||||
@ -178,16 +156,11 @@ proc init*(
|
||||
## It requires the `header` argument properly initalised so that for PoA
|
||||
## networks, the miner address is retrievable via `ecRecover()`.
|
||||
self.init(
|
||||
ac = AccountsCache.init(com.db, parent.stateRoot, com.pruneTrie),
|
||||
parent = parent,
|
||||
timestamp = header.timestamp,
|
||||
gasLimit = header.gasLimit,
|
||||
fee = header.fee,
|
||||
prevRandao = header.prevRandao,
|
||||
difficulty = header.difficulty,
|
||||
miner = com.minerAddress(header),
|
||||
com = com,
|
||||
tracer = tracer)
|
||||
ac = AccountsCache.init(com.db, parent.stateRoot, com.pruneTrie),
|
||||
parent = parent,
|
||||
blockCtx = com.blockCtx(header),
|
||||
com = com,
|
||||
tracer = tracer)
|
||||
|
||||
proc new*(
|
||||
T: type BaseVMState;
|
||||
@ -252,37 +225,29 @@ proc statelessInit*(
|
||||
vmState.init(
|
||||
ac = AccountsCache.init(com.db, parent.stateRoot, com.pruneTrie),
|
||||
parent = parent,
|
||||
timestamp = header.timestamp,
|
||||
gasLimit = header.gasLimit,
|
||||
fee = header.fee,
|
||||
prevRandao = header.prevRandao,
|
||||
difficulty = header.difficulty,
|
||||
miner = com.minerAddress(header),
|
||||
blockCtx = com.blockCtx(header),
|
||||
com = com,
|
||||
tracer = tracer,
|
||||
asyncFactory = asyncFactory)
|
||||
return true
|
||||
|
||||
method coinbase*(vmState: BaseVMState): EthAddress {.base, gcsafe.} =
|
||||
vmState.minerAddress
|
||||
vmState.blockCtx.coinbase
|
||||
|
||||
method blockNumber*(vmState: BaseVMState): BlockNumber {.base, gcsafe.} =
|
||||
# it should return current block number
|
||||
# and not head.blockNumber
|
||||
vmState.parent.blockNumber + 1
|
||||
|
||||
method difficulty*(vmState: BaseVMState): UInt256 {.base, gcsafe.} =
|
||||
method difficultyOrPrevRandao*(vmState: BaseVMState): UInt256 {.base, gcsafe.} =
|
||||
if vmState.com.consensus == ConsensusType.POS:
|
||||
# EIP-4399/EIP-3675
|
||||
UInt256.fromBytesBE(vmState.prevRandao.data)
|
||||
UInt256.fromBytesBE(vmState.blockCtx.prevRandao.data)
|
||||
else:
|
||||
vmState.blockDifficulty
|
||||
vmState.blockCtx.difficulty
|
||||
|
||||
method baseFee*(vmState: BaseVMState): UInt256 {.base, gcsafe.} =
|
||||
if vmState.fee.isSome:
|
||||
vmState.fee.get
|
||||
else:
|
||||
0.u256
|
||||
vmState.blockCtx.fee.get(0.u256)
|
||||
|
||||
when defined(geth):
|
||||
import db/geth_db
|
||||
@ -335,7 +300,7 @@ func forkDeterminationInfoForVMState*(vmState: BaseVMState): ForkDeterminationIn
|
||||
# FIXME-Adam: Is this timestamp right? Note that up above in blockNumber we add 1;
|
||||
# should timestamp be adding 12 or something?
|
||||
# Also, can I get the TD? Do I need to?
|
||||
forkDeterminationInfo(vmState.blockNumber, vmState.timestamp)
|
||||
forkDeterminationInfo(vmState.blockNumber, vmState.blockCtx.timestamp)
|
||||
|
||||
func determineFork*(vmState: BaseVMState): EVMFork =
|
||||
vmState.com.toEVMFork(vmState.forkDeterminationInfoForVMState)
|
||||
|
@ -42,15 +42,20 @@ type
|
||||
GenerateWitness
|
||||
ClearCache
|
||||
|
||||
BaseVMState* = ref object of RootObj
|
||||
com* : CommonRef
|
||||
gasPool* : GasInt
|
||||
parent* : BlockHeader
|
||||
BlockContext* = object
|
||||
timestamp* : EthTime
|
||||
gasLimit* : GasInt
|
||||
fee* : Option[UInt256]
|
||||
prevRandao* : Hash256
|
||||
blockDifficulty* : UInt256
|
||||
difficulty* : UInt256
|
||||
coinbase* : EthAddress
|
||||
excessBlobGas* : uint64
|
||||
|
||||
BaseVMState* = ref object of RootObj
|
||||
com* : CommonRef
|
||||
gasPool* : GasInt
|
||||
parent* : BlockHeader
|
||||
blockCtx* : BlockContext
|
||||
flags* : set[VMFlag]
|
||||
tracer* : TracerRef
|
||||
receipts* : seq[Receipt]
|
||||
@ -61,7 +66,6 @@ type
|
||||
txVersionedHashes*: VersionedHashes
|
||||
gasCosts* : GasCosts
|
||||
fork* : EVMFork
|
||||
minerAddress* : EthAddress
|
||||
asyncFactory* : AsyncOperationFactory
|
||||
|
||||
Computation* = ref object
|
||||
|
@ -189,7 +189,7 @@ proc populateTransactionObject*(tx: Transaction, header: BlockHeader, txIndex: i
|
||||
result.accessList = some(toAccessTupleList(tx.accessList))
|
||||
|
||||
if tx.txType >= TxEIP4844:
|
||||
result.maxFeePerBlobGas = some(encodeQuantity(tx.maxFeePerBlobGas.uint64))
|
||||
result.maxFeePerBlobGas = some(encodeQuantity(tx.maxFeePerBlobGas))
|
||||
result.versionedHashes = some(tx.versionedHashes)
|
||||
|
||||
proc populateBlockObject*(header: BlockHeader, chain: CoreDbRef, fullTx: bool, isUncle = false): BlockObject
|
||||
|
@ -247,8 +247,8 @@ proc prepareToRunComputation(host: TransactionHost, call: CallParams) =
|
||||
# EIP-4844
|
||||
if fork >= FkCancun:
|
||||
let blobFee = calcDataFee(call.versionedHashes.len,
|
||||
vmState.parent.excessBlobGas).GasInt
|
||||
db.subBalance(call.sender, blobFee.u256)
|
||||
vmState.blockCtx.excessBlobGas)
|
||||
db.subBalance(call.sender, blobFee)
|
||||
|
||||
proc calculateAndPossiblyRefundGas(host: TransactionHost, call: CallParams): GasInt =
|
||||
let c = host.computation
|
||||
|
@ -53,17 +53,17 @@ proc setupTxContext(host: TransactionHost) =
|
||||
host.txContext.tx_gas_price = vmState.txGasPrice.u256.toEvmc
|
||||
host.txContext.tx_origin = vmState.txOrigin.toEvmc
|
||||
# vmState.coinbase now unused
|
||||
host.txContext.block_coinbase = vmState.minerAddress.toEvmc
|
||||
host.txContext.block_coinbase = vmState.blockCtx.coinbase.toEvmc
|
||||
# vmState.blockNumber now unused
|
||||
host.txContext.block_number = (vmState.blockNumber
|
||||
.truncate(typeof(host.txContext.block_number)))
|
||||
# vmState.timestamp now unused
|
||||
host.txContext.block_timestamp = vmState.timestamp.toUnix
|
||||
host.txContext.block_timestamp = vmState.blockCtx.timestamp.toUnix
|
||||
# vmState.gasLimit now unused
|
||||
host.txContext.block_gas_limit = vmState.gasLimit
|
||||
host.txContext.block_gas_limit = vmState.blockCtx.gasLimit
|
||||
# vmState.difficulty now unused
|
||||
host.txContext.chain_id = vmState.com.chainId.uint.u256.toEvmc
|
||||
host.txContext.block_base_fee = vmState.baseFee.toEvmc
|
||||
host.txContext.block_base_fee = vmState.blockCtx.fee.get(0.u256).toEvmc
|
||||
|
||||
if vmState.txVersionedHashes.len > 0:
|
||||
type
|
||||
@ -82,7 +82,7 @@ proc setupTxContext(host: TransactionHost) =
|
||||
|
||||
# EIP-4399
|
||||
# Transfer block randomness to difficulty OPCODE
|
||||
let difficulty = vmState.difficulty.toEvmc
|
||||
let difficulty = vmState.difficultyOrPrevRandao.toEvmc
|
||||
host.txContext.block_prev_randao = flip256(difficulty)
|
||||
|
||||
host.cachedTxContext = true
|
||||
|
@ -96,11 +96,13 @@ proc debugAccounts*(vmState: BaseVMState): string =
|
||||
proc debug*(vms: BaseVMState): string =
|
||||
result.add "com.consensus : " & $vms.com.consensus & "\n"
|
||||
result.add "parent : " & $vms.parent.blockHash & "\n"
|
||||
result.add "timestamp : " & $vms.timestamp.toUnix & "\n"
|
||||
result.add "gasLimit : " & $vms.gasLimit & "\n"
|
||||
result.add "fee : " & $vms.fee & "\n"
|
||||
result.add "prevRandao : " & $vms.prevRandao & "\n"
|
||||
result.add "blockDifficulty : " & $vms.blockDifficulty & "\n"
|
||||
result.add "timestamp : " & $vms.blockCtx.timestamp.toUnix & "\n"
|
||||
result.add "gasLimit : " & $vms.blockCtx.gasLimit & "\n"
|
||||
result.add "fee : " & $vms.blockCtx.fee & "\n"
|
||||
result.add "prevRandao : " & $vms.blockCtx.prevRandao & "\n"
|
||||
result.add "blockDifficulty : " & $vms.blockCtx.difficulty & "\n"
|
||||
result.add "coinbase : " & $vms.blockCtx.coinbase & "\n"
|
||||
result.add "excessBlobGas : " & $vms.blockCtx.excessBlobGas & "\n"
|
||||
result.add "flags : " & $vms.flags & "\n"
|
||||
result.add "receipts.len : " & $vms.receipts.len & "\n"
|
||||
result.add "stateDB.root : " & $vms.stateDB.rootHash & "\n"
|
||||
@ -108,7 +110,6 @@ proc debug*(vms: BaseVMState): string =
|
||||
result.add "txOrigin : " & $vms.txOrigin & "\n"
|
||||
result.add "txGasPrice : " & $vms.txGasPrice & "\n"
|
||||
result.add "fork : " & $vms.fork & "\n"
|
||||
result.add "minerAddress : " & $vms.minerAddress & "\n"
|
||||
|
||||
proc `$`(x: ChainId): string =
|
||||
$int(x)
|
||||
|
@ -20,7 +20,7 @@ export
|
||||
vms.buildWitness,
|
||||
vms.coinbase,
|
||||
vms.determineFork,
|
||||
vms.difficulty,
|
||||
vms.difficultyOrPrevRandao,
|
||||
vms.baseFee,
|
||||
vms.forkDeterminationInfoForVMState,
|
||||
vms.generateWitness,
|
||||
|
@ -21,7 +21,8 @@ export
|
||||
vmt.MsgFlags,
|
||||
vmt.TracerFlags,
|
||||
vmt.TracerRef,
|
||||
vmt.VMFlag
|
||||
vmt.VMFlag,
|
||||
vmt.BlockContext
|
||||
|
||||
when defined(evmc_enabled):
|
||||
import
|
||||
|
@ -119,7 +119,7 @@ proc tx7(i: int): Transaction =
|
||||
maxFee: 10.GasInt,
|
||||
accessList: accesses,
|
||||
versionedHashes: @[digest],
|
||||
maxFeePerBlobGas: 10000000.GasInt,
|
||||
maxFeePerBlobGas: 10000000.u256,
|
||||
)
|
||||
|
||||
proc tx8(i: int): Transaction =
|
||||
@ -136,7 +136,7 @@ proc tx8(i: int): Transaction =
|
||||
maxFee: 10.GasInt,
|
||||
accessList: accesses,
|
||||
versionedHashes: @[digest],
|
||||
maxFeePerBlobGas: 10000000.GasInt,
|
||||
maxFeePerBlobGas: 10000000.u256,
|
||||
)
|
||||
|
||||
proc privKey(keyHex: string): PrivateKey =
|
||||
|
@ -366,7 +366,7 @@ proc opEnvMain*() =
|
||||
assembler:
|
||||
title: "EIP-4399 PrevRandao: EMPTY_UNCLE_HASH"
|
||||
setup:
|
||||
vmState.prevRandao = EMPTY_UNCLE_HASH
|
||||
vmState.blockCtx.prevRandao = EMPTY_UNCLE_HASH
|
||||
code:
|
||||
PrevRandao
|
||||
STOP
|
||||
@ -387,7 +387,7 @@ proc opEnvMain*() =
|
||||
stack:
|
||||
"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
|
||||
fork: Cancun
|
||||
|
||||
|
||||
assembler:
|
||||
title: "EIP-4844: BlobHash 0"
|
||||
code:
|
||||
@ -397,7 +397,7 @@ proc opEnvMain*() =
|
||||
stack:
|
||||
"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
|
||||
fork: Cancun
|
||||
|
||||
|
||||
assembler:
|
||||
title: "EIP-4844: BlobHash 2"
|
||||
code:
|
||||
@ -407,7 +407,7 @@ proc opEnvMain*() =
|
||||
stack:
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
fork: Cancun
|
||||
|
||||
|
||||
assembler:
|
||||
title: "EIP-4844: BlobHash 32 Bit high"
|
||||
code:
|
||||
@ -417,7 +417,7 @@ proc opEnvMain*() =
|
||||
stack:
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
fork: Cancun
|
||||
|
||||
|
||||
assembler:
|
||||
title: "EIP-4844: BlobHash 64 Bit high"
|
||||
code:
|
||||
@ -427,7 +427,7 @@ proc opEnvMain*() =
|
||||
stack:
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
fork: Cancun
|
||||
|
||||
|
||||
assembler:
|
||||
title: "EIP-4844: BlobHash 128 Bit high"
|
||||
code:
|
||||
@ -437,7 +437,7 @@ proc opEnvMain*() =
|
||||
stack:
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
fork: Cancun
|
||||
|
||||
|
||||
assembler:
|
||||
title: "EIP-4844: BlobHash 256 Bit high"
|
||||
code:
|
||||
|
@ -137,7 +137,7 @@ proc parseTx*(n: JsonNode, dataIndex, gasIndex, valueIndex: int): Transaction =
|
||||
maxFee : omitZero(GasInt, "maxFeePerGas"),
|
||||
accessList: omitZero(AccessList, "accessLists", dataIndex),
|
||||
maxPriorityFee: omitZero(GasInt, "maxPriorityFeePerGas"),
|
||||
maxFeePerBlobGas: omitZero(GasInt, "maxFeePerBlobGas"),
|
||||
maxFeePerBlobGas: omitZero(UInt256, "maxFeePerBlobGas"),
|
||||
versionedHashes: omitZero(VersionedHashes, "blobVersionedHashes")
|
||||
)
|
||||
|
||||
|
@ -234,7 +234,7 @@ proc parseTx(n: JsonNode, chainId: ChainID): Transaction =
|
||||
required(tx, GasInt, maxPriorityFeePerGas)
|
||||
required(tx, GasInt, maxFeePerGas)
|
||||
omitZero(tx, AccessList, accessList)
|
||||
required(tx, GasInt, maxFeePerBlobGas)
|
||||
required(tx, UInt256, maxFeePerBlobGas)
|
||||
required(tx, VersionedHashes, blobVersionedHashes)
|
||||
|
||||
var eip155 = true
|
||||
|
2
vendor/nim-eth
vendored
2
vendor/nim-eth
vendored
@ -1 +1 @@
|
||||
Subproject commit ac680ed79bf9e4e78ca14a001eb7f78acdf7b07d
|
||||
Subproject commit fe88d9e6b73f97d92cefa861add6f069ef70abf2
|
Loading…
x
Reference in New Issue
Block a user