Beersy
BRC-142

Multicast Transaction Bundle Frame Format

Sending many tiny transactions as separate packets spends more on overhead than on content. This packs the ones heading the same way into a single frame.

Jeff Harrischanged 2 Aug 20268 min read
small txs12345bundle

Summary

Why
Sending each small transaction as its own multicast packet wastes forwarding capacity because packet-rate, not byte-rate, is the real cost of fan-out.
What
BRC-142 is a wire format that packs multiple small BSV transactions bound for the same shard group into a single multicast datagram.
How
A coalescing node groups transactions bound for the same shard group and into a bundle header plus length-prefixed member list, and the receiving edge decoalesces it back into individual BRC-124 or BRC-128 frames (or raw BRC-12/BRC-30 transactions) before delivering to consumers.

What this lets you do

  • Pack many small transactions into one multicast datagram
  • Mix raw and Extended Format transactions in the same bundle
  • Skip carrying per-member transaction IDs and let receivers recompute them
  • Retransmit a lost bundle as a whole using existing NACK machinery
  • Re-bucket a bundle when shard-bit width changes mid-flight

Written by claude-sonnet-5 from the specification text. Where the two differ, the original is correct.

Reference for an AI

Everything an assistant needs to answer questions about BRC-142 accurately, including what it depends on.

The specification

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 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.

This BRC is licensed under the Open BSV License.

Motivation

Basic BSV payments are small — a typical pay-to-public-key-hash () 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.

OffsetSizeFieldDescription
04Network Magic0xE3E1F3E8 (BSV mainnet P2P magic)
42Protocol Ver0x02BF (703)
61Frame Version0x08 (BRC-142 bundle)
71Flagsbit0 = TxIDsPresent (per-member Transaction ID present, all-or-none); bits 1–7 reserved (0)
832Subtree IDThe single 32-byte subtree shared by all members; zeros = unset
408XXH64(senderIPv6 ∥ groupIdx ∥ ); the bundle flow identity
488SeqNumPer-flow monotonic counter, starts at 1; 0 = unset
562GroupIdxShard group index this bundle was built for (uint16 BE)
581ShardBitsShard-bit width GroupIdx was computed at (1–12); pins the generation
591Reserved0x00
602TxCountNumber of members (uint16 BE)
624PayloadLenTotal byte length of the member section that follows (uint32 BE)
66*Member sectionTxCount members (below)

Member Format

The header is followed by TxCount length-prefixed members:

Offset (relative)SizeFieldDescription
02TxLenMember transaction byte length (uint16 BE)
232TxIDPresent only when Flags.TxIDsPresent; raw 256-bit TxID
2 or 34TxLenTxSerialised BSV transaction — BRC-12 raw or BRC-30 Extended Format
  • TxLen is 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 TxIDsPresent flag) 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 recompute SHA256d(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 PayloadLen bytes are consumed; TxCount is 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 () 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 ), 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

ConditionAction
Frame Version ≠ 0x08Not a bundle; decode per its version
Bad magicSilent drop
Datagram shorter than 66-byte headerSilent drop
PayloadLen exceeds datagram remainderSilent drop (truncated)
Member runs past PayloadLenSilent drop (malformed)
Member group ≠ GroupIdx at ShardBitsEncoder 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

Constants Reference

NameValueHexDescription
FrameVerBundle80x08BRC-142 bundle frame version
BundleHeaderSize660x42Bundle header size in bytes
FlagTxIDsPresent10x01Flags bit 0: per-member TxIDs present
MaxMembers655350xFFFFTxCount ceiling (uint16)
MaxMemberTxLen655350xFFFFLargest member transaction (uint16)
Was this helpful?

Search Beersy

Search standards by number, title, author or topic