From 38c58c4febfe3b60a8381bd9110f63e69eb6ec49 Mon Sep 17 00:00:00 2001 From: andri lim Date: Tue, 10 Sep 2024 16:52:03 +0700 Subject: [PATCH] Implement EIP-2935: Serve historical block hashes from state (#2606) * Implement EIP-2935: Serve historical block hashes from state * Fix EIP-2935 in t8n --- nimbus/constants.nim | 1 + nimbus/core/executor/process_block.nim | 7 +++-- nimbus/core/executor/process_transaction.nim | 30 ++++++++++++++++++++ tools/t8n/transition.nim | 12 ++++++++ 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/nimbus/constants.nim b/nimbus/constants.nim index a2f61379d..85aec2a9a 100644 --- a/nimbus/constants.nim +++ b/nimbus/constants.nim @@ -107,4 +107,5 @@ const result[19] = x.byte initAddress(3) + HISTORY_STORAGE_ADDRESS* = hexToByteArray[20]("0x0aae40965e6800cd9b1f4b05ff21581047e3f91e") # End diff --git a/nimbus/core/executor/process_block.nim b/nimbus/core/executor/process_block.nim index 0a3654ece..f8c881aaf 100644 --- a/nimbus/core/executor/process_block.nim +++ b/nimbus/core/executor/process_block.nim @@ -66,6 +66,9 @@ proc procBlkPreamble( if blk.transactions.calcTxRoot != header.txRoot: return err("Mismatched txRoot") + if com.isPragueOrLater(header.timestamp): + ?vmState.processParentBlockHash(header.parentHash) + if com.isCancunOrLater(header.timestamp): if header.parentBeaconBlockRoot.isNone: return err("Post-Cancun block header must have parentBeaconBlockRoot") @@ -144,10 +147,10 @@ proc procBlkEpilogue( if not skipReceipts: let bloom = createBloom(vmState.receipts) - + if header.logsBloom != bloom: return err("bloom mismatch") - + let receiptsRoot = calcReceiptsRoot(vmState.receipts) if header.receiptsRoot != receiptsRoot: # TODO replace logging with better error diff --git a/nimbus/core/executor/process_transaction.nim b/nimbus/core/executor/process_transaction.nim index 5453e65fd..77fca5e51 100644 --- a/nimbus/core/executor/process_transaction.nim +++ b/nimbus/core/executor/process_transaction.nim @@ -157,6 +157,36 @@ proc processBeaconBlockRoot*(vmState: BaseVMState, beaconRoot: Hash256): statedb.persist(clearEmptyAccount = true) ok() +proc processParentBlockHash*(vmState: BaseVMState, prevHash: Hash256): + Result[void, string] = + ## processParentBlockHash stores the parent block hash in the + ## history storage contract as per EIP-2935. + let + statedb = vmState.stateDB + call = CallParams( + vmState : vmState, + sender : SYSTEM_ADDRESS, + gasLimit : 30_000_000.GasInt, + gasPrice : 0.GasInt, + to : HISTORY_STORAGE_ADDRESS, + input : @(prevHash.data), + + # It's a systemCall, no need for other knicks knacks + sysCall : true, + noAccessList: true, + noIntrinsic : true, + noGasCharge : true, + noRefund : true, + ) + + # runComputation a.k.a syscall/evm.call + let res = call.runComputation(string) + if res.len > 0: + return err("processParentBlockHash: " & res) + + statedb.persist(clearEmptyAccount = true) + ok() + proc processTransaction*( vmState: BaseVMState; ## Parent accounts environment for transaction tx: Transaction; ## Transaction to validate diff --git a/tools/t8n/transition.nim b/tools/t8n/transition.nim index 6e80220d1..ee0dda8dd 100644 --- a/tools/t8n/transition.nim +++ b/tools/t8n/transition.nim @@ -234,6 +234,18 @@ proc exec(ctx: var TransContext, vmState.processBeaconBlockRoot(ctx.env.parentBeaconBlockRoot.get).isOkOr: raise newError(ErrorConfig, error) + if vmState.com.isPragueOrLater(ctx.env.currentTimestamp) and + ctx.env.blockHashes.len > 0: + let + prevNumber = ctx.env.currentNumber - 1 + prevHash = ctx.env.blockHashes.getOrDefault(prevNumber) + + if prevHash == static(Hash256()): + raise newError(ErrorConfig, "previous block hash not found for block number: " & $prevNumber) + + vmState.processParentBlockHash(prevHash).isOkOr: + raise newError(ErrorConfig, error) + for txIndex, txRes in txList: if txRes.isErr: rejected.add RejectedTx(