Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

devnet-6: Update EIP-7840: Add BaseFeeUpdateFraction #3022

Merged
merged 3 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions hive_integration/nodocker/engine/cancun/helpers.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Nimbus
# Copyright (c) 2023-2024 Status Research & Development GmbH
# Copyright (c) 2023-2025 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)
Expand Down Expand Up @@ -39,19 +39,27 @@ const
DATAHASH_START_ADDRESS* = toAddress(0x20000.u256)
DATAHASH_ADDRESS_COUNT* = 1000

func getMinExcessBlobGasForBlobGasPrice(data_gas_price: uint64, electra: bool): uint64 =
func getCancunBlobBaseFee*(excessBlobGas: uint64): UInt256 =
const blobBaseFeeUpdateFraction = 3338477.u256
fakeExponential(
MIN_BLOB_GASPRICE.u256,
excessBlobGas.u256,
blobBaseFeeUpdateFraction
)

func getMinExcessBlobGasForBlobGasPrice(data_gas_price: uint64): uint64 =
var
current_excess_data_gas = 0'u64
current_data_gas_price = 1'u64

while current_data_gas_price < data_gas_price:
current_excess_data_gas += GAS_PER_BLOB.uint64
current_data_gas_price = getBlobBaseFee(current_excess_data_gas, electra).truncate(uint64)
current_data_gas_price = getCancunBlobBaseFee(current_excess_data_gas).truncate(uint64)

return current_excess_data_gas

func getMinExcessBlobsForBlobGasPrice*(data_gas_price: uint64, electra: bool): uint64 =
return getMinExcessBlobGasForBlobGasPrice(data_gas_price, electra) div GAS_PER_BLOB.uint64
func getMinExcessBlobsForBlobGasPrice*(data_gas_price: uint64): uint64 =
return getMinExcessBlobGasForBlobGasPrice(data_gas_price) div GAS_PER_BLOB.uint64

proc addBlobTransaction*(pool: TestBlobTxPool, tx: PooledTransaction) =
let txHash = rlpHash(tx)
Expand Down
4 changes: 2 additions & 2 deletions hive_integration/nodocker/engine/cancun/step_newpayloads.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Nimbus
# Copyright (c) 2023-2024 Status Research & Development GmbH
# Copyright (c) 2023-2025 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)
Expand Down Expand Up @@ -96,7 +96,7 @@ proc verifyPayload(step: NewPayloads,

var
totalBlobCount = 0
expectedBlobGasPrice = getBlobBaseFee(expectedExcessBlobGas, com.isPragueOrLater(payload.timestamp.EthTime))
expectedBlobGasPrice = getCancunBlobBaseFee(expectedExcessBlobGas)

for tx in blobTxsInPayload:
let blobCount = tx.versionedHashes.len
Expand Down
4 changes: 2 additions & 2 deletions hive_integration/nodocker/engine/cancun_tests.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Nimbus
# Copyright (c) 2023-2024 Status Research & Development GmbH
# Copyright (c) 2023-2025 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)
Expand Down Expand Up @@ -41,7 +41,7 @@ import

# Precalculate the first data gas cost increase
const
DATA_GAS_COST_INCREMENT_EXCEED_BLOBS = getMinExcessBlobsForBlobGasPrice(2, false).int
DATA_GAS_COST_INCREMENT_EXCEED_BLOBS = getMinExcessBlobsForBlobGasPrice(2).int
TARGET_BLOBS_PER_BLOCK = int(TARGET_BLOB_GAS_PER_BLOCK div GAS_PER_BLOB)

proc getGenesis(param: NetworkParams) =
Expand Down
16 changes: 12 additions & 4 deletions nimbus/common/chain_config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -394,10 +394,18 @@ proc validateChainConfig(conf: ChainConfig): bool =
proc configureBlobSchedule(conf: ChainConfig) =
var prevFork = Cancun
if conf.blobSchedule[Cancun].isNone:
conf.blobSchedule[Cancun] = Opt.some(BlobSchedule(target: 3'u64, max: 6'u64))
conf.blobSchedule[Cancun] = Opt.some(BlobSchedule(target: 3'u64, max: 6'u64, baseFeeUpdateFraction: 3_338_477'u64))
else:
if conf.blobSchedule[Cancun].value.baseFeeUpdateFraction == 0:
conf.blobSchedule[Cancun].value.baseFeeUpdateFraction = 3_338_477'u64

for fork in Prague..HardFork.high:
if conf.blobSchedule[fork].isNone:
conf.blobSchedule[fork] = conf.blobSchedule[prevFork]
if conf.blobSchedule[fork].value.baseFeeUpdateFraction == 0:
# Set fallback to Cancun's baseFeeUpdateFraction and prevent division by zero
warn "baseFeeUpdateFraction not set, fallback to Cancun's", fork=fork
conf.blobSchedule[fork].value.baseFeeUpdateFraction = 3_338_477'u64
prevFork = fork

proc parseGenesis*(data: string): Genesis
Expand Down Expand Up @@ -485,9 +493,9 @@ proc parseGenesisAlloc*(data: string, ga: var GenesisAlloc): bool

func defaultBlobSchedule*(): array[Cancun..HardFork.high, Opt[BlobSchedule]] =
[
Cancun: Opt.some(BlobSchedule(target: 3'u64, max: 6'u64)),
Prague: Opt.some(BlobSchedule(target: 6'u64, max: 9'u64)),
Osaka : Opt.some(BlobSchedule(target: 6'u64, max: 9'u64)),
Cancun: Opt.some(BlobSchedule(target: 3'u64, max: 6'u64, baseFeeUpdateFraction: 3_338_477'u64)),
Prague: Opt.some(BlobSchedule(target: 6'u64, max: 9'u64, baseFeeUpdateFraction: 5_007_716'u64)),
Osaka : Opt.some(BlobSchedule(target: 9'u64, max: 12'u64, baseFeeUpdateFraction: 5_007_716'u64)),
]

func chainConfigForNetwork*(id: NetworkId): ChainConfig =
Expand Down
7 changes: 7 additions & 0 deletions nimbus/common/common.nim
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,9 @@ func toEVMFork*(com: CommonRef, forkDeterminer: ForkDeterminationInfo): EVMFork
let fork = com.toHardFork(forkDeterminer)
ToEVMFork[fork]

func toEVMFork*(com: CommonRef, header: Header): EVMFork =
com.toEVMFork(forkDeterminationInfo(header))

func isSpuriousOrLater*(com: CommonRef, number: BlockNumber): bool =
com.toHardFork(number.forkDeterminationInfo) >= Spurious

Expand Down Expand Up @@ -424,6 +427,10 @@ func targetBlobsPerBlock*(com: CommonRef, fork: HardFork): uint64 =
doAssert(fork >= Cancun)
com.config.blobSchedule[fork].expect("blobSchedule initialized").target

func baseFeeUpdateFraction*(com: CommonRef, fork: HardFork): uint64 =
doAssert(fork >= Cancun)
com.config.blobSchedule[fork].expect("blobSchedule initialized").baseFeeUpdateFraction

# ------------------------------------------------------------------------------
# Setters
# ------------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions nimbus/common/hardforks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ type
BlobSchedule* = object
target*: uint64
max* : uint64
baseFeeUpdateFraction*: uint64

# if you add more fork block
# please update forkBlockField constant too
Expand Down
2 changes: 0 additions & 2 deletions nimbus/constants.nim
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,11 @@ const
GAS_PER_BLOB* = (1 shl 17).uint64 # 2^17
TARGET_BLOB_GAS_PER_BLOCK* = 393216
MIN_BLOB_GASPRICE* = 1'u64
BLOB_BASE_FEE_UPDATE_FRACTION* = 3338477
MAX_BLOB_GAS_PER_BLOCK* = 786432
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
Expand Down
23 changes: 13 additions & 10 deletions nimbus/core/eip4844.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Nimbus
# Copyright (c) 2023-2024 Status Research & Development GmbH
# Copyright (c) 2023-2025 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)
Expand Down Expand Up @@ -115,19 +115,22 @@ proc getTotalBlobGas*(versionedHashesLen: int): uint64 =
GAS_PER_BLOB * versionedHashesLen.uint64

# getBlobBaseFee implements get_data_gas_price from EIP-4844
func getBlobBaseFee*(excessBlobGas: uint64, electra: bool): UInt256 =
let blobBaseFeeUpdateFraction = getBlobBaseFeeUpdateFraction(electra).u256
fakeExponential(
MIN_BLOB_GASPRICE.u256,
excessBlobGas.u256,
blobBaseFeeUpdateFraction
)
func getBlobBaseFee*(excessBlobGas: uint64, com: CommonRef, fork: EVMFork): UInt256 =
if fork >= FkCancun:
let blobBaseFeeUpdateFraction = com.getBlobBaseFeeUpdateFraction(fork).u256
fakeExponential(
MIN_BLOB_GASPRICE.u256,
excessBlobGas.u256,
blobBaseFeeUpdateFraction
)
else:
0.u256

proc calcDataFee*(versionedHashesLen: int,
excessBlobGas: uint64,
electra: bool): UInt256 =
com: CommonRef, fork: EVMFork): UInt256 =
getTotalBlobGas(versionedHashesLen).u256 *
getBlobBaseFee(excessBlobGas, electra)
getBlobBaseFee(excessBlobGas, com, fork)

func blobGasUsed(txs: openArray[Transaction]): uint64 =
for tx in txs:
Expand Down
8 changes: 4 additions & 4 deletions nimbus/core/eip7691.nim
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ 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

const
EVMForkToFork: array[FkCancun..EVMFork.high, HardFork] = [
Cancun,
Expand All @@ -38,3 +34,7 @@ const
func getMaxBlobsPerBlock*(com: CommonRef, fork: EVMFork): uint64 =
doAssert(fork >= FkCancun)
com.maxBlobsPerBlock(EVMForkToFork[fork])

func getBlobBaseFeeUpdateFraction*(com: CommonRef, fork: EVMFork): uint64 =
doAssert(fork >= FkCancun)
com.baseFeeUpdateFraction(EVMForkToFork[fork])
3 changes: 1 addition & 2 deletions nimbus/core/tx_pool/tx_desc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,7 @@ proc classifyValid(xp: TxPoolRef; tx: Transaction, sender: Address): bool =
if tx.txType == TxEip4844:
let
excessBlobGas = xp.excessBlobGas
electra = xp.vmState.fork >= FkPrague
blobGasPrice = getBlobBaseFee(excessBlobGas, electra)
blobGasPrice = getBlobBaseFee(excessBlobGas, xp.vmState.com, xp.vmState.fork)
if tx.maxFeePerBlobGas < blobGasPrice:
debug "Invalid transaction: maxFeePerBlobGas lower than blobGasPrice",
maxFeePerBlobGas = tx.maxFeePerBlobGas,
Expand Down
2 changes: 1 addition & 1 deletion nimbus/core/validate.nim
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ proc validateTransaction*(

if tx.txType == TxEip4844:
# ensure that the user was willing to at least pay the current data gasprice
let blobGasPrice = getBlobBaseFee(excessBlobGas, fork >= FkPrague)
let blobGasPrice = getBlobBaseFee(excessBlobGas, com, fork)
if tx.maxFeePerBlobGas < blobGasPrice:
return err("invalid tx: maxFeePerBlobGas smaller than blobGasPrice. " &
&"maxFeePerBlobGas={tx.maxFeePerBlobGas}, blobGasPrice={blobGasPrice}")
Expand Down
8 changes: 4 additions & 4 deletions nimbus/rpc/oracle.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Nimbus
# Copyright (c) 2024 Status Research & Development GmbH
# Copyright (c) 2024-2025 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
Expand Down Expand Up @@ -100,13 +100,13 @@ func calcBaseFee(com: CommonRef, bc: BlockContent): UInt256 =
# fills in the rest of the fields.
proc processBlock(oracle: Oracle, bc: BlockContent, percentiles: openArray[float64]): ProcessedFees =
let
electra = com.isPragueOrLater(bc.header.timestamp)
fork = com.toEVMFork(bc.header)
maxBlobGasPerBlock = getMaxBlobGasPerBlock(electra)
result = ProcessedFees(
baseFee: bc.header.baseFeePerGas.get(0.u256),
blobBaseFee: getBlobBaseFee(bc.header.excessBlobGas.get(0'u64), electra),
blobBaseFee: getBlobBaseFee(bc.header.excessBlobGas.get(0'u64), com, fork),
nextBaseFee: calcBaseFee(oracle.com, bc),
nextBlobBaseFee: getBlobBaseFee(calcExcessBlobGas(bc.header, electra), electra),
nextBlobBaseFee: getBlobBaseFee(calcExcessBlobGas(bc.header, com, fork), com, fork),
gasUsedRatio: float64(bc.header.gasUsed) / float64(bc.header.gasLimit),
blobGasUsedRatio: float64(bc.header.blobGasUsed.get(0'u64)) / float64(maxBlobGasPerBlock)
)
Expand Down
6 changes: 3 additions & 3 deletions nimbus/rpc/rpc_utils.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Nimbus
# Copyright (c) 2018-2024 Status Research & Development GmbH
# Copyright (c) 2018-2025 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
Expand Down Expand Up @@ -180,7 +180,7 @@ proc populateBlockObject*(blockHash: Hash32,
result.requestsHash = header.requestsHash

proc populateReceipt*(receipt: Receipt, gasUsed: GasInt, tx: Transaction,
txIndex: uint64, header: Header, electra: bool): ReceiptObject =
txIndex: uint64, header: Header, com: CommonRef): ReceiptObject =
let sender = tx.recoverSender()
var res = ReceiptObject()
res.transactionHash = tx.rlpHash
Expand Down Expand Up @@ -236,7 +236,7 @@ proc populateReceipt*(receipt: Receipt, gasUsed: GasInt, tx: Transaction,

if tx.txType == TxEip4844:
res.blobGasUsed = Opt.some(Quantity(tx.versionedHashes.len.uint64 * GAS_PER_BLOB.uint64))
res.blobGasPrice = Opt.some(getBlobBaseFee(header.excessBlobGas.get(0'u64), electra))
res.blobGasPrice = Opt.some(getBlobBaseFee(header.excessBlobGas.get(0'u64), com, com.toEVMFork(header)))

return res

Expand Down
9 changes: 4 additions & 5 deletions nimbus/rpc/server_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ proc setupServerAPI*(api: ServerAPIRef, server: RpcServer, ctx: EthContext) =
let gasUsed = receipt.cumulativeGasUsed - prevGasUsed
prevGasUsed = receipt.cumulativeGasUsed
if idx == txDetails.index:
return populateReceipt(receipt, gasUsed, tx, txDetails.index, header, api.com.isPragueOrLater(header.timestamp))
return populateReceipt(receipt, gasUsed, tx, txDetails.index, header, api.com)
idx.inc
else:
# Receipt in memory
Expand All @@ -382,8 +382,7 @@ proc setupServerAPI*(api: ServerAPIRef, server: RpcServer, ctx: EthContext) =
if txid == idx:
return populateReceipt(
receipt, gasUsed, blkdesc.blk.transactions[txid], txid, blkdesc.blk.header,
api.com.isPragueOrLater(blkdesc.blk.header.timestamp)
)
api.com)

idx.inc

Expand Down Expand Up @@ -666,7 +665,7 @@ proc setupServerAPI*(api: ServerAPIRef, server: RpcServer, ctx: EthContext) =
for receipt in receipts:
let gasUsed = receipt.cumulativeGasUsed - prevGasUsed
prevGasUsed = receipt.cumulativeGasUsed
recs.add populateReceipt(receipt, gasUsed, txs[index], index, header, api.com.isPragueOrLater(header.timestamp))
recs.add populateReceipt(receipt, gasUsed, txs[index], index, header, api.com)
inc index
return Opt.some(recs)
except CatchableError:
Expand All @@ -692,7 +691,7 @@ proc setupServerAPI*(api: ServerAPIRef, server: RpcServer, ctx: EthContext) =
if header.excessBlobGas.isNone:
raise newException(ValueError, "excessBlobGas missing from latest header")
let blobBaseFee =
getBlobBaseFee(header.excessBlobGas.get, api.com.isPragueOrLater(header.timestamp)) * header.blobGasUsed.get.u256
getBlobBaseFee(header.excessBlobGas.get, api.com, api.com.toEVMFork(header)) * header.blobGasUsed.get.u256
if blobBaseFee > high(uint64).u256:
raise newException(ValueError, "blobBaseFee is bigger than uint64.max")
return w3Qty blobBaseFee.truncate(uint64)
Expand Down
4 changes: 2 additions & 2 deletions nimbus/transaction/call_common.nim
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ proc setupHost(call: CallParams, keepStack: bool): TransactionHost =
origin : call.origin.get(call.sender),
gasPrice : call.gasPrice,
versionedHashes: call.versionedHashes,
blobBaseFee : getBlobBaseFee(vmState.blockCtx.excessBlobGas, vmState.fork >= FkPrague),
blobBaseFee : getBlobBaseFee(vmState.blockCtx.excessBlobGas, vmState.com, vmState.fork),
)

# reset global gasRefund counter each time
Expand Down Expand Up @@ -232,7 +232,7 @@ proc prepareToRunComputation(host: TransactionHost, call: CallParams) =
# EIP-4844
if fork >= FkCancun:
let blobFee = calcDataFee(call.versionedHashes.len,
vmState.blockCtx.excessBlobGas, fork >= FkPrague)
vmState.blockCtx.excessBlobGas, vmState.com, fork)
db.subBalance(call.sender, blobFee)

proc calculateAndPossiblyRefundGas(host: TransactionHost, call: CallParams): GasInt =
Expand Down
6 changes: 4 additions & 2 deletions tests/customgenesis/blobschedule_cancun_osaka.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
"blobSchedule": {
"cancun": {
"target": 3,
"max": 6
"max": 6,
"baseFeeUpdateFraction": 3338477
},
"osaka": {
"target": 6,
"max": 9
"max": 9,
"baseFeeUpdateFraction": 5007716
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions tests/customgenesis/blobschedule_cancun_prague.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
"blobSchedule": {
"cancun": {
"target": 3,
"max": 6
"max": 6,
"baseFeeUpdateFraction": 3338477
},
"prague": {
"target": 6,
"max": 9
"max": 9,
"baseFeeUpdateFraction": 5007716
}
}
}
Expand Down
27 changes: 27 additions & 0 deletions tests/customgenesis/blobschedule_nobasefee.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"config": {
"chainId": 7,
"homesteadBlock": 0,
"eip150Block": 0,
"eip150Hash": "0x5de1ee4135274003348e80b788e5afa4b18b18d320a5622218d5c493fedf5689",
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"muirGlacierBlock": 0,
"berlinBlock": 0,
"londonBlock": 0,
"blobSchedule": {
"cancun": {
"target": 3,
"max": 6
},
"prague": {
"target": 6,
"max": 9
}
}
}
}
3 changes: 2 additions & 1 deletion tests/customgenesis/blobschedule_prague.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"blobSchedule": {
"prague": {
"target": 6,
"max": 9
"max": 9,
"baseFeeUpdateFraction": 5007716
}
}
}
Expand Down
Loading
Loading