Beersy
BRC-149

Multicast BEEF Object Frame Format

Once a second of object has its own space, it needs a frame to travel in and a route back for submissions. This defines those wire forms.

Jeff Harrischanged 18 Sept 20266 min read

Reference for an AI

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

Summary

Why
BEEF-encoded transaction objects cannot be split into pieces or told apart from other traffic on a shared connection because they are not self-delimiting, so a wire wrapper is needed to carry them, fragment them, and route them safely.
What
BRC-149 defines the wire formats for sending transaction objects over a multicast network: a 92-byte-header multicast frame, a for publishers, and a for subscribers.
How
A publisher packages a BEEF object with a list of target topics into a submission record, ingress infrastructure stamps and fans it out as FrameVer 0x09 frames per topic (fragmenting oversized objects per BRC-130), and a delivery edge either streams whole frames or strips them into topic-tagged delivery records for a…

What this lets you do

  • Wrap a BEEF, BEEF V2, or object for multicast delivery
  • Submit one object to multiple topics in a single record
  • Detect which wire grammar (framed, submission record, or bare transaction) is on a shared port
  • Fragment oversized BEEF objects while keeping topic and content identifiers intact
  • Strip frames down to a lightweight per-object record for unicast subscriber delivery

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

ContentIDTopicIDBEEF payloadpayload0

The specification

Abstract

This BRC specifies the three wire forms of the BRC-148 : the multicast object frame (FrameVer 0x09, assigned here), which carries one BEEF-family transaction object on the plane's domain-tagged shard groups; the , the unicast envelope a publisher sends to operator ingress naming one object to one or more topics; and the , the unicast envelope a delivery edge streams to a subscriber. The frame reuses the BRC-124 92-byte header layout at identical offsets, so existing classifiers, retransmission, and fragmentation infrastructure require no changes. The records exist because BEEF bytes are not self-delimiting without a full structural parse — which the fabric never performs — so unlike the BRC-143/BRC-144 push lanes, BEEF lanes carry an explicit length-carrying envelope.

This BRC is licensed under the Open BSV License.

Motivation

BRC-148 allocates the BEEF object plane (domain 0x1), defines its topical sharding, filtering, and coordination, and constrains the header fields that addressing, retransmission, and filtering depend on — but, following the convention that frame formats are specified separately from addressing (BRC-124 vs BRC-129; BRC-143/BRC-144 vs their carriage rules), it defers the concrete formats to this BRC. This BRC assigns the and fixes the byte layouts: the fabric frame, and the two unicast record forms that carry BEEF objects between participants and operator infrastructure.

Specification

BEEF object frame (FrameVer 0x09) — 92-byte header + payload

FrameVer 0x09 is assigned to the BEEF object frame (the next code after BRC-142's 0x08).

OffsetSizeTypeFieldDescription
04uint32 BENetwork Magic0xE3E1F3E8 (BSV mainnet P2P magic). Frames with incorrect magic are rejected.
42uint16 BEProtocol Version0x02BF (703). Informational; receivers do not validate.
61byteFrame Version0x09 — BEEF object frame. Any other value is handled by a different decoder.
71byteReserved0x00 on send; ignored on receive (reserved for future plane-level message types). The BEEF encoding version is not duplicated here — it is the payload's first four bytes.
832[32]byteSHA-256d(payload bytes) — the object's identity; and the BRC-130 reassembly verification hash. With it keys both fragment reassembly and duplicate suppression. Never the subject TxID.
408uint64 BEPer-(sender, group) flow identifier; stamped at ingress; 0 = unset. Derivation and flow semantics per BRC-148 §Frame carriage (TopicID excluded).
488uint64 BEPer-sender monotonic counter within the (sender, group) flow; stamped at ingress; 0 = unstamped. Drives gap detection, NACK recovery, and retransmit dedup.
5632[32]byteTopicIDSHA-256(UTF-8 topic name). The delivery-selectivity key: group derivation takes its top bits, and fan-out filters subscribers on it. Occupies the field that carries the in transaction frames.
884uint32 BEPayload LengthByte length of the payload.
92*[]bytePayloadThe BEEF object verbatim — no envelope, no re-encoding, proof data intact.

Payload leading bytes — BEEF version word

Payload [0:4]TypeEncodingReference
0100BEEFuint32 LE (4022206465)BEEFBRC-62
0200BEEFuint32 LE (4022206466)BEEF V2 (TXID-only extension)BRC-96
010101014-byte prefix (32-byte subject TxID follows)BRC-95

The version word is the BRC-148 version filter's input — an encoding-capability gate only, never an overlay namespace. Intentionally absent from the header: the subject TxID (consumer-level semantics inside the payload) and any per-format sub-type byte (the marker is self-identifying at a fixed offset).

Fragmentation

Objects exceeding the path MTU are carried as BRC-130 fragments (FrameVer 0x03, OrigFrameVer = 0x09) with bytes 0–91 layout-identical to the table above, so ContentID and TopicID appear in every fragment; ContentID is the reassembly verification hash. Reassembly MUST key slots on the (ContentID, TopicID) pair — sibling emissions of one object to different topics share a ContentID, so a ContentID-only key collapses them and delivers only one. The interaction with filtering is specified in BRC-148 §Frame carriage.

Submission record (ingress)

A publisher submits the pair (topic list, BEEF object) as one record:

Offset  Size  Field
  0       2   Tag         (uint16 BE = 0xBEEF — record discriminator on shared ports)
  2       1   RecordVer   (0x01)
  3       1   TopicCount  (1..15)
  4       …   Topics      (TopicCount × { uint8 NameLen (1..64) ∥ NameLen bytes UTF-8 topic name })
  …       4   ObjectLen   (uint32 BE, ≥ 1; operators bound the maximum accepted size)
  …       …   Object      (the BEEF object; leading marker per the version-word table)

For each named topic the ingress derives TopicID = SHA-256(name), computes the object's ContentID once, and emits one FrameVer 0x09 frame to that topic's group — sibling emissions share a ContentID, and ingress duplicate suppression keys on the (ContentID, TopicID) pair per BRC-148. A record whose object does not lead with a marker from the version-word table, whose lengths violate the bounds above, or whose object exceeds the operator's size bound MUST be rejected. A malformed record desynchronises its stream; the receiver MUST close the connection.

Fan-out admission

TopicCount ranges 1..15, but a multi-topic record fans one object out to that many full-object frames — an up-to-15× amplification of one submission, attacker-declarable and free on an anonymous path. Admission is therefore conditioned on the ingress identity path: open / public / anonymous ingress MUST admit TopicCount == 1 and MUST reject a public record with TopicCount > 1; multi-topic (TopicCount > 1) is an authenticated-ingress capability, where the operator accounts the fan-out (typically the first N topics free and additional topics charged at the operator's delivery rate; N is operator policy). This is an admission policy over an unchanged wire grammar — the 92-byte frame and record layout are identical on both paths.

Detection on shared ports

Single-topic BEEF submission records MAY ride the open transaction port (multi-topic records require the authenticated path, above) alongside the existing grammars, distinguished by leading bytes — network magic 0xE3E1F3E8 selects a framed datagram, the 0xBEEF tag selects a submission record, and anything else is a bare transaction (BRC-12 raw / BRC-30 Extended Format, whose little-endian version byte at offset 1 is 0x00 — the three forms cannot collide). Over TCP the grammar is committed once per connection; over UDP it is detected per datagram, and a record must fit one datagram (larger objects submit over a stream transport). Operators MAY additionally expose a dedicated single-record-grammar port for flow separation; it carries no additional admission semantics.

Delivery record (egress)

A delivery edge streaming BEEF objects to a subscriber over a unicast lane emits, per delivered object:

Offset  Size  Field
  0      32   TopicID    (the matched topic's identifier)
 32       4   ObjectLen  (uint32 BE, ≥ 1)
 36       …   Object     (the BEEF object verbatim)

The record carries the TopicID, not the topic name — the subscriber elected its topics and maps identifiers back locally. Subscribers taking whole FrameVer 0x09 frames instead of a stripped lane need no record; the frame already carries both identifiers.

References

Was this helpful?

Search Beersy

Search standards by number, title, author or topic