# 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.