feat(mesh): archy nodes run as RNS transport nodes

The Reticulum daemon gains --enable-transport, which writes
enable_transport = yes into the RNS config it regenerates on every
start, and the Rust supervisor always passes it. Archy nodes now relay
RNS traffic and rebroadcast announces, so archy nodes (and Sideband/
NomadNet peers) beyond direct RF range discover and reach each other
through any archy node in between — edge-only operation left every
node limited to its own radio horizon. RNS's per-interface airtime
caps bound the extra announce overhead on LoRa.

Verified: config generation with the flag on/off, daemon --selftest
green with transport enabled, mesh test module 116/116.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
archipelago 2026-07-29 06:21:43 -04:00
parent 5c19effdd1
commit 8e0939170c
2 changed files with 13 additions and 1 deletions

View File

@ -154,6 +154,12 @@ fn daemon_command(
}
}
}
// Archy nodes are RNS transport nodes: they relay traffic and rebroadcast
// announces, so archy nodes (and Sideband/NomadNet peers) beyond direct RF
// range discover and reach each other through any archy node in between.
// Edge-only operation (`enable_transport = no`) left every node an island
// limited to its own radio horizon.
cmd.arg("--enable-transport");
if let (Some(ed), Some(x)) = (archy_ed_pubkey_hex, archy_x25519_pubkey_hex) {
cmd.arg("--archy-ed-pubkey-hex")
.arg(ed)

View File

@ -82,6 +82,7 @@ def _write_rns_config(
no_radio: bool,
tcp_listen: str | None = None,
tcp_connect: list[str] | None = None,
enable_transport: bool = False,
) -> None:
"""Materialise an RNS config file. RNode interface for real radios; plain-TCP
server/client interface(s) for radio-less dev/verification (e.g. Aurora
@ -136,7 +137,7 @@ def _write_rns_config(
)
cfg.write_text(
"[reticulum]\n"
" enable_transport = no\n"
f" enable_transport = {'yes' if enable_transport else 'no'}\n"
" share_instance = no\n"
" panic_on_interface_error = no\n\n"
"[interfaces]\n" + interfaces
@ -191,6 +192,7 @@ class ReticulumDaemon:
no_radio=self.args.no_radio,
tcp_listen=self.args.tcp_listen,
tcp_connect=self.args.tcp_connect,
enable_transport=self.args.enable_transport,
)
self.reticulum = RNS.Reticulum(configdir=str(configdir))
self.identity = load_identity(self.seed)
@ -641,6 +643,10 @@ def _parse_args(argv):
p.add_argument("--txpower", type=int, default=17)
p.add_argument("--spreadingfactor", type=int, default=8)
p.add_argument("--codingrate", type=int, default=5)
p.add_argument("--enable-transport", action="store_true",
help="run as an RNS transport node: relay traffic and rebroadcast "
"announces so nodes beyond direct RF range discover each other "
"through this one")
p.add_argument("--no-radio", action="store_true", help="bring up with no RNode (selftest)")
p.add_argument("--check", action="store_true", help="print derived dest hash and exit (no RNS)")
p.add_argument("--selftest", action="store_true", help="bring up RNS+LXMF with no radio, verify, exit")