> For the complete documentation index, see [llms.txt](https://hub.bsvblockchain.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hub.bsvblockchain.org/brc/transactions/0131.md).

# Multicast Block Announcement Frame Format

Jeff Harris (<jeff@lightweb.net>)

## Abstract

This BRC specifies the wire format for distributing block data over the IPv6 multicast fabric. A new frame version (`0x04`) reuses the BRC-124 92-byte header layout and carries either a block announcement, whose payload is a complete [BRC-144](/brc/transactions/0144.md) block object, or a standalone coinbase transaction, delivered to all subscribers via a dedicated control-plane multicast group (`FF0E::B:FFFE`). On this fabric a block announcement and the block data are the same thing: the announcement carries the block. The standalone coinbase message type (`MsgType 0x02`) is deprecated but retained and reserved; see the CoinbaseTx Payload section and [BRC-133](/brc/transactions/0133.md).

## Copyright

This BRC is licensed under the Open BSV License.

## Motivation

The multicast fabric defined in BRC-124 shards transaction delivery across deterministic IPv6 multicast groups. Block events require a complementary distribution path:

1. **Block announcements** must reach every subscriber — miners, exchanges, and overlay services — so they can update block templates, advance chain state, and validate received transactions against the new tip. The announcement carries the whole block object, because a subscriber that learns of a block without its subtree list and coinbase must fetch them over some other path, which the fabric exists to avoid.
2. **Coinbase transactions** must reach every subscriber regardless of shard assignment, since every node needs the coinbase to reconstruct the block Merkle root. The coinbase therefore travels INSIDE the block object, where it inherits the block's proof of work; the standalone message type that once carried it separately is deprecated (see `CoinbaseTx Payload`).
3. Both events must carry the same sequencing and reliability guarantees (HashKey/SeqNum stamping and NACK-based retransmission) as ordinary transaction frames, so existing retry infrastructure works without modification.

Defining a new `FrameVer` byte satisfies these requirements with minimal protocol surface: the BRC-124 header layout is fully preserved, the same proxy/listener/retry machinery applies, and the only routing change is substituting the shard-derived multicast group with the dedicated control group.

## Specification

### Frame Header Format (92 bytes)

The BRC-131 header is layout-identical to the BRC-124 header. 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  | 0x04 — BRC-131 block control                       |
| 7      | 1    | —         | MsgType        | 0x01 = BlockAnnounce; 0x02 = CoinbaseTx            |
| 8      | 32   | 8-byte    | ContentID      | BlockHash (announce) or CoinbaseTxID (coinbase)    |
| 40     | 8    | 8-byte    | HashKey        | XXH64(senderIPv6 ∥ flowIdx ∥ zeros); proxy-stamped |
| 48     | 8    | 8-byte    | SeqNum         | Per-sender monotonic counter; stamped by proxy     |
| 56     | 32   | 8-byte    | Reserved32     | All zeros                                          |
| 88     | 4    | 8-byte    | Payload Length | uint32 BE                                          |
| 92     | \*   | —         | Payload        | MsgType-specific (see below)                       |

**Distinction from BRC-124:** Byte 7 carries `MsgType` rather than `Reserved=0x00`. The 32 bytes at 56–87 are always zeros (no subtree ID; block frames address all subscribers).

### Field Definitions

#### Network Magic (bytes 0–3)

The value `0xE3E1F3E8` (BSV mainnet P2P magic). Frames with incorrect magic are rejected.

#### Protocol Version (bytes 4–5)

`0x02BF` (703). Informational; receivers do not validate.

#### Frame Version (byte 6)

`0x04` for BRC-131 frames. Any other value causes the frame to be handled by a different decoder.

#### MsgType (byte 7)

Identifies the payload type:

| Value  | Constant           | Payload                                   |
| ------ | ------------------ | ----------------------------------------- |
| `0x01` | `BlockMsgAnnounce` | A BRC-144 block object, carried verbatim  |
| `0x02` | `BlockMsgCoinbase` | Raw serialized coinbase transaction bytes |

Any other value is rejected. `0x02` is deprecated (see the CoinbaseTx Payload section) and stays reserved for standalone coinbase carriage; it must not be reassigned.

#### ContentID (bytes 8–39)

A 32-byte identifier:

* **BlockAnnounce:** the block hash in internal byte order (not reversed display order).
* **CoinbaseTx:** SHA256d of the raw coinbase transaction bytes (the CoinbaseTxID).

#### HashKey (bytes 40–47)

`uint64` big-endian. XXH64 of `(senderIPv6[16] ∥ flowIdx[4] ∥ zeroSubtreeID[32])` where `flowIdx` is a 4-byte big-endian value selected by `MsgType`, so the two payload types form independent flows on the shared egress group:

* **BlockAnnounce** (`MsgType 0x01`): `flowIdx = 0x0000FFFE` (`GroupBlockBroadcast`).
* **CoinbaseTx** (`MsgType 0x02`): `flowIdx = 0x0000FFF8` (`GroupCoinbaseFlow`, a virtual HashKey index — see [BRC-129](/brc/transactions/0129.md) and [BRC-133](/brc/transactions/0133.md)).

Stamped in-place by the proxy if zero on arrival.

#### SeqNum (bytes 48–55)

`uint64` big-endian. Monotonic per-sender counter for the `(HashKey, flowIdx)` flow. Stamped in-place by the proxy if zero on arrival. Used by listeners and retry endpoints as the secondary cache key.

#### Reserved32 (bytes 56–87)

All zero bytes. Block control frames have no subtree ID; the field is reserved for future use.

#### Payload Length (bytes 88–91)

`uint32` big-endian. Number of payload bytes immediately following the header.

#### Payload (byte 92 onward)

MsgType-specific (see below).

### BlockAnnounce Payload (MsgType 0x01)

The payload is a complete [BRC-144](/brc/transactions/0144.md) block object, carried verbatim with no additional envelope:

| Size   | Field            | Description                                                                 |
| ------ | ---------------- | --------------------------------------------------------------------------- |
| 80     | BlockHeader      | Standard 80-byte BSV block header                                           |
| 8      | TransactionCount | uint64 BE. Transactions committed by the block                              |
| 8      | SizeInBytes      | uint64 BE. Total serialized block size                                      |
| 8      | SubtreeCount (M) | uint64 BE. Number of subtree roots that follow                              |
| 32 × M | SubtreeHashes    | Ordered subtree Merkle roots, each 32 bytes                                 |
| \*     | Coinbase         | Full coinbase transaction (BRC-12), self-delimiting by structure            |
| 8      | Height           | uint64 BE. Block height                                                     |
| 8      | CoinbaseBUMPLen  | uint64 BE. Byte length of the coinbase BUMP that follows                    |
| \*     | CoinbaseBUMP     | BRC-74 Merkle path of the coinbase; present only when `CoinbaseBUMPLen > 0` |

The fixed prefix through `SubtreeCount` is **104 bytes**; everything after it is variable. The `Coinbase` carries no length prefix — it is self-delimiting by transaction structure, so a reader parses it and resumes at `Height`. The field definitions, including the block-header layout and the coinbase-placeholder rule for the first subtree, are normative in [BRC-144](/brc/transactions/0144.md) and are not restated here.

**Minimum payload size:** 120 bytes plus the coinbase transaction (M = 0, no BUMP). **Total payload size:** 120 + 32 × M + `len(Coinbase)` + `CoinbaseBUMPLen` bytes.

The `ContentID` in the frame header is the 32-byte block hash, which a receiver verifies as `SHA256d(BlockHeader)` over the payload's first 80 bytes. The `SubtreeHashes` are the ordered Merkle roots of the sharded transaction subtrees included in this block, matching the producer's subtree enumeration. `M` may be zero for empty blocks or blocks with no sharded subtrees.

**There is no separate coinbase identifier field.** The coinbase transaction itself is present, so its id is `SHA256d(Coinbase)` and a reader that wants the id computes it. A payload that ends after the subtree hashes, with no coinbase, is malformed and MUST be rejected.

> **Revision note.** Earlier revisions of this BRC defined this payload as an 80-byte header, a 32-byte coinbase id and a `uint32` subtree count — a lean announcement that named the block without carrying it. No implementation ever produced that grammar: every producer has emitted the BRC-144 block object described above, and this revision makes the specification say so. Because the two grammars share a prefix, a reader built to the old text does not fail cleanly on a zero-subtree block; it reads a `SubtreeCount` of zero out of the coinbase's null previous-output hash and reports a coinbase id that is actually the block's count fields. A reader MUST therefore treat the payload as a BRC-144 object.

### CoinbaseTx Payload (MsgType 0x02)

**Deprecated, and retained deliberately.** Current implementations never produce `CoinbaseTx` frames: a coinbase transaction is invalid to a node unless it is connected to its block, so the coinbase travels inline in the [BRC-144](/brc/transactions/0144.md) block body, where it inherits the block's proof of work. A standalone coinbase frame carries no proof of work of its own, and a listener that gates block-control frames before fan-out (the reference listener's block-control gate, on by default) drops it; the reference implementation counts it under the drop reason `coinbase_legacy`. The message type is kept, not withdrawn, because a future design may need to carry blocks and their coinbase separately across the multicast fabric and recombine them at the edges. `MsgType 0x02` and [BRC-133](/brc/transactions/0133.md) therefore remain reserved for that purpose. The format below remains normative for any implementation that emits or accepts the message type.

The payload is the raw serialized coinbase transaction — the same encoding as a BRC-12 transaction payload (version LE32 + inputs + outputs + locktime LE32), with no additional envelope.

The `ContentID` in the frame header is the SHA256d of these raw bytes (the CoinbaseTxID), which is also `SHA256d(Coinbase)` over the coinbase carried inside the corresponding `BlockAnnounce` frame.

### Control-Plane Multicast Group

BRC-131 frames are distributed exclusively on the **GroupBlockBroadcast** group:

| Index  | Scope  | IPv6 Address | Constant            |
| ------ | ------ | ------------ | ------------------- |
| 0xFFFE | global | FF0E::B:FFFE | GroupBlockBroadcast |

The global scope (`FF0E`) ensures block announcements cross site boundaries. The group index `0xFFFE` is in the reserved control-plane range and is never used as a shard group for any `shard_bits` ≤ 12.

The address is shown in ASM form (`FF0E::B:FFFE`), which under RFC 8815 is intra-domain only; inter-domain delivery across site boundaries uses the SSM address `FF3E::B:FFFE` (see [BRC-129](/brc/transactions/0129.md)). The frame format, `HashKey`, `SeqNum`, and NACK path are unchanged across modes. Under SSM, receivers `(S,G)`-join using the block-announce source (the emitting proxy, `senderIPv6`); block-broadcast sources are distributed per BRC-129.

### Sequence Tracking and Retransmission

BRC-131 frames use the same XXH64 hash-chain sequencing as BRC-124:

* **HashKey** is computed as `XXH64(senderIPv6 ∥ flowIdx ∥ zeroSubtreeID)` where `flowIdx = 0x0000FFFE` for BlockAnnounce and `0x0000FFF8` for CoinbaseTx (see the HashKey field definition).
* **SeqNum** is a monotonic per-sender counter for the `(HashKey, flowIdx)` flow.
* The proxy stamps both fields in-place if `SeqNum == 0` on arrival.
* Listeners detect gaps by comparing consecutive `SeqNum` values on the control flow and dispatch BRC-126 NACKs to retry endpoints.
* Retry endpoints cache BRC-131 frames by `HashKey ∥ SeqNum` and retransmit to `FF0E::B:FFFE` on NACK. **The retransmit destination is the control group, not the shard group derived from ContentID.**

### TCP Transport

The read sequence is identical to BRC-124:

1. Read 44 bytes (sufficient for legacy header or BRC-131 start).
2. Inspect `FrameVer` at byte 6.
   * **Version 0x04 (BRC-131):** read 48 more bytes to complete the 92-byte header; `PayLen` is at bytes 88–91.
3. Read exactly `PayLen` bytes.
4. Process the complete frame.

### Fragmentation (BRC-130 Extension)

When `len(Payload) > fragDataSize`, the proxy fragments the frame using BRC-130. The `OrigFrameVer` field at byte 100 of the BRC-130 fragment header is set to `0x04`. The `MsgType` byte is preserved in the BRC-130 fragment's byte 7. Fragment gap tracking uses the `(HashKey, flowIdx, zeroSubtreeID)` flow identically to BRC-124 fragments.

A block announcement carries the whole block object, so its size follows the block: the fixed prefix and the subtree list are small (104 + 32 × 128 = 4200 bytes for 128 subtrees), and the coinbase transaction and its optional BUMP carry the rest. Announcements therefore routinely exceed a 9000-byte jumbo frame and fragmentation is the normal case, not the exception.

### Error Handling

| Condition                | UDP Behavior | TCP Behavior      |
| ------------------------ | ------------ | ----------------- |
| Bad magic                | Silent drop  | Connection closed |
| FrameVer ≠ 0x04          | Not BRC-131  | Not BRC-131       |
| Unknown MsgType          | Silent drop  | Connection closed |
| Payload length too large | Silent drop  | Connection closed |
| Truncated datagram       | Silent drop  | Connection closed |
| SeqNum == 0 at listener  | Discard      | Discard           |

## Examples

### BlockAnnounce Frame (M=2 subtrees)

```
// Header (92 bytes)
E3E1F3E8                                                          // Network Magic
02BF                                                              // Protocol Version
04                                                                // Frame Version (BRC-131)
01                                                                // MsgType (BlockAnnounce)
<32-byte block hash>                                              // ContentID
<8-byte HashKey>                                                  // Proxy-stamped XXH64
<8-byte SeqNum>                                                   // Proxy-stamped monotonic
0000000000000000000000000000000000000000000000000000000000000000  // Reserved32
<4-byte PayloadLen>                                               // 184 + len(Coinbase)

// Payload — a BRC-144 block object
<80-byte block header>                                            // BlockHeader
0000000000000FA0                                                  // TransactionCount = 4000
00000000001E8480                                                  // SizeInBytes = 2,000,000
0000000000000002                                                  // SubtreeCount = 2
<32-byte subtree hash 0>                                          // SubtreeHashes[0]
<32-byte subtree hash 1>                                          // SubtreeHashes[1]
<coinbase transaction>                                            // Coinbase (self-delimiting)
00000000000C3500                                                  // Height = 800,000
0000000000000000                                                  // CoinbaseBUMPLen = 0
```

### CoinbaseTx Frame

```
// Header (92 bytes)
E3E1F3E8                                                          // Network Magic
02BF                                                              // Protocol Version
04                                                                // Frame Version (BRC-131)
02                                                                // MsgType (CoinbaseTx)
<32-byte CoinbaseTxID>                                            // ContentID = SHA256d(payload)
<8-byte HashKey>                                                  // Proxy-stamped XXH64
<8-byte SeqNum>                                                   // Proxy-stamped monotonic
0000000000000000000000000000000000000000000000000000000000000000  // Reserved32
<4-byte PayloadLen>                                               // Coinbase tx byte count

// Payload
<raw coinbase transaction bytes>
```

## Alignment Verification

| Field          | Offset | Offset % 8 |
| -------------- | ------ | ---------- |
| ContentID      | 8      | 0 ✓        |
| HashKey        | 40     | 0 ✓        |
| SeqNum         | 48     | 0 ✓        |
| Reserved32     | 56     | 0 ✓        |
| Payload Length | 88     | 0 ✓        |
| Payload        | 92     | 4          |

## Constants Reference

| Name                   | Value | Hex    | Description                                                    |
| ---------------------- | ----- | ------ | -------------------------------------------------------------- |
| FrameVerV4             | 4     | 0x04   | BRC-131 block control frame version                            |
| BlockMsgAnnounce       | 1     | 0x01   | MsgType: block announcement (payload = a BRC-144 block object) |
| BlockMsgCoinbase       | 2     | 0x02   | MsgType: coinbase transaction (deprecated; reserved)           |
| GroupBlockBroadcast    | 65534 | 0xFFFE | Control-plane group index for block frames                     |
| BlockHeaderSize        | 80    | 0x50   | Standard BSV block header size (bytes)                         |
| BlockObjectFixedPrefix | 104   | 0x68   | BRC-144 fixed prefix through SubtreeCount                      |
| HeaderSize             | 92    | 0x5C   | BRC-131 header size (identical to BRC-124)                     |

## References

* [BRC-12: Raw Transaction Format](/brc/transactions/0012.md) — Coinbase payload encoding
* [BRC-124: Multicast Transaction Frame Format](/brc/transactions/0124.md) — Header layout reused by BRC-131
* [BRC-126: Multicast Retransmission Protocol](/brc/transactions/0126.md) — NACK/ACK/MISS used for block frame retransmission
* [BRC-129: Multicast Group Address Assignments](/brc/transactions/0129.md) — GroupBlockBroadcast index allocation
* [BRC-130: Multicast Transaction Frame Fragmentation](/brc/transactions/0130.md) — BRC-130 fragmentation with OrigFrameVer=0x04
* [BRC-119: SubTree Unified Merkle Path (STUMP) Format](/brc/transactions/0119.md) — Defines the subtree concept referenced in BlockAnnounce
* [BRC-133: Multicast Coinbase Transaction Frame Format](/brc/transactions/0133.md): the standalone coinbase carriage using `MsgType 0x02` (deprecated, retained)
* [BRC-144: Block Frame Format](/brc/transactions/0144.md): the block body that carries the coinbase inline


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://hub.bsvblockchain.org/brc/transactions/0131.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
