devnet-5: Implement EIP-7691: Blob throughput increase (#2957)
This commit is contained in:
parent
1dff892995
commit
80f8b3c2b1
|
@ -39,19 +39,19 @@ const
|
||||||
DATAHASH_START_ADDRESS* = toAddress(0x20000.u256)
|
DATAHASH_START_ADDRESS* = toAddress(0x20000.u256)
|
||||||
DATAHASH_ADDRESS_COUNT* = 1000
|
DATAHASH_ADDRESS_COUNT* = 1000
|
||||||
|
|
||||||
func getMinExcessBlobGasForBlobGasPrice(data_gas_price: uint64): uint64 =
|
func getMinExcessBlobGasForBlobGasPrice(data_gas_price: uint64, electra: bool): uint64 =
|
||||||
var
|
var
|
||||||
current_excess_data_gas = 0'u64
|
current_excess_data_gas = 0'u64
|
||||||
current_data_gas_price = 1'u64
|
current_data_gas_price = 1'u64
|
||||||
|
|
||||||
while current_data_gas_price < data_gas_price:
|
while current_data_gas_price < data_gas_price:
|
||||||
current_excess_data_gas += GAS_PER_BLOB.uint64
|
current_excess_data_gas += GAS_PER_BLOB.uint64
|
||||||
current_data_gas_price = getBlobBaseFee(current_excess_data_gas).truncate(uint64)
|
current_data_gas_price = getBlobBaseFee(current_excess_data_gas, electra).truncate(uint64)
|
||||||
|
|
||||||
return current_excess_data_gas
|
return current_excess_data_gas
|
||||||
|
|
||||||
func getMinExcessBlobsForBlobGasPrice*(data_gas_price: uint64): uint64 =
|
func getMinExcessBlobsForBlobGasPrice*(data_gas_price: uint64, electra: bool): uint64 =
|
||||||
return getMinExcessBlobGasForBlobGasPrice(data_gas_price) div GAS_PER_BLOB.uint64
|
return getMinExcessBlobGasForBlobGasPrice(data_gas_price, electra) div GAS_PER_BLOB.uint64
|
||||||
|
|
||||||
proc addBlobTransaction*(pool: TestBlobTxPool, tx: PooledTransaction) =
|
proc addBlobTransaction*(pool: TestBlobTxPool, tx: PooledTransaction) =
|
||||||
let txHash = rlpHash(tx)
|
let txHash = rlpHash(tx)
|
||||||
|
|
|
@ -73,7 +73,7 @@ proc verifyPayload(step: NewPayloads,
|
||||||
excessBlobGas: Opt.some(parentExcessBlobGas),
|
excessBlobGas: Opt.some(parentExcessBlobGas),
|
||||||
blobGasUsed: Opt.some(parentBlobGasUsed)
|
blobGasUsed: Opt.some(parentBlobGasUsed)
|
||||||
)
|
)
|
||||||
expectedExcessBlobGas = calcExcessBlobGas(parent)
|
expectedExcessBlobGas = calcExcessBlobGas(parent, com.isPragueOrLater(payload.timestamp.EthTime))
|
||||||
|
|
||||||
if com.isCancunOrLater(payload.timestamp.EthTime):
|
if com.isCancunOrLater(payload.timestamp.EthTime):
|
||||||
if payload.excessBlobGas.isNone:
|
if payload.excessBlobGas.isNone:
|
||||||
|
@ -96,7 +96,7 @@ proc verifyPayload(step: NewPayloads,
|
||||||
|
|
||||||
var
|
var
|
||||||
totalBlobCount = 0
|
totalBlobCount = 0
|
||||||
expectedBlobGasPrice = getBlobBaseFee(expectedExcessBlobGas)
|
expectedBlobGasPrice = getBlobBaseFee(expectedExcessBlobGas, com.isPragueOrLater(payload.timestamp.EthTime))
|
||||||
|
|
||||||
for tx in blobTxsInPayload:
|
for tx in blobTxsInPayload:
|
||||||
let blobCount = tx.versionedHashes.len
|
let blobCount = tx.versionedHashes.len
|
||||||
|
|
|
@ -41,7 +41,7 @@ import
|
||||||
|
|
||||||
# Precalculate the first data gas cost increase
|
# Precalculate the first data gas cost increase
|
||||||
const
|
const
|
||||||
DATA_GAS_COST_INCREMENT_EXCEED_BLOBS = getMinExcessBlobsForBlobGasPrice(2).int
|
DATA_GAS_COST_INCREMENT_EXCEED_BLOBS = getMinExcessBlobsForBlobGasPrice(2, false).int
|
||||||
TARGET_BLOBS_PER_BLOCK = int(TARGET_BLOB_GAS_PER_BLOCK div GAS_PER_BLOB)
|
TARGET_BLOBS_PER_BLOCK = int(TARGET_BLOB_GAS_PER_BLOCK div GAS_PER_BLOB)
|
||||||
|
|
||||||
proc getGenesis(param: NetworkParams) =
|
proc getGenesis(param: NetworkParams) =
|
||||||
|
|
|
@ -92,10 +92,15 @@ const
|
||||||
GAS_PER_BLOB* = (1 shl 17).uint64 # 2^17
|
GAS_PER_BLOB* = (1 shl 17).uint64 # 2^17
|
||||||
TARGET_BLOB_GAS_PER_BLOCK* = 393216
|
TARGET_BLOB_GAS_PER_BLOCK* = 393216
|
||||||
MIN_BLOB_GASPRICE* = 1'u64
|
MIN_BLOB_GASPRICE* = 1'u64
|
||||||
BLOB_GASPRICE_UPDATE_FRACTION* = 3338477'u64
|
BLOB_BASE_FEE_UPDATE_FRACTION* = 3338477
|
||||||
MAX_BLOB_GAS_PER_BLOCK* = 786432
|
MAX_BLOB_GAS_PER_BLOCK* = 786432
|
||||||
MAX_BLOBS_PER_BLOCK* = int(MAX_BLOB_GAS_PER_BLOCK div GAS_PER_BLOB)
|
MAX_BLOBS_PER_BLOCK* = int(MAX_BLOB_GAS_PER_BLOCK div GAS_PER_BLOB)
|
||||||
|
|
||||||
|
MAX_BLOB_GAS_PER_BLOCK_ELECTRA* = 1179648
|
||||||
|
TARGET_BLOB_GAS_PER_BLOCK_ELECTRA* = 786432
|
||||||
|
BLOB_BASE_FEE_UPDATE_FRACTION_ELECTRA* = 5007716
|
||||||
|
MAX_BLOBS_PER_BLOCK_ELECTRA* = int(MAX_BLOB_GAS_PER_BLOCK_ELECTRA div GAS_PER_BLOB)
|
||||||
|
|
||||||
# EIP-4788 addresses
|
# EIP-4788 addresses
|
||||||
# BEACON_ROOTS_ADDRESS is the address where historical beacon roots are stored as per EIP-4788
|
# BEACON_ROOTS_ADDRESS is the address where historical beacon roots are stored as per EIP-4788
|
||||||
BEACON_ROOTS_ADDRESS* = address"0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02"
|
BEACON_ROOTS_ADDRESS* = address"0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02"
|
||||||
|
|
|
@ -15,6 +15,7 @@ import
|
||||||
kzg4844/kzg,
|
kzg4844/kzg,
|
||||||
results,
|
results,
|
||||||
stint,
|
stint,
|
||||||
|
./eip7691,
|
||||||
../constants,
|
../constants,
|
||||||
../common/common
|
../common/common
|
||||||
|
|
||||||
|
@ -81,15 +82,16 @@ proc pointEvaluation*(input: openArray[byte]): Result[void, string] =
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
# calcExcessBlobGas implements calc_excess_data_gas from EIP-4844
|
# calcExcessBlobGas implements calc_excess_data_gas from EIP-4844
|
||||||
proc calcExcessBlobGas*(parent: Header): uint64 =
|
proc calcExcessBlobGas*(parent: Header, electra: bool): uint64 =
|
||||||
let
|
let
|
||||||
excessBlobGas = parent.excessBlobGas.get(0'u64)
|
excessBlobGas = parent.excessBlobGas.get(0'u64)
|
||||||
blobGasUsed = parent.blobGasUsed.get(0'u64)
|
blobGasUsed = parent.blobGasUsed.get(0'u64)
|
||||||
|
targetBlobGasPerBlock = getTargetBlobGasPerBlock(electra)
|
||||||
|
|
||||||
if excessBlobGas + blobGasUsed < TARGET_BLOB_GAS_PER_BLOCK:
|
if excessBlobGas + blobGasUsed < targetBlobGasPerBlock:
|
||||||
0'u64
|
0'u64
|
||||||
else:
|
else:
|
||||||
excessBlobGas + blobGasUsed - TARGET_BLOB_GAS_PER_BLOCK
|
excessBlobGas + blobGasUsed - targetBlobGasPerBlock
|
||||||
|
|
||||||
# fakeExponential approximates factor * e ** (num / denom) using a taylor expansion
|
# fakeExponential approximates factor * e ** (num / denom) using a taylor expansion
|
||||||
# as described in the EIP-4844 spec.
|
# as described in the EIP-4844 spec.
|
||||||
|
@ -113,17 +115,19 @@ proc getTotalBlobGas*(versionedHashesLen: int): uint64 =
|
||||||
GAS_PER_BLOB * versionedHashesLen.uint64
|
GAS_PER_BLOB * versionedHashesLen.uint64
|
||||||
|
|
||||||
# getBlobBaseFee implements get_data_gas_price from EIP-4844
|
# getBlobBaseFee implements get_data_gas_price from EIP-4844
|
||||||
func getBlobBaseFee*(excessBlobGas: uint64): UInt256 =
|
func getBlobBaseFee*(excessBlobGas: uint64, electra: bool): UInt256 =
|
||||||
|
let blobBaseFeeUpdateFraction = getBlobBaseFeeUpdateFraction(electra).u256
|
||||||
fakeExponential(
|
fakeExponential(
|
||||||
MIN_BLOB_GASPRICE.u256,
|
MIN_BLOB_GASPRICE.u256,
|
||||||
excessBlobGas.u256,
|
excessBlobGas.u256,
|
||||||
BLOB_GASPRICE_UPDATE_FRACTION.u256
|
blobBaseFeeUpdateFraction
|
||||||
)
|
)
|
||||||
|
|
||||||
proc calcDataFee*(versionedHashesLen: int,
|
proc calcDataFee*(versionedHashesLen: int,
|
||||||
excessBlobGas: uint64): UInt256 =
|
excessBlobGas: uint64,
|
||||||
|
electra: bool): UInt256 =
|
||||||
getTotalBlobGas(versionedHashesLen).u256 *
|
getTotalBlobGas(versionedHashesLen).u256 *
|
||||||
getBlobBaseFee(excessBlobGas)
|
getBlobBaseFee(excessBlobGas, electra)
|
||||||
|
|
||||||
func blobGasUsed(txs: openArray[Transaction]): uint64 =
|
func blobGasUsed(txs: openArray[Transaction]): uint64 =
|
||||||
for tx in txs:
|
for tx in txs:
|
||||||
|
@ -150,13 +154,15 @@ func validateEip4844Header*(
|
||||||
return err("expect EIP-4844 excessBlobGas in block header")
|
return err("expect EIP-4844 excessBlobGas in block header")
|
||||||
|
|
||||||
let
|
let
|
||||||
|
electra = com.isPragueOrLater(header.timestamp)
|
||||||
headerBlobGasUsed = header.blobGasUsed.get()
|
headerBlobGasUsed = header.blobGasUsed.get()
|
||||||
blobGasUsed = blobGasUsed(txs)
|
blobGasUsed = blobGasUsed(txs)
|
||||||
headerExcessBlobGas = header.excessBlobGas.get
|
headerExcessBlobGas = header.excessBlobGas.get
|
||||||
excessBlobGas = calcExcessBlobGas(parentHeader)
|
excessBlobGas = calcExcessBlobGas(parentHeader, electra)
|
||||||
|
maxBlobGasPerBlock = getMaxBlobGasPerBlock(electra)
|
||||||
|
|
||||||
if blobGasUsed > MAX_BLOB_GAS_PER_BLOCK:
|
if blobGasUsed > maxBlobGasPerBlock:
|
||||||
return err("blobGasUsed " & $blobGasUsed & " exceeds maximum allowance " & $MAX_BLOB_GAS_PER_BLOCK)
|
return err("blobGasUsed " & $blobGasUsed & " exceeds maximum allowance " & $maxBlobGasPerBlock)
|
||||||
|
|
||||||
if headerBlobGasUsed != blobGasUsed:
|
if headerBlobGasUsed != blobGasUsed:
|
||||||
return err("calculated blobGas not equal header.blobGasUsed")
|
return err("calculated blobGas not equal header.blobGasUsed")
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Nimbus
|
||||||
|
# Copyright (c) 2024 Status Research & Development GmbH
|
||||||
|
# Licensed under either of
|
||||||
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
||||||
|
# http://opensource.org/licenses/MIT)
|
||||||
|
# at your option. This file may not be copied, modified, or distributed except
|
||||||
|
# according to those terms.
|
||||||
|
|
||||||
|
{.push raises: [].}
|
||||||
|
|
||||||
|
import
|
||||||
|
../constants
|
||||||
|
|
||||||
|
func getMaxBlobGasPerBlock*(electra: bool): uint64 =
|
||||||
|
if electra: MAX_BLOB_GAS_PER_BLOCK_ELECTRA.uint64
|
||||||
|
else: MAX_BLOB_GAS_PER_BLOCK.uint64
|
||||||
|
|
||||||
|
func getTargetBlobGasPerBlock*(electra: bool): uint64 =
|
||||||
|
if electra: TARGET_BLOB_GAS_PER_BLOCK_ELECTRA.uint64
|
||||||
|
else: TARGET_BLOB_GAS_PER_BLOCK.uint64
|
||||||
|
|
||||||
|
func getBlobBaseFeeUpdateFraction*(electra: bool): uint64 =
|
||||||
|
if electra: BLOB_BASE_FEE_UPDATE_FRACTION_ELECTRA.uint64
|
||||||
|
else: BLOB_BASE_FEE_UPDATE_FRACTION.uint64
|
||||||
|
|
||||||
|
func getMaxBlobsPerBlock*(electra: bool): uint64 =
|
||||||
|
if electra: MAX_BLOBS_PER_BLOCK_ELECTRA.uint64
|
||||||
|
else: MAX_BLOBS_PER_BLOCK.uint64
|
|
@ -22,6 +22,7 @@ import
|
||||||
../../evm/types,
|
../../evm/types,
|
||||||
../../constants,
|
../../constants,
|
||||||
../eip4844,
|
../eip4844,
|
||||||
|
../eip7691,
|
||||||
../validate
|
../validate
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -88,10 +89,12 @@ proc processTransactionImpl(
|
||||||
vmState.gasPool -= tx.gasLimit
|
vmState.gasPool -= tx.gasLimit
|
||||||
|
|
||||||
# blobGasUsed will be added to vmState.blobGasUsed if the tx is ok.
|
# blobGasUsed will be added to vmState.blobGasUsed if the tx is ok.
|
||||||
let blobGasUsed = tx.getTotalBlobGas
|
let
|
||||||
if vmState.blobGasUsed + blobGasUsed > MAX_BLOB_GAS_PER_BLOCK:
|
blobGasUsed = tx.getTotalBlobGas
|
||||||
|
maxBlobGasPerBlock = getMaxBlobGasPerBlock(vmState.fork >= FkPrague)
|
||||||
|
if vmState.blobGasUsed + blobGasUsed > maxBlobGasPerBlock:
|
||||||
return err("blobGasUsed " & $blobGasUsed &
|
return err("blobGasUsed " & $blobGasUsed &
|
||||||
" exceeds maximum allowance " & $MAX_BLOB_GAS_PER_BLOCK)
|
" exceeds maximum allowance " & $maxBlobGasPerBlock)
|
||||||
|
|
||||||
# Actually, the eip-1559 reference does not mention an early exit.
|
# Actually, the eip-1559 reference does not mention an early exit.
|
||||||
#
|
#
|
||||||
|
|
|
@ -123,7 +123,7 @@ proc setupVMState(com: CommonRef; parent: Header): BaseVMState =
|
||||||
prevRandao : pos.prevRandao,
|
prevRandao : pos.prevRandao,
|
||||||
difficulty : UInt256.zero(),
|
difficulty : UInt256.zero(),
|
||||||
coinbase : pos.feeRecipient,
|
coinbase : pos.feeRecipient,
|
||||||
excessBlobGas: calcExcessBlobGas(parent),
|
excessBlobGas: calcExcessBlobGas(parent, com.isPragueOrLater(pos.timestamp)),
|
||||||
parentHash : parent.blockHash,
|
parentHash : parent.blockHash,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import
|
||||||
../../evm/types,
|
../../evm/types,
|
||||||
../eip4844,
|
../eip4844,
|
||||||
../eip6110,
|
../eip6110,
|
||||||
|
../eip7691,
|
||||||
"."/[tx_desc, tx_item, tx_tabs, tx_tabs/tx_status, tx_info],
|
"."/[tx_desc, tx_item, tx_tabs, tx_tabs/tx_status, tx_info],
|
||||||
tx_tasks/[tx_bucket]
|
tx_tasks/[tx_bucket]
|
||||||
|
|
||||||
|
@ -81,7 +82,7 @@ proc classifyValidatePacked(vmState: BaseVMState; item: TxItemRef): bool =
|
||||||
fork = vmState.fork
|
fork = vmState.fork
|
||||||
gasLimit = vmState.blockCtx.gasLimit
|
gasLimit = vmState.blockCtx.gasLimit
|
||||||
tx = item.tx.eip1559TxNormalization(baseFee.truncate(GasInt))
|
tx = item.tx.eip1559TxNormalization(baseFee.truncate(GasInt))
|
||||||
excessBlobGas = calcExcessBlobGas(vmState.parent)
|
excessBlobGas = calcExcessBlobGas(vmState.parent, vmState.fork >= FkPrague)
|
||||||
|
|
||||||
roDB.validateTransaction(
|
roDB.validateTransaction(
|
||||||
tx, item.sender, gasLimit, baseFee, excessBlobGas, fork).isOk
|
tx, item.sender, gasLimit, baseFee, excessBlobGas, fork).isOk
|
||||||
|
@ -210,12 +211,15 @@ proc vmExecGrabItem(pst: var TxPacker; item: TxItemRef): GrabResult
|
||||||
return ContinueWithNextAccount
|
return ContinueWithNextAccount
|
||||||
|
|
||||||
# EIP-4844
|
# EIP-4844
|
||||||
if pst.numBlobPerBlock + item.tx.versionedHashes.len > MAX_BLOBS_PER_BLOCK:
|
let maxBlobsPerBlob = getMaxBlobsPerBlock(vmState.fork >= FkPrague)
|
||||||
|
if (pst.numBlobPerBlock + item.tx.versionedHashes.len).uint64 > maxBlobsPerBlob:
|
||||||
return ContinueWithNextAccount
|
return ContinueWithNextAccount
|
||||||
pst.numBlobPerBlock += item.tx.versionedHashes.len
|
pst.numBlobPerBlock += item.tx.versionedHashes.len
|
||||||
|
|
||||||
let blobGasUsed = item.tx.getTotalBlobGas
|
let
|
||||||
if vmState.blobGasUsed + blobGasUsed > MAX_BLOB_GAS_PER_BLOCK:
|
blobGasUsed = item.tx.getTotalBlobGas
|
||||||
|
maxBlobGasPerBlock = getMaxBlobGasPerBlock(vmState.fork >= FkPrague)
|
||||||
|
if vmState.blobGasUsed + blobGasUsed > maxBlobGasPerBlock:
|
||||||
return ContinueWithNextAccount
|
return ContinueWithNextAccount
|
||||||
vmState.blobGasUsed += blobGasUsed
|
vmState.blobGasUsed += blobGasUsed
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,9 @@ import
|
||||||
chronicles,
|
chronicles,
|
||||||
eth/common/[transactions, keys]
|
eth/common/[transactions, keys]
|
||||||
|
|
||||||
import ../../../transaction
|
import
|
||||||
|
../../../transaction,
|
||||||
|
../../../common/evmforks
|
||||||
|
|
||||||
{.push raises: [].}
|
{.push raises: [].}
|
||||||
|
|
||||||
|
@ -112,7 +114,7 @@ proc txFeesCovered(xp: TxPoolRef; item: TxItemRef): bool =
|
||||||
if item.tx.txType == TxEip4844:
|
if item.tx.txType == TxEip4844:
|
||||||
let
|
let
|
||||||
excessBlobGas = xp.excessBlobGas
|
excessBlobGas = xp.excessBlobGas
|
||||||
blobGasPrice = getBlobBaseFee(excessBlobGas)
|
blobGasPrice = getBlobBaseFee(excessBlobGas, xp.nextFork >= FkPrague)
|
||||||
if item.tx.maxFeePerBlobGas < blobGasPrice:
|
if item.tx.maxFeePerBlobGas < blobGasPrice:
|
||||||
debug "invalid tx: maxFeePerBlobGas smaller than blobGasPrice",
|
debug "invalid tx: maxFeePerBlobGas smaller than blobGasPrice",
|
||||||
maxFeePerBlobGas=item.tx.maxFeePerBlobGas,
|
maxFeePerBlobGas=item.tx.maxFeePerBlobGas,
|
||||||
|
|
|
@ -18,7 +18,7 @@ import
|
||||||
../transaction/call_types,
|
../transaction/call_types,
|
||||||
../transaction,
|
../transaction,
|
||||||
../utils/utils,
|
../utils/utils,
|
||||||
"."/[dao, eip4844, eip7702, gaslimit, withdrawals],
|
"."/[dao, eip4844, eip7702, eip7691, gaslimit, withdrawals],
|
||||||
./pow/[difficulty, header],
|
./pow/[difficulty, header],
|
||||||
stew/objects,
|
stew/objects,
|
||||||
results
|
results
|
||||||
|
@ -260,8 +260,9 @@ proc validateTxBasic*(
|
||||||
if tx.versionedHashes.len == 0:
|
if tx.versionedHashes.len == 0:
|
||||||
return err("invalid tx: there must be at least one blob")
|
return err("invalid tx: there must be at least one blob")
|
||||||
|
|
||||||
if tx.versionedHashes.len > MAX_BLOBS_PER_BLOCK:
|
let maxBlobsPerBlob = getMaxBlobsPerBlock(fork >= FkPrague)
|
||||||
return err(&"invalid tx: versioned hashes len exceeds MAX_BLOBS_PER_BLOCK={MAX_BLOBS_PER_BLOCK}. get={tx.versionedHashes.len}")
|
if tx.versionedHashes.len.uint64 > maxBlobsPerBlob:
|
||||||
|
return err(&"invalid tx: versioned hashes len exceeds MAX_BLOBS_PER_BLOCK={maxBlobsPerBlob}. get={tx.versionedHashes.len}")
|
||||||
|
|
||||||
for i, bv in tx.versionedHashes:
|
for i, bv in tx.versionedHashes:
|
||||||
if bv.data[0] != VERSIONED_HASH_VERSION_KZG:
|
if bv.data[0] != VERSIONED_HASH_VERSION_KZG:
|
||||||
|
@ -348,7 +349,7 @@ proc validateTransaction*(
|
||||||
|
|
||||||
if tx.txType == TxEip4844:
|
if tx.txType == TxEip4844:
|
||||||
# ensure that the user was willing to at least pay the current data gasprice
|
# ensure that the user was willing to at least pay the current data gasprice
|
||||||
let blobGasPrice = getBlobBaseFee(excessBlobGas)
|
let blobGasPrice = getBlobBaseFee(excessBlobGas, fork >= FkPrague)
|
||||||
if tx.maxFeePerBlobGas < blobGasPrice:
|
if tx.maxFeePerBlobGas < blobGasPrice:
|
||||||
return err("invalid tx: maxFeePerBlobGas smaller than blobGasPrice. " &
|
return err("invalid tx: maxFeePerBlobGas smaller than blobGasPrice. " &
|
||||||
&"maxFeePerBlobGas={tx.maxFeePerBlobGas}, blobGasPrice={blobGasPrice}")
|
&"maxFeePerBlobGas={tx.maxFeePerBlobGas}, blobGasPrice={blobGasPrice}")
|
||||||
|
|
|
@ -16,6 +16,7 @@ import
|
||||||
../transaction,
|
../transaction,
|
||||||
../common/common,
|
../common/common,
|
||||||
../core/eip4844,
|
../core/eip4844,
|
||||||
|
../core/eip7691,
|
||||||
../core/chain/forked_chain
|
../core/chain/forked_chain
|
||||||
|
|
||||||
from ./rpc_types import
|
from ./rpc_types import
|
||||||
|
@ -98,13 +99,16 @@ func calcBaseFee(com: CommonRef, bc: BlockContent): UInt256 =
|
||||||
# the block field filled in, retrieves the block from the backend if not present yet and
|
# the block field filled in, retrieves the block from the backend if not present yet and
|
||||||
# fills in the rest of the fields.
|
# fills in the rest of the fields.
|
||||||
proc processBlock(oracle: Oracle, bc: BlockContent, percentiles: openArray[float64]): ProcessedFees =
|
proc processBlock(oracle: Oracle, bc: BlockContent, percentiles: openArray[float64]): ProcessedFees =
|
||||||
|
let
|
||||||
|
electra = com.isPragueOrLater(bc.header.timestamp)
|
||||||
|
maxBlobGasPerBlock = getMaxBlobGasPerBlock(electra)
|
||||||
result = ProcessedFees(
|
result = ProcessedFees(
|
||||||
baseFee: bc.header.baseFeePerGas.get(0.u256),
|
baseFee: bc.header.baseFeePerGas.get(0.u256),
|
||||||
blobBaseFee: getBlobBaseFee(bc.header.excessBlobGas.get(0'u64)),
|
blobBaseFee: getBlobBaseFee(bc.header.excessBlobGas.get(0'u64), electra),
|
||||||
nextBaseFee: calcBaseFee(oracle.com, bc),
|
nextBaseFee: calcBaseFee(oracle.com, bc),
|
||||||
nextBlobBaseFee: getBlobBaseFee(calcExcessBlobGas(bc.header)),
|
nextBlobBaseFee: getBlobBaseFee(calcExcessBlobGas(bc.header, electra), electra),
|
||||||
gasUsedRatio: float64(bc.header.gasUsed) / float64(bc.header.gasLimit),
|
gasUsedRatio: float64(bc.header.gasUsed) / float64(bc.header.gasLimit),
|
||||||
blobGasUsedRatio: float64(bc.header.blobGasUsed.get(0'u64)) / float64(MAX_BLOB_GAS_PER_BLOCK)
|
blobGasUsedRatio: float64(bc.header.blobGasUsed.get(0'u64)) / float64(maxBlobGasPerBlock)
|
||||||
)
|
)
|
||||||
|
|
||||||
if percentiles.len == 0:
|
if percentiles.len == 0:
|
||||||
|
|
|
@ -180,7 +180,7 @@ proc populateBlockObject*(blockHash: Hash32,
|
||||||
result.requestsHash = header.requestsHash
|
result.requestsHash = header.requestsHash
|
||||||
|
|
||||||
proc populateReceipt*(receipt: Receipt, gasUsed: GasInt, tx: Transaction,
|
proc populateReceipt*(receipt: Receipt, gasUsed: GasInt, tx: Transaction,
|
||||||
txIndex: uint64, header: Header): ReceiptObject =
|
txIndex: uint64, header: Header, electra: bool): ReceiptObject =
|
||||||
let sender = tx.recoverSender()
|
let sender = tx.recoverSender()
|
||||||
var res = ReceiptObject()
|
var res = ReceiptObject()
|
||||||
res.transactionHash = tx.rlpHash
|
res.transactionHash = tx.rlpHash
|
||||||
|
@ -236,7 +236,7 @@ proc populateReceipt*(receipt: Receipt, gasUsed: GasInt, tx: Transaction,
|
||||||
|
|
||||||
if tx.txType == TxEip4844:
|
if tx.txType == TxEip4844:
|
||||||
res.blobGasUsed = Opt.some(Quantity(tx.versionedHashes.len.uint64 * GAS_PER_BLOB.uint64))
|
res.blobGasUsed = Opt.some(Quantity(tx.versionedHashes.len.uint64 * GAS_PER_BLOB.uint64))
|
||||||
res.blobGasPrice = Opt.some(getBlobBaseFee(header.excessBlobGas.get(0'u64)))
|
res.blobGasPrice = Opt.some(getBlobBaseFee(header.excessBlobGas.get(0'u64), electra))
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
|
@ -353,7 +353,7 @@ proc setupServerAPI*(api: ServerAPIRef, server: RpcServer, ctx: EthContext) =
|
||||||
let gasUsed = receipt.cumulativeGasUsed - prevGasUsed
|
let gasUsed = receipt.cumulativeGasUsed - prevGasUsed
|
||||||
prevGasUsed = receipt.cumulativeGasUsed
|
prevGasUsed = receipt.cumulativeGasUsed
|
||||||
if idx == txDetails.index:
|
if idx == txDetails.index:
|
||||||
return populateReceipt(receipt, gasUsed, tx, txDetails.index, header)
|
return populateReceipt(receipt, gasUsed, tx, txDetails.index, header, api.com.isPragueOrLater(header.timestamp))
|
||||||
idx.inc
|
idx.inc
|
||||||
else:
|
else:
|
||||||
# Receipt in memory
|
# Receipt in memory
|
||||||
|
@ -366,7 +366,8 @@ proc setupServerAPI*(api: ServerAPIRef, server: RpcServer, ctx: EthContext) =
|
||||||
|
|
||||||
if txid == idx:
|
if txid == idx:
|
||||||
return populateReceipt(
|
return populateReceipt(
|
||||||
receipt, gasUsed, blkdesc.blk.transactions[txid], txid, blkdesc.blk.header
|
receipt, gasUsed, blkdesc.blk.transactions[txid], txid, blkdesc.blk.header,
|
||||||
|
api.com.isPragueOrLater(blkdesc.blk.header.timestamp)
|
||||||
)
|
)
|
||||||
|
|
||||||
idx.inc
|
idx.inc
|
||||||
|
@ -640,7 +641,7 @@ proc setupServerAPI*(api: ServerAPIRef, server: RpcServer, ctx: EthContext) =
|
||||||
for receipt in receipts:
|
for receipt in receipts:
|
||||||
let gasUsed = receipt.cumulativeGasUsed - prevGasUsed
|
let gasUsed = receipt.cumulativeGasUsed - prevGasUsed
|
||||||
prevGasUsed = receipt.cumulativeGasUsed
|
prevGasUsed = receipt.cumulativeGasUsed
|
||||||
recs.add populateReceipt(receipt, gasUsed, txs[index], index, header)
|
recs.add populateReceipt(receipt, gasUsed, txs[index], index, header, api.com.isPragueOrLater(header.timestamp))
|
||||||
inc index
|
inc index
|
||||||
return Opt.some(recs)
|
return Opt.some(recs)
|
||||||
except CatchableError:
|
except CatchableError:
|
||||||
|
@ -666,7 +667,7 @@ proc setupServerAPI*(api: ServerAPIRef, server: RpcServer, ctx: EthContext) =
|
||||||
if header.excessBlobGas.isNone:
|
if header.excessBlobGas.isNone:
|
||||||
raise newException(ValueError, "excessBlobGas missing from latest header")
|
raise newException(ValueError, "excessBlobGas missing from latest header")
|
||||||
let blobBaseFee =
|
let blobBaseFee =
|
||||||
getBlobBaseFee(header.excessBlobGas.get) * header.blobGasUsed.get.u256
|
getBlobBaseFee(header.excessBlobGas.get, api.com.isPragueOrLater(header.timestamp)) * header.blobGasUsed.get.u256
|
||||||
if blobBaseFee > high(uint64).u256:
|
if blobBaseFee > high(uint64).u256:
|
||||||
raise newException(ValueError, "blobBaseFee is bigger than uint64.max")
|
raise newException(ValueError, "blobBaseFee is bigger than uint64.max")
|
||||||
return w3Qty blobBaseFee.truncate(uint64)
|
return w3Qty blobBaseFee.truncate(uint64)
|
||||||
|
|
|
@ -135,7 +135,7 @@ proc setupHost(call: CallParams, keepStack: bool): TransactionHost =
|
||||||
origin : call.origin.get(call.sender),
|
origin : call.origin.get(call.sender),
|
||||||
gasPrice : call.gasPrice,
|
gasPrice : call.gasPrice,
|
||||||
versionedHashes: call.versionedHashes,
|
versionedHashes: call.versionedHashes,
|
||||||
blobBaseFee : getBlobBaseFee(vmState.blockCtx.excessBlobGas),
|
blobBaseFee : getBlobBaseFee(vmState.blockCtx.excessBlobGas, vmState.fork >= FkPrague),
|
||||||
)
|
)
|
||||||
|
|
||||||
# reset global gasRefund counter each time
|
# reset global gasRefund counter each time
|
||||||
|
@ -231,7 +231,7 @@ proc prepareToRunComputation(host: TransactionHost, call: CallParams) =
|
||||||
# EIP-4844
|
# EIP-4844
|
||||||
if fork >= FkCancun:
|
if fork >= FkCancun:
|
||||||
let blobFee = calcDataFee(call.versionedHashes.len,
|
let blobFee = calcDataFee(call.versionedHashes.len,
|
||||||
vmState.blockCtx.excessBlobGas)
|
vmState.blockCtx.excessBlobGas, fork >= FkPrague)
|
||||||
db.subBalance(call.sender, blobFee)
|
db.subBalance(call.sender, blobFee)
|
||||||
|
|
||||||
proc calculateAndPossiblyRefundGas(host: TransactionHost, call: CallParams): GasInt =
|
proc calculateAndPossiblyRefundGas(host: TransactionHost, call: CallParams): GasInt =
|
||||||
|
|
|
@ -348,7 +348,7 @@ proc exec(ctx: TransContext,
|
||||||
if ctx.env.currentExcessBlobGas.isSome:
|
if ctx.env.currentExcessBlobGas.isSome:
|
||||||
excessBlobGas = ctx.env.currentExcessBlobGas
|
excessBlobGas = ctx.env.currentExcessBlobGas
|
||||||
elif ctx.env.parentExcessBlobGas.isSome and ctx.env.parentBlobGasUsed.isSome:
|
elif ctx.env.parentExcessBlobGas.isSome and ctx.env.parentBlobGasUsed.isSome:
|
||||||
excessBlobGas = Opt.some calcExcessBlobGas(vmState.parent)
|
excessBlobGas = Opt.some calcExcessBlobGas(vmState.parent, vmState.fork >= FkPrague)
|
||||||
|
|
||||||
if excessBlobGas.isSome:
|
if excessBlobGas.isSome:
|
||||||
result.result.blobGasUsed = Opt.some vmState.blobGasUsed
|
result.result.blobGasUsed = Opt.some vmState.blobGasUsed
|
||||||
|
@ -525,7 +525,7 @@ proc transitionAction*(ctx: var TransContext, conf: T8NConf) =
|
||||||
# If it is not explicitly defined, but we have the parent values, we try
|
# If it is not explicitly defined, but we have the parent values, we try
|
||||||
# to calculate it ourselves.
|
# to calculate it ourselves.
|
||||||
if parent.excessBlobGas.isSome and parent.blobGasUsed.isSome:
|
if parent.excessBlobGas.isSome and parent.blobGasUsed.isSome:
|
||||||
ctx.env.currentExcessBlobGas = Opt.some calcExcessBlobGas(parent)
|
ctx.env.currentExcessBlobGas = Opt.some calcExcessBlobGas(parent, com.isPragueOrLater(ctx.env.currentTimestamp))
|
||||||
|
|
||||||
let header = envToHeader(ctx.env)
|
let header = envToHeader(ctx.env)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue