Multicast Shard Manifest Announcement Protocol
Jeff Harris (jeff@lightweb.net)
Abstract
This BRC specifies the shard manifest announcement protocol for the BSV multicast transaction distribution pipeline. It defines a single UDP datagram format — ShardManifest (MsgType 0x40) — by which any participant periodically declares its shard_bits configuration and the set of shard groups it has joined. Manifests are emitted directly to the control-plane beacon group (0xFFFD, see BRC-129), the same group used by BRC-126 ADVERT beacons, and are distinguished by their MsgType byte. The protocol provides operator visibility into network-wide sharding configuration, enables cross-peer divergence detection, and defines a normative consumer profile for automated, rate-limited shard-bit coordination. It is observation-only by default: there is no retransmission and no acknowledgment.
Copyright
This BRC is licensed under the Open BSV License.
Motivation
Every component of the multicast pipeline — ingress proxy, listener, retry endpoint, and transaction producer — must agree on a single shard_bits value to interoperate, because the shard group index for a transaction is derived as groupIndex = binary.BigEndian.Uint32(txid[0:4]) >> (32 − shardBits) (BRC-129). Today this value is configured manually on each component and there is no on-network signal to verify agreement. A silent mismatch causes senders and receivers to use disjoint group spaces, dropping traffic without an obvious cause.
BRC-139 introduces a small, dedicated announcement that lets every participant:
Periodically declare its current
shard_bitsand the set of shard group indices it claims to have joined.Let observers detect inconsistent configuration across peers.
Carry identity, timestamp, TTL, and a
GenerationIDso a normative consumer profile can implement automated, rate-limitedshard_bitsshifts safely.
The protocol reuses the existing beacon group rather than allocating a new control-plane index, and requires no proxy involvement: manifests do not transit the BRC-124 ingress path.
Specification
Common Message Preamble
ShardManifest datagrams share the BRC-126 control-message preamble: the MsgType byte at offset 6 occupies the same position as FrameVersion in BRC-124 data frames. Value 0x40 identifies a ShardManifest and is distinct from both the data-frame version codes (0x01–0x07) and the BRC-126 control messages (0x10–0x2F). All multi-byte integers are big-endian.
ShardManifest Wire Format (MsgType 0x40) — 64-byte header + variable payload
MsgType 0x40) — 64-byte header + variable payload0
4
Magic
0xE3E1F3E8 (BSV mainnet P2P magic)
4
2
ProtoVer
0x02BF
6
1
MsgType
0x40 (ShardManifest)
8
16
SrcIPv6
Announcer's primary IPv6 (informational; datagram source is authoritative)
24
4
InstanceID
CRC32c of hostname; stable across restarts
28
4
Epoch
Unix seconds when the announcement was generated
32
2
TTL
Validity in seconds; 0 = use consumer default
34
2
AnnounceInterval
Seconds between sends; consumers compute TTL hint = 3 × this
38
2
GroupCount
N: number of groupIndex entries in list form (0 if bitmap or no claim)
40
2
BitmapBytes
M: length of trailing bitmap; 0 ⇒ list form
42
2
SourceCount
K: number of trailing 16-byte source-IPv6 entries; 0 unless SourcesValid
44
4
ManifestCRC
CRC32c over the whole datagram with these 4 bytes treated as zero
48
16
GenerationID
Operator-supplied 128-bit value; bumped whenever ShardBits changes
64
*
Payload
Groups, then Sources, then Successor block (see below)
The payload sections appear in this order after the 64-byte header:
Groups — when
GroupsValid=1: eitherGroupCount × 2bytes of big-endiangroupIndex(sorted ascending, no duplicates), or exactlyBitmapBytesbytes of bitmap (LSB-first, biti= group indexi). Empty whenGroupsValid=0.Sources — when
SourcesValid=1:SourceCount × 16bytes of source IPv6 addresses in network byte order.Successor — when
SuccessorValid=1: a 24-byte Successor block (see Successor block).
Total datagram size = 64 + max(N×2, M) + K×16 + (24 if SuccessorValid else 0). Implementations SHOULD keep the total size ≤ 1232 B to avoid IPv6 fragmentation on typical paths. With ShardBits=12 (4,096 groups) the bitmap form is exactly 512 B; the list form is 2 B per joined group. Operators with large source lists SHOULD spread them across multiple announcers (each advertising its own source as the lone entry) so individual datagrams stay within the recommended MTU.
Encoding-form rules
GroupsValid
BitmapBytes
GroupCount
Groups payload form
0
0
0
identity-only (no group claim)
1
> 0
0
bitmap, exactly BitmapBytes bytes; bit positions 0..(BitmapBytes×8)-1
1
0
> 0
list, exactly GroupCount × 2 bytes, sorted ascending, no duplicates
A datagram with GroupsValid=1 and both BitmapBytes=0 and GroupCount=0 is malformed and MUST be rejected. A datagram with GroupsValid=1 and both BitmapBytes>0 and GroupCount>0 is also malformed. For bitmap form, bits at positions ≥ 2^ShardBits MUST be zero and MUST be ignored by consumers.
Sources payload (when SourcesValid=1)
SourcesValid=1)Each 16-byte entry is a publisher source IPv6 in network byte order, contributed by this announcer. Consumers MUST reject the datagram when SourcesValid=1 && SourceCount=0 or when SourcesValid=0 && SourceCount>0, treat entries as set-valued (order not significant), and deduplicate across the union of all currently-valid manifests. When SourceModeSSM=1, consumers feed the union into the Source-Specific Multicast (S,G) join calls for data-plane groups derived from the announced parameters. Each sender SHOULD announce only its own data-plane source (typically a single entry) rather than the operator-curated full fleet list, so per-datagram size stays small and the source set tracks publisher lifecycle.
Successor block (when SuccessorValid=1)
SuccessorValid=1)The Successor block signals an in-flight generation transition: the announcer commits to a future ShardBits (and optionally SourceModeSSM) value that becomes the sole active generation at TransitionEpoch. It enables live re-sharding consumers to enter a bridging window before cutover. When present, a 24-byte block is appended immediately after the Sources payload:
0
16
SuccessorGenerationID
The incoming generation's 128-bit ID
16
1
SuccessorShardBits
1–12; MUST satisfy |Successor − ShardBits| ≤ 1
17
1
SuccessorFlags
Bit 0 = SuccessorSourceModeSSM; bits 1–7 reserved (0)
18
2
Reserved
MUST be 0
20
4
TransitionEpoch
Unix seconds at which the successor becomes the sole generation
Consumer rules (normative when auto-configuration is enabled):
Reject the datagram when
|SuccessorShardBits − ShardBits| > 1.Reject the datagram when
SuccessorValid=1 && Authoritative=0(live re-sharding signals require operator authority).Apply the existing adoption gates (quorum, hysteresis) to the Successor block as a unit; the tuple
(SuccessorGenerationID, SuccessorShardBits, SuccessorFlags, TransitionEpoch)is the candidate value.Consumers that implement live re-sharding MAY enter a bridging window between the moment the Successor block first satisfies quorum and
local_clock ≥ TransitionEpoch. Consumers that do not implement live re-sharding MUST treat Successor-block adoption as a divergence event and wait for the pilot to rollGenerationID(promoting the successor to the active generation) before reacting on the new value.
Pilots MUST choose TransitionEpoch ≥ now + 2 × AnnounceInterval (RECOMMENDED ≥ now + 4 × AnnounceInterval) and MUST reject configurations below that floor. Clock skew between pilot and consumers MUST stay below AnnounceInterval / 2; operators SHOULD run NTP.
Flags
0
GroupsValid
The trailing payload carries a valid joined-groups encoding.
1
Authoritative
Operator-curated authoritative announcer; counts toward adoption quorum.
2
Shutdown
Final announcement before graceful shutdown; consumers MAY evict immediately.
3
SourceModeSSM
Data plane uses Source-Specific Multicast (FF3x::/32, RFC 4607); consumers MUST use the SSM prefix.
4
SourcesValid
The trailing payload includes SourceCount × 16 bytes of publisher source IPv6 addresses. 0 ⇒ none.
5
PilotOnly
Groups describe desired fleet state, not the announcer's own joins; implies Authoritative=1.
6
SuccessorValid
The trailing payload includes a 24-byte Successor block; requires Authoritative=1.
Bit 7 is reserved and MUST be 0. Consumers MUST reject PilotOnly=1 && Authoritative=0 and SuccessorValid=1 && Authoritative=0 as malformed.
RoleHint
RoleHint is informational; consumers SHOULD NOT make filtering decisions on it.
0
generic
1
proxy
2
listener
3
retry-endpoint
4
producer
5
manifest-only
Values ≥ 6 are reserved.
ManifestCRC
ManifestCRC is a CRC32c (Castagnoli polynomial) computed over the entire datagram with the four CRC bytes themselves treated as zero. Consumers MUST verify the CRC before acting on the manifest.
Multicast Group and Scope
Manifests are sent directly to the beacon group defined in BRC-129 (index 0xFFFD), the same group used by BRC-126 ADVERT:
0xFFFD
FF05
FF05::B:FFFD
0xFFFD
FF08
FF08::B:FFFD
0xFFFD
FF0E
FF0E::B:FFFD
The announcer chooses one or more scopes; when multiple are configured the same datagram is sent to each. The proxy is not involved. Because BRC-126 ADVERT (MsgType 0x20) shares this group, listeners MUST dispatch on the MsgType byte (offset 6) before parsing: 0x40 ⇒ ShardManifest; 0x20 ⇒ BRC-126 ADVERT.
Cadence and Freshness
AnnounceInterval
300 s
Every 5 minutes
Default TTL
900 s
3 × AnnounceInterval (used when TTL = 0)
Send jitter
±10 %
RECOMMENDED, to avoid global synchronisation
Consumers MUST treat entries older than Epoch + TTL (or Epoch + 3 × AnnounceInterval when TTL=0) as expired. There is no retransmission and no NACK semantics; loss is tolerated by re-announcement, and an empty registry is valid.
Identity and State
Consumers SHOULD key registry entries on (SrcIPv6, InstanceID). The authoritative SrcIPv6 is taken from the IPv6 datagram header; the in-frame SrcIPv6 field is informational only. InstanceID is the CRC32c of the announcer's hostname, matching BRC-126 ADVERT semantics, and is stable across restarts. GenerationID is an operator-supplied 128-bit value (typically a UUID) that operators MUST bump whenever ShardBits changes; it is opaque to the protocol and consumers compare it for change detection.
Consumer Behaviour — Observation (informative)
A consumer MAY join the beacon group(s) of interest and:
Dispatch incoming datagrams on the
MsgTypebyte.0x40⇒ ShardManifest.Verify
ManifestCRC; reject on mismatch.Upsert into a registry keyed on
(SrcIPv6, InstanceID).Evict on
Epoch + TTL(orEpoch + 3 × AnnounceIntervalwhenTTL=0).Surface metrics: per-peer
ShardBits, joined-group count, last-seen, and the count of distinctShardBitsvalues currently observed (divergence).
Consumer Behaviour — Auto-configuration (normative when opted in)
A consumer that opts in to automatic configuration MUST implement the observation requirements above and additionally MUST satisfy the following. Components that do not opt in are unaffected.
Authoritative-only adoption. Manifests with
Authoritative=0MUST NOT contribute to any adopted value (they MAY still be indexed for visibility and contribute to the source-set union below).Quorum. A candidate value is eligible for adoption only when reported by at least
pilot-quorumdistinct authoritative announcers (keyed on(SrcIPv6, InstanceID)) within their TTL window.pilot-quorumMUST be configurable; default2.Hysteresis. A candidate that satisfies quorum MUST hold quorum continuously for
≥ 2 × AnnounceIntervalbefore adoption. A change in adopted value resets the timer.ShardBitsshift bound. A consumer MUST NOT adopt aShardBitsvalue differing from the currently adopted value by more than ±1 within any rollingAnnounceIntervalwindow.Manual pin precedence. An operator-pinned value is the local authority and MUST NOT be overridden by adoption; the consumer MUST still evaluate quorum and emit divergence telemetry when the adopted candidate differs from the pin.
Fields subject to adoption: ShardBits, SourceModeSSM, and the deduplicated union of SourcesValid payloads (the source set is not gated by quorum — it is the union of every currently-valid manifest's sources, irrespective of Authoritative). MCGroupID is not carried in the payload; consumers MUST derive it from the destination address of the beacon socket on which the manifest was received. Consumers SHOULD rate-limit source-set additions and removals before feeding them into kernel join calls to avoid thrashing the multicast forwarding information base, and MUST NOT label any metric with raw source IPv6 addresses.
Safety Guidance
Bump
GenerationIDwheneverShardBitschanges.Keep authoritative announcers to a small operator-curated set (RECOMMENDED: three instances across failure domains).
Deploy authoritative announcers with
PilotOnly=1so consumers can distinguish operator intent from an announcer's own joins.Treat non-authoritative manifests as observational (and, when
SourcesValid=1, as per-publisher source contributions).Warn — do not auto-shift — on observed
ShardBitsdivergence; the adoption gates already prevent unsafe shifts, but operator visibility is where misconfiguration is caught.
Interactions With Other BRCs
BRC-126 (Retransmission / ADVERT) — shares the beacon group
0xFFFDand listen port. Distinguished by theMsgTypebyte (0x20ADVERT vs0x40ShardManifest). BRC-139 is neither retransmitted nor a retransmitter.BRC-127 (Subtree group announcements) — orthogonal: BRC-127 announces SubtreeID→GroupID bindings on
0xFFFCvia the proxy; BRC-139 announces participant configuration directly on0xFFFD.BRC-129 (Multicast addressing) — no new index allocated; manifests reuse the existing beacon group, and
ShardBits ≤ 12per BRC-129.
References
BRC-82: Defining a Scalable IPv6 Multicast Protocol for Blockchain Transaction Broadcast and Update Delivery — Overall multicast protocol architecture
BRC-124: Multicast Transaction Frame Format — Data-plane frame format and
HashKey/SeqNumderivationBRC-126: Multicast Transaction NACK Retransmission Protocol — ADVERT beacon sharing the same beacon group
BRC-129: IPv6 Multicast Group Address Assignments — Beacon group and
shard_bitsbound
Constants Reference
MagicBSV
3823236072
0xE3E1F3E8
BSV mainnet P2P magic
ProtoVer
703
0x02BF
Protocol version
MsgTypeShardManifest
64
0x40
ShardManifest datagram type
ShardManifestHeaderSize
64
0x40
Fixed header size in bytes
GroupBeacon
65533
0xFFFD
Control-plane beacon group index
FlagGroupsValid
1
0x01
Flags bit 0: groups payload present
FlagAuthoritative
2
0x02
Flags bit 1: operator-curated announcer
FlagShutdown
4
0x04
Flags bit 2: final pre-shutdown announcement
FlagSourceModeSSM
8
0x08
Flags bit 3: data plane uses SSM addressing
FlagSourcesValid
16
0x10
Flags bit 4: sources payload present
FlagPilotOnly
32
0x20
Flags bit 5: groups describe desired fleet state
FlagSuccessorValid
64
0x40
Flags bit 6: Successor block present
DefaultAnnounceInterval
300
—
Default re-announce period (s)
DefaultTTLMultiplier
3
—
TTL = 3 × AnnounceInterval when TTL=0
Last updated
Was this helpful?

