diff options
Diffstat (limited to 'src/rpc.cpp')
| -rw-r--r-- | src/rpc.cpp | 76 |
1 files changed, 63 insertions, 13 deletions
diff --git a/src/rpc.cpp b/src/rpc.cpp index 6531fe8..bd5fd8b 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp | |||
| @@ -4949,13 +4949,19 @@ static void AcceptOneFn(void* arg) | |||
| 4949 | std::string host = relay.substr(0, colon); | 4949 | std::string host = relay.substr(0, colon); |
| 4950 | int port = atoi(relay.substr(colon + 1).c_str()); | 4950 | int port = atoi(relay.substr(colon + 1).c_str()); |
| 4951 | 4951 | ||
| 4952 | LogPrint("pool", "[pool] accept thread started for relay %s\n", relay.c_str()); | 4952 | LogPrint("pool", "[pool] accept thread started for relay %s%s\n", relay.c_str(), |
| 4953 | fBtfRelayPinned ? " (/rvrelay pin)" : ""); | ||
| 4954 | |||
| 4955 | // Registration health for this relay. A pin has no fallback, so a pin that | ||
| 4956 | // never registers means the pool is simply unreachable -- and that has to | ||
| 4957 | // be loud. The 2026-07-30 incident went unnoticed because this loop logged | ||
| 4958 | // failures at one flat line and success not at all, so "which relay is this | ||
| 4959 | // pool actually registered at" could not be answered from the log. | ||
| 4960 | int nConsecFail = 0; | ||
| 4961 | int64 nFirstFail = 0; | ||
| 4962 | bool fEverRegistered = false; | ||
| 4953 | 4963 | ||
| 4954 | while (!fShutdown && gPoolRunning) { | 4964 | while (!fShutdown && gPoolRunning) { |
| 4955 | // Advertise this relay as the pool's meeting node BEFORE registering, | ||
| 4956 | // so that miners which resolve our descriptor find a relay where the | ||
| 4957 | // pool (not the node's peer-accept) holds the registration. | ||
| 4958 | BtfSetActiveRelay(relay); | ||
| 4959 | // Returns as soon as the relay lists us -- registered, not yet paired. | 4965 | // Returns as soon as the relay lists us -- registered, not yet paired. |
| 4960 | btf::RvSocket rv = btf::RvServiceRegister(host.c_str(), (unsigned short)port, pk); | 4966 | btf::RvSocket rv = btf::RvServiceRegister(host.c_str(), (unsigned short)port, pk); |
| 4961 | 4967 | ||
| @@ -4964,12 +4970,36 @@ static void AcceptOneFn(void* arg) | |||
| 4964 | break; | 4970 | break; |
| 4965 | } | 4971 | } |
| 4966 | if (rv == btf::RV_INVALID) { | 4972 | if (rv == btf::RV_INVALID) { |
| 4967 | LogPrint("pool", "[pool] relay %s: RvServiceRegister failed" | 4973 | nConsecFail++; |
| 4968 | " -- backing off 30s before retry\n", relay.c_str()); | 4974 | if (nFirstFail == 0) nFirstFail = GetTime(); |
| 4975 | LogPrint("pool", "[pool] relay %s: registration failed (attempt %d," | ||
| 4976 | " failing for %llds) -- backing off 30s before retry\n", | ||
| 4977 | relay.c_str(), nConsecFail, (long long)(GetTime() - nFirstFail)); | ||
| 4978 | if (fBtfRelayPinned && (nConsecFail == 3 || nConsecFail % 10 == 0)) | ||
| 4979 | LogPrint("pool", "[pool] WARNING: pinned relay %s refused registration" | ||
| 4980 | " %d times running (%llds); /rvrelay leaves no fallback, so" | ||
| 4981 | " miners cannot reach this pool%s\n", | ||
| 4982 | relay.c_str(), nConsecFail, (long long)(GetTime() - nFirstFail), | ||
| 4983 | fEverRegistered ? "" : " -- it has never registered once"); | ||
| 4969 | for (int i = 0; i < 30 && !fShutdown && gPoolRunning; i++) Sleep(1000); | 4984 | for (int i = 0; i < 30 && !fShutdown && gPoolRunning; i++) Sleep(1000); |
| 4970 | continue; | 4985 | continue; |
| 4971 | } | 4986 | } |
| 4972 | 4987 | ||
| 4988 | // Advertise THIS relay only now. Setting it before the call published a | ||
| 4989 | // meeting node we were not yet listed at, so a miner resolving the | ||
| 4990 | // descriptor inside that window burned its dial on a relay holding no | ||
| 4991 | // registration for us. net.cpp's peer-accept has always ordered it this | ||
| 4992 | // way round; the pool had not. | ||
| 4993 | BtfSetActiveRelay(relay); | ||
| 4994 | if (!fEverRegistered || nConsecFail > 0) | ||
| 4995 | LogPrint("pool", "[pool] registered at relay %s%s%s -- advertising it as" | ||
| 4996 | " the pool's meeting node\n", relay.c_str(), | ||
| 4997 | fBtfRelayPinned ? " (/rvrelay pin)" : "", | ||
| 4998 | nConsecFail > 0 ? ", recovered" : ""); | ||
| 4999 | fEverRegistered = true; | ||
| 5000 | nConsecFail = 0; | ||
| 5001 | nFirstFail = 0; | ||
| 5002 | |||
| 4973 | // Block for a miner to actually arrive. RvServiceRegister used to do | 5003 | // Block for a miner to actually arrive. RvServiceRegister used to do |
| 4974 | // this itself and returned with the relay's 0x01 pairing byte already | 5004 | // this itself and returned with the relay's 0x01 pairing byte already |
| 4975 | // consumed; it no longer does. Without waiting here, BtfServiceWrap | 5005 | // consumed; it no longer does. Without waiting here, BtfServiceWrap |
| @@ -5024,9 +5054,21 @@ static void AcceptLoopFn(void*) | |||
| 5024 | LogPrint("pool", "[pool] .btf identity ready after %ds\n", waitSecs * 2); | 5054 | LogPrint("pool", "[pool] .btf identity ready after %ds\n", waitSecs * 2); |
| 5025 | 5055 | ||
| 5026 | std::set<std::string> spawned; // relays we've already started a thread for | 5056 | std::set<std::string> spawned; // relays we've already started a thread for |
| 5057 | std::set<std::string> skipped; // discovered relays the pin excluded, logged once each | ||
| 5027 | 5058 | ||
| 5028 | while (!fShutdown && gPoolRunning) { | 5059 | while (!fShutdown && gPoolRunning) { |
| 5060 | // BtfAllRelays() already honours the pin: with /rvrelay set it returns | ||
| 5061 | // vBtfMeetingRelays alone, so no thread is ever spawned for a | ||
| 5062 | // discovered relay. Name the ones it drops -- a pool registering at a | ||
| 5063 | // stranger's relay is exactly the thing that should not be silent. | ||
| 5029 | vector<string> relays = BtfAllRelays(); | 5064 | vector<string> relays = BtfAllRelays(); |
| 5065 | if (fBtfRelayPinned) { | ||
| 5066 | for (const string& r : BtfDiscoveredRelays()) | ||
| 5067 | if (std::find(relays.begin(), relays.end(), r) == relays.end() && | ||
| 5068 | skipped.insert(r).second) | ||
| 5069 | LogPrint("pool", "[pool] not registering at discovered relay %s" | ||
| 5070 | " -- /rvrelay pins the relay list\n", r.c_str()); | ||
| 5071 | } | ||
| 5030 | if (relays.empty()) { | 5072 | if (relays.empty()) { |
| 5031 | LogPrint("pool", "[pool] no relays available -- miners cannot connect yet\n"); | 5073 | LogPrint("pool", "[pool] no relays available -- miners cannot connect yet\n"); |
| 5032 | } else { | 5074 | } else { |
| @@ -5042,8 +5084,9 @@ static void AcceptLoopFn(void*) | |||
| 5042 | relay.c_str()); | 5084 | relay.c_str()); |
| 5043 | } else { | 5085 | } else { |
| 5044 | spawned.insert(relay); | 5086 | spawned.insert(relay); |
| 5045 | LogPrint("pool", "[pool] accept thread spawned for relay %s" | 5087 | LogPrint("pool", "[pool] accept thread spawned for relay %s%s" |
| 5046 | " (%zu total)\n", relay.c_str(), spawned.size()); | 5088 | " (%zu total)\n", relay.c_str(), |
| 5089 | fBtfRelayPinned ? " (/rvrelay pin)" : "", spawned.size()); | ||
| 5047 | } | 5090 | } |
| 5048 | } | 5091 | } |
| 5049 | } | 5092 | } |
| @@ -5079,10 +5122,17 @@ void ThreadRPCServer(void*) | |||
| 5079 | // armed for its one wallet probe before it is allowed to send. | 5122 | // armed for its one wallet probe before it is allowed to send. |
| 5080 | ReconcilePayouts(); | 5123 | ReconcilePayouts(); |
| 5081 | 5124 | ||
| 5082 | _beginthread(AcceptLoopFn, 0, NULL); | 5125 | // _beginthread cannot throw (it reports -1), but an unchecked failure |
| 5083 | _beginthread(LocalAcceptFn, 0, NULL); | 5126 | // leaves the pool running deaf: nobody accepts, announces, or pays, and |
| 5084 | _beginthread(ThreadBtfPoolAnnouncer, 0, NULL); | 5127 | // nothing in the log says why. |
| 5085 | _beginthread(PayoutThreadFn, 0, NULL); | 5128 | if (_beginthread(AcceptLoopFn, 0, NULL) == (uintptr_t)-1) |
| 5129 | LogPrint("pool", "[pool] FATAL: accept loop thread failed to spawn -- miners cannot connect\n"); | ||
| 5130 | if (_beginthread(LocalAcceptFn, 0, NULL) == (uintptr_t)-1) | ||
| 5131 | LogPrint("pool", "[pool] local accept thread failed to spawn\n"); | ||
| 5132 | if (_beginthread(ThreadBtfPoolAnnouncer, 0, NULL) == (uintptr_t)-1) | ||
| 5133 | LogPrint("pool", "[pool] announcer thread failed to spawn -- pool will not be advertised\n"); | ||
| 5134 | if (_beginthread(PayoutThreadFn, 0, NULL) == (uintptr_t)-1) | ||
| 5135 | LogPrint("pool", "[pool] FATAL: payout thread failed to spawn -- no one gets paid\n"); | ||
| 5086 | 5136 | ||
| 5087 | PoolEventLoop(); // blocks until gPoolRunning = false or fShutdown | 5137 | PoolEventLoop(); // blocks until gPoolRunning = false or fShutdown |
| 5088 | 5138 | ||