Skip to content

feat(#76): --no-fallback-rpc for a provably Glif-free standalone daemon#108

Open
Reiers wants to merge 2 commits into
mainfrom
feat/108-no-fallback-rpc
Open

feat(#76): --no-fallback-rpc for a provably Glif-free standalone daemon#108
Reiers wants to merge 2 commits into
mainfrom
feat/108-no-fallback-rpc

Conversation

@Reiers

@Reiers Reiers commented Jul 2, 2026

Copy link
Copy Markdown
Owner

What

Adds a --no-fallback-rpc flag to the standalone lantern daemon CLI. When set, no upstream RPC (Glif) is wired as a runtime fallback: head comes only from gossipsub, cold blocks only from gateway+Bitswap.

Why

The CLI daemon wired Glif unconditionally as the last-resort runtime source at four sites (initial fetcher, polling Sync head, gossip inline-backfill, rebuilt bitswap fetcher). pkg/daemon already had Config.NoFallbackRPC; the CLI never exposed it, so a stock-Curio operator (or our soak) could not run a provably Glif-free node. This is the exact critique raised about Lantern's third-party dependency surface. Closes the gap for #76.

How

  • --no-fallback-rpc gates all four runtime Glif sites.
  • Polling Sync + gossip backfill get truly-nil interfaces (nilRPCSource/nilBackfillSource) so the existing nil-guards in hstore.Sync and net/blockingest fire (no Glif client constructed, both become no-ops). Avoids the typed-nil-in-interface trap.
  • Startup guard: refuses to boot without libp2p (gossip is the sole head source), mirroring pkg/daemon/start.go.
  • A gossip stall now surfaces as an observable stalled head instead of a silent Glif fetch.

Scope / honest boundary

The one-time boot anchor (#54) still uses multi-source agreement (gateway+Glif) and is separate from runtime fetch counters. Follow-up filed for anchor Glif-independence.

Tests

  • go build + go vet + gofmt clean (linux/amd64 cross-compile too).
  • chain/header/store + net/blockingest nil-guard tests pass.
  • Verified on the calibration soak node: flag registers, guard fires on --no-libp2p / empty --p2p-listen.

Soak evidence: #104 Setup checkbox 4. Related: #76, #50.

The standalone `lantern daemon` CLI wired Glif unconditionally as the
last-resort runtime source (fetch fan-out + polling Sync head + gossip
inline-backfill), with no way to opt out. pkg/daemon already had
Config.NoFallbackRPC; this exposes the same capability on the CLI.

--no-fallback-rpc removes Glif from all four runtime sites:
 - initial combined fetcher (gateway-only cold blocks)
 - polling Sync head source -> truly-nil RPCSource (nil-guard no-op)
 - gossip inline-backfill source -> truly-nil BackfillSource
 - rebuilt bitswap fetcher (bitswap+gateway, no glif)

Head then comes ONLY from gossipsub; a stall surfaces as an observable
stalled head instead of a silent Glif fetch. Guard: refuses to start
without libp2p (gossip is the sole head source). The one-time boot
anchor (#54) still uses multi-source agreement (gateway+Glif) and is
separate from runtime fetch counters -> follow-up for anchor Glif-independence.

Truly-nil interface helpers (nilRPCSource/nilBackfillSource) avoid the
typed-nil-in-interface trap the consumers' nil-guards depend on.

Build+vet+gofmt clean; hstore + blockingest nil-guard tests pass.
Soak evidence: #104 Setup checkbox 4.
… backfill, anchor seed, fail-loud

Clean, non-panicking bridge-off (--no-fallback-rpc) plumbing:
- Daemon prefers the persisted multi-source quorum anchor
  (bootstrap-anchor.json from init/repair) over re-probing gateway+glif;
  gateway/RPC becomes true last resort. Bridge-off refuses to boot without
  a usable persisted anchor (clear error, not a panic).
- bitswapBackedSource is nil-glif-safe: HeadEpoch/TipsetCIDsByHeight return
  a sentinel (no nil-deref); FetchBlock serves bitswap-only.
- Ingestor gains an explicit parent-walk backfill mode (SetParentWalkBackfill):
  resolve head+N gaps by CID-walking the gossip block's Parents instead of
  the RPC-shaped height->CID lookup. Height-based path unchanged for glif.
- Bridge-off seeds the REAL anchor tipset (replacing the synthetic head)
  from the block source so gossip has a genuine content-addressed base.

KNOWN GAP (not yet functional end-to-end): block RETRIEVAL. Bridge-off needs
to fetch specific chain blocks by CID from peers. Bitswap has no calibration
chain-block providers (glif carries 100% of fetches on the soak node) and the
only gateway is mainnet. The Filecoin-native fix is a ChainExchange/BlockSync
client (#91) against the same libp2p quorum peers; Lantern today only has a
certexchange (F3) client + a chainxchg NotFound responder. This scaffolding is
the layer #91 plugs into.

build/vet/gofmt clean; blockingest + hstore tests pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant