Multicast Transaction Bundle Frame Format
Jeff Harris (jeff@lightweb.net)
Abstract
This BRC specifies a coalescing extension to the BRC-124 and BRC-128 Multicast Transaction Frame Formats. A bundle packs many small BSV transactions — standard (BRC-12 raw) or Extended Format (BRC-30 EF) — that share one shard group and subtree into a single datagram, so a payload that would otherwise cross a multicast fabric as N small packets crosses it as one. It is the inverse of BRC-130 fragmentation, which splits one oversized transaction across many datagrams. Bundling reduces packets-per-second — the dominant per-packet forwarding cost of multicast fan-out — without changing transaction semantics.
Copyright
This BRC is licensed under the Open BSV License.
Motivation
Basic BSV payments are small — a typical pay-to-public-key-hash (P2PKH) transaction is only ~200 bytes — even though Bitcoin script imposes no such limit and many transactions are far larger. A large share of fabric traffic is therefore small-packet, and multicast fan-out cost is dominated by packets-per-second, not bandwidth: each replicated packet carries a per-packet forwarding cost largely independent of its size. A node that already forwards individual BRC-124/128 frames can pack many same-destination transactions into one datagram, cutting the packet rate it imposes on every downstream hop while carrying the same transactions. Bundling is an operator-side optimization: senders need not participate, and a node may bundle, or not, without coordination.
Specification
Bundle Header Format (66 bytes)
A bundle is identified by Frame Version 0x08. Unlike BRC-130, a bundle header is not layout-compatible with BRC-124 — a bundle has no single Transaction ID. All multi-byte integers are big-endian.
0
4
Network Magic
0xE3E1F3E8 (BSV mainnet P2P magic)
4
2
Protocol Ver
0x02BF (703)
6
1
Frame Version
0x08 (BRC-142 bundle)
7
1
Flags
bit0 = TxIDsPresent (per-member Transaction ID present, all-or-none); bits 1–7 reserved (0)
8
32
Subtree ID
The single 32-byte subtree shared by all members; zeros = unset
40
8
HashKey
XXH64(senderIPv6 ∥ groupIdx ∥ subtreeID); the bundle flow identity
48
8
SeqNum
Per-flow monotonic counter, starts at 1; 0 = unset
56
2
GroupIdx
Shard group index this bundle was built for (uint16 BE)
58
1
ShardBits
Shard-bit width GroupIdx was computed at (1–12); pins the generation
59
1
Reserved
0x00
60
2
TxCount
Number of members (uint16 BE)
62
4
PayloadLen
Total byte length of the member section that follows (uint32 BE)
66
*
Member section
TxCount members (below)
Member Format
The header is followed by TxCount length-prefixed members:
0
2
TxLen
Member transaction byte length (uint16 BE)
2
32
TxID
Present only when Flags.TxIDsPresent; raw 256-bit TxID
2 or 34
TxLen
Tx
Serialised BSV transaction — BRC-12 raw or BRC-30 Extended Format
TxLenis a fixed uint16: a member must fit one datagram, so 16 bits suffices; a transaction that would exceed the path MTU is ineligible and uses BRC-130.The per-member Transaction ID is optional (the
TxIDsPresentflag) because it is recomputable from the transaction, so carrying it is redundant wire data — and at 32 bytes per member it is a real density cost on small payments (~14% fewer members for a ~200-byte P2PKH tx), working against the packing this format exists for. Omit it by default and let receivers recomputeSHA256d(Tx). Carry it (set the flag) when a receiver needs the id without recompute — line-rate dedup or accounting — or for Extended Format members, whose canonical id is the hash of the de-extended base transaction (not of the EF bytes) and so cannot be cheaply recomputed. It is not a retransmission aid.A member is a transaction in BRC-12 (raw) or BRC-30 (Extended Format) serialization; an EF member self-identifies by its 6-byte marker (payload bytes 4–9), so the two may be mixed in one bundle with no per-member type flag. The bundle carries only the transaction bytes — the egress format is the downstream consumer's contract, not the bundle's. On decoalesce the edge re-emits each member in the consumer's format: as a multicast frame — BRC-124 (raw) or BRC-128 (Extended Format), both Frame Version 0x02 — or in the transaction's own BRC-12 / BRC-30 format.
Parsers read members until
PayloadLenbytes are consumed;TxCountis a cross-check.
Group, Subtree, and Flow Identity
Every member of a bundle satisfies GroupIndex(member TxID) == GroupIdx at ShardBits (BRC-129) and carries the bundle's Subtree ID. A bundle is therefore a single (sender, group, subtree) flow with one HashKey and one monotonic SeqNum, exactly as a BRC-124 frame. This lets a bundle reuse the BRC-126 retransmission machinery unchanged: gap detection and NACK operate on the bundle SeqNum stream.
A bundle is transport-agnostic: the on-wire bytes are identical under Any-Source (ASM) and Source-Specific (SSM) multicast. Addressing, scopes, and the SSM (S,G) join and source-discovery model are those of the underlying shard group in BRC-129; the bundle's source is the coalescing node (senderIPv6, the first HashKey ingredient), so a receiver joins the same (S,G) it would for the group's BRC-124 frames.
GroupIdx and ShardBits are carried explicitly, rather than derived from member Transaction IDs, so any node can classify and re-bucket a bundle deterministically during a BRC-139 shard-bit transition — when the active ShardBits, and therefore the group a Transaction ID maps to, is changing.
Coalescing and Decoalescing
A coalescing node buckets input frames by (group, subtree) and packs each bucket into bundles, starting a new bundle when the next member would exceed the path MTU or TxCount = 65535. A bundle never exceeds the path MTU and never fragments: BRC-142 and BRC-130 are mutually exclusive per datagram. Coalescing is bounded so a partial bundle is not held indefinitely — the bound (a maximum delay or a batch window) is implementation-defined — and is opt-in, at an implementation-defined granularity (per node or per flow; latency-sensitive relay opts out).
Decoalescing splits a bundle back into individual transactions in the downstream consumer's format — each re-emitted as a multicast frame (BRC-124 for a raw transaction or BRC-128 for an Extended Format one, both Frame Version 0x02) or in the transaction's own BRC-12 / BRC-30 format. The default is edge-decoalesce: the fabric carries bundles and the edge node splits them before per-consumer delivery, leaving the consumer contract unchanged. Each emitted frame inherits the bundle's Subtree ID, carries its own (carried or recomputed) Transaction ID, and is assigned a per-transaction SeqNum on the egress flow. A consumer MAY instead opt to receive bundles directly.
Retransmission
The retransmission unit is the whole bundle. A lost bundle is a datagram the receiver never saw, so it can only request the bundle by its SeqNum, not a member within it. A retry endpoint caches and retransmits a bundle keyed on (HashKey, SeqNum) exactly as a BRC-124 frame.
Re-bucketing
A relay forwarding a bundle into a domain or generation running a different ShardBits MUST re-bucket it: decoalesce and re-coalesce at the target ShardBits (learned from the BRC-139 manifest), routing each member to its correct group, preserving the Subtree ID, and re-stamping the flow HashKey and SeqNum. A relay MUST NOT deliver a bundle to a subscriber whose interest is finer than the bundle's ShardBits without re-bucketing, since that subscriber would receive — and, on loss, re-request — transactions outside its interest.
Error Handling
Frame Version ≠ 0x08
Not a bundle; decode per its version
Bad magic
Silent drop
Datagram shorter than 66-byte header
Silent drop
PayloadLen exceeds datagram remainder
Silent drop (truncated)
Member runs past PayloadLen
Silent drop (malformed)
Member group ≠ GroupIdx at ShardBits
Encoder invariant — origin MUST pack only same-group members (not decoder-enforced)
Compatibility
BRC-12 (0x01) and BRC-124/128 (0x02) receivers MUST discard datagrams with Frame Version 0x08; a bundle does not parse as a single-transaction frame.
BRC-142 receivers implement decoalescing (or re-bucketing, at a relay) and deliver individual transactions downstream — as multicast frames (BRC-124/128, 0x02) or in the transaction's base BRC-12 / BRC-30 format, per the consumer's contract — preserving existing consumer behaviour.
Network Magic and Protocol Version are at the BRC-124 offsets, so firewall rules and classifiers matching those still recognise the datagram. The Transaction ID, HashKey, and SeqNum offsets differ from BRC-124, so a classifier reading those fields must branch on Frame Version 0x08.
References
BRC-12: Raw Transaction Format — raw member payload and base egress format
BRC-124: Multicast Transaction Frame Format — base frame coalesced by this BRC
BRC-30: Transaction Extended Format (EF) — EF member payload and base egress format
BRC-128: Multicast Extended Transaction Frame Format — Extended Format members
BRC-126: Multicast Transaction NACK Retransmission Protocol — bundle-unit retransmission
BRC-129: IPv6 Multicast Group Address Assignments — group/subtree addressing
BRC-130: Multicast Transaction Frame Fragmentation — the inverse; mutually exclusive per datagram
BRC-139: Multicast Shard Manifest Announcement Protocol — ShardBits/generation coordination
Constants Reference
FrameVerBundle
8
0x08
BRC-142 bundle frame version
BundleHeaderSize
66
0x42
Bundle header size in bytes
FlagTxIDsPresent
1
0x01
Flags bit 0: per-member TxIDs present
MaxMembers
65535
0xFFFF
TxCount ceiling (uint16)
MaxMemberTxLen
65535
0xFFFF
Largest member transaction (uint16)
Last updated
Was this helpful?

