Skip to content

Commit

Permalink
devnet-5: Update EIP-7685: exclude empty requests data in commitment (#…
Browse files Browse the repository at this point in the history
…2963)

* devnet-5: Update EIP-7685: exclude empty requests data in commitment

* Fix test vector

* Add more tests

* Fix executionRequests order validation

* Simplify test vector

* Fix t8n executionRequests output
  • Loading branch information
jangko authored Dec 21, 2024
1 parent 036dd23 commit 86fc24a
Show file tree
Hide file tree
Showing 33 changed files with 1,257 additions and 91 deletions.
2 changes: 1 addition & 1 deletion hive_integration/nodocker/engine/clmock.nim
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ type
latestPayloadAttributes*: PayloadAttributes
latestExecutedPayload* : ExecutableData
latestForkchoice* : ForkchoiceStateV1
latestExecutionRequests*: Opt[array[3, seq[byte]]]
latestExecutionRequests*: Opt[seq[seq[byte]]]

# Merge related
firstPoSBlockNumber* : Opt[uint64]
Expand Down
4 changes: 2 additions & 2 deletions hive_integration/nodocker/engine/engine_client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ proc newPayloadV4*(client: RpcClient,
payload: ExecutionPayloadV3,
versionedHashes: seq[VersionedHash],
parentBeaconBlockRoot: Hash32,
executionRequests: array[3, seq[byte]]):
executionRequests: seq[seq[byte]]):
Result[PayloadStatusV1, string] =
wrapTrySimpleRes:
client.engine_newPayloadV4(payload, versionedHashes,
Expand Down Expand Up @@ -196,7 +196,7 @@ proc newPayloadV4*(client: RpcClient,
payload: ExecutionPayload,
versionedHashes: Opt[seq[VersionedHash]],
parentBeaconBlockRoot: Opt[Hash32],
executionRequests: Opt[array[3, seq[byte]]]):
executionRequests: Opt[seq[seq[byte]]]):
Result[PayloadStatusV1, string] =
wrapTrySimpleRes:
client.engine_newPayloadV4(payload, versionedHashes,
Expand Down
2 changes: 1 addition & 1 deletion hive_integration/nodocker/engine/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ type
attr* : PayloadAttributes
beaconRoot* : Opt[Hash32]
versionedHashes*: Opt[seq[Hash32]]
executionRequests*: Opt[array[3, seq[byte]]]
executionRequests*: Opt[seq[seq[byte]]]

const
DefaultTimeout* = 60 # seconds
Expand Down
31 changes: 29 additions & 2 deletions nimbus/beacon/api_handler/api_newpayload.nim
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,35 @@ template validatePayload(apiVersion, payloadVersion, payload) =
raise invalidParams("newPayload" & $apiVersion &
"excessBlobGas is expected from execution payload")

func validateExecutionRequest(requests: openArray[seq[byte]]): Result[void, string] {.raises:[].} =
var previousRequestType = -1
for request in requests:
if request.len == 0:
return err("Execution request data must not be empty")

let requestType = request[0]
if requestType.int <= previousRequestType:
return err("Execution requests are not in strictly ascending order")

if request.len == 1:
return err("Empty data for request type " & $requestType)

if requestType notin [
DEPOSIT_REQUEST_TYPE,
WITHDRAWAL_REQUEST_TYPE,
CONSOLIDATION_REQUEST_TYPE]:
return err("Invalid execution request type: " & $requestType)

previousRequestType = requestType.int

ok()

proc newPayload*(ben: BeaconEngineRef,
apiVersion: Version,
payload: ExecutionPayload,
versionedHashes = Opt.none(seq[Hash32]),
beaconRoot = Opt.none(Hash32),
executionRequests = Opt.none(array[3, seq[byte]])): PayloadStatusV1 =
executionRequests = Opt.none(seq[seq[byte]])): PayloadStatusV1 =

trace "Engine API request received",
meth = "newPayload",
Expand All @@ -104,6 +127,10 @@ proc newPayload*(ben: BeaconEngineRef,
raise invalidParams("newPayload" & $apiVersion &
": executionRequests is expected from execution payload")

validateExecutionRequest(executionRequests.get).isOkOr:
raise invalidParams("newPayload" & $apiVersion &
": " & error)

let
com = ben.com
db = com.db
Expand Down Expand Up @@ -195,7 +222,7 @@ proc newPayload*(ben: BeaconEngineRef,
warn "Error importing block",
number = header.number,
hash = blockHash.short,
parent = header.parentHash.short,
parent = header.parentHash.short,
error = vres.error()
ben.setInvalidAncestor(header, blockHash)
let blockHash = latestValidHash(db, parent, ttd)
Expand Down
2 changes: 1 addition & 1 deletion nimbus/beacon/payload_queue.nim
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type
payload*: ExecutionPayload
blockValue*: UInt256
blobsBundle*: Opt[BlobsBundleV1]
executionRequests*: Opt[array[3, seq[byte]]]
executionRequests*: Opt[seq[seq[byte]]]
targetBlobsPerBlock*: Opt[Quantity]

PayloadItem = object
Expand Down
2 changes: 1 addition & 1 deletion nimbus/common/chain_config_hash.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Nimbus
# Copyright (c) 2021-2024 Status Research & Development GmbH
# Copyright (c) 2024 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
5 changes: 5 additions & 0 deletions nimbus/common/genesis.nim
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import
eth/common/[blocks, hashes, accounts, headers, addresses],
../db/[ledger, core_db],
../constants,
../utils/utils,
./chain_config

# ------------------------------------------------------------------------------
Expand Down Expand Up @@ -78,6 +79,10 @@ proc toGenesisHeader*(
result.excessBlobGas = Opt.some g.excessBlobGas.get(0'u64)
result.parentBeaconBlockRoot = Opt.some g.parentBeaconBlockRoot.get(default(Hash32))

if fork >= Prague:
const EmptyRequestsHash = calcRequestsHash()
result.requestsHash = Opt.some(EmptyRequestsHash)

proc toGenesisHeader*(
genesis: Genesis;
fork: HardFork;
Expand Down
6 changes: 5 additions & 1 deletion nimbus/core/executor/process_block.nim
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,11 @@ proc procBlkEpilogue(
let
depositReqs =
?parseDepositLogs(vmState.allLogs, vmState.com.depositContractAddress)
requestsHash = calcRequestsHash(depositReqs, withdrawalReqs, consolidationReqs)
requestsHash = calcRequestsHash([
(DEPOSIT_REQUEST_TYPE, depositReqs),
(WITHDRAWAL_REQUEST_TYPE, withdrawalReqs),
(CONSOLIDATION_REQUEST_TYPE, consolidationReqs)
])

if header.requestsHash.get != requestsHash:
debug "wrong requestsHash in block",
Expand Down
4 changes: 2 additions & 2 deletions nimbus/core/tx_pool.nim
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ type AssembledBlock* = object
blk*: EthBlock
blobsBundle*: Opt[BlobsBundle]
blockValue*: UInt256
executionRequests*: Opt[array[3, seq[byte]]]
executionRequests*: Opt[seq[seq[byte]]]

proc assembleBlock*(
xp: TxPoolRef,
Expand Down Expand Up @@ -517,7 +517,7 @@ proc assembleBlock*(
if com.isPragueOrLater(blk.header.timestamp):
Opt.some(pst.executionRequests)
else:
Opt.none(array[3, seq[byte]])
Opt.none(seq[seq[byte]])

ok AssembledBlock(
blk: blk,
Expand Down
20 changes: 14 additions & 6 deletions nimbus/core/tx_pool/tx_packer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -357,17 +357,25 @@ proc assembleHeader*(pst: TxPacker): Header =
result.excessBlobGas = Opt.some vmState.blockCtx.excessBlobGas

if com.isPragueOrLater(pos.timestamp):
let requestsHash = calcRequestsHash(pst.depositReqs,
pst.withdrawalReqs, pst.consolidationReqs)
let requestsHash = calcRequestsHash([
(DEPOSIT_REQUEST_TYPE, pst.depositReqs),
(WITHDRAWAL_REQUEST_TYPE, pst.withdrawalReqs),
(CONSOLIDATION_REQUEST_TYPE, pst.consolidationReqs)
])
result.requestsHash = Opt.some(requestsHash)

func blockValue*(pst: TxPacker): UInt256 =
pst.blockValue

func executionRequests*(pst: var TxPacker): array[3, seq[byte]] =
result[0] = move(pst.depositReqs)
result[1] = move(pst.withdrawalReqs)
result[2] = move(pst.consolidationReqs)
func executionRequests*(pst: var TxPacker): seq[seq[byte]] =
template append(dst, reqType, reqData) =
if reqData.len > 0:
reqData.insert(reqType)
dst.add(move(reqData))

result.append(DEPOSIT_REQUEST_TYPE, pst.depositReqs)
result.append(WITHDRAWAL_REQUEST_TYPE, pst.withdrawalReqs)
result.append(CONSOLIDATION_REQUEST_TYPE, pst.consolidationReqs)

# ------------------------------------------------------------------------------
# End
Expand Down
2 changes: 1 addition & 1 deletion nimbus/rpc/engine_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ proc setupEngineAPI*(engine: BeaconEngineRef, server: RpcServer) =
server.rpc("engine_newPayloadV4") do(payload: ExecutionPayload,
expectedBlobVersionedHashes: Opt[seq[Hash32]],
parentBeaconBlockRoot: Opt[Hash32],
executionRequests: Opt[array[3, seq[byte]]]) -> PayloadStatusV1:
executionRequests: Opt[seq[seq[byte]]]) -> PayloadStatusV1:
return engine.newPayload(Version.V4, payload,
expectedBlobVersionedHashes, parentBeaconBlockRoot, executionRequests)

Expand Down
25 changes: 20 additions & 5 deletions nimbus/utils/utils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ import

export eth_types_rlp

const
DEPOSIT_REQUEST_TYPE* = 0x00.byte
WITHDRAWAL_REQUEST_TYPE* = 0x01.byte
CONSOLIDATION_REQUEST_TYPE* = 0x02.byte

template calcTxRoot*(transactions: openArray[Transaction]): Root =
orderedTrieRoot(transactions)

Expand All @@ -28,7 +33,7 @@ template calcWithdrawalsRoot*(withdrawals: openArray[Withdrawal]): Root =
template calcReceiptsRoot*(receipts: openArray[Receipt]): Root =
orderedTrieRoot(receipts)

func calcRequestsHash*(requests: varargs[seq[byte]]): Hash32 =
func calcRequestsHash*(requests: varargs[tuple[reqType: byte, data: seq[byte]]]): Hash32 =
func calcHash(reqType: byte, data: openArray[byte]): Hash32 =
var ctx: sha256
ctx.init()
Expand All @@ -39,16 +44,26 @@ func calcRequestsHash*(requests: varargs[seq[byte]]): Hash32 =

var ctx: sha256
ctx.init()
for i, data in requests:
ctx.update(calcHash(i.byte, data).data)
for req in requests:
if req.data.len > 0:
ctx.update(calcHash(req.reqType, req.data).data)
ctx.finish(result.data)
ctx.clear()

func calcRequestsHash*(requests: openArray[seq[byte]]): Hash32 =
var ctx: sha256
ctx.init()
for req in requests:
if req.len > 0:
ctx.update(sha256.digest(req).data)
ctx.finish(result.data)
ctx.clear()

func calcRequestsHash*(reqs: Opt[array[3, seq[byte]]]): Opt[Hash32] =
func calcRequestsHash*(reqs: Opt[seq[seq[byte]]]): Opt[Hash32] =
if reqs.isNone:
Opt.none(Hash32)
else:
Opt.some(calcRequestsHash(reqs.get()[0], reqs.get()[1], reqs.get()[2]))
Opt.some(calcRequestsHash(reqs.get))

func sumHash*(hashes: varargs[Hash32]): Hash32 =
var ctx: sha256
Expand Down
2 changes: 1 addition & 1 deletion nrpc/nrpc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ proc syncToEngineApi(conf: NRpcConf) {.async.} =
engine_api.VersionedHash(kzg_commitment_to_versioned_hash(it)),
)
# Execution Requests for Electra
let execution_requests = [
let execution_requests = @[
SSZ.encode(forkyBlck.message.body.execution_requests.deposits),
SSZ.encode(forkyBlck.message.body.execution_requests.withdrawals),
SSZ.encode(forkyBlck.message.body.execution_requests.consolidations),
Expand Down
Loading

0 comments on commit 86fc24a

Please sign in to comment.