Consensus gossip uses gossipsub v1.1 (/meshsub/1.1.0). A topic names the
fork, object, and encoding:
/eth2/{fork_digest}/{topic_name}/ssz_snappy
fork_digest is four lowercase hexadecimal bytes with no 0x prefix. The
client computes it from the message context and genesis validators root. A
node MUST reject an unknown topic and SHOULD wait for genesis values before
subscribing.
Envelope and message ID
The sender SSZ-encodes the topic type and compresses it with Snappy block
compression. Consensus gossip omits the optional gossipsub from, seqno,
signature, and key fields and uses the StrictNoSign policy. Application
signatures stay inside the SSZ object.
The message ID is 20 bytes from
SHA256(MESSAGE_DOMAIN_VALID_SNAPPY + snappy_decompress(data))[:20] for valid
Snappy, or from SHA256(MESSAGE_DOMAIN_INVALID_SNAPPY + data)[:20] when
decompression fails.
The message ID is 20 bytes from the domain, the topic length as little-endian
Uint64, the topic bytes, and the payload. A client serving multiple fork
digests selects the rule from the topic digest.
Limits and encoding
MAX_PAYLOAD_SIZE is 10,485,760 uncompressed bytes. For n SSZ bytes,
max_compressed_len(n) = 32 + n + n / 6; the full gossipsub RPC frame must fit
max(max_compressed_len(MAX_PAYLOAD_SIZE) + 1024, 1 MiB). The compressed
Message.data and uncompressed payload MUST each stay within their bound and
the lower type-specific bound. A receiver checks these limits before SSZ
decoding and MUST reject trailing or malformed Snappy data.
The active type-specific uncompressed bounds are:
MAX_SIGNED_AGGREGATE_AND_PROOF_SIZE = 16,829,
MAX_ATTESTER_SLASHING_SIZE = 2,097,616,
MAX_DATA_COLUMN_SIDECAR_SIZE = 8,585,272, and
MAX_SIGNED_EXECUTION_PAYLOAD_BID_SIZE = 196,932.
Validation outcomes
The topic validator checks the expected SSZ type and then the topic-specific
rules. ACCEPT forwards the object and records it in the seen cache. IGNORE
handles duplicates, future slots, unavailable parent state, or data that is
outside the propagation window. REJECT handles malformed SSZ, bad
signatures, wrong subnets, invalid roots, and operation-limit violations.
Only a rejected protocol violation can lower the peer's application score;
local policy decides whether to prune or disconnect.
Topic transition
Each fork uses a distinct topic path even when the object name stays the same. A node SHOULD subscribe to the active path and the path for the next configured fork before activation. It may ignore an early next-fork message within the 500-millisecond clock-disparity allowance. Once the next path is active, it must not score a peer only because the peer still publishes on the prior path. The two paths share application-level duplicate caches during the transition, and the node SHOULD unsubscribe from the prior path after two epochs. A node must not rebroadcast an object from one fork topic to the other.
Topic inventory
The global topic set includes beacon_block, beacon_aggregate_and_proof,
beacon_attestation_{subnet_id}, voluntary_exit, proposer_slashing, and
attester_slashing.
The object pages own each payload's validation.
The topic set also includes sync-committee and light-client topics.
The topic set includes blob sidecar topics.
The topic set uses data-column sidecars while it keeps the sidecar request transition.
The topic set also includes execution-payload bid, envelope, and payload-attestation topics.