# Consensus Specs ## Transport * dialing and listening to libP2P * listening atleast IPv4 or IPv6 * dialing both IPv4 and IPv6 * publicly dialable * interoperability shouldn't be compromised ## Encryption and Decryption * xx handshake pattern, libP2P noise ## Protocol Negotiation * multiselect (if not, then multistream-select) ## Multiplexing * for tcp: mplex (may: yamux) * for quic: none ## Client Storage: Metadata: sequence_no - incremented for each change in local metadata (for version) persistent_attestation_subnets_subscription ## Gossipsub * messages are enveloped in protobuf messages. * clients SHOULD NOT subscribe to gossipsub topics until `forkDigestValue` (genesis state values) are known. * message size: max `GOSSIP_MAX_SIZE` * `StrictNoSign` signature [policy](https://github.com/libp2p/specs/blob/master/pubsub/README.md#signature-policy-options) * message.id set based on valid/invalid snappy decompression in data * extended validators? * topics: `beacon_block`, `beacon_aggregate_and_proof`, `voluntary_exit`, `proposer_slashing`, `attester_slashing`, `beacon_attestation_{subnet_id}` * attestation topics divided into subnets, topics rotated throughout the epoch * All gossipsub messages are SSZ-encoded and then compressed with Snappy **block** compression ## Req/Resp Domain * ONE stream PER request/response interaction * new stream --> request message (encoded) sent immediately --> responder validates --> responder processes request until stream half closed --> write response --> stream fully closed * half close stream once request msg written * sream read closed by requester if: * error occuured in resp chunk * resp chunk fails validation * responser closes stream * max resp chunks read <!-- * chunk stream is terminated as error encountered --> * The contents are first SSZ-encoded and then compressed with Snappy **frames** compression. * For objects containing a single field, only the field is [SSZ-encoded](https://github.com/ethereum/consensus-specs/blob/252b852a61289efeb961a497f56302a70aeb7c77/ssz/simple-serialize.md) not a container with a single field. * Encoding: * unsigned protobuf variant shouldn't be larger than 10 bytes * must encoded raw ssz bytes length prefix must be within the SSZ payload size bounds * ```36+n+n // 6``` bytes should be read after reading the n bytes length prefix in header * messages that contain only a single field must be encoded directly as the type of that field and not as an SSZ container. * req/resp content: * Status ```( fork_digest: ForkDigest finalized_root: Root finalized_epoch: Epoch head_root: Root head_slot: Slot ``` * client with lower finalized epoch or head slot requests blocks. * Goodbye * single response chunk `1,2,3`. `[4, 127]` reserved for future usages. * BeaconBlocksByRange ```( start_slot: Slot count: uint64 step: uint64 # Deprecated, must be set to 1 ``` * Requests beacon blocks in the slot range `[start_slot, start_slot + count)]` * No block returned if slot is empty. * MUST keep a record of signed blocks seen on the epoch range `[max(GENESIS_EPOCH, current_epoch - MIN_EPOCHS_FOR_BLOCK_REQUESTS), current_epoch]` * BeaconBlocksByRoot * MUST support requesting blocks since the latest finalized epoch. * Ping * GetMetaData * **Questions** * If the (finalized_root, finalized_epoch) shared by the peer is not in the client's chain at the expected epoch. For example, if Peer 1 sends (root, epoch) of (A, 5) and Peer 2 sends (B, 3) but Peer 1 has root C at epoch 3, then Peer 1 would disconnect because it knows that their chains are irreparably disjoint. How is the criteria being set? * Under abnormal network condition or after some rounds of BeaconBlocksByRange requests, the client might need to send Status request again to learn if the peer has a higher head. Implementers are free to implement such behavior in their own way. How Prysm does this? * /eth2/beacon_chain/req/beacon_blocks_by_range/1/ is deprecated. Clients MAY respond with an empty list during the deprecation transition period. How is the list supposed to be fetched then? * do we check peer reputation in Prysm? * Is the response chunk sent once the request is completely processed or as and when the request message is processed? <!-- aggregate attestation, lmd vote --> ## Discv5 * Should be. integrated into libp2p stack by implementing an adaptor to make it conform to the service discovery and peer routing abstractions and interfaces. ## Attestation Subnet Subscription * for a hard fork, a node must select and subscribe to subnets of the future fork with min `EPOCHS_PER_SUBNET_SUBSCRIPTION` epochs in advance of the fork.