diff options
| author | bitflash-maintainer <noreply@bitflash.invalid> | 2026-08-08 04:37:52 +0000 |
|---|---|---|
| committer | bitflash-maintainer <noreply@bitflash.invalid> | 2026-08-23 04:37:36 +0000 |
| commit | 76f154a4c600082b346124e9e9af26ce401600da (patch) | |
| tree | b748e59a06b5b2dc45a319ecd9b208f446d0dfcd | |
| parent | 6e4865c14c858d00c6cfa6967e66a86b31cd12f8 (diff) | |
nostr: make /rvrelay a true pin -- never merge discovered relays
A pool started with /rvrelay=ONE still spawned an accept thread for every
Nostr-discovered relay (BtfAllRelays always merged g_discoveredRelays), and
each thread optimistically overwrote the advertised meeting node before
registering -- so a discovered Tailscale-only relay (a mesh host)
flapped the published .btf descriptor and public miners could not connect.
fBtfRelayPinned (set only when /rvrelay parses) makes BtfAllRelays return
exactly the pinned list. Also validate the /rvrelay value at parse time:
with the pin in place no discovered relay can mask a typo.
(cherry picked from commit 0a4d2b02fa5382c5e788b5f0e2f8a844695dec47)
| -rw-r--r-- | src/main_gui.cpp | 16 | ||||
| -rw-r--r-- | src/nostr.cpp | 10 | ||||
| -rw-r--r-- | src/nostr.h | 8 |
3 files changed, 31 insertions, 3 deletions
diff --git a/src/main_gui.cpp b/src/main_gui.cpp index 0b4e091..d0969b5 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp | |||
| @@ -261,8 +261,20 @@ static void ParseStartupArguments(int argc, char* argv[]) | |||
| 261 | string rvRelay = argval2(argc, argv, "/rvrelay", "-rvrelay"); | 261 | string rvRelay = argval2(argc, argv, "/rvrelay", "-rvrelay"); |
| 262 | if (!rvRelay.empty()) | 262 | if (!rvRelay.empty()) |
| 263 | { | 263 | { |
| 264 | vBtfMeetingRelays.clear(); | 264 | if (!LooksLikeRelay(rvRelay)) |
| 265 | vBtfMeetingRelays.push_back(rvRelay); | 265 | { |
| 266 | // A malformed pin must not replace the seed list: with the pin | ||
| 267 | // set, no discovered relay can ever mask the typo, and the pool | ||
| 268 | // would publish a garbage (or no) meeting node forever. | ||
| 269 | fprintf(stderr, "Ignoring /rvrelay=%s: expected host:port\n", | ||
| 270 | rvRelay.c_str()); | ||
| 271 | } | ||
| 272 | else | ||
| 273 | { | ||
| 274 | vBtfMeetingRelays.clear(); | ||
| 275 | vBtfMeetingRelays.push_back(rvRelay); | ||
| 276 | fBtfRelayPinned = true; | ||
| 277 | } | ||
| 266 | } | 278 | } |
| 267 | 279 | ||
| 268 | string announceRelay = argval2(argc, argv, "/announcerelay", "-announcerelay"); | 280 | string announceRelay = argval2(argc, argv, "/announcerelay", "-announcerelay"); |
diff --git a/src/nostr.cpp b/src/nostr.cpp index 21104bc..6d85bf6 100644 --- a/src/nostr.cpp +++ b/src/nostr.cpp | |||
| @@ -110,6 +110,12 @@ vector<string> vBtfMeetingRelays = { | |||
| 110 | "31.44.4.249:8434", // New Jersey, US | 110 | "31.44.4.249:8434", // New Jersey, US |
| 111 | "90.156.222.107:8434", // Almaty, KZ | 111 | "90.156.222.107:8434", // Almaty, KZ |
| 112 | }; | 112 | }; |
| 113 | // True when the operator pinned the relay list with /rvrelay: discovered | ||
| 114 | // relays must NOT be merged in (BtfAllRelays), otherwise one accept thread | ||
| 115 | // per discovered relay is spawned and each one optimistically overwrites the | ||
| 116 | // advertised meeting node (BtfSetActiveRelay) before registering -- a | ||
| 117 | // discovered but unreachable relay then flaps the published .btf descriptor. | ||
| 118 | bool fBtfRelayPinned = false; | ||
| 113 | string strBtfActiveRelay; | 119 | string strBtfActiveRelay; |
| 114 | static CCriticalSection cs_activeRelay; | 120 | static CCriticalSection cs_activeRelay; |
| 115 | 121 | ||
| @@ -144,7 +150,7 @@ static map<string, BtfPoolAnnouncement> g_discoveredPools; | |||
| 144 | static CCriticalSection cs_discoveredPools; | 150 | static CCriticalSection cs_discoveredPools; |
| 145 | 151 | ||
| 146 | // Basic sanity: "host:port" with a numeric 1..65535 port and a plausible host. | 152 | // Basic sanity: "host:port" with a numeric 1..65535 port and a plausible host. |
| 147 | static bool LooksLikeRelay(const string& r) | 153 | bool LooksLikeRelay(const string& r) |
| 148 | { | 154 | { |
| 149 | size_t colon = r.rfind(':'); | 155 | size_t colon = r.rfind(':'); |
| 150 | if (colon == string::npos || colon == 0 || colon + 1 >= r.size()) | 156 | if (colon == string::npos || colon == 0 || colon + 1 >= r.size()) |
| @@ -172,6 +178,8 @@ static bool LooksLikeRelay(const string& r) | |||
| 172 | vector<string> BtfAllRelays() | 178 | vector<string> BtfAllRelays() |
| 173 | { | 179 | { |
| 174 | vector<string> all = vBtfMeetingRelays; | 180 | vector<string> all = vBtfMeetingRelays; |
| 181 | if (fBtfRelayPinned) | ||
| 182 | return all; | ||
| 175 | CRITICAL_BLOCK(cs_discoveredRelays) | 183 | CRITICAL_BLOCK(cs_discoveredRelays) |
| 176 | foreach(const string& r, g_discoveredRelays) | 184 | foreach(const string& r, g_discoveredRelays) |
| 177 | if (find(all.begin(), all.end(), r) == all.end()) | 185 | if (find(all.begin(), all.end(), r) == all.end()) |
diff --git a/src/nostr.h b/src/nostr.h index b5eb5e3..827b2f3 100644 --- a/src/nostr.h +++ b/src/nostr.h | |||
| @@ -43,6 +43,14 @@ void BtfSetActiveRelay(const std::string& relay); | |||
| 43 | // If set (via /announcerelay=host:port), this node announces that relay on | 43 | // If set (via /announcerelay=host:port), this node announces that relay on |
| 44 | // Nostr so other nodes discover it automatically -- no manual seed-list edit. | 44 | // Nostr so other nodes discover it automatically -- no manual seed-list edit. |
| 45 | extern std::string strBtfAnnounceRelay; | 45 | extern std::string strBtfAnnounceRelay; |
| 46 | // True when /rvrelay pinned the meeting relay list: BtfAllRelays then returns | ||
| 47 | // ONLY vBtfMeetingRelays, never Nostr-discovered volunteer relays. Without | ||
| 48 | // this, a pool that pins one public relay still spawns an accept thread per | ||
| 49 | // discovered relay, and each thread's optimistic BtfSetActiveRelay makes the | ||
| 50 | // published descriptor flap to relays the pool may not be reachable at. | ||
| 51 | extern bool fBtfRelayPinned; | ||
| 52 | // Basic sanity check on a "host:port" relay address (numeric port 1..65535). | ||
| 53 | bool LooksLikeRelay(const std::string& r); | ||
| 46 | // Every relay to try: curated seeds + relays discovered from Nostr announcements. | 54 | // Every relay to try: curated seeds + relays discovered from Nostr announcements. |
| 47 | std::vector<std::string> BtfAllRelays(); | 55 | std::vector<std::string> BtfAllRelays(); |
| 48 | 56 | ||