nostr: separate next-branch advert namespace by default

Bump the default Nostr-discovery advert namespace from
`fips-overlay-v1` to `fips-overlay-v1-next` on next. Master
continues to publish under `fips-overlay-v1`.

Background: next runs FMP-v1 (Noise XX, msg1 33 bytes) which is
wire-incompatible with master's FMP-v0. Until now both branches
defaulted to the same Nostr advert namespace, so a stock
next-branch daemon's open-discovery sweep would happily pick up
master peers' adverts (and vice versa), succeed at the UDP punch,
adopt the socket, and fail every FMP handshake at the version-gate.
The per-peer-mismatch cooldown introduced on master is the safety
net for any case that slips past this default; the namespace
separation is the structural answer.

Three sites updated:

- `src/discovery/nostr/types.rs` `ADVERT_IDENTIFIER` const
  documents why the value is branch-specific.
- `src/config/node.rs` `default_app()` matches.
- `src/discovery/nostr/tests.rs` and the
  `testing/nat/scripts/nostr-relay-test.sh` malformed-advert
  fixture publish under the new namespace so test harnesses see
  the same adverts a real daemon would.

Operators who need cross-branch discovery during a coordinated
rolling upgrade can override `node.discovery.nostr.app` in
fips.yaml back to `fips-overlay-v1`.
This commit is contained in:
Johnathan Corgan
2026-05-06 15:09:16 +00:00
parent acb750c0d2
commit fb834dc2ca
5 changed files with 31 additions and 4 deletions
+16
View File
@@ -62,6 +62,22 @@ with v0.2.x peers.
- TLV extension section added to LookupRequest and LookupResponse
after fixed fields. Transit nodes forward TLV bytes verbatim.
#### Nostr-Discovery Advert Namespace
- Default Nostr-discovery advert namespace bumped from
`fips-overlay-v1` to `fips-overlay-v1-next` on the `next` branch.
Master continues to publish under `fips-overlay-v1`. Effect: a
stock `next`-branch daemon's open-discovery sweep no longer
discovers `master` peers, and vice versa — eliminating the
cross-version retraversal storms that arise when both sides
punched a UDP socket via Nostr but cannot complete an FMP
handshake. Operators who genuinely want cross-branch reach (e.g.
during a coordinated rolling upgrade) can override per-daemon
via `node.discovery.nostr.app` in `fips.yaml`. The
`protocol_mismatch_cooldown_secs` defense-in-depth on master is
the safety net against any peer that bypasses this default
(config override, future fork, static-peer config).
#### Shared-Media Beacons
- Ethernet frame header unified to 4 bytes `[type][flags][length:2
+5 -1
View File
@@ -462,7 +462,11 @@ impl NostrDiscoveryConfig {
}
fn default_app() -> String {
"fips-overlay-v1".to_string()
// Branch-specific default. `next` runs FMP-v1 which is wire-
// incompatible with `master`'s FMP-v0, so the two namespaces
// separate the discovery overlays by default — operators who
// want cross-branch discovery can override here.
"fips-overlay-v1-next".to_string()
}
fn default_signal_ttl_secs() -> u64 {
+1 -1
View File
@@ -39,7 +39,7 @@ fn can_reach(local_nat: NatType, remote_nat: NatType) -> bool {
fn signed_overlay_advert_event(created_at_secs: u64, expiration_secs: Option<u64>) -> nostr::Event {
let keys = nostr::Keys::generate();
let content = r#"{"identifier":"fips-overlay-v1","version":1,"endpoints":[{"transport":"tcp","addr":"203.0.113.10:443"}]}"#;
let content = r#"{"identifier":"fips-overlay-v1-next","version":1,"endpoints":[{"transport":"tcp","addr":"203.0.113.10:443"}]}"#;
let mut builder = EventBuilder::new(Kind::Custom(ADVERT_KIND), content)
.custom_created_at(Timestamp::from(created_at_secs));
if let Some(expiration_secs) = expiration_secs {
+8 -1
View File
@@ -3,7 +3,14 @@ use crate::discovery::EstablishedTraversal;
use serde::{Deserialize, Serialize};
pub const ADVERT_KIND: u16 = 37195;
pub const ADVERT_IDENTIFIER: &str = "fips-overlay-v1";
/// Default Nostr-discovery advert namespace identifier on the `next`
/// branch. Distinct from `master`'s `fips-overlay-v1` so peers running
/// the FMP-v1 protocol on `next` are not discovered by `master` peers
/// (and vice versa) — the `next`-branch FMP wire format is incompatible
/// with `master`'s, so cross-branch discovery only ever produces failed
/// handshakes. Operators who genuinely want cross-branch reach can
/// override per-peer via `node.discovery.nostr.app` in config.
pub const ADVERT_IDENTIFIER: &str = "fips-overlay-v1-next";
pub const ADVERT_VERSION: u32 = 1;
pub const SIGNAL_KIND: u16 = 21059;
// Defined at the top-level `discovery` module; re-exported here so the
+1 -1
View File
@@ -191,7 +191,7 @@ pubkey = xonly_pubkey(secret).hex()
created_at = int(time.time())
kind = 37195
tags = [
["d", "fips-overlay-v1"],
["d", "fips-overlay-v1-next"],
["app", "fips.nat.lab.v1"],
]
content = "this-is-not-a-valid-overlay-advert-{garbage}"