For the complete documentation index, see llms.txt. This page is also available as Markdown.

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.

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

Last updated

Was this helpful?