From 6cd8f3ba55e64e9dc0bb9988f81f0a4525a4cc15 Mon Sep 17 00:00:00 2001 From: tersec Date: Sat, 12 Aug 2023 03:10:12 +0000 Subject: [PATCH] Update constants/presets for consistency with consensus-specs v1.4.0 (#5284) --- beacon_chain/networking/eth2_network.nim | 23 ++++++++++++----------- beacon_chain/spec/datatypes/constants.nim | 10 +++++++++- beacon_chain/spec/network.nim | 9 ++------- beacon_chain/spec/presets.nim | 6 ++++++ beacon_chain/spec/validator.nim | 3 ++- beacon_chain/sync/sync_manager.nim | 5 +++-- beacon_chain/sync/sync_protocol.nim | 10 +++++----- 7 files changed, 39 insertions(+), 27 deletions(-) diff --git a/beacon_chain/networking/eth2_network.nim b/beacon_chain/networking/eth2_network.nim index 0b183fd7d..0a661a7fc 100644 --- a/beacon_chain/networking/eth2_network.nim +++ b/beacon_chain/networking/eth2_network.nim @@ -661,7 +661,7 @@ proc sendErrorResponse(peer: Peer, proc sendNotificationMsg(peer: Peer, protocolId: string, requestBytes: Bytes) {.async.} = var - deadline = sleepAsync RESP_TIMEOUT + deadline = sleepAsync RESP_TIMEOUT_DUR streamFut = peer.network.openStream(peer, protocolId) await streamFut or deadline @@ -798,17 +798,18 @@ proc uncompressFramedStream(conn: Connection, func chunkMaxSize[T](): uint32 = # compiler error on (T: type) syntax... + static: doAssert MAX_CHUNK_SIZE < high(uint32).uint64 when T is ForkySignedBeaconBlock: when T is phase0.SignedBeaconBlock or T is altair.SignedBeaconBlock or T is bellatrix.SignedBeaconBlock or T is capella.SignedBeaconBlock or T is deneb.SignedBeaconBlock: - MAX_CHUNK_SIZE_BELLATRIX + MAX_CHUNK_SIZE.uint32 else: {.fatal: "what's the chunk size here?".} elif isFixedSize(T): uint32 fixedPortionSize(T) else: - MAX_CHUNK_SIZE_BELLATRIX + MAX_CHUNK_SIZE.uint32 from ../spec/datatypes/capella import SignedBeaconBlock from ../spec/datatypes/deneb import SignedBeaconBlock @@ -816,10 +817,10 @@ from ../spec/datatypes/deneb import SignedBeaconBlock template gossipMaxSize(T: untyped): uint32 = const maxSize = static: when isFixedSize(T): - fixedPortionSize(T) + fixedPortionSize(T).uint32 elif T is bellatrix.SignedBeaconBlock or T is capella.SignedBeaconBlock or T is deneb.SignedBeaconBlock: - GOSSIP_MAX_SIZE_BELLATRIX + GOSSIP_MAX_SIZE # TODO https://github.com/status-im/nim-ssz-serialization/issues/20 for # Attestation, AttesterSlashing, and SignedAggregateAndProof, which all # have lists bounded at MAX_VALIDATORS_PER_COMMITTEE (2048) items, thus @@ -827,10 +828,10 @@ template gossipMaxSize(T: untyped): uint32 = elif T is Attestation or T is AttesterSlashing or T is SignedAggregateAndProof or T is phase0.SignedBeaconBlock or T is altair.SignedBeaconBlock or T is SomeForkyLightClientObject: - GOSSIP_MAX_SIZE_BELLATRIX + GOSSIP_MAX_SIZE else: {.fatal: "unknown type " & name(T).} - static: doAssert maxSize <= GOSSIP_MAX_SIZE_BELLATRIX + static: doAssert maxSize <= GOSSIP_MAX_SIZE maxSize.uint32 proc readChunkPayload*(conn: Connection, peer: Peer, @@ -1110,7 +1111,7 @@ proc handleIncomingStream(network: Eth2Node, nbc_reqresp_messages_received.inc(1, [shortProtocolId(protocolId)]) # TODO(zah) The TTFB timeout is not implemented in LibP2P streams back-end - let deadline = sleepAsync RESP_TIMEOUT + let deadline = sleepAsync RESP_TIMEOUT_DUR const isEmptyMsg = when MsgRec is object: # We need nested `when` statements here, because Nim doesn't properly @@ -2336,7 +2337,7 @@ proc createEth2Node*(rng: ref HmacDrbgContext, try: # This doesn't have to be a tight bound, just enough to avoid denial of # service attacks. - let decoded = snappy.decode(m.data, GOSSIP_MAX_SIZE_BELLATRIX) + let decoded = snappy.decode(m.data, static(GOSSIP_MAX_SIZE.uint32)) ok(gossipId(decoded, phase0Prefix, topic)) except CatchableError: err(ValidationResult.Reject) @@ -2393,7 +2394,7 @@ proc createEth2Node*(rng: ref HmacDrbgContext, sign = false, verifySignature = false, anonymize = true, - maxMessageSize = GOSSIP_MAX_SIZE_BELLATRIX, + maxMessageSize = static(GOSSIP_MAX_SIZE.int), parameters = params) switch.mount(pubsub) @@ -2504,7 +2505,7 @@ proc gossipEncode(msg: auto): seq[byte] = let uncompressed = SSZ.encode(msg) # This function only for messages we create. A message this large amounts to # an internal logic error. - doAssert uncompressed.len <= GOSSIP_MAX_SIZE_BELLATRIX + doAssert uncompressed.lenu64 <= GOSSIP_MAX_SIZE snappy.encode(uncompressed) diff --git a/beacon_chain/spec/datatypes/constants.nim b/beacon_chain/spec/datatypes/constants.nim index c61f18e02..42bf5de79 100644 --- a/beacon_chain/spec/datatypes/constants.nim +++ b/beacon_chain/spec/datatypes/constants.nim @@ -20,7 +20,7 @@ const NODE_ID_BITS* = 256 # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/phase0/p2p-interface.md#configuration - EPOCHS_PER_SUBNET_SUBSCRIPTION* = 256 + EPOCHS_PER_SUBNET_SUBSCRIPTION* = 256'u64 SUBNETS_PER_NODE* = 2'u64 ATTESTATION_SUBNET_COUNT*: uint64 = 64 ATTESTATION_SUBNET_EXTRA_BITS* = 0 @@ -65,3 +65,11 @@ const # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/deneb/p2p-interface.md#configuration BLOB_SIDECAR_SUBNET_COUNT*: uint64 = 6 + + # https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/phase0/p2p-interface.md#configuration + MAX_REQUEST_BLOCKS* = 1024'u64 + RESP_TIMEOUT* = 10 + + # https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/bellatrix/p2p-interface.md#configuration + GOSSIP_MAX_SIZE* = 10'u64 * 1024 * 1024 # bytes + MAX_CHUNK_SIZE* = 10'u64 * 1024 * 1024 # bytes diff --git a/beacon_chain/spec/network.nim b/beacon_chain/spec/network.nim index f8bd612c6..8e5bc8b84 100644 --- a/beacon_chain/spec/network.nim +++ b/beacon_chain/spec/network.nim @@ -23,17 +23,12 @@ const topicAggregateAndProofsSuffix* = "beacon_aggregate_and_proof/ssz_snappy" topicBlsToExecutionChangeSuffix* = "bls_to_execution_change/ssz_snappy" - # https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/phase0/p2p-interface.md#configuration - MAX_REQUEST_BLOCKS* = 1024 - RESP_TIMEOUT* = 10.seconds + # The spec now includes this as a bare integer as `RESP_TIMEOUT` + RESP_TIMEOUT_DUR* = RESP_TIMEOUT.seconds # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/altair/light-client/p2p-interface.md#configuration MAX_REQUEST_LIGHT_CLIENT_UPDATES* = 128 - # https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/bellatrix/p2p-interface.md#configuration - GOSSIP_MAX_SIZE_BELLATRIX* = 10 * 1024 * 1024 # bytes - MAX_CHUNK_SIZE_BELLATRIX* = 10 * 1024 * 1024 # bytes - # https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/p2p-interface.md#configuration MAX_REQUEST_BLOCKS_DENEB* = 128 # TODO Make use of in request code MAX_REQUEST_BLOB_SIDECARS* = MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK diff --git a/beacon_chain/spec/presets.nim b/beacon_chain/spec/presets.nim index 445e51ade..16fa6d165 100644 --- a/beacon_chain/spec/presets.nim +++ b/beacon_chain/spec/presets.nim @@ -576,6 +576,12 @@ proc readRuntimeConfig*( checkCompatibility DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF checkCompatibility DOMAIN_CONTRIBUTION_AND_PROOF + checkCompatibility GOSSIP_MAX_SIZE + checkCompatibility MAX_REQUEST_BLOCKS + checkCompatibility EPOCHS_PER_SUBNET_SUBSCRIPTION + checkCompatibility MAX_CHUNK_SIZE + checkCompatibility SUBNETS_PER_NODE + # Never pervasively implemented, still under discussion checkCompatibility TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH diff --git a/beacon_chain/spec/validator.nim b/beacon_chain/spec/validator.nim index d28e6327e..560ea9c12 100644 --- a/beacon_chain/spec/validator.nim +++ b/beacon_chain/spec/validator.nim @@ -483,7 +483,8 @@ func compute_subscribed_subnet(node_id: UInt256, epoch: Epoch, index: uint64): let node_id_prefix = truncate( node_id shr (NODE_ID_BITS - ATTESTATION_SUBNET_PREFIX_BITS), uint64) - node_offset = truncate(node_id mod EPOCHS_PER_SUBNET_SUBSCRIPTION, uint64) + node_offset = truncate( + node_id mod static(EPOCHS_PER_SUBNET_SUBSCRIPTION.u256), uint64) permutation_seed = eth2digest(uint_to_bytes( uint64((epoch + node_offset) div EPOCHS_PER_SUBNET_SUBSCRIPTION))) permutated_prefix = compute_shuffled_index( diff --git a/beacon_chain/sync/sync_manager.nim b/beacon_chain/sync/sync_manager.nim index b18da9ad2..7248a7459 100644 --- a/beacon_chain/sync/sync_manager.nim +++ b/beacon_chain/sync/sync_manager.nim @@ -76,7 +76,8 @@ type stamp*: chronos.Moment slots*: uint64 - BeaconBlocksRes = NetRes[List[ref ForkedSignedBeaconBlock, MAX_REQUEST_BLOCKS]] + BeaconBlocksRes = + NetRes[List[ref ForkedSignedBeaconBlock, Limit MAX_REQUEST_BLOCKS]] BlobSidecarsRes = NetRes[List[ref BlobSidecar, Limit(MAX_REQUEST_BLOB_SIDECARS)]] proc now*(sm: typedesc[SyncMoment], slots: uint64): SyncMoment {.inline.} = @@ -389,7 +390,7 @@ proc syncStep[A, B](man: SyncManager[A, B], index: int, peer: A) {.async.} = queue_input_slot = man.queue.inpSlot, queue_output_slot = man.queue.outSlot, queue_last_slot = man.queue.finalSlot, direction = man.direction - await sleepAsync(RESP_TIMEOUT) + await sleepAsync(RESP_TIMEOUT_DUR) return debug "Creating new request for peer", wall_clock_slot = wallSlot, diff --git a/beacon_chain/sync/sync_protocol.nim b/beacon_chain/sync/sync_protocol.nim index 30144544c..af9d8af32 100644 --- a/beacon_chain/sync/sync_protocol.nim +++ b/beacon_chain/sync/sync_protocol.nim @@ -261,7 +261,7 @@ p2pProtocol BeaconSync(version = 1, # given incoming flag let ourStatus = peer.networkState.getCurrentStatus() - theirStatus = await peer.status(ourStatus, timeout = RESP_TIMEOUT) + theirStatus = await peer.status(ourStatus, timeout = RESP_TIMEOUT_DUR) if theirStatus.isOk: discard await peer.handleStatus(peer.networkState, theirStatus.get()) @@ -298,7 +298,7 @@ p2pProtocol BeaconSync(version = 1, reqCount: uint64, reqStep: uint64, response: MultipleChunksResponse[ - ref ForkedSignedBeaconBlock, MAX_REQUEST_BLOCKS]) + ref ForkedSignedBeaconBlock, Limit MAX_REQUEST_BLOCKS]) {.async, libp2pProtocol("beacon_blocks_by_range", 2).} = # TODO Semantically, this request should return a non-ref, but doing so # runs into extreme inefficiency due to the compiler introducing @@ -320,7 +320,7 @@ p2pProtocol BeaconSync(version = 1, if reqCount == 0 or reqStep == 0: raise newException(InvalidInputsError, "Empty range requested") - var blocks: array[MAX_REQUEST_BLOCKS, BlockId] + var blocks: array[MAX_REQUEST_BLOCKS.int, BlockId] let dag = peer.networkState.dag # Limit number of blocks in response @@ -367,7 +367,7 @@ p2pProtocol BeaconSync(version = 1, # spec constant MAX_REQUEST_BLOCKS is enforced: blockRoots: BlockRootsList, response: MultipleChunksResponse[ - ref ForkedSignedBeaconBlock, MAX_REQUEST_BLOCKS]) + ref ForkedSignedBeaconBlock, Limit MAX_REQUEST_BLOCKS]) {.async, libp2pProtocol("beacon_blocks_by_root", 2).} = # TODO Semantically, this request should return a non-ref, but doing so # runs into extreme inefficiency due to the compiler introducing @@ -710,7 +710,7 @@ proc updateStatus*(peer: Peer): Future[bool] {.async.} = nstate = peer.networkState(BeaconSync) ourStatus = getCurrentStatus(nstate) - let theirFut = awaitne peer.status(ourStatus, timeout = RESP_TIMEOUT) + let theirFut = awaitne peer.status(ourStatus, timeout = RESP_TIMEOUT_DUR) if theirFut.failed(): return false else: