Skip to content

Commit

Permalink
devnet-6: Update EIP-7840: Add BaseFeeUpdateFraction
Browse files Browse the repository at this point in the history
  • Loading branch information
jangko committed Jan 27, 2025
1 parent c11f20f commit ca86ad2
Show file tree
Hide file tree
Showing 20 changed files with 87 additions and 64 deletions.
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
8 changes: 4 additions & 4 deletions nimbus/common/chain_config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ 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))
for fork in Prague..HardFork.high:
if conf.blobSchedule[fork].isNone:
conf.blobSchedule[fork] = conf.blobSchedule[prevFork]
Expand Down Expand Up @@ -485,9 +485,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: 6'u64, max: 9'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
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
8 changes: 5 additions & 3 deletions tests/customgenesis/merge.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@
"petersburgBlock": 0,
"istanbulBlock": 0,
"muirGlacierBlock": 0,
"berlinBlock": 0,
"berlinBlock": 0,
"londonBlock": 0,
"blobSchedule": {
"cancun": {
"target": 3,
"max": 6
"max": 6,
"baseFeeUpdateFraction": 3338477
},
"prague": {
"target": 6,
"max": 9
"max": 9,
"baseFeeUpdateFraction": 5007716
}
}
},
Expand Down
Loading

0 comments on commit ca86ad2

Please sign in to comment.