Part of the BSV Layered Multicast open-source project. See the main repository for the full architecture, design docs, and BRC specifications.
A landing-tier bridge that runs an unmodified Arcade v2 + merkle-service stack with a multicast delivery fabric as its transport.
It is the application-tier sibling of teranode-bridge. Where that bridge fronts a mining Teranode cluster, this one fronts the broadcaster tier: an Arcade operator is a delivery consumer, not a miner. Subtrees and blocks arrive down the tunnel, transactions go up on the open class, and nothing here carries miner entitlements. The shared machinery (lane termination, the object cache, the retrieval plane, hash-order discipline, block wire conversion) is imported from teranode-bridge's public packages, never forked.
fabric ══push══▶ arcade-bridge
lanes ─▶ cache ─┬─▶ announce ──▶ merkle-service (hash, dataHubUrl)
└─▶ retrieval ◀─ fetch ── merkle-service
Arcade ─▶ POST /txs ─▶ facade ─▶ up-tunnel ─▶ fabric ─▶ every miner
- Proof ingest. Pushed subtrees and blocks are cached and announced to
merkle-service with its own Kafka messages,
dataHubUrlpointing at the bridge's retrieval plane, so the fetch never leaves the box and Arcade's lifecycle runs unchanged. - Broadcast. The propagation facade serves the Teranode-shaped
POST /txsArcade already speaks and sends one copy up the tunnel instead of O(N) unicast POSTs; the fabric fans it out to every miner. Standard-format submissions are hydrated to extended format, and Teranode's failure-list grammar is preserved.
Architecture covers both contracts in full.
- Architecture: components, the announce and fetch contract, the facade contract, hydration, byte order, failure modes
- Configuration: every flag, defaults, deployment examples, reading the stats
- Metrics reference: every series and the chart's alert expressions
- BRC-143 Subtree Data and BRC-144 Block Frame: what the delivery lanes carry
- BRC-30 Transaction Extended Format: what the up-tunnel stream carries
- Deliver once: one crossing per landing site, and how a co-located Arcade + Teranode site fans locally
- Go 1.26 or later
- A reachable merkle-service Kafka and an Arcade v2 stack (or
-mode sink, which needs neither) - Network reachability from the stack's containers back to the bridge's retrieval plane (containers cannot dial loopback; advertise an address they can reach)
go build ./cmd/arcade-bridge
go test -race ./...# Sink: receive, parse, count and serve, with no announce targets.
# Use for lane burn-in before the Arcade stack attaches.
./arcade-bridge -mode sink -stats-every 10s
# Feed plus facade: also serve Arcade's broadcast path into the fabric.
./arcade-bridge \
-advertise 'http://192.0.2.10:9165' \
-kafka 'localhost:19092' \
-edge-ingress '2001:db8:59::a,2001:db8:59::b' \
-hydrate-asset 'http://192.0.2.20:20090/api/v1'See docs/configuration.md for the full flag reference.
| Port | Direction | Carries |
|---|---|---|
9143 |
in | subtree lane (bare BRC-143 push frames) |
9144 |
in | block lane (bare BRC-144 push frames) |
9165 |
in | retrieval plane, merkle-service's fetches (/api/v1) |
9166 |
in | propagation facade (POST /txs, POST /tx, GET /health) |
9167 |
in | /metrics, /healthz, /readyz |
8725 |
out | bare BRC-30 EF transaction stream to the fabric ingress |
The delivery lanes use the canonical 9143/9144 shared with teranode-bridge
(lane numbering); a site running both stacks uses one slot and a
local tee (deliver once).
Prometheus series are arcade_bridge_* on -metrics-addr (default
[::]:9167), covering lane, cache, announce, facade, and up-tunnel counters.
The same numbers appear as structured log/slog stats blocks every
-stats-every (default 60s). /readyz reports ready once the lanes are bound
and the retrieval plane is listening. See the
metrics reference.
A Kubernetes Helm chart is published from a dedicated chart repository:
- Repository:
charts/arcade-bridge - OCI:
helm install bridge oci://ghcr.io/lightwebinc/charts/arcade-bridge
config.advertise and config.kafka are effectively required unless
config.mode=sink; setting config.edgeIngress turns the facade on. See the
chart README for the three-service shape and scaling notes.
.
├── cmd/arcade-bridge/ # entrypoint: flags, wiring, per-class lane handlers, collector
├── msannounce/ # merkle-service announcement messages + Kafka producer
├── facade/ # Teranode-shaped POST /txs surface + EF hydration
├── uptunnel/ # bare EF stream to the fabric ingress, with failover
├── docs/ # architecture, configuration, metrics reference
├── Dockerfile
├── Makefile
└── .github/workflows/{ci,codeql,image-publish,release,vuln}.yml
github.com/lightwebinc/teranode-bridge: the shared landing-tier packages (lanes,cache,registry,retrieval,hashid,tnwire)github.com/lightwebinc/shard-common:objfmt, the push object-frame codecsgithub.com/bsv-blockchain/go-sdk: transaction parsing and extended-format serializationgithub.com/twmb/franz-go: Kafka producer
Arcade's and merkle-service's modules are deliberately not linked; their announcement wire shape is reproduced and pinned by contract-fixture tests.
Releases and notes live on GitHub Releases; there is no CHANGELOG.
Apache 2.0. See LICENSE.