From e2e22662e19cfb0fe9ada94a9d9c6cd52e25b5bd Mon Sep 17 00:00:00 2001 From: tersec Date: Wed, 18 Dec 2024 14:42:19 +0000 Subject: [PATCH] implement EIP-7691 blob sidecar req/resp endpoints (#6769) * implement EIP-7691 blob sidecar req/resp endpoints * refactor common code out of the blob root/range request handlers * use template instead of proc --- beacon_chain/spec/datatypes/constants.nim | 7 + beacon_chain/spec/network.nim | 2 +- beacon_chain/spec/presets.nim | 2 + beacon_chain/sync/sync_protocol.nim | 239 +++++++++++++--------- 4 files changed, 156 insertions(+), 94 deletions(-) diff --git a/beacon_chain/spec/datatypes/constants.nim b/beacon_chain/spec/datatypes/constants.nim index cb4c4761a..4db4ae9d0 100644 --- a/beacon_chain/spec/datatypes/constants.nim +++ b/beacon_chain/spec/datatypes/constants.nim @@ -86,3 +86,10 @@ const # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.5/specs/electra/beacon-chain.md#withdrawal-prefixes COMPOUNDING_WITHDRAWAL_PREFIX* = 0x02 + + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.10/specs/electra/beacon-chain.md#execution-1 + MAX_BLOBS_PER_BLOCK_ELECTRA* = 9'u64 + + # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.10/specs/electra/p2p-interface.md#configuration + MAX_REQUEST_BLOB_SIDECARS_ELECTRA* = + MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK_ELECTRA diff --git a/beacon_chain/spec/network.nim b/beacon_chain/spec/network.nim index 373f99ca0..3dabaa73a 100644 --- a/beacon_chain/spec/network.nim +++ b/beacon_chain/spec/network.nim @@ -37,7 +37,7 @@ const # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.9/specs/_features/eip7594/p2p-interface.md#configuration MAX_REQUEST_DATA_COLUMN_SIDECARS*: uint64 = MAX_REQUEST_BLOCKS_DENEB * NUMBER_OF_COLUMNS - + defaultEth2TcpPort* = 9000 defaultEth2TcpPortDesc* = $defaultEth2TcpPort diff --git a/beacon_chain/spec/presets.nim b/beacon_chain/spec/presets.nim index 697f20cf4..76b1a9e00 100644 --- a/beacon_chain/spec/presets.nim +++ b/beacon_chain/spec/presets.nim @@ -824,6 +824,8 @@ proc readRuntimeConfig*( checkCompatibility MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK, "MAX_REQUEST_BLOB_SIDECARS" checkCompatibility BLOB_SIDECAR_SUBNET_COUNT + checkCompatibility MAX_BLOBS_PER_BLOCK_ELECTRA + checkCompatibility MAX_REQUEST_BLOB_SIDECARS_ELECTRA # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.10/specs/phase0/fork-choice.md#configuration # Isn't being used as a preset in the usual way: at any time, there's one correct value diff --git a/beacon_chain/sync/sync_protocol.nim b/beacon_chain/sync/sync_protocol.nim index 00aa946e7..43d20fe0a 100644 --- a/beacon_chain/sync/sync_protocol.nim +++ b/beacon_chain/sync/sync_protocol.nim @@ -91,10 +91,10 @@ proc readChunkPayload*( await conn.readExactly(addr contextBytes, sizeof contextBytes) except CatchableError: return neterr UnexpectedEOF - let contextFork = + let contextFork = peer.network.forkDigests[].consensusForkForDigest(contextBytes).valueOr: return neterr InvalidContextBytes - + withConsensusFork(contextFork): when consensusFork >= ConsensusFork.Fulu: let res = await readChunkPayload(conn, peer, DataColumnSidecar) @@ -107,6 +107,99 @@ proc readChunkPayload*( {.pop.} # TODO fix p2p macro for raises +template getBlobSidecarsByRoot( + versionNumber: static string, peer: Peer, dag: ChainDAGRef, response: auto, + blobIds: BlobIdentifierList) = + trace "got v" & versionNumber & " blobs range request", + peer, len = blobIds.len + if blobIds.len == 0: + raise newException(InvalidInputsError, "No blobs requested") + + let count = blobIds.len + + var + found = 0 + bytes: seq[byte] + + for i in 0..= dag.head.slot.epoch: + GENESIS_EPOCH + else: + dag.head.slot.epoch - dag.cfg.MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS + + if startSlot.epoch < epochBoundary: + raise newException(ResourceUnavailableError, BlobsOutOfRange) + + var blockIds: array[int(maxReqSidecars), BlockId] + let + count = int min(reqCount, blockIds.lenu64) + endIndex = count - 1 + startIndex = + dag.getBlockRange(startSlot, 1, blockIds.toOpenArray(0, endIndex)) + + var + found = 0 + bytes: seq[byte] + + for i in startIndex..endIndex: + for j in 0..