> 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/0132.md).

# Multicast Subtree Data Frame Format

Jeff Harris (<jeff@lightweb.net>)

## Abstract

This BRC defines frame version `0x05` for distributing complete Merkle subtree contents — transaction hashes and optional per-transaction metadata — over the IPv6 multicast fabric. Subtree data frames are delivered to all subscribers via the dedicated `GroupSubtreeDataAnnounce` multicast group (`FF0X::B:FFFB`), independently of the per-shard groups used for individual transaction distribution.

## Copyright

This BRC is licensed under the Open BSV License.

## Motivation

The multicast fabric distributes individual transactions shard-by-shard (BRC-124) and block-level metadata (BRC-131). BRC-132 fills the remaining gap: delivering the contents of each Merkle subtree so that subscribers can:

1. Reconstruct the subtree Merkle tree locally.
2. Verify block inclusion without fetching individual transactions.
3. Power block-assembly tooling and downstream analytics without per-transaction retrieval.

BRC-132 complements BRC-127, which maps SubtreeIDs to GroupIDs for shard-level filtering. BRC-127 announces *where* a subtree lives; BRC-132 delivers *what* it contains.

## Specification

### Multicast Group

Subtree data frames are sent to the `GroupSubtreeDataAnnounce` group (index `0xFFFB`):

| Index  | Scope  | Compressed Address | Constant                 |
| ------ | ------ | ------------------ | ------------------------ |
| 0xFFFB | site   | FF05::B:FFFB       | GroupSubtreeDataAnnounce |
| 0xFFFB | org    | FF08::B:FFFB       | GroupSubtreeDataAnnounce |
| 0xFFFB | global | FF0E::B:FFFB       | GroupSubtreeDataAnnounce |

Scope selection follows the `GroupBeacon` pattern defined in BRC-129. Operators select one or more scopes via the `-announce-scope` flag on listening components.

### Frame Header Format (92 bytes)

The BRC-132 header is layout-identical to the BRC-124 header. All infrastructure components that inspect Magic, HashKey, or SeqNum read correct values at the same offsets. The header is read using the same 44+48 two-step protocol as BRC-124 and BRC-131.

| Offset | Size | Align | Field         | Value / Notes                                            |
| ------ | ---- | ----- | ------------- | -------------------------------------------------------- |
| 0      | 4    | —     | Network Magic | `0xE3E1F3E8` (BSV mainnet P2P magic)                     |
| 4      | 2    | —     | Protocol Ver  | `0x02BF` (703, BSV large-block baseline)                 |
| 6      | 1    | —     | Frame Version | `0x05` — BRC-132 subtree data                            |
| 7      | 1    | —     | MsgType       | `0x01` = HashesOnly, `0x02` = FullNodes                  |
| 8      | 32   | 8B    | SubtreeID     | SHA-256 Merkle root of the subtree (content ID)          |
| 40     | 8    | 8B    | HashKey       | `XXH64(senderIPv6 ∥ 0xFFFB ∥ SubtreeID)`; proxy-stamped  |
| 48     | 8    | 8B    | SeqNum        | Monotonic counter per (sender, SubtreeID); proxy-stamped |
| 56     | 32   | 8B    | LayoutPad32   | All zeros; retained for uniform `HeaderSize = 92`        |
| 88     | 4    | 8B    | PayloadLen    | Payload size in bytes (uint32 BE)                        |
| 92     | \*   | —     | Payload       | MsgType-specific subtree data (see §Payload Format)      |

**Key distinctions from BRC-124:**

* Byte 7 carries `MsgType` rather than `Reserved = 0x00`.
* Bytes 8–39 carry `SubtreeID` (the Merkle root), not a `TxID`.
* `LayoutPad32` (bytes 56–87) is always zero. SubtreeID already serves as content identifier and flow scope; no secondary field is needed. The field is retained so that `HeaderSize = 92` remains uniform across V2/V4/V5.
* `HashKey` is computed as `XXH64(senderIPv6 ∥ 0xFFFB ∥ SubtreeID)`. Each distinct subtree from the same sender has an independent sequence stream, so loss in one subtree does not create false gaps in another.

### MsgType Values

| MsgType | Constant               | Node Size | Description                             |
| ------- | ---------------------- | --------- | --------------------------------------- |
| `0x01`  | `SubtreeMsgHashesOnly` | 32 bytes  | TxHashes only (network transfer format) |
| `0x02`  | `SubtreeMsgFullNodes`  | 48 bytes  | TxHash + Fee + Size per node            |

Any other MsgType value causes the frame to be rejected with `ErrBadSubtreeMsg`.

### Payload Format

Both MsgType variants share a 24-byte metadata prefix followed by N node entries and a conflict set.

#### Common Prefix (24 bytes)

| Offset | Size | Field          | Description                                     |
| ------ | ---- | -------------- | ----------------------------------------------- |
| 0      | 8    | TotalFees      | Aggregate fee sum for the subtree (uint64 BE)   |
| 8      | 8    | TotalSizeBytes | Aggregate serialised tx size (uint64 BE, bytes) |
| 16     | 8    | NodeCount      | Number of transaction nodes (uint64 BE)         |

#### MsgType 0x01 — HashesOnly

| Offset       | Size   | Field                     |
| ------------ | ------ | ------------------------- |
| 24           | 32 × N | TxHashes                  |
| 24 + 32N     | 8      | ConflictCount (uint64 BE) |
| 24 + 32N + 8 | 32 × M | ConflictHashes            |

Maximum size at 1M nodes, 0 conflicts: 24 + 32 × 1,048,576 + 8 ≈ **32 MB**.

#### MsgType 0x02 — FullNodes

| Offset       | Size   | Field                                            |
| ------------ | ------ | ------------------------------------------------ |
| 24           | 48 × N | Nodes: TxHash (32B) ∥ Fee (8B BE) ∥ Size (8B BE) |
| 24 + 48N     | 8      | ConflictCount (uint64 BE)                        |
| 24 + 48N + 8 | 32 × M | ConflictHashes                                   |

Maximum size at 1M nodes, 0 conflicts: 24 + 48 × 1,048,576 + 8 ≈ **48 MB**.

### Fragmentation

Payloads of 32–48 MB exceed any path MTU. The proxy fragments each BRC-132 frame using BRC-130:

* `OrigFrameVer = 0x05` in each BRC-130 fragment header (byte 100).
* `MsgType` is preserved in fragment header byte 7 (same pattern as BRC-131 `fragmentBlock`).
* Fragment reassembly is keyed by SubtreeID (bytes 8–39), matching the `TxID` slot used by BRC-124 fragments.
* SHA256d hash verification does **not** apply — SubtreeID is a Merkle root, not a payload double-hash. The `verifyHash` flag must be `false` for V5 reassembly slots.
* Optional post-reassembly Merkle-root verification is available (see §Merkle Verification).

Fragment counts at MTU 9000 (fragDataSize = 8848 bytes):

| Subtree size                   | Fragments |
| ------------------------------ | --------- |
| \~32 MB (HashesOnly, 1M nodes) | \~3,793   |
| \~48 MB (FullNodes, 1M nodes)  | \~5,689   |

Both fit within the `uint16` `FragTotal` limit of 65,535.

### Sequence Tracking and Retransmission

BRC-132 frames participate in the same NACK-based reliability mechanism as BRC-124 and BRC-131:

* The proxy stamps `HashKey` and `SeqNum` in-place before forwarding. Each `(senderIPv6, SubtreeID)` pair owns an independent monotonic sequence stream.
* If `SeqNum` is already non-zero on arrival, the frame is forwarded verbatim (pre-stamped path).
* Listeners detect gaps on the `(HashKey, 0xFFFB, SubtreeID)` flow and dispatch BRC-126 NACKs to retry endpoints.
* Retry endpoints join `FF0X::B:FFFB` and cache BRC-132 frames and BRC-130 fragments (`OrigFrameVer = 0x05`) by `HashKey ∥ SeqNum`. On NACK, the frame is retransmitted to `FF0X::B:FFFB`. The retry endpoint TTL for BRC-132 frames defaults to 120 s (compared to 60 s for transaction frames) to accommodate large reassembly windows.

### Merkle Verification

After reassembly, optional Merkle-root recomputation verifies the SubtreeID:

* Enabled by `-subtree-data-verify-merkle` / `SUBTREE_DATA_VERIFY_MERKLE=true` on the listener.
* The listener decodes the payload into nodes and computes SHA256d pairwise up the binary tree, then compares the root to SubtreeID.
* Computationally significant at 1M nodes (\~1M double-SHA256 operations); **disabled by default**.
* On mismatch: drop the reassembly slot; increment `bsl_reassembly_merkle_mismatch_total`.

### Error Handling

| Condition                      | Action                                         |
| ------------------------------ | ---------------------------------------------- |
| `raw[6] != 0x05`               | Not BRC-132; handled by other decoders         |
| Bad magic                      | Silent drop                                    |
| Unknown MsgType                | Drop; `ErrBadSubtreeMsg`                       |
| PayloadLen exceeds buffer      | Drop; `io.ErrUnexpectedEOF`                    |
| Datagram shorter than 92 bytes | Drop; `ErrTooShort`                            |
| `SeqNum == 0`                  | Frame not proxy-stamped; listener discards     |
| Merkle mismatch (optional)     | Drop; `bsl_reassembly_merkle_mismatch_total++` |

## Constants Reference

| Name                           | Value | Hex      | Description                                 |
| ------------------------------ | ----- | -------- | ------------------------------------------- |
| `FrameVerV5`                   | 5     | `0x05`   | BRC-132 subtree data frame version          |
| `SubtreeMsgHashesOnly`         | 1     | `0x01`   | MsgType: TxHashes only (32B per node)       |
| `SubtreeMsgFullNodes`          | 2     | `0x02`   | MsgType: TxHash + Fee + Size (48B per node) |
| `GroupSubtreeDataAnnounce`     | 65531 | `0xFFFB` | Subtree data multicast group index          |
| `HeaderSize`                   | 92    | `0x5C`   | BRC-132 header size (identical to BRC-124)  |
| `SubtreeDataPayloadHeaderSize` | 24    | `0x18`   | Fixed metadata prefix size                  |
| `SubtreeNodeHashSize`          | 32    | `0x20`   | Node size in HashesOnly payload             |
| `SubtreeNodeFullSize`          | 48    | `0x30`   | Node size in FullNodes payload              |

## References

* [BRC-119: SubTree Unified Merkle Path (STUMP) Format](/brc/transactions/0119.md) — SubtreeID definition and Merkle subtree structure
* [BRC-124: Multicast Transaction Frame Format](/brc/transactions/0124.md) — Base header layout reused by BRC-132
* [BRC-126: BSV Multicast NACK Retransmission Protocol](/brc/transactions/0126.md) — NACK-based reliability used for subtree frame retransmission
* [BRC-127: Multicast Subtree Group Announcement Frame Format](/brc/transactions/0127.md) — SubtreeID→GroupID metadata; distinct from BRC-132 data delivery
* [BRC-129: IPv6 Multicast Group Address Assignments](/brc/transactions/0129.md) — Group index allocations; `0xFFFB` = GroupSubtreeDataAnnounce
* [BRC-130: Multicast Frame Fragmentation](/brc/transactions/0130.md) — Fragmentation for large subtree payloads; `OrigFrameVer = 0x05`
* [BRC-131: Block Announcement Protocol](/brc/transactions/0131.md) — `FrameVerV4` pattern followed by BRC-132


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hub.bsvblockchain.org/brc/transactions/0132.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
