diff --git a/src/lean_spec/subspecs/networking/config.py b/src/lean_spec/subspecs/networking/config.py index d2011e4f..93b1740d 100644 --- a/src/lean_spec/subspecs/networking/config.py +++ b/src/lean_spec/subspecs/networking/config.py @@ -2,13 +2,15 @@ from typing_extensions import Final +from lean_spec.types.byte_arrays import Bytes4 + from .types import DomainType MAX_REQUEST_BLOCKS: Final = 2**10 """Maximum number of blocks in a single request.""" -MESSAGE_DOMAIN_INVALID_SNAPPY: Final[DomainType] = b"\x00\x00\x00\x00" +MESSAGE_DOMAIN_INVALID_SNAPPY: Final[DomainType] = Bytes4(b"\x00\x00\x00\x00") """4-byte domain for gossip message-id isolation of invalid snappy messages.""" -MESSAGE_DOMAIN_VALID_SNAPPY: Final[DomainType] = b"\x01\x00\x00\x00" +MESSAGE_DOMAIN_VALID_SNAPPY: Final[DomainType] = Bytes4(b"\x01\x00\x00\x00") """4-byte domain for gossip message-id isolation of valid snappy messages.""" diff --git a/src/lean_spec/subspecs/networking/reqresp/message.py b/src/lean_spec/subspecs/networking/reqresp/message.py index 5980b56c..440ee030 100644 --- a/src/lean_spec/subspecs/networking/reqresp/message.py +++ b/src/lean_spec/subspecs/networking/reqresp/message.py @@ -5,11 +5,10 @@ domain. All messages are SSZ-encoded and then compressed with Snappy frames. """ -from pydantic import Field -from typing_extensions import Annotated +from typing import ClassVar, Type from lean_spec.subspecs.containers import Checkpoint, SignedBlockWithAttestation -from lean_spec.types import Bytes32, StrictBaseModel +from lean_spec.types import Bytes32, SSZList, SSZType, StrictBaseModel from ..config import MAX_REQUEST_BLOCKS from ..types import ProtocolId @@ -67,24 +66,26 @@ class Status(StrictBaseModel): BLOCKS_BY_ROOT_PROTOCOL_V1: ProtocolId = "/leanconsensus/req/blocks_by_root/1/" """The protocol ID for the BlocksByRoot v1 request/response message.""" -BlocksByRootRequest = Annotated[ - list[Bytes32], - Field(max_length=MAX_REQUEST_BLOCKS), -] -""" -A request for one or more blocks by their root hashes. -This is primarily used to recover recent or missing blocks from a peer. -""" +class BlocksByRootRequest(SSZList[Bytes32]): + """ + A request for one or more blocks by their root hashes. -BlocksByRootResponse = Annotated[ - list[SignedBlockWithAttestation], - Field(max_length=MAX_REQUEST_BLOCKS), -] -""" -A response containing the requested `SignedBlockWithAttestation` objects. + This is primarily used to recover recent or missing blocks from a peer. + """ -The length of the list may be less than the number of requested blocks if -the responding peer does not have all of them. Each block is sent in a -separate `response_chunk`. -""" + ELEMENT_TYPE: ClassVar[Type[SSZType]] = Bytes32 + LIMIT: ClassVar[int] = MAX_REQUEST_BLOCKS + + +class BlocksByRootResponse(SSZList[SignedBlockWithAttestation]): + """ + A response containing the requested `SignedBlockWithAttestation` objects. + + The length of the list may be less than the number of requested blocks if + the responding peer does not have all of them. Each block is sent in a + separate `response_chunk`. + """ + + ELEMENT_TYPE: ClassVar[Type[SSZType]] = SignedBlockWithAttestation + LIMIT: ClassVar[int] = MAX_REQUEST_BLOCKS diff --git a/src/lean_spec/subspecs/networking/types.py b/src/lean_spec/subspecs/networking/types.py index 0aae6ab7..7cf4f12d 100644 --- a/src/lean_spec/subspecs/networking/types.py +++ b/src/lean_spec/subspecs/networking/types.py @@ -1,11 +1,22 @@ """Networking-related type definitions for the specification.""" -from typing import Annotated +from lean_spec.types import Uint64 +from lean_spec.types.byte_arrays import Bytes4, Bytes32 -from pydantic import Field - -DomainType = Annotated[bytes, Field(min_length=4, max_length=4)] +DomainType = Bytes4 """A 4-byte value used for domain separation in message-ids.""" +NodeId = Bytes32 +"""32-byte node identifier for Discovery v5, derived from ``keccak256(pubkey)``.""" + ProtocolId = str """A string representing a libp2p protocol ID.""" + +SeqNumber = Uint64 +"""Sequence number used in ENR records, metadata, and ping messages.""" + +SubnetId = Uint64 +"""Subnet identifier (0-63) for attestation subnet partitioning.""" + +Multiaddr = str +"""Multiaddress string, e.g. ``/ip4/192.168.1.1/tcp/9000``."""