diff --git a/nimbus/constants.nim b/nimbus/constants.nim index 5406191eac..c8064fe111 100644 --- a/nimbus/constants.nim +++ b/nimbus/constants.nim @@ -109,4 +109,6 @@ const HISTORY_STORAGE_ADDRESS* = hexToByteArray[20]("0x0aae40965e6800cd9b1f4b05ff21581047e3f91e") DEPOSIT_CONTRACT_ADDRESS* = hexToByteArray[20]("0x00000000219ab540356cbb839cbe05303d7705fa") + WITHDRAWAL_REQUEST_ADDRESS* = hexToByteArray[20]("0x00A3ca265EBcb825B45F985A16CEFB49958cE017") + CONSOLIDATION_REQUEST_ADDRESS* = hexToByteArray[20]("0x00b42dbF2194e931E80326D950320f7d9Dbeac02") # End diff --git a/nimbus/core/executor/process_block.nim b/nimbus/core/executor/process_block.nim index 1a5b65e207..baa6a43200 100644 --- a/nimbus/core/executor/process_block.nim +++ b/nimbus/core/executor/process_block.nim @@ -193,6 +193,23 @@ proc procBlkEpilogue( expectedDeposits.add req if depositReqs != expectedDeposits: return err("EIP-6110 deposit requests mismatch") + + let withdrawalReqs = processDequeueWithdrawalRequests(vmState) + var expectedWithdrawals: seq[Request] + for req in blk.requests.get: + if req.requestType == WithdrawalRequestType: + expectedWithdrawals.add req + if withdrawalReqs != expectedWithdrawals: + return err("EIP-7002 withdrawal requests mismatch") + + let consolidationReqs = processDequeueConsolidationRequests(vmState) + var expectedConsolidations: seq[Request] + for req in blk.requests.get: + if req.requestType == ConsolidationRequestType: + expectedConsolidations.add req + if consolidationReqs != expectedConsolidations: + return err("EIP-7251 consolidation requests mismatch") + ok() # ------------------------------------------------------------------------------ diff --git a/nimbus/core/executor/process_transaction.nim b/nimbus/core/executor/process_transaction.nim index 77fca5e510..975a58c806 100644 --- a/nimbus/core/executor/process_transaction.nim +++ b/nimbus/core/executor/process_transaction.nim @@ -13,6 +13,8 @@ import std/strformat, results, + stew/arrayops, + stew/endians2, ../../common/common, ../../db/ledger, ../../transaction/call_evm, @@ -159,7 +161,7 @@ proc processBeaconBlockRoot*(vmState: BaseVMState, beaconRoot: Hash256): proc processParentBlockHash*(vmState: BaseVMState, prevHash: Hash256): Result[void, string] = - ## processParentBlockHash stores the parent block hash in the + ## processParentBlockHash stores the parent block hash in the ## history storage contract as per EIP-2935. let statedb = vmState.stateDB @@ -186,7 +188,87 @@ proc processParentBlockHash*(vmState: BaseVMState, prevHash: Hash256): statedb.persist(clearEmptyAccount = true) ok() - + +func parseWithdrawalRequest(data: openArray[byte]): WithdrawalRequest = + template copyFrom(T: type, input, a, b): auto = + T.initCopyFrom(input.toOpenArray(a, b)) + WithdrawalRequest( + sourceAddress: array[20, byte].copyFrom(data, 0, 19), + validatorPubkey: array[48, byte].copyFrom(data, 20, 20+47), + amount: uint64.fromBytesLE(data.toOpenArray(68, 68+7)), + ) + +proc processDequeueWithdrawalRequests*(vmState: BaseVMState): seq[Request] = + ## processDequeueWithdrawalRequests applies the EIP-7002 system call + ## to the withdrawal requests contract. + let + statedb = vmState.stateDB + call = CallParams( + vmState : vmState, + sender : SYSTEM_ADDRESS, + gasLimit : 30_000_000.GasInt, + gasPrice : 0.GasInt, + to : WITHDRAWAL_REQUEST_ADDRESS, + + # 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(Blob) + statedb.persist(clearEmptyAccount = true) + + for i in 0..