upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/headless.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/headless.cpp')
-rw-r--r--src/headless.cpp177
1 files changed, 177 insertions, 0 deletions
diff --git a/src/headless.cpp b/src/headless.cpp
new file mode 100644
index 0000000..94597f1
--- /dev/null
+++ b/src/headless.cpp
@@ -0,0 +1,177 @@
1// Copyright (c) 2026 Bitflash developers
2// Distributed under the MIT/X11 software license.
3//
4// Headless entry point for the Linux node/miner `bitflash-node`. Replaces the
5// wxWidgets GUI (ui.cpp) with a command-line daemon: it loads the chain and
6// wallet, starts the P2P/Nostr node (which auto-discovers .btf peers through
7// the rendezvous relay), and optionally mines with RandomX. No GUI, no wx.
8//
9// ./bitflash-node -gen mine with the CPU, auto-connect peers
10// ./bitflash-node -gen -datadir=/path use a specific data directory
11// ./bitflash-node -rvrelay=host:port use a specific rendezvous relay
12// ./bitflash-node -connectbtf=<addr>.btf pin a specific peer
13// ./bitflash-node -solomine -gen mine without waiting for a peer (test)
14
15#include "headers.h"
16#include <csignal>
17
18// ---- UI hooks the core references, provided here as headless equivalents ----
19
20// The core asks the GUI to repaint on new blocks/transactions; nothing to do.
21void MainFrameRepaint() {}
22
23// Wallet address book -- defined in ui.cpp on Windows; the core (db.cpp) reads
24// and writes it, so the headless build must provide the definition.
25map<string, string> mapAddressBook;
26
27// Format a unix timestamp for transaction listings (ui.cpp used wxDateTime).
28string DateTimeStr(int64 nTime)
29{
30 time_t t = (time_t)nTime;
31 struct tm* ptm = localtime(&t);
32 if (!ptm)
33 return "";
34 char buf[64];
35 strftime(buf, sizeof(buf), "%m/%d/%y %H:%M", ptm);
36 return string(buf);
37}
38
39
40// ---- argument parsing (mirrors ui.cpp's ParseParameters) ----
41static map<string, string> ParseParameters(int argc, char* argv[])
42{
43 map<string, string> mapArgs;
44 for (int i = 0; i < argc; i++)
45 {
46 string s = argv[i];
47 string val;
48 size_t eq = s.find('=');
49 if (eq != string::npos)
50 {
51 val = s.substr(eq + 1);
52 s = s.substr(0, eq);
53 }
54 for (size_t j = 0; j < s.size(); j++)
55 s[j] = (char)tolower((unsigned char)s[j]);
56 if (!s.empty() && s[0] == '-')
57 s[0] = '/';
58 mapArgs[s] = val;
59 }
60 return mapArgs;
61}
62
63
64static void HandleSignal(int)
65{
66 fShutdown = true;
67}
68
69
70int main(int argc, char* argv[])
71{
72 map<string, string> mapArgs = ParseParameters(argc, argv);
73
74 if (mapArgs.count("/?") || mapArgs.count("/help") || mapArgs.count("/h"))
75 {
76 fprintf(stderr,
77 "Bitflash headless node\n"
78 "Usage: %s [options]\n"
79 " -gen generate coins (mine with RandomX)\n"
80 " -datadir=<dir> data directory (default ~/.bitflash)\n"
81 " -port=<n> P2P listen port (default 8433)\n"
82 " -rvrelay=host:port rendezvous meeting relay (has a seed default)\n"
83 " -connectbtf=<a>.btf keep a connection to a specific .btf peer\n"
84 " -solomine mine without waiting for a peer (testing)\n"
85 " -debug verbose logging\n",
86 argv[0]);
87 return 0;
88 }
89
90 // Parameters (same set the Windows UI honors)
91 if (mapArgs.count("/datadir"))
92 strSetDataDir = mapArgs["/datadir"];
93 if (mapArgs.count("/port"))
94 nListenPort = htons(atoi(mapArgs["/port"].c_str()));
95 if (mapArgs.count("/proxy"))
96 addrProxy = CAddress(mapArgs["/proxy"].c_str());
97 if (mapArgs.count("/rvrelay"))
98 strBtfMeetingRelay = mapArgs["/rvrelay"];
99 if (mapArgs.count("/connectbtf"))
100 strBtfConnect = mapArgs["/connectbtf"];
101 if (mapArgs.count("/debug"))
102 fDebug = true;
103 if (mapArgs.count("/solomine"))
104 fSoloMineTest = true;
105 if (mapArgs.count("/gen"))
106 fGenerateBitcoins = mapArgs["/gen"].empty() ? true : atoi(mapArgs["/gen"].c_str());
107
108 printf("\nBitflash headless node starting\n");
109
110 //
111 // Load data files (mirror of the Windows OnInit2 startup)
112 //
113 printf("Loading addresses...\n");
114 if (!LoadAddresses())
115 printf("Error loading addr.dat\n");
116
117 printf("Loading block index...\n");
118 if (!LoadBlockIndex())
119 {
120 printf("Error loading blkindex.dat\n");
121 return 1;
122 }
123
124 printf("Loading wallet...\n");
125 if (!LoadWallet())
126 {
127 printf("Error loading wallet.dat\n");
128 return 1;
129 }
130
131 printf("Done loading. nBestHeight=%d, wallet keys=%d\n",
132 nBestHeight, (int)mapKeys.size());
133
134 // Rebroadcast any wallet transactions not yet in a block
135 ReacceptWalletTransactions();
136
137 //
138 // Start the node (P2P + Nostr discovery + .btf rendezvous)
139 //
140 string strErrors;
141 if (!StartNode(strErrors))
142 {
143 printf("StartNode failed: %s\n", strErrors.c_str());
144 return 1;
145 }
146
147 //
148 // Start mining if requested
149 //
150 if (fGenerateBitcoins)
151 {
152 if (_beginthread(ThreadBitcoinMiner, 0, NULL) == (uintptr_t)-1)
153 printf("Error: _beginthread(ThreadBitcoinMiner) failed\n");
154 else
155 printf("Mining enabled (RandomX, CPU)\n");
156 }
157 else
158 {
159 printf("Mining disabled (pass -gen to mine)\n");
160 }
161
162 //
163 // Run until interrupted
164 //
165 signal(SIGINT, HandleSignal);
166 signal(SIGTERM, HandleSignal);
167 printf("Bitflash node running. Press Ctrl-C to stop.\n");
168
169 while (!fShutdown)
170 Sleep(500);
171
172 printf("Shutting down...\n");
173 StopNode();
174 Sleep(500);
175 printf("Bitflash node stopped.\n");
176 return 0;
177}