# Ethereum Consensus P2P Minimal Specification
## Overview
This document defines the **absolute minimum** requirements for implementing a P2P networking layer that can successfully connect to and interoperate with all major Ethereum consensus clients (Prysm, Lighthouse, Teku, Lodestar, Grandine, Nimbus).
These are not generic recommendations but **exact specifications** extracted from production client implementations, providing a bulletproof guide for new consensus client P2P development.
---
## 1. Request/Response (Req/Resp) Protocols
### Protocol Format
**Pattern**: `/eth2/beacon_chain/req/{method}/{version}/{encoding}`
**Encoding**: `ssz_snappy` (SSZ serialization + Snappy compression)
### Core Protocols (MANDATORY)
#### Status Protocol
- **ID**: `/eth2/beacon_chain/req/status/1/ssz_snappy`
- **Purpose**: Initial handshake and chain state exchange
- **Request**: `StatusMessage{fork_digest, finalized_root, finalized_epoch, head_root, head_slot}`
- **Response**: `StatusMessage` (same structure)
- **When**: First message on every new connection
- **Timeout**: Must respond within 5 seconds (TTFB)
#### Goodbye Protocol
- **ID**: `/eth2/beacon_chain/req/goodbye/1/ssz_snappy`
- **Purpose**: Graceful disconnection notification
- **Request**: `uint64` (goodbye reason code)
- **Response**: None (notification only)
- **When**: Before closing connection
#### Ping Protocol
- **ID**: `/eth2/beacon_chain/req/ping/1/ssz_snappy`
- **Purpose**: Keep-alive and metadata sequence tracking
- **Request**: `uint64` (sequence number)
- **Response**: `uint64` (local metadata sequence number)
- **Frequency**: As needed for liveness checks
#### Metadata Protocol
- **ID**: `/eth2/beacon_chain/req/metadata/2/ssz_snappy` (Altair+)
- **Purpose**: Exchange node metadata and capabilities
- **Request**: Empty
- **Response**: `MetaData{seq_number, attnets, syncnets}`
- **When**: After status exchange, when metadata changes
#### BeaconBlocksByRange Protocol
- **ID**: `/eth2/beacon_chain/req/beacon_blocks_by_range/2/ssz_snappy`
- **Purpose**: Sync blocks by slot range
- **Request**: `{start_slot, count, step}` (step typically 1)
- **Response**: Stream of `SignedBeaconBlock`
- **Limits**:
- Pre-Deneb: 1024 blocks max
- Deneb+: 128 blocks max
- **Critical**: Required for sync capability
#### BeaconBlocksByRoot Protocol
- **ID**: `/eth2/beacon_chain/req/beacon_blocks_by_root/2/ssz_snappy`
- **Purpose**: Fetch specific blocks by root
- **Request**: `List<Hash32>` (max 64 roots)
- **Response**: Stream of `SignedBeaconBlock`
- **Critical**: Required for sync capability
### Deneb+ Blob Protocols (MANDATORY for Deneb networks)
#### BlobSidecarsByRange Protocol
- **ID**: `/eth2/beacon_chain/req/blob_sidecars_by_range/1/ssz_snappy`
- **Request**: `{start_slot, count}`
- **Response**: Stream of `BlobSidecar`
- **Limits**: 768 blob sidecars max (Deneb), 1152 (Electra)
#### BlobSidecarsByRoot Protocol
- **ID**: `/eth2/beacon_chain/req/blob_sidecars_by_root/1/ssz_snappy`
- **Request**: `List<BlobIdentifier>` (max 64)
- **Response**: Stream of `BlobSidecar`
### Critical Timeouts
- **TTFB_TIMEOUT**: 5 seconds (time to first byte)
- **RESP_TIMEOUT**: 10 seconds (complete response)
- **MAX_PAYLOAD_SIZE**: 10,485,760 bytes (10 MiB)
---
## 2. GossipSub Configuration
### Core Parameters (MANDATORY)
```
D = 8 # Target mesh size
D_low = 6 # Minimum mesh size
D_high = 12 # Maximum mesh size
D_lazy = 6 # Lazy propagation degree
D_score = 5 # Score-based mesh target (D * 2/3)
D_out = 3 # Outbound mesh connections
heartbeat_interval = 700ms
fanout_ttl = 60 seconds
seen_ttl = ~780 seconds (2+ epochs)
history_length = 6
history_gossip = 3
advertise = 3
```
### Scoring Thresholds (MANDATORY)
```
gossip_threshold = -4000
publish_threshold = -8000
graylist_threshold = -16000
accept_px_threshold = 100
opportunistic_graft_threshold = 5
ip_colocation_factor_weight = -35.11
ip_colocation_factor_threshold = 10
behaviour_penalty_weight = -15.92
behaviour_penalty_threshold = 6
```
### Topic Subscriptions (MANDATORY)
#### Core Topics
- `/eth2/{fork_digest}/beacon_block/ssz_snappy`
- `/eth2/{fork_digest}/beacon_aggregate_and_proof/ssz_snappy`
- `/eth2/{fork_digest}/voluntary_exit/ssz_snappy`
- `/eth2/{fork_digest}/proposer_slashing/ssz_snappy`
- `/eth2/{fork_digest}/attester_slashing/ssz_snappy`
#### Subnet Topics (Dynamic Subscription Required)
- **Attestation Subnets**: `/eth2/{fork_digest}/beacon_attestation_{subnet_id}/ssz_snappy`
- Total subnets: 64
- **Minimum subscription**: 2 subnets per node
- Subscription duration: 256 epochs (~27 hours)
- **Sync Committee Subnets**: `/eth2/{fork_digest}/sync_committee_{subnet_id}/ssz_snappy`
- Total subnets: 4 (Altair+)
#### Fork-Specific Topics
- **Capella+**: `/eth2/{fork_digest}/bls_to_execution_change/ssz_snappy`
- **Deneb+**: `/eth2/{fork_digest}/blob_sidecar_{subnet_id}/ssz_snappy` (6 subnets)
### Message Size Limits
- **Max message size**: `max(compressed_length + 1024, 1MB)`
- **Compressed length formula**: `length + 32 + length/6`
- **Flood publish threshold**: 16,384 bytes (16 KiB)
---
## 3. Discovery (ENR & Discv5)
### Mandatory ENR Fields
- **eth2**: Fork identification
- Format: `{fork_digest, next_fork_version, next_fork_epoch}`
- **Critical**: Must be updated on every fork
- **attnets**: Attestation subnet subscriptions (64-bit bitvector)
- **syncnets**: Sync committee subnet subscriptions (4-bit bitvector, Altair+)
### Optional ENR Fields
- **cgc**: Custody group count (PeerDAS/Fulu+)
### Network Parameters
- **Default ports**: TCP 9000, UDP 9000
- **Subnet subscription duration**: 256 epochs
- **Minimum subnet subscriptions**: 2 attestation subnets
---
## 4. Transport Layer
### LibP2P Stack (MANDATORY)
- **Transport**: TCP (required), QUIC (optional but recommended)
- **Security**: Noise XX protocol
- **Multiplexing**: mplex (required), yamux (preferred if available)
- **Peer Discovery**: discv5 over UDP
### Connection Management
- **Target peers**: 64-100 peers
- **Connection limits**: Rate limiting per IP (typically 4-8 concurrent)
- **Timeouts**:
- Connection establishment: 5-60 seconds
- Stream reset: 5 seconds
---
## 5. Message Encoding
### Serialization (MANDATORY)
- **Format**: SSZ (Simple Serialize)
- **Compression**: Snappy compression for all messages
- **Protocol suffix**: `ssz_snappy`
### Message Structure
- **RPC**: Length-prefixed SSZ + Snappy compression
- **Gossip**: Direct SSZ + Snappy compression
- **Context bytes**: 4-byte fork digest for versioned protocols
- **Error responses**: Structured with status codes
### Size Constraints
- **Maximum payload**: 10,485,760 bytes (10 MiB)
- **Request limits**:
- Blocks: 1024 (pre-Deneb) / 128 (Deneb+)
- Blob sidecars: 768 (Deneb) / 1152 (Electra)
- Roots: 64 per request
---
## 6. Performance Requirements
### Rate Limiting (MANDATORY)
- **Per-peer block requests**: 500 blocks/minute
- **Per-peer blob requests**: 2000 blob sidecars/minute (~250MB)
- **Concurrent requests**: 100 per peer maximum
- **Global quotas**: Implement to prevent DoS
### Timing Requirements
- **Attestation propagation**: Within 32 slots
- **Clock disparity tolerance**: 500ms maximum
- **Gossip message validation**: Accept/Ignore/Reject within seconds
---
## 7. Fork Management
### Version Handling
- **Status protocol**: Version 1 (all forks)
- **Metadata protocol**: Version 2 (Altair+), Version 3 (Fulu+)
- **Block protocols**: Version 2 (includes execution payloads)
- **Blob protocols**: Version 1 (Deneb+)
### Fork Transitions
- **Topic subscriptions**:
- Subscribe to new fork topics 5 slots before fork
- Maintain old fork topics for 2 epochs after fork
- **ENR updates**: Update fork digest immediately on fork activation
- **Peer filtering**: Disconnect peers with mismatched fork digests
---
## 8. Critical Implementation Notes
### Mandatory for Basic Connectivity
1. **All core req/resp protocols** must be implemented
2. **GossipSub mesh parameters** must match exactly
3. **ENR eth2 field** must be present and correct
4. **Minimum 2 attestation subnet subscriptions** required
5. **SSZ + Snappy encoding** for all messages
6. **Noise encryption** with proper libp2p stack
### Interoperability Requirements
- **Timeout compliance**: Respect all specified timeouts
- **Rate limiting**: Implement to prevent peer penalties
- **Fork compatibility**: Handle all active fork versions
- **Subnet rotation**: Properly rotate attestation subnet subscriptions
- **Error handling**: Graceful handling of protocol violations
### Performance Optimizations
- **Connection pooling**: Maintain stable peer connections
- **Request batching**: Batch requests within limits
- **Compression efficiency**: Proper Snappy frame handling
- **Memory management**: Bounded message processing
---
## 9. Implementation Checklist
### Phase 1: Basic Connectivity
- [ ] TCP transport with Noise encryption
- [ ] Status, Goodbye, Ping, Metadata protocols
- [ ] Basic GossipSub with beacon block topic
- [ ] ENR with eth2, attnets fields
- [ ] SSZ serialization with Snappy compression
### Phase 2: Sync Capability
- [ ] BeaconBlocksByRange and BeaconBlocksByRoot protocols
- [ ] All mandatory gossip topics
- [ ] Proper timeout and rate limiting
- [ ] Attestation subnet subscriptions (minimum 2)
- [ ] Fork digest management
### Phase 3: Full Compliance
- [ ] Blob protocols (Deneb+ networks)
- [ ] Complete GossipSub scoring
- [ ] Advanced ENR fields
- [ ] All fork-specific features
- [ ] Performance optimizations
### Phase 4: Advanced Features
- [ ] Light client protocols (optional)
- [ ] PeerDAS support (Fulu+)
- [ ] QUIC transport
- [ ] Advanced peer management
---
## 10. Testing and Validation
### Interoperability Testing
- **Multi-client networks**: Test against all major clients
- **Fork transitions**: Verify behavior during network upgrades
- **Stress testing**: High peer counts and message volumes
- **Edge cases**: Network partitions, malformed messages
### Compliance Verification
- **Protocol compliance**: All req/resp protocols work correctly
- **GossipSub behavior**: Messages propagate properly
- **Discovery**: Peers find each other via ENR
- **Performance**: Meets timing and throughput requirements
---
This specification provides the exact parameters needed to implement a consensus client P2P layer that will successfully interoperate with the entire Ethereum consensus network. All values are derived from production client implementations and represent the de facto standards of the network.