upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/main_gui.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main_gui.cpp')
-rw-r--r--src/main_gui.cpp107
1 files changed, 105 insertions, 2 deletions
diff --git a/src/main_gui.cpp b/src/main_gui.cpp
index bee4b95..e941522 100644
--- a/src/main_gui.cpp
+++ b/src/main_gui.cpp
@@ -1,6 +1,7 @@
1// Bitflash entry point -- starts node threads then runs GUI (or headless). 1// Bitflash entry point -- starts node threads then runs GUI (or headless).
2 2
3#include "headers_core.h" 3#include "headers_core.h"
4#include "proxy.h"
4#include "selftest.h" 5#include "selftest.h"
5#include "walletcmd.h" 6#include "walletcmd.h"
6#include <thread> // hardware_concurrency, to sanity-check /genproclimit 7#include <thread> // hardware_concurrency, to sanity-check /genproclimit
@@ -110,7 +111,8 @@ static void PrintUsage()
110 printf(" /debug\n"); 111 printf(" /debug\n");
111 printf(" /gen\n"); 112 printf(" /gen\n");
112 printf(" /nogui or /daemon\n"); 113 printf(" /nogui or /daemon\n");
113 printf(" /selftest=wallet-keypool, wallet-hd, wallet-format, wallet-crypto, or wallet-encrypt\n"); 114 printf(" /selftest=wallet-keypool, wallet-hd, wallet-format, wallet-crypto, wallet-encrypt,\n");
115 printf(" net-message, consensus-limits, pool-stratum, parse-money, or socks5-proxy\n");
114 printf("\n"); 116 printf("\n");
115 printf("Mining mode:\n"); 117 printf("Mining mode:\n");
116 printf(" /operator\n"); 118 printf(" /operator\n");
@@ -118,6 +120,8 @@ static void PrintUsage()
118 printf(" /payoutaddr=BTF_ADDRESS (participant: pay shares to this address, no wallet needed)\n"); 120 printf(" /payoutaddr=BTF_ADDRESS (participant: pay shares to this address, no wallet needed)\n");
119 printf(" /payoutfile=FILE (participant: rotate payout addresses from file)\n"); 121 printf(" /payoutfile=FILE (participant: rotate payout addresses from file)\n");
120 printf(" /hashthreads=N (participant: mining threads, default cores-1)\n"); 122 printf(" /hashthreads=N (participant: mining threads, default cores-1)\n");
123 printf(" /stratumbridge=POOL_BTF_ADDRESS\n");
124 printf(" /stratumbridgeport=N (default 3333; listen on 127.0.0.1)\n");
121 printf(" /solomine\n"); 125 printf(" /solomine\n");
122 printf(" /genproclimit=N (mining threads; 0 or absent = every core but one)\n"); 126 printf(" /genproclimit=N (mining threads; 0 or absent = every core but one)\n");
123 printf(" /checkblocks=N (blocks re-verified at startup, default 288, 0 = all)\n"); 127 printf(" /checkblocks=N (blocks re-verified at startup, default 288, 0 = all)\n");
@@ -126,6 +130,8 @@ static void PrintUsage()
126 printf(" /poolname=NAME\n"); 130 printf(" /poolname=NAME\n");
127 printf(" /poolfee=PCT\n"); 131 printf(" /poolfee=PCT\n");
128 printf(" /pooldashboard=URL (alias: /pooldash=URL)\n"); 132 printf(" /pooldashboard=URL (alias: /pooldash=URL)\n");
133 printf(" /poolstatusfile=PATH (write pool status JSON for dashboards)\n");
134 printf(" /poolroundsfile=PATH (write public pool round proofs JSON)\n");
129 printf("\n"); 135 printf("\n");
130 printf(".btf and rendezvous:\n"); 136 printf(".btf and rendezvous:\n");
131 printf(" /connectbtf=PEER_BTF_ADDRESS\n"); 137 printf(" /connectbtf=PEER_BTF_ADDRESS\n");
@@ -134,6 +140,8 @@ static void PrintUsage()
134 printf("\n"); 140 printf("\n");
135 printf("Network:\n"); 141 printf("Network:\n");
136 printf(" /port=N (P2P listen port, default 8433)\n"); 142 printf(" /port=N (P2P listen port, default 8433)\n");
143 printf(" /socks=HOST:PORT (SOCKS5 proxy for outbound Nostr and .btf relay dials)\n");
144 printf(" /tor[=HOST:PORT] (Tor mode; default SOCKS5 proxy is 127.0.0.1:9050)\n");
137 printf(" /btfseed=ADDRESS:ENCHEX (extra bootstrap peer, repeatable)\n"); 145 printf(" /btfseed=ADDRESS:ENCHEX (extra bootstrap peer, repeatable)\n");
138 printf("\n"); 146 printf("\n");
139 printf("Wallet:\n"); 147 printf("Wallet:\n");
@@ -240,6 +248,22 @@ static void ParseStartupArguments(int argc, char* argv[])
240 if (!hashThreads.empty()) 248 if (!hashThreads.empty())
241 nHashThreads = atoi(hashThreads.c_str()); 249 nHashThreads = atoi(hashThreads.c_str());
242 250
251 if (arg(argc,argv,"/stratumbridge") || arg(argc,argv,"-stratumbridge"))
252 {
253 fStratumBridge = true;
254 string bridgePool = argval2(argc, argv, "/stratumbridge", "-stratumbridge");
255 if (!bridgePool.empty())
256 strParticipantPool = bridgePool;
257 }
258
259 string bridgePort = argval2(argc, argv, "/stratumbridgeport", "-stratumbridgeport");
260 if (!bridgePort.empty())
261 {
262 int nPort = atoi(bridgePort.c_str());
263 if (nPort > 0 && nPort <= 65535)
264 nStratumBridgePort = nPort;
265 }
266
243 string poolName = argval2(argc, argv, "/poolname", "-poolname"); 267 string poolName = argval2(argc, argv, "/poolname", "-poolname");
244 if (!poolName.empty()) 268 if (!poolName.empty())
245 strPoolName = poolName; 269 strPoolName = poolName;
@@ -260,6 +284,14 @@ static void ParseStartupArguments(int argc, char* argv[])
260 if (!poolFee.empty()) 284 if (!poolFee.empty())
261 dPoolFeePercent = atof(poolFee.c_str()); 285 dPoolFeePercent = atof(poolFee.c_str());
262 286
287 string poolStatusFile = argval2(argc, argv, "/poolstatusfile", "-poolstatusfile");
288 if (!poolStatusFile.empty())
289 strPoolStatusFile = poolStatusFile;
290
291 string poolRoundsFile = argval2(argc, argv, "/poolroundsfile", "-poolroundsfile");
292 if (!poolRoundsFile.empty())
293 strPoolRoundsFile = poolRoundsFile;
294
263 string btfConnect = argval2(argc, argv, "/connectbtf", "-connectbtf"); 295 string btfConnect = argval2(argc, argv, "/connectbtf", "-connectbtf");
264 if (!btfConnect.empty()) 296 if (!btfConnect.empty())
265 strBtfConnect = btfConnect; 297 strBtfConnect = btfConnect;
@@ -287,6 +319,36 @@ static void ParseStartupArguments(int argc, char* argv[])
287 if (!announceRelay.empty()) 319 if (!announceRelay.empty())
288 strBtfAnnounceRelay = announceRelay; 320 strBtfAnnounceRelay = announceRelay;
289 321
322 bool fTorMode = arg(argc, argv, "/tor") || arg(argc, argv, "-tor");
323 if (fTorMode)
324 {
325 string socksProxy = argval2(argc, argv, "/socks", "-socks");
326 if (!socksProxy.empty())
327 fprintf(stderr, "Warning: /tor takes precedence over /socks=%s\n",
328 socksProxy.c_str());
329
330 string torProxy = argval2(argc, argv, "/tor", "-tor");
331 string err;
332 if (!BtfEnableTorProxy(torProxy, err))
333 fprintf(stderr, "Ignoring /tor=%s: %s\n", torProxy.c_str(), err.c_str());
334 else
335 fprintf(stderr, "Tor mode enabled through SOCKS5 proxy %s\n",
336 BtfSocks5ProxyName().c_str());
337 }
338 else
339 {
340 string socksProxy = argval2(argc, argv, "/socks", "-socks");
341 if (!socksProxy.empty())
342 {
343 string err;
344 if (!BtfSetSocks5Proxy(socksProxy, err))
345 fprintf(stderr, "Ignoring /socks=%s: %s\n", socksProxy.c_str(), err.c_str());
346 else
347 fprintf(stderr, "SOCKS5 proxy enabled for outbound discovery/relay dials: %s\n",
348 BtfSocks5ProxyName().c_str());
349 }
350 }
351
290 // /btfseed=ADDRESS:ENCHEX -- extra bootstrap peers, repeatable. Useful for 352 // /btfseed=ADDRESS:ENCHEX -- extra bootstrap peers, repeatable. Useful for
291 // testing the seed path and for private networks that ship no compiled list. 353 // testing the seed path and for private networks that ship no compiled list.
292 for (int i = 1; i < argc; i++) 354 for (int i = 1; i < argc; i++)
@@ -368,6 +430,36 @@ static void FatalStartupError(bool fHeadless, const string& strWhat, const strin
368#endif 430#endif
369} 431}
370 432
433#ifdef _WIN32
434// Windows equivalent of the SIGINT/SIGTERM handler the headless loop installs on
435// POSIX. Without it a headless node on Windows had no way to reach the clean
436// StopNode()+DBFlush() path: Ctrl-C, closing the console window, a service stop
437// and OS shutdown all killed it mid-write, and a wallet.dat left unflushed by
438// Berkeley DB will not reopen. For CLOSE/LOGOFF/SHUTDOWN the OS terminates us
439// shortly after the handler returns, so we set fShutdown and then block until the
440// main loop signals the flush is done -- returning any sooner throws the flush
441// away, which is the whole bug. (A `taskkill /F` is still an uncatchable hard
442// kill; nothing can help there, and nothing should pretend to.)
443static volatile bool g_fHeadlessShutdownDone = false;
444static BOOL WINAPI HeadlessConsoleCtrlHandler(DWORD dwCtrlType)
445{
446 switch (dwCtrlType)
447 {
448 case CTRL_C_EVENT:
449 case CTRL_BREAK_EVENT:
450 case CTRL_CLOSE_EVENT:
451 case CTRL_LOGOFF_EVENT:
452 case CTRL_SHUTDOWN_EVENT:
453 fShutdown = true;
454 while (!g_fHeadlessShutdownDone)
455 Sleep(50);
456 return TRUE;
457 default:
458 return FALSE;
459 }
460}
461#endif
462
371int main(int argc, char* argv[]) 463int main(int argc, char* argv[])
372{ 464{
373 if (arg(argc,argv,"/help") || arg(argc,argv,"-help") || 465 if (arg(argc,argv,"/help") || arg(argc,argv,"-help") ||
@@ -676,6 +768,10 @@ int main(int argc, char* argv[])
676 if (_beginthread(ThreadRPCServer, 0, NULL) == (uintptr_t)-1) 768 if (_beginthread(ThreadRPCServer, 0, NULL) == (uintptr_t)-1)
677 printf("Error: _beginthread(ThreadRPCServer) failed\n"); 769 printf("Error: _beginthread(ThreadRPCServer) failed\n");
678 } 770 }
771 if (fStratumBridge) {
772 if (_beginthread(ThreadStratumBridge, 0, NULL) == (uintptr_t)-1)
773 printf("Error: _beginthread(ThreadStratumBridge) failed\n");
774 }
679 if (fGenerateBitcoins) 775 if (fGenerateBitcoins)
680 StartMinerThreads(); 776 StartMinerThreads();
681 777
@@ -688,7 +784,9 @@ int main(int argc, char* argv[])
688#endif 784#endif
689 785
690 if (fHeadless) { 786 if (fHeadless) {
691#ifndef _WIN32 787#ifdef _WIN32
788 SetConsoleCtrlHandler(HeadlessConsoleCtrlHandler, TRUE);
789#else
692 auto sig=[](int){fShutdown=true;}; 790 auto sig=[](int){fShutdown=true;};
693 signal(SIGINT,sig); signal(SIGTERM,sig); 791 signal(SIGINT,sig); signal(SIGTERM,sig);
694#endif 792#endif
@@ -700,6 +798,11 @@ int main(int argc, char* argv[])
700 // called here, which is why a wallet.dat copied elsewhere would not 798 // called here, which is why a wallet.dat copied elsewhere would not
701 // open -- issue #40. Not optional. 799 // open -- issue #40. Not optional.
702 DBFlush(true); 800 DBFlush(true);
801#ifdef _WIN32
802 // wallet.dat is safely flushed and closed now; let a pending console
803 // control handler (CLOSE/LOGOFF/SHUTDOWN) return so the OS can finish.
804 g_fHeadlessShutdownDone = true;
805#endif
703 return 0; 806 return 0;
704 } 807 }
705 808