diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp index c0a8825..0414714 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
| @@ -3739,6 +3739,33 @@ static bool PoolParticipantMiner() | |||
| 3739 | } | 3739 | } |
| 3740 | LogPrint("worker", "[worker] pool resolved to meeting node %s\n", meetingHostPort.c_str()); | 3740 | LogPrint("worker", "[worker] pool resolved to meeting node %s\n", meetingHostPort.c_str()); |
| 3741 | 3741 | ||
| 3742 | // The descriptor names ONE meeting node, but the pool parks a | ||
| 3743 | // registration at every relay it knows (one accept thread per relay, | ||
| 3744 | // rpc.cpp:AcceptOneFn), so any seed relay can pair us. Insisting on the | ||
| 3745 | // advertised entry forever turns one bad path into a miner that idles | ||
| 3746 | // indefinitely while a working path exists (issue #17); after a few | ||
| 3747 | // consecutive tunnel failures, rotate the seed relays into the attempts | ||
| 3748 | // too. Only ONE participant session runs (StartMinerThreads), so these | ||
| 3749 | // statics are single-threaded. | ||
| 3750 | static const int TUNNEL_FAILOVER_AFTER = 3; | ||
| 3751 | static int nTunnelFails = 0; // consecutive tunnel failures, this pool | ||
| 3752 | static size_t iFailoverRelay = 0; // rotation cursor over vBtfMeetingRelays | ||
| 3753 | static std::string strFailPool; // pool the counters belong to | ||
| 3754 | if (strFailPool != strParticipantPool) { | ||
| 3755 | strFailPool = strParticipantPool; | ||
| 3756 | nTunnelFails = 0; | ||
| 3757 | iFailoverRelay = 0; | ||
| 3758 | } | ||
| 3759 | if (nTunnelFails >= TUNNEL_FAILOVER_AFTER && !vBtfMeetingRelays.empty()) { | ||
| 3760 | std::string alt = vBtfMeetingRelays[iFailoverRelay++ % vBtfMeetingRelays.size()]; | ||
| 3761 | if (alt != meetingHostPort) { | ||
| 3762 | LogPrint("worker", "[worker] advertised meeting node %s failed %d" | ||
| 3763 | " times in a row -- trying seed relay %s instead\n", | ||
| 3764 | meetingHostPort.c_str(), nTunnelFails, alt.c_str()); | ||
| 3765 | meetingHostPort = alt; | ||
| 3766 | } | ||
| 3767 | } | ||
| 3768 | |||
| 3742 | size_t colon = meetingHostPort.rfind(':'); | 3769 | size_t colon = meetingHostPort.rfind(':'); |
| 3743 | if (colon == std::string::npos) { | 3770 | if (colon == std::string::npos) { |
| 3744 | LogPrint("worker", "[worker] bad meeting node format '%s'\n", meetingHostPort.c_str()); | 3771 | LogPrint("worker", "[worker] bad meeting node format '%s'\n", meetingHostPort.c_str()); |
| @@ -3762,12 +3789,14 @@ static bool PoolParticipantMiner() | |||
| 3762 | s = btf::BtfClientTunnel(host.c_str(), (unsigned short)port, | 3789 | s = btf::BtfClientTunnel(host.c_str(), (unsigned short)port, |
| 3763 | target_pubkey, service_enc_pub, &tunnelFail); | 3790 | target_pubkey, service_enc_pub, &tunnelFail); |
| 3764 | if (s == INVALID_SOCKET) { | 3791 | if (s == INVALID_SOCKET) { |
| 3792 | nTunnelFails++; | ||
| 3765 | LogPrint("worker", "[worker] tunnel connect FAILED via %s: %s\n", | 3793 | LogPrint("worker", "[worker] tunnel connect FAILED via %s: %s\n", |
| 3766 | meetingHostPort.c_str(), btf::TunnelFailText(tunnelFail)); | 3794 | meetingHostPort.c_str(), btf::TunnelFailText(tunnelFail)); |
| 3767 | SetParticipantMiningStatus(std::string("tunnel connect failed: ") | 3795 | SetParticipantMiningStatus(std::string("tunnel connect failed: ") |
| 3768 | + btf::TunnelFailText(tunnelFail)); | 3796 | + btf::TunnelFailText(tunnelFail)); |
| 3769 | return false; | 3797 | return false; |
| 3770 | } | 3798 | } |
| 3799 | nTunnelFails = 0; | ||
| 3771 | LogPrint("worker", "[worker] tunnel open via %s\n", meetingHostPort.c_str()); | 3800 | LogPrint("worker", "[worker] tunnel open via %s\n", meetingHostPort.c_str()); |
| 3772 | SetParticipantMiningStatus("tunnel open"); | 3801 | SetParticipantMiningStatus("tunnel open"); |
| 3773 | } | 3802 | } |