Skip to content

nmc(PF): lock external-daemon fallback-path conformance - #493

Merged
frstrtr merged 1 commit into
masterfrom
nmc/pf-fallback-path-conformance
Jun 25, 2026
Merged

nmc(PF): lock external-daemon fallback-path conformance#493
frstrtr merged 1 commit into
masterfrom
nmc/pf-fallback-path-conformance

Conversation

@frstrtr

@frstrtr frstrtr commented Jun 25, 2026

Copy link
Copy Markdown
Owner

Phase PF — fallback-path conformance (external-daemon half)

The V36 external_fallback invariant requires the external-daemon RPC fallback (NMC = .140 namecoind submitauxblock) to PERSIST as the retained path alongside the embedded P2P relay — "embedded is default, external is the retained fallback path; do NOT remove external-daemon code paths."

Gap this closes

The existing dispatcher KAT (nmc_block_broadcast_test) and host-wiring DELIVERY KAT (nmc_host_dualpath_test) both bind the fallback leg to a fake that always acks, so neither distinguishes which backend serves the fallback. PF owns that fact.

What it locks (nmc_fallback_path_conformance_test, 3 KATs)

  1. ExternalDaemonFallbackCarriesWhenEmbeddedP2pDown — with the embedded P2P relay down, the external namecoind submitauxblock saves the won aux block (rpc_ok, any(), landed_first="rpc").
  2. EmbeddedSelfLegCannotServeAsFallback_BlockLost — the conformance lock. The embedded backend's own submit_aux_block is daemon-less and returns false unconditionally (aux_chain_embedded.hpp:153). Mis-wiring set_fallback_backend to it leaves the wiring looking present but turns the retained fallback into a dead path: with P2P also down the won block is silently lost (any()==false). This makes that regression RED.
  3. ExternalFallbackPersistsAlongsideWorkingEmbeddedP2p — the external fallback always-fires alongside a working embedded relay (not optimized away "because embedded works").

Scope / safety

Phase PF fallback-path half. The V36 external_fallback invariant requires
the external-daemon (.140 namecoind submitauxblock) RPC fallback to PERSIST
as the retained path alongside the embedded P2P relay. Existing dispatcher
and host-wiring KATs bind the fallback leg to an always-ack fake, so neither
distinguishes WHICH backend serves it.

This adds nmc_fallback_path_conformance_test (3 KATs) locking the one fact PF
owns: the fallback MUST be the external namecoind RPC (a daemon that can ack),
NOT the embedded backend daemon-less submit_aux_block (structurally false,
aux_chain_embedded.hpp:153). Mis-wiring set_fallback_backend to the embedded
self-leg leaves the wiring looking present but turns the retained fallback into
a dead path -- a won aux block is silently lost when P2P is down. Test 2 makes
that regression RED; test 1 proves the external path carries when P2P is down;
test 3 locks that the external fallback always-fires alongside a working
embedded relay (not optimized away).

Test-only, NMC-fenced (src/impl/nmc/ only), zero consensus surface. Registered
in test/CMakeLists.txt + gtest_add_tests and the build.yml --target allowlist
(both legs) to avoid a #137-style NOT_BUILT sentinel.
@frstrtr
frstrtr merged commit b22daa7 into master Jun 25, 2026
20 of 21 checks passed
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