Abstract
This BRC specifies how standalone 80-byte BSV block headers are distributed to downstream consumers, in two forms. The datagram form wraps the header in a minimal 172-byte frame that reuses the 92-byte BRC-124 header layout, ensuring compatibility with existing infrastructure classifiers and firewall rules, and is carried over IPv6 multicast or unicast datagrams. The stream form writes the bare 80-byte header, with no frame at all, on a single-class byte stream dedicated to headers. Both are produced by splitting the block header out of a BRC-131 block announcement.
Copyright
This BRC is licensed under the Open BSV License.
Motivation
BRC-131 BlockAnnounce frames distribute block headers alongside CoinbaseTxID
and a variable-length list of subtree root hashes. Many downstream consumers
need only the 80-byte block header:
- SPV clients require only the header chain to verify proof-of-work and compute chain state; subtree hashes and CoinbaseTxID are irrelevant.
- Mining coordinators need the previous-block hash and timestamp to build new templates; the remaining announce payload adds unnecessary latency on constrained links.
- Header-chain archival services store and index raw 80-byte headers and discard everything else.
Delivering the full BlockAnnounce payload to these consumers wastes bandwidth
and increases processing overhead. BRC-135 defines a fixed-size, minimal frame
that any node receiving a BlockAnnounce can produce by extracting the 80-byte
header and re-emitting it to downstream consumers. A node that produces BRC-135
frames is referred to as an emitter throughout this specification.
Specification
Terminology
| Term | Definition |
|---|---|
| Emitter | Any node that receives a BRC-131 BlockAnnounce frame and produces a BRC-135 block header frame from it. |
| Consumer | A downstream node that receives and processes BRC-135 frames. |
| BlockHash | The SHA256d hash of the 80-byte block header, in internal byte order. |
Multicast Group
This section governs the datagram form; the stream form has no group and is specified under Stream Delivery Form below.
BRC-135 frames are emitted to the emitter's configured multicast egress group or
unicast egress address. They MUST NOT be re-injected onto the primary fabric
group FF0E::B:FFFE — doing so would create a feedback loop as other fabric
subscribers would receive the split frame on the control channel they already
subscribe to.
When multicast egress is enabled, the emitter sends BRC-135 frames to the
GroupBlockHeader index (0xFFFA) on the egress scope, typically a different
scope or group-id from the ingress fabric:
| Index | Scope | Compressed Address | Notes |
|---|---|---|---|
| 0xFFFA | egress (varies) | FF05:: |
Emitter multicast egress channel |
The egress group-id is set independently of the fabric group-id. This ensures BRC-135 frames reach only downstream consumers, not peer fabric subscribers or retry endpoints on the ingress fabric.
The egress address is shown in ASM (FF05) form; under SSM, substitute the
FF3x prefix per BRC-129. The frame format is unchanged. The
frame's source is the emitter (emitterIPv6), which stamps its own identity, so
downstream consumers (S,G)-join per emitter. Under SSM the multi-emitter
reliability pattern uses distinct per-emitter sources (or VRRP active-standby);
anycast or shared-source emission is not supported (BRC-129).
Frame Header Format (92 bytes)
The BRC-135 header is layout-identical to BRC-124. All infrastructure components that inspect Magic, HashKey, or SeqNum read correct values at the same offsets. All multi-byte integers are big-endian.
| Offset | Size | Alignment | Field | Description |
|---|---|---|---|---|
| 0 | 4 | — | Network Magic | 0xE3E1F3E8 (BSV mainnet P2P magic) |
| 4 | 2 | — | Protocol Ver | 0x02BF (703, BSV large-block baseline) |
| 6 | 1 | — | Frame Version | 0x07 — BRC-135 block header |
| 7 | 1 | — | Reserved | 0x00 |
| 8 | 32 | 8-byte | BlockHash | SHA256d of the 80-byte block header (internal byte order) |
| 40 | 8 | 8-byte | HashKey | XXH64(emitterIPv6 ∥ 0xFFFA ∥ zeros); stamped by emitter |
| 48 | 8 | 8-byte | SeqNum | Monotonic per-emitter counter; stamped by emitter |
| 56 | 32 | 8-byte | LayoutPad32 | All zeros (no subtree scope for block headers) |
| 88 | 4 | — | PayloadLen | 0x00000050 (80 = fixed block header size, uint32 BE) |
| 92 | 80 | — | Payload | Raw 80-byte BSV block header |
Total frame size: 172 bytes (92 header + 80 payload). Always fits in a single UDP datagram — no fragmentation is required.
Field Definitions
Network Magic (bytes 0–3)
The value 0xE3E1F3E8 (BSV mainnet P2P network magic). This enables standard
BSV firewall rules and network monitoring tools to correctly classify BRC-135
frames. Frames with incorrect magic MUST be rejected.
Protocol Version (bytes 4–5)
The value 0x02BF (703 in decimal). Informational; receivers do not validate
it.
Frame Version (byte 6)
The value 0x07 identifies a BRC-135 block header frame. Any other version is
handled by other decoders.
Reserved (byte 7)
Must be 0x00. Unlike BRC-131 which uses this byte for MsgType, BRC-135 has no
message subtypes — the frame always carries exactly one block header.
BlockHash (bytes 8–39)
The SHA256d of the 80-byte block header in internal byte order. This value is
identical to the ContentID field in a BRC-131 BlockAnnounce frame for the
same block.
HashKey (bytes 40–47)
A stable per-emitter flow identifier computed as:
HashKey = XXH64(emitterIPv6 [16 bytes] ∥ 0x0000FFFA [4 bytes BE] ∥ zeros [32 bytes])
The 0xFFFA group index is GroupBlockHeader, the emitter multicast egress
channel (see the group table above). The 32 zero bytes correspond to the absent
SubtreeID. The HashKey is constant for the lifetime of the emitter process.
A value of 0 indicates the field is unset.
SeqNum (bytes 48–55)
A 64-bit unsigned integer (big-endian) containing a monotonic counter starting at 1, incremented for each BRC-135 frame emitted. Each emitter maintains a single counter for all block header frames.
A value of 0 indicates the field is unset.
LayoutPad32 (bytes 56–87)
All zeros. This field is retained to keep the header at 92 bytes, maintaining layout uniformity with BRC-124 and other frame versions. Block header frames have no subtree scope.
PayloadLen (bytes 88–91)
Always 0x00000050 (80 in decimal). A frame with any other PayloadLen MUST be
rejected.
Payload (bytes 92–171)
The raw 80-byte BSV block header, byte-for-byte identical to the first 80 bytes
of a BRC-131 BlockAnnounce payload:
| Offset | Size | Encoding | Field | Description |
|---|---|---|---|---|
| 0 | 4 | int32 LE | Version | Block version |
| 4 | 32 | bytes | PrevBlockHash | Hash of previous block (internal order) |
| 36 | 32 | bytes | MerkleRoot | Merkle root of the block's tx tree |
| 68 | 4 | uint32 LE | Timestamp | Block timestamp (Unix epoch seconds) |
| 72 | 4 | uint32 LE | Bits | Compact difficulty target |
| 76 | 4 | uint32 LE | Nonce | Proof-of-work nonce |
No additional framing or envelope is applied. The block header is copied
verbatim from the BRC-131 BlockAnnounce payload bytes [0:80].
Frame Production
Any node that receives a BRC-131 BlockAnnounce frame (FrameVer=0x04,
MsgType=0x01) MAY produce a BRC-135 frame:
- Extract the 80-byte block header from
BlockAnnouncepayload bytes[0:80]— the first 80 bytes of the BRC-144 block object that payload carries. - Copy the
BlockHashfrom the BRC-131 frame'sContentIDfield (bytes 8–39). - Stamp
HashKeyusing the emitter's own IPv6 address per the formula above. - Increment and stamp
SeqNum. - Emit the 172-byte frame to the configured egress.
The emitter stamps HashKey and SeqNum using its own identity — not the
proxy's. This reflects that the emitter is the originator of the split frame.
Each emitter produces an independent sequence stream.
Sequencing
BRC-135 frames carry their own independent HashKey/SeqNum flow:
- Each emitter maintains a single SeqNum counter for all block headers.
- Downstream consumers that track gaps identify the emitter via HashKey.
- If a consumer receives BRC-135 frames from multiple emitters (e.g., via anycast or failover), each emitter produces an independent sequence stream.
Retransmission
BRC-135 frames are not retransmitted via the standard BRC-126 NACK path on the primary fabric. They are a derived product — if a downstream consumer misses a BRC-135 frame, it can recover from a different source:
- Redundant emitters — multiple emitters produce the same block header; downstream consumers subscribe to more than one for reliability.
- Re-request from upstream — the consumer re-requests the full BRC-131
BlockAnnouncevia BRC-126 NACK to a retry endpoint, then extracts the header locally. - Application-level retry — the downstream consumer requests the block
header by hash from any BSV peer using the standard
getheadersprotocol.
If a deployment requires NACK-based retransmission for BRC-135 frames on the
egress network, a secondary retry endpoint can be deployed on the egress segment
that joins the egress multicast group and caches BRC-135 frames by
HashKey ∥ SeqNum. This is an optional deployment topology, not a
protocol-level requirement.
Error Handling
| Condition | Action |
|---|---|
| raw[6] != 0x07 | Not BRC-135; handled by other decoders |
| Bad magic | Silent drop |
| PayloadLen != 80 | Drop; ErrBadBlockHeaderLen |
| Datagram shorter than 172 bytes | Drop; ErrTooShort |
| BlockHash mismatch (optional) | Drop; integrity verification failed |
Stream Delivery Form
On a single-class byte stream carrying nothing but block headers, the
emitter writes the bare 80-byte header and nothing else: no frame header, no
tag, no length prefix, no record envelope. A block header is fixed size, so the
stream is self-delimiting — a consumer reads 80 bytes at a time, and the Nth
header begins at byte offset 80 × (N − 1).
This is the form for a persistent unicast connection dedicated to headers, where the connection itself identifies the class. It is deliberately minimal:
- No frame header. The 92-byte header exists to classify a datagram on a shared multicast group and to carry the emitter's sequencing. A dedicated stream needs neither: the connection names the class, and the transport already orders and delivers what is written.
- No sequencing fields.
HashKeyandSeqNumidentify the emitter's flow, which is meaningless to a subscriber and differs between the primary and standby emitters that may serve it. What a consumer verifies is the header itself, and the chain it builds from them. - No length prefix. Eighty bytes is fixed by consensus. A length would be redundant, and a reader that trusted it over the fixed size would desynchronise on a malformed writer rather than on the first bad header.
A consumer of the stream form:
- Read exactly 80 bytes.
- Chain — check that
PrevBlockHash(bytes 4–35) equalsSHA256dof the previous header it accepted, which is what makes a stream of headers a chain rather than a list. - Identify — compute
BlockHash = SHA256d(header)where the block id is needed; the stream carries no separate identifier.
A stream is a live tail: a consumer that connects mid-chain receives headers from connect time forward and cannot bootstrap a chain from this stream alone.
The two forms carry the same 80 bytes and differ only in envelope, so an emitter MAY serve both, and a consumer MUST NOT expect frame fields on the stream form.
Consumer Processing
A consumer receiving BRC-135 datagram frames:
- Validate — Check
raw[0:4] == 0xE3E1F3E8,raw[6] == 0x07,PayloadLen == 80. - Extract — Read the 80-byte block header from
raw[92:172]. - Verify — Optionally compute
SHA256d(raw[92:172])and compare againstBlockHash(bytes 8–39) to confirm integrity. - Gap track — If consuming from a single emitter, monitor
SeqNumcontinuity on theHashKeyflow to detect missed headers.
Examples
BRC-135 Frame Hex Dump
A BRC-135 frame carrying the block header for block hash 00000000000000000...:
// Header (92 bytes)
E3E1F3E8 // Network Magic
02BF // Protocol Version
07 // Frame Version (BRC-135)
00 // Reserved
00000000000000000001a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3 // BlockHash
00112233AABBCCDD // HashKey (XXH64 of emitter flow)
0000000000000001 // SeqNum (1)
0000000000000000000000000000000000000000000000000000000000000000 // LayoutPad32 (zeros)
00000050 // PayloadLen (80)
// Payload (80 bytes — raw BSV block header)
20000000 // Version (LE)
00000000000000000... // PrevBlockHash (32 bytes)
aabbccdd00112233... // MerkleRoot (32 bytes)
665B1A00 // Timestamp (LE)
1D00FFFF // Bits (LE)
12345678 // Nonce (LE)
References
- BRC-124: Multicast Transaction Frame Format — Base header layout reused by BRC-135
- BRC-131: Block Announcement Frame Format — Source of the 80-byte block header extracted by the emitter
- BRC-133: Coinbase Transaction Frame Format — Companion control-plane frame type
- BRC-134: Anchor Transaction Frame Format — Companion control-plane frame type
- BRC-126: Retransmission Protocol — NACK/ACK/MISS used for upstream block frame retransmission
- BRC-129: Multicast Group Address Assignments — Control-plane group index allocations
Constants Reference
| Name | Value | Hex | Description |
|---|---|---|---|
| FrameVerV7 | 7 | 0x07 | BRC-135 block header frame version |
| BlockHeaderPayload | 80 | 0x50 | Fixed payload size (standard BSV block header) |
| BlockHeaderFrameSize | 172 | 0xAC | Total frame size (92 + 80) |
| GroupBlockHeader | 65530 | 0xFFFA | Block header egress channel (BRC-135 mc-egress) |
| GroupBlockBroadcast | 65534 | 0xFFFE | Control group index (shared with BRC-131/133/134) |
| HeaderSize | 92 | 0x5C | BRC-135 header size (identical to BRC-124) |