Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2020 The Bitcoin Core developers
3 : // Distributed under the MIT software license, see the accompanying
4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 :
6 : #if defined(HAVE_CONFIG_H)
7 : #include <config/bitcoin-config.h>
8 : #endif
9 :
10 : #include <init.h>
11 :
12 : #include <addrman.h>
13 : #include <amount.h>
14 : #include <banman.h>
15 : #include <blockfilter.h>
16 : #include <chain.h>
17 : #include <chainparams.h>
18 : #include <compat/sanity.h>
19 : #include <consensus/validation.h>
20 : #include <fs.h>
21 : #include <hash.h>
22 : #include <httprpc.h>
23 : #include <httpserver.h>
24 : #include <index/blockfilterindex.h>
25 : #include <index/txindex.h>
26 : #include <interfaces/chain.h>
27 : #include <interfaces/node.h>
28 : #include <key.h>
29 : #include <miner.h>
30 : #include <net.h>
31 : #include <net_permissions.h>
32 : #include <net_processing.h>
33 : #include <netbase.h>
34 : #include <node/context.h>
35 : #include <node/ui_interface.h>
36 : #include <policy/feerate.h>
37 : #include <policy/fees.h>
38 : #include <policy/policy.h>
39 : #include <policy/settings.h>
40 : #include <rpc/blockchain.h>
41 : #include <rpc/register.h>
42 : #include <rpc/server.h>
43 : #include <rpc/util.h>
44 : #include <scheduler.h>
45 : #include <script/sigcache.h>
46 : #include <script/standard.h>
47 : #include <shutdown.h>
48 : #include <sync.h>
49 : #include <timedata.h>
50 : #include <torcontrol.h>
51 : #include <txdb.h>
52 : #include <txmempool.h>
53 : #include <util/asmap.h>
54 : #include <util/check.h>
55 : #include <util/moneystr.h>
56 : #include <util/string.h>
57 : #include <util/system.h>
58 : #include <util/threadnames.h>
59 : #include <util/translation.h>
60 : #include <validation.h>
61 :
62 : #include <validationinterface.h>
63 : #include <walletinitinterface.h>
64 :
65 : #include <functional>
66 : #include <set>
67 : #include <stdint.h>
68 : #include <stdio.h>
69 :
70 : #ifndef WIN32
71 : #include <attributes.h>
72 : #include <cerrno>
73 : #include <signal.h>
74 : #include <sys/stat.h>
75 : #endif
76 :
77 : #include <boost/algorithm/string/replace.hpp>
78 : #include <boost/signals2/signal.hpp>
79 : #include <boost/thread/thread.hpp>
80 :
81 : #if ENABLE_ZMQ
82 : #include <zmq/zmqabstractnotifier.h>
83 : #include <zmq/zmqnotificationinterface.h>
84 : #include <zmq/zmqrpc.h>
85 : #endif
86 :
87 : static bool fFeeEstimatesInitialized = false;
88 : static const bool DEFAULT_PROXYRANDOMIZE = true;
89 : static const bool DEFAULT_REST_ENABLE = false;
90 : static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
91 :
92 : #ifdef WIN32
93 : // Win32 LevelDB doesn't use filedescriptors, and the ones used for
94 : // accessing block files don't count towards the fd_set size limit
95 : // anyway.
96 : #define MIN_CORE_FILEDESCRIPTORS 0
97 : #else
98 : #define MIN_CORE_FILEDESCRIPTORS 150
99 : #endif
100 :
101 : static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat";
102 :
103 : static const char* DEFAULT_ASMAP_FILENAME="ip_asn.map";
104 :
105 : /**
106 : * The PID file facilities.
107 : */
108 : static const char* BITCOIN_PID_FILENAME = "bitcoind.pid";
109 :
110 1058 : static fs::path GetPidFile(const ArgsManager& args)
111 : {
112 1058 : return AbsPathForConfigVal(fs::path(args.GetArg("-pid", BITCOIN_PID_FILENAME)));
113 0 : }
114 :
115 529 : NODISCARD static bool CreatePidFile(const ArgsManager& args)
116 : {
117 529 : fsbridge::ofstream file{GetPidFile(args)};
118 529 : if (file) {
119 : #ifdef WIN32
120 : tfm::format(file, "%d\n", GetCurrentProcessId());
121 : #else
122 529 : tfm::format(file, "%d\n", getpid());
123 : #endif
124 529 : return true;
125 : } else {
126 0 : return InitError(strprintf(_("Unable to create the PID file '%s': %s"), GetPidFile(args).string(), std::strerror(errno)));
127 : }
128 529 : }
129 :
130 : //////////////////////////////////////////////////////////////////////////////
131 : //
132 : // Shutdown
133 : //
134 :
135 : //
136 : // Thread management and startup/shutdown:
137 : //
138 : // The network-processing threads are all part of a thread group
139 : // created by AppInit() or the Qt main() function.
140 : //
141 : // A clean exit happens when StartShutdown() or the SIGTERM
142 : // signal handler sets ShutdownRequested(), which makes main thread's
143 : // WaitForShutdown() interrupts the thread group.
144 : // And then, WaitForShutdown() makes all other on-going threads
145 : // in the thread group join the main thread.
146 : // Shutdown() is then called to clean up database connections, and stop other
147 : // threads that should only be stopped after the main network-processing
148 : // threads have exited.
149 : //
150 : // Shutdown for Qt is very similar, only it uses a QTimer to detect
151 : // ShutdownRequested() getting set, and then does the normal Qt
152 : // shutdown thing.
153 : //
154 :
155 640 : static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
156 :
157 640 : static std::thread g_load_block;
158 :
159 640 : static boost::thread_group threadGroup;
160 :
161 529 : void Interrupt(NodeContext& node)
162 : {
163 529 : InterruptHTTPServer();
164 529 : InterruptHTTPRPC();
165 529 : InterruptRPC();
166 529 : InterruptREST();
167 529 : InterruptTorControl();
168 529 : InterruptMapPort();
169 529 : if (node.connman)
170 507 : node.connman->Interrupt();
171 529 : if (g_txindex) {
172 6 : g_txindex->Interrupt();
173 6 : }
174 533 : ForEachBlockFilterIndex([](BlockFilterIndex& index) { index.Interrupt(); });
175 529 : }
176 :
177 529 : void Shutdown(NodeContext& node)
178 : {
179 529 : static Mutex g_shutdown_mutex;
180 529 : TRY_LOCK(g_shutdown_mutex, lock_shutdown);
181 529 : if (!lock_shutdown) return;
182 529 : LogPrintf("%s: In progress...\n", __func__);
183 1058 : Assert(node.args);
184 :
185 : /// Note: Shutdown() must be able to handle cases in which initialization failed part of the way,
186 : /// for example if the data directory was found to be locked.
187 : /// Be sure that anything that writes files or flushes caches only does this if the respective
188 : /// module was initialized.
189 529 : util::ThreadRename("shutoff");
190 529 : if (node.mempool) node.mempool->AddTransactionsUpdated(1);
191 :
192 529 : StopHTTPRPC();
193 529 : StopREST();
194 529 : StopRPC();
195 529 : StopHTTPServer();
196 1053 : for (const auto& client : node.chain_clients) {
197 524 : client->flush();
198 : }
199 529 : StopMapPort();
200 :
201 : // Because these depend on each-other, we make sure that neither can be
202 : // using the other before destroying them.
203 529 : if (node.peerman) UnregisterValidationInterface(node.peerman.get());
204 : // Follow the lock order requirements:
205 : // * CheckForStaleTipAndEvictPeers locks cs_main before indirectly calling GetExtraOutboundCount
206 : // which locks cs_vNodes.
207 : // * ProcessMessage locks cs_main and g_cs_orphans before indirectly calling ForEachNode which
208 : // locks cs_vNodes.
209 : // * CConnman::Stop calls DeleteNode, which calls FinalizeNode, which locks cs_main and calls
210 : // EraseOrphansFor, which locks g_cs_orphans.
211 : //
212 : // Thus the implicit locking order requirement is: (1) cs_main, (2) g_cs_orphans, (3) cs_vNodes.
213 529 : if (node.connman) {
214 507 : node.connman->StopThreads();
215 507 : LOCK2(::cs_main, ::g_cs_orphans);
216 507 : node.connman->StopNodes();
217 507 : }
218 :
219 529 : StopTorControl();
220 :
221 : // After everything has been shut down, but before things get flushed, stop the
222 : // CScheduler/checkqueue, threadGroup and load block thread.
223 529 : if (node.scheduler) node.scheduler->stop();
224 529 : if (g_load_block.joinable()) g_load_block.join();
225 529 : threadGroup.interrupt_all();
226 529 : threadGroup.join_all();
227 :
228 : // After the threads that potentially access these pointers have been stopped,
229 : // destruct and reset all to nullptr.
230 529 : node.peerman.reset();
231 529 : node.connman.reset();
232 529 : node.banman.reset();
233 :
234 529 : if (node.mempool && node.mempool->IsLoaded() && node.args->GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
235 490 : DumpMempool(*node.mempool);
236 : }
237 :
238 529 : if (fFeeEstimatesInitialized)
239 : {
240 497 : ::feeEstimator.FlushUnconfirmed();
241 497 : fs::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME;
242 497 : CAutoFile est_fileout(fsbridge::fopen(est_path, "wb"), SER_DISK, CLIENT_VERSION);
243 497 : if (!est_fileout.IsNull())
244 497 : ::feeEstimator.Write(est_fileout);
245 : else
246 0 : LogPrintf("%s: Failed to write fee estimates to %s\n", __func__, est_path.string());
247 497 : fFeeEstimatesInitialized = false;
248 497 : }
249 :
250 : // FlushStateToDisk generates a ChainStateFlushed callback, which we should avoid missing
251 529 : if (node.chainman) {
252 507 : LOCK(cs_main);
253 1005 : for (CChainState* chainstate : node.chainman->GetAll()) {
254 498 : if (chainstate->CanFlushToDisk()) {
255 498 : chainstate->ForceFlushStateToDisk();
256 : }
257 : }
258 507 : }
259 :
260 : // After there are no more peers/RPC left to give us new data which may generate
261 : // CValidationInterface callbacks, flush them...
262 529 : GetMainSignals().FlushBackgroundCallbacks();
263 :
264 : // Stop and delete all indexes only after flushing background callbacks.
265 529 : if (g_txindex) {
266 6 : g_txindex->Stop();
267 6 : g_txindex.reset();
268 6 : }
269 533 : ForEachBlockFilterIndex([](BlockFilterIndex& index) { index.Stop(); });
270 529 : DestroyAllBlockFilterIndexes();
271 :
272 : // Any future callbacks will be dropped. This should absolutely be safe - if
273 : // missing a callback results in an unrecoverable situation, unclean shutdown
274 : // would too. The only reason to do the above flushes is to let the wallet catch
275 : // up with our current chain to avoid any strange pruning edge cases and make
276 : // next startup faster by avoiding rescan.
277 :
278 529 : if (node.chainman) {
279 507 : LOCK(cs_main);
280 1005 : for (CChainState* chainstate : node.chainman->GetAll()) {
281 498 : if (chainstate->CanFlushToDisk()) {
282 498 : chainstate->ForceFlushStateToDisk();
283 498 : chainstate->ResetCoinsViews();
284 498 : }
285 : }
286 507 : pblocktree.reset();
287 507 : }
288 1053 : for (const auto& client : node.chain_clients) {
289 524 : client->stop();
290 : }
291 :
292 : #if ENABLE_ZMQ
293 529 : if (g_zmq_notification_interface) {
294 2 : UnregisterValidationInterface(g_zmq_notification_interface);
295 2 : delete g_zmq_notification_interface;
296 2 : g_zmq_notification_interface = nullptr;
297 2 : }
298 : #endif
299 :
300 529 : node.chain_clients.clear();
301 529 : UnregisterAllValidationInterfaces();
302 529 : GetMainSignals().UnregisterBackgroundSignalScheduler();
303 529 : globalVerifyHandle.reset();
304 529 : ECC_Stop();
305 529 : node.mempool.reset();
306 529 : node.chainman = nullptr;
307 529 : node.scheduler.reset();
308 :
309 : try {
310 529 : if (!fs::remove(GetPidFile(*node.args))) {
311 0 : LogPrintf("%s: Unable to remove PID file: File does not exist\n", __func__);
312 : }
313 0 : } catch (const fs::filesystem_error& e) {
314 0 : LogPrintf("%s: Unable to remove PID file: %s\n", __func__, fsbridge::get_filesystem_error_message(e));
315 0 : }
316 :
317 529 : node.args = nullptr;
318 529 : LogPrintf("%s: done\n", __func__);
319 529 : }
320 :
321 : /**
322 : * Signal handlers are very limited in what they are allowed to do.
323 : * The execution context the handler is invoked in is not guaranteed,
324 : * so we restrict handler operations to just touching variables:
325 : */
326 : #ifndef WIN32
327 0 : static void HandleSIGTERM(int)
328 : {
329 0 : StartShutdown();
330 0 : }
331 :
332 0 : static void HandleSIGHUP(int)
333 : {
334 0 : LogInstance().m_reopen_file = true;
335 0 : }
336 : #else
337 : static BOOL WINAPI consoleCtrlHandler(DWORD dwCtrlType)
338 : {
339 : StartShutdown();
340 : Sleep(INFINITE);
341 : return true;
342 : }
343 : #endif
344 :
345 : #ifndef WIN32
346 1599 : static void registerSignalHandler(int signal, void(*handler)(int))
347 : {
348 1599 : struct sigaction sa;
349 1599 : sa.sa_handler = handler;
350 1599 : sigemptyset(&sa.sa_mask);
351 1599 : sa.sa_flags = 0;
352 1599 : sigaction(signal, &sa, nullptr);
353 1599 : }
354 : #endif
355 :
356 640 : static boost::signals2::connection rpc_notify_block_change_connection;
357 526 : static void OnRPCStarted()
358 : {
359 526 : rpc_notify_block_change_connection = uiInterface.NotifyBlockTip_connect(std::bind(RPCNotifyBlockChange, std::placeholders::_2));
360 526 : }
361 :
362 526 : static void OnRPCStopped()
363 : {
364 526 : rpc_notify_block_change_connection.disconnect();
365 526 : RPCNotifyBlockChange(nullptr);
366 526 : g_best_block_cv.notify_all();
367 526 : LogPrint(BCLog::RPC, "RPC stopped.\n");
368 526 : }
369 :
370 1010 : void SetupServerArgs(NodeContext& node)
371 : {
372 1010 : assert(!node.args);
373 1010 : node.args = &gArgs;
374 : ArgsManager& argsman = *node.args;
375 :
376 1010 : SetupHelpOptions(argsman);
377 1010 : argsman.AddArg("-help-debug", "Print help message with debugging options and exit", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); // server-only for now
378 :
379 1010 : const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN);
380 1010 : const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET);
381 1010 : const auto regtestBaseParams = CreateBaseChainParams(CBaseChainParams::REGTEST);
382 1010 : const auto defaultChainParams = CreateChainParams(CBaseChainParams::MAIN);
383 1010 : const auto testnetChainParams = CreateChainParams(CBaseChainParams::TESTNET);
384 1010 : const auto regtestChainParams = CreateChainParams(CBaseChainParams::REGTEST);
385 :
386 : // Hidden Options
387 8080 : std::vector<std::string> hidden_args = {
388 1010 : "-dbcrashratio", "-forcecompactdb",
389 : // GUI args. These will be overwritten by SetupUIArgs for the GUI
390 1010 : "-choosedatadir", "-lang=<lang>", "-min", "-resetguisettings", "-splash", "-uiplatform"};
391 :
392 1010 : argsman.AddArg("-version", "Print version and exit", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
393 : #if HAVE_SYSTEM
394 1010 : argsman.AddArg("-alertnotify=<cmd>", "Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
395 : #endif
396 1010 : argsman.AddArg("-assumevalid=<hex>", strprintf("If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s)", defaultChainParams->GetConsensus().defaultAssumeValid.GetHex(), testnetChainParams->GetConsensus().defaultAssumeValid.GetHex()), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
397 1010 : argsman.AddArg("-blocksdir=<dir>", "Specify directory to hold blocks subdirectory for *.dat files (default: <datadir>)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
398 : #if HAVE_SYSTEM
399 1010 : argsman.AddArg("-blocknotify=<cmd>", "Execute command when the best block changes (%s in cmd is replaced by block hash)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
400 : #endif
401 1010 : argsman.AddArg("-blockreconstructionextratxn=<n>", strprintf("Extra transactions to keep in memory for compact block reconstructions (default: %u)", DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
402 1010 : argsman.AddArg("-blocksonly", strprintf("Whether to reject transactions from network peers. Automatic broadcast and rebroadcast of any transactions from inbound peers is disabled, unless the peer has the 'forcerelay' permission. RPC transactions are not affected. (default: %u)", DEFAULT_BLOCKSONLY), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
403 1010 : argsman.AddArg("-conf=<file>", strprintf("Specify path to read-only configuration file. Relative paths will be prefixed by datadir location. (default: %s)", BITCOIN_CONF_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
404 1010 : argsman.AddArg("-datadir=<dir>", "Specify data directory", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
405 1010 : argsman.AddArg("-dbbatchsize", strprintf("Maximum database write batch size in bytes (default: %u)", nDefaultDbBatchSize), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::OPTIONS);
406 1010 : argsman.AddArg("-dbcache=<n>", strprintf("Maximum database cache size <n> MiB (%d to %d, default: %d). In addition, unused mempool memory is shared for this cache (see -maxmempool).", nMinDbCache, nMaxDbCache, nDefaultDbCache), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
407 1010 : argsman.AddArg("-debuglogfile=<file>", strprintf("Specify location of debug log file. Relative paths will be prefixed by a net-specific datadir location. (-nodebuglogfile to disable; default: %s)", DEFAULT_DEBUGLOGFILE), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
408 1010 : argsman.AddArg("-feefilter", strprintf("Tell other nodes to filter invs to us by our mempool min fee (default: %u)", DEFAULT_FEEFILTER), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::OPTIONS);
409 1010 : argsman.AddArg("-includeconf=<file>", "Specify additional configuration file, relative to the -datadir path (only useable from configuration file, not command line)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
410 1010 : argsman.AddArg("-loadblock=<file>", "Imports blocks from external file on startup", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
411 1010 : argsman.AddArg("-maxmempool=<n>", strprintf("Keep the transaction memory pool below <n> megabytes (default: %u)", DEFAULT_MAX_MEMPOOL_SIZE), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
412 1010 : argsman.AddArg("-maxorphantx=<n>", strprintf("Keep at most <n> unconnectable transactions in memory (default: %u)", DEFAULT_MAX_ORPHAN_TRANSACTIONS), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
413 1010 : argsman.AddArg("-mempoolexpiry=<n>", strprintf("Do not keep transactions in the mempool longer than <n> hours (default: %u)", DEFAULT_MEMPOOL_EXPIRY), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
414 1010 : argsman.AddArg("-minimumchainwork=<hex>", strprintf("Minimum work assumed to exist on a valid chain in hex (default: %s, testnet: %s)", defaultChainParams->GetConsensus().nMinimumChainWork.GetHex(), testnetChainParams->GetConsensus().nMinimumChainWork.GetHex()), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::OPTIONS);
415 1010 : argsman.AddArg("-par=<n>", strprintf("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)",
416 1010 : -GetNumCores(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
417 1010 : argsman.AddArg("-persistmempool", strprintf("Whether to save the mempool on shutdown and load on restart (default: %u)", DEFAULT_PERSIST_MEMPOOL), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
418 1010 : argsman.AddArg("-pid=<file>", strprintf("Specify pid file. Relative paths will be prefixed by a net-specific datadir location. (default: %s)", BITCOIN_PID_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
419 1010 : argsman.AddArg("-prune=<n>", strprintf("Reduce storage requirements by enabling pruning (deleting) of old blocks. This allows the pruneblockchain RPC to be called to delete specific blocks, and enables automatic pruning of old blocks if a target size in MiB is provided. This mode is incompatible with -txindex and -rescan. "
420 : "Warning: Reverting this setting requires re-downloading the entire blockchain. "
421 1010 : "(default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >=%u = automatically prune block files to stay under the specified target size in MiB)", MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
422 1010 : argsman.AddArg("-reindex", "Rebuild chain state and block index from the blk*.dat files on disk", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
423 1010 : argsman.AddArg("-reindex-chainstate", "Rebuild chain state from the currently indexed blocks. When in pruning mode or if blocks on disk might be corrupted, use full -reindex instead.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
424 1010 : argsman.AddArg("-settings=<file>", strprintf("Specify path to dynamic settings data file. Can be disabled with -nosettings. File is written at runtime and not meant to be edited by users (use %s instead for custom settings). Relative paths will be prefixed by datadir location. (default: %s)", BITCOIN_CONF_FILENAME, BITCOIN_SETTINGS_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
425 : #ifndef WIN32
426 1010 : argsman.AddArg("-sysperms", "Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
427 : #else
428 : hidden_args.emplace_back("-sysperms");
429 : #endif
430 1010 : argsman.AddArg("-txindex", strprintf("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)", DEFAULT_TXINDEX), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
431 2020 : argsman.AddArg("-blockfilterindex=<type>",
432 1010 : strprintf("Maintain an index of compact filters by block (default: %s, values: %s).", DEFAULT_BLOCKFILTERINDEX, ListBlockFilterTypes()) +
433 : " If <type> is not supplied or if <type> = 1, indexes for all known types are enabled.",
434 1010 : ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
435 :
436 1010 : argsman.AddArg("-addnode=<ip>", "Add a node to connect to and attempt to keep the connection open (see the `addnode` RPC command help for more info). This option can be specified multiple times to add multiple nodes.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
437 1010 : argsman.AddArg("-asmap=<file>", strprintf("Specify asn mapping used for bucketing of the peers (default: %s). Relative paths will be prefixed by the net-specific datadir location.", DEFAULT_ASMAP_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
438 1010 : argsman.AddArg("-bantime=<n>", strprintf("Default duration (in seconds) of manually configured bans (default: %u)", DEFAULT_MISBEHAVING_BANTIME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
439 1010 : argsman.AddArg("-bind=<addr>", "Bind to given address and always listen on it. Use [host]:port notation for IPv6", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
440 1010 : argsman.AddArg("-connect=<ip>", "Connect only to the specified node; -noconnect disables automatic connections (the rules for this peer are the same as for -addnode). This option can be specified multiple times to connect to multiple nodes.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
441 1010 : argsman.AddArg("-discover", "Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
442 1010 : argsman.AddArg("-dns", strprintf("Allow DNS lookups for -addnode, -seednode and -connect (default: %u)", DEFAULT_NAME_LOOKUP), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
443 1010 : argsman.AddArg("-dnsseed", "Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect used)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
444 1010 : argsman.AddArg("-externalip=<ip>", "Specify your own public address", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
445 1010 : argsman.AddArg("-forcednsseed", strprintf("Always query for peer addresses via DNS lookup (default: %u)", DEFAULT_FORCEDNSSEED), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
446 1010 : argsman.AddArg("-listen", "Accept connections from outside (default: 1 if no -proxy or -connect)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
447 1010 : argsman.AddArg("-listenonion", strprintf("Automatically create Tor onion service (default: %d)", DEFAULT_LISTEN_ONION), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
448 1010 : argsman.AddArg("-maxconnections=<n>", strprintf("Maintain at most <n> connections to peers (default: %u)", DEFAULT_MAX_PEER_CONNECTIONS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
449 1010 : argsman.AddArg("-maxreceivebuffer=<n>", strprintf("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXRECEIVEBUFFER), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
450 1010 : argsman.AddArg("-maxsendbuffer=<n>", strprintf("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXSENDBUFFER), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
451 1010 : argsman.AddArg("-maxtimeadjustment", strprintf("Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)", DEFAULT_MAX_TIME_ADJUSTMENT), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
452 1010 : argsman.AddArg("-maxuploadtarget=<n>", strprintf("Tries to keep outbound traffic under the given target (in MiB per 24h). Limit does not apply to peers with 'download' permission. 0 = no limit (default: %d)", DEFAULT_MAX_UPLOAD_TARGET), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
453 1010 : argsman.AddArg("-onion=<ip:port>", "Use separate SOCKS5 proxy to reach peers via Tor onion services, set -noonion to disable (default: -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
454 1010 : argsman.AddArg("-onlynet=<net>", "Make outgoing connections only through network <net> (ipv4, ipv6 or onion). Incoming connections are not affected by this option. This option can be specified multiple times to allow multiple networks.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
455 1010 : argsman.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
456 1010 : argsman.AddArg("-peerblockfilters", strprintf("Serve compact block filters to peers per BIP 157 (default: %u)", DEFAULT_PEERBLOCKFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
457 1010 : argsman.AddArg("-permitbaremultisig", strprintf("Relay non-P2SH multisig (default: %u)", DEFAULT_PERMIT_BAREMULTISIG), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
458 1010 : argsman.AddArg("-port=<port>", strprintf("Listen for connections on <port> (default: %u, testnet: %u, regtest: %u)", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort(), regtestChainParams->GetDefaultPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
459 1010 : argsman.AddArg("-proxy=<ip:port>", "Connect through SOCKS5 proxy, set -noproxy to disable (default: disabled)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
460 1010 : argsman.AddArg("-proxyrandomize", strprintf("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)", DEFAULT_PROXYRANDOMIZE), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
461 1010 : argsman.AddArg("-seednode=<ip>", "Connect to a node to retrieve peer addresses, and disconnect. This option can be specified multiple times to connect to multiple nodes.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
462 1010 : argsman.AddArg("-networkactive", "Enable all P2P network activity (default: 1). Can be changed by the setnetworkactive RPC command", ArgsManager::ALLOW_BOOL, OptionsCategory::CONNECTION);
463 1010 : argsman.AddArg("-timeout=<n>", strprintf("Specify connection timeout in milliseconds (minimum: 1, default: %d)", DEFAULT_CONNECT_TIMEOUT), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
464 1010 : argsman.AddArg("-peertimeout=<n>", strprintf("Specify p2p connection timeout in seconds. This option determines the amount of time a peer may be inactive before the connection to it is dropped. (minimum: 1, default: %d)", DEFAULT_PEER_CONNECT_TIMEOUT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CONNECTION);
465 1010 : argsman.AddArg("-torcontrol=<ip>:<port>", strprintf("Tor control port to use if onion listening enabled (default: %s)", DEFAULT_TOR_CONTROL), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
466 1010 : argsman.AddArg("-torpassword=<pass>", "Tor control port password (default: empty)", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::CONNECTION);
467 : #ifdef USE_UPNP
468 : #if USE_UPNP
469 : argsman.AddArg("-upnp", "Use UPnP to map the listening port (default: 1 when listening and no -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
470 : #else
471 1010 : argsman.AddArg("-upnp", strprintf("Use UPnP to map the listening port (default: %u)", 0), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
472 : #endif
473 : #else
474 : hidden_args.emplace_back("-upnp");
475 : #endif
476 2020 : argsman.AddArg("-whitebind=<[permissions@]addr>", "Bind to the given address and add permission flags to the peers connecting to it. "
477 1010 : "Use [host]:port notation for IPv6. Allowed permissions: " + Join(NET_PERMISSIONS_DOC, ", ") + ". "
478 1010 : "Specify multiple permissions separated by commas (default: download,noban,mempool,relay). Can be specified multiple times.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
479 :
480 1010 : argsman.AddArg("-whitelist=<[permissions@]IP address or network>", "Add permission flags to the peers connecting from the given IP address (e.g. 1.2.3.4) or "
481 : "CIDR-notated network (e.g. 1.2.3.0/24). Uses the same permissions as "
482 1010 : "-whitebind. Can be specified multiple times." , ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
483 :
484 1010 : g_wallet_init_interface.AddWalletOptions(argsman);
485 :
486 : #if ENABLE_ZMQ
487 1010 : argsman.AddArg("-zmqpubhashblock=<address>", "Enable publish hash block in <address>", ArgsManager::ALLOW_ANY, OptionsCategory::ZMQ);
488 1010 : argsman.AddArg("-zmqpubhashtx=<address>", "Enable publish hash transaction in <address>", ArgsManager::ALLOW_ANY, OptionsCategory::ZMQ);
489 1010 : argsman.AddArg("-zmqpubrawblock=<address>", "Enable publish raw block in <address>", ArgsManager::ALLOW_ANY, OptionsCategory::ZMQ);
490 1010 : argsman.AddArg("-zmqpubrawtx=<address>", "Enable publish raw transaction in <address>", ArgsManager::ALLOW_ANY, OptionsCategory::ZMQ);
491 1010 : argsman.AddArg("-zmqpubhashblockhwm=<n>", strprintf("Set publish hash block outbound message high water mark (default: %d)", CZMQAbstractNotifier::DEFAULT_ZMQ_SNDHWM), ArgsManager::ALLOW_ANY, OptionsCategory::ZMQ);
492 1010 : argsman.AddArg("-zmqpubhashtxhwm=<n>", strprintf("Set publish hash transaction outbound message high water mark (default: %d)", CZMQAbstractNotifier::DEFAULT_ZMQ_SNDHWM), ArgsManager::ALLOW_ANY, OptionsCategory::ZMQ);
493 1010 : argsman.AddArg("-zmqpubrawblockhwm=<n>", strprintf("Set publish raw block outbound message high water mark (default: %d)", CZMQAbstractNotifier::DEFAULT_ZMQ_SNDHWM), ArgsManager::ALLOW_ANY, OptionsCategory::ZMQ);
494 1010 : argsman.AddArg("-zmqpubrawtxhwm=<n>", strprintf("Set publish raw transaction outbound message high water mark (default: %d)", CZMQAbstractNotifier::DEFAULT_ZMQ_SNDHWM), ArgsManager::ALLOW_ANY, OptionsCategory::ZMQ);
495 : #else
496 : hidden_args.emplace_back("-zmqpubhashblock=<address>");
497 : hidden_args.emplace_back("-zmqpubhashtx=<address>");
498 : hidden_args.emplace_back("-zmqpubrawblock=<address>");
499 : hidden_args.emplace_back("-zmqpubrawtx=<address>");
500 : hidden_args.emplace_back("-zmqpubhashblockhwm=<n>");
501 : hidden_args.emplace_back("-zmqpubhashtxhwm=<n>");
502 : hidden_args.emplace_back("-zmqpubrawblockhwm=<n>");
503 : hidden_args.emplace_back("-zmqpubrawtxhwm=<n>");
504 : #endif
505 :
506 1010 : argsman.AddArg("-checkblocks=<n>", strprintf("How many blocks to check at startup (default: %u, 0 = all)", DEFAULT_CHECKBLOCKS), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
507 1010 : argsman.AddArg("-checklevel=<n>", strprintf("How thorough the block verification of -checkblocks is: %s (0-4, default: %u)", Join(CHECKLEVEL_DOC, ", "), DEFAULT_CHECKLEVEL), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
508 1010 : argsman.AddArg("-checkblockindex", strprintf("Do a consistency check for the block tree, chainstate, and other validation data structures occasionally. (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
509 1010 : argsman.AddArg("-checkmempool=<n>", strprintf("Run checks every <n> transactions (default: %u, regtest: %u)", defaultChainParams->DefaultConsistencyChecks(), regtestChainParams->DefaultConsistencyChecks()), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
510 1010 : argsman.AddArg("-checkpoints", strprintf("Enable rejection of any forks from the known historical chain until block %s (default: %u)", defaultChainParams->Checkpoints().GetHeight(), DEFAULT_CHECKPOINTS_ENABLED), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
511 1010 : argsman.AddArg("-deprecatedrpc=<method>", "Allows deprecated RPC method(s) to be used", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
512 1010 : argsman.AddArg("-dropmessagestest=<n>", "Randomly drop 1 of every <n> network messages", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
513 1010 : argsman.AddArg("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", DEFAULT_STOPAFTERBLOCKIMPORT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
514 1010 : argsman.AddArg("-stopatheight", strprintf("Stop running after reaching the given height in the main chain (default: %u)", DEFAULT_STOPATHEIGHT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
515 1010 : argsman.AddArg("-limitancestorcount=<n>", strprintf("Do not accept transactions if number of in-mempool ancestors is <n> or more (default: %u)", DEFAULT_ANCESTOR_LIMIT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
516 1010 : argsman.AddArg("-limitancestorsize=<n>", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds <n> kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
517 1010 : argsman.AddArg("-limitdescendantcount=<n>", strprintf("Do not accept transactions if any ancestor would have <n> or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
518 1010 : argsman.AddArg("-limitdescendantsize=<n>", strprintf("Do not accept transactions if any ancestor would have more than <n> kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
519 1010 : argsman.AddArg("-addrmantest", "Allows to test address relay on localhost", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
520 2020 : argsman.AddArg("-debug=<category>", "Output debugging information (default: -nodebug, supplying <category> is optional). "
521 1010 : "If <category> is not supplied or if <category> = 1, output all debugging information. <category> can be: " + LogInstance().LogCategoriesString() + ".",
522 1010 : ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
523 1010 : argsman.AddArg("-debugexclude=<category>", strprintf("Exclude debugging information for a category. Can be used in conjunction with -debug=1 to output debug logs for all categories except one or more specified categories."), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
524 1010 : argsman.AddArg("-logips", strprintf("Include IP addresses in debug output (default: %u)", DEFAULT_LOGIPS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
525 1010 : argsman.AddArg("-logtimestamps", strprintf("Prepend debug output with timestamp (default: %u)", DEFAULT_LOGTIMESTAMPS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
526 : #ifdef HAVE_THREAD_LOCAL
527 1010 : argsman.AddArg("-logthreadnames", strprintf("Prepend debug output with name of the originating thread (only available on platforms supporting thread_local) (default: %u)", DEFAULT_LOGTHREADNAMES), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
528 : #else
529 : hidden_args.emplace_back("-logthreadnames");
530 : #endif
531 1010 : argsman.AddArg("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
532 1010 : argsman.AddArg("-mocktime=<n>", "Replace actual time with " + UNIX_EPOCH_TIME + " (default: 0)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
533 1010 : argsman.AddArg("-maxsigcachesize=<n>", strprintf("Limit sum of signature cache and script execution cache sizes to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
534 1010 : argsman.AddArg("-maxtipage=<n>", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
535 1010 : argsman.AddArg("-printpriority", strprintf("Log transaction fee per kB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
536 1010 : argsman.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -daemon. To disable logging to file, set -nodebuglogfile)", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
537 1010 : argsman.AddArg("-shrinkdebugfile", "Shrink debug.log file on client startup (default: 1 when no -debug)", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
538 1010 : argsman.AddArg("-uacomment=<cmt>", "Append comment to the user agent string", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
539 :
540 1010 : SetupChainParamsBaseOptions(argsman);
541 :
542 1010 : argsman.AddArg("-acceptnonstdtxn", strprintf("Relay and mine \"non-standard\" transactions (%sdefault: %u)", "testnet/regtest only; ", !testnetChainParams->RequireStandard()), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
543 1010 : argsman.AddArg("-incrementalrelayfee=<amt>", strprintf("Fee rate (in %s/kB) used to define cost of relay, used for mempool limiting and BIP 125 replacement. (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_INCREMENTAL_RELAY_FEE)), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
544 1010 : argsman.AddArg("-dustrelayfee=<amt>", strprintf("Fee rate (in %s/kB) used to define dust, the value of an output such that it will cost more than its value in fees at this fee rate to spend it. (default: %s)", CURRENCY_UNIT, FormatMoney(DUST_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
545 1010 : argsman.AddArg("-bytespersigop", strprintf("Equivalent bytes per sigop in transactions for relay and mining (default: %u)", DEFAULT_BYTES_PER_SIGOP), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
546 1010 : argsman.AddArg("-datacarrier", strprintf("Relay and mine data carrier transactions (default: %u)", DEFAULT_ACCEPT_DATACARRIER), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
547 1010 : argsman.AddArg("-datacarriersize", strprintf("Maximum size of data in data carrier transactions we relay and mine (default: %u)", MAX_OP_RETURN_RELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
548 1010 : argsman.AddArg("-minrelaytxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)",
549 2020 : CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
550 1010 : argsman.AddArg("-whitelistforcerelay", strprintf("Add 'forcerelay' permission to whitelisted inbound peers with default permissions. This will relay transactions even if the transactions were already in the mempool. (default: %d)", DEFAULT_WHITELISTFORCERELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
551 1010 : argsman.AddArg("-whitelistrelay", strprintf("Add 'relay' permission to whitelisted inbound peers with default permissions. This will accept relayed transactions even when not relaying transactions (default: %d)", DEFAULT_WHITELISTRELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
552 :
553 :
554 1010 : argsman.AddArg("-blockmaxweight=<n>", strprintf("Set maximum BIP141 block weight (default: %d)", DEFAULT_BLOCK_MAX_WEIGHT), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
555 1010 : argsman.AddArg("-blockmintxfee=<amt>", strprintf("Set lowest fee rate (in %s/kB) for transactions to be included in block creation. (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_BLOCK_MIN_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
556 1010 : argsman.AddArg("-blockversion=<n>", "Override block version to test forking scenarios", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::BLOCK_CREATION);
557 :
558 1010 : argsman.AddArg("-rest", strprintf("Accept public REST requests (default: %u)", DEFAULT_REST_ENABLE), ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
559 1010 : argsman.AddArg("-rpcallowip=<ip>", "Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
560 1010 : argsman.AddArg("-rpcauth=<userpw>", "Username and HMAC-SHA-256 hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcauth. The client then connects normally using the rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This option can be specified multiple times", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::RPC);
561 1010 : argsman.AddArg("-rpcbind=<addr>[:port]", "Bind to given address to listen for JSON-RPC connections. Do not expose the RPC server to untrusted networks such as the public internet! This option is ignored unless -rpcallowip is also passed. Port is optional and overrides -rpcport. Use [host]:port notation for IPv6. This option can be specified multiple times (default: 127.0.0.1 and ::1 i.e., localhost)", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY | ArgsManager::SENSITIVE, OptionsCategory::RPC);
562 1010 : argsman.AddArg("-rpccookiefile=<loc>", "Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
563 1010 : argsman.AddArg("-rpcpassword=<pw>", "Password for JSON-RPC connections", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::RPC);
564 1010 : argsman.AddArg("-rpcport=<port>", strprintf("Listen for JSON-RPC connections on <port> (default: %u, testnet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::RPC);
565 1010 : argsman.AddArg("-rpcserialversion", strprintf("Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(1) (default: %d)", DEFAULT_RPC_SERIALIZE_VERSION), ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
566 1010 : argsman.AddArg("-rpcservertimeout=<n>", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::RPC);
567 1010 : argsman.AddArg("-rpcthreads=<n>", strprintf("Set the number of threads to service RPC calls (default: %d)", DEFAULT_HTTP_THREADS), ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
568 1010 : argsman.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::RPC);
569 1010 : argsman.AddArg("-rpcwhitelist=<whitelist>", "Set a whitelist to filter incoming RPC calls for a specific user. The field <whitelist> comes in the format: <USERNAME>:<rpc 1>,<rpc 2>,...,<rpc n>. If multiple whitelists are set for a given user, they are set-intersected. See -rpcwhitelistdefault documentation for information on default whitelist behavior.", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
570 1010 : argsman.AddArg("-rpcwhitelistdefault", "Sets default behavior for rpc whitelisting. Unless rpcwhitelistdefault is set to 0, if any -rpcwhitelist is set, the rpc server acts as if all rpc users are subject to empty-unless-otherwise-specified whitelists. If rpcwhitelistdefault is set to 1 and no -rpcwhitelist is set, rpc server acts as if all rpc users are subject to empty whitelists.", ArgsManager::ALLOW_BOOL, OptionsCategory::RPC);
571 1010 : argsman.AddArg("-rpcworkqueue=<n>", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::RPC);
572 1010 : argsman.AddArg("-server", "Accept command line and JSON-RPC commands", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
573 :
574 : #if HAVE_DECL_DAEMON
575 1010 : argsman.AddArg("-daemon", "Run in the background as a daemon and accept commands", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
576 : #else
577 : hidden_args.emplace_back("-daemon");
578 : #endif
579 :
580 : // Add the hidden options
581 1010 : argsman.AddHiddenArgs(hidden_args);
582 1010 : }
583 :
584 1 : std::string LicenseInfo()
585 : {
586 1 : const std::string URL_SOURCE_CODE = "<https://github.com/bitcoin/bitcoin>";
587 :
588 2 : return CopyrightHolders(strprintf(_("Copyright (C) %i-%i").translated, 2009, COPYRIGHT_YEAR) + " ") + "\n" +
589 1 : "\n" +
590 1 : strprintf(_("Please contribute if you find %s useful. "
591 1 : "Visit %s for further information about the software.").translated,
592 1 : PACKAGE_NAME, "<" PACKAGE_URL ">") +
593 1 : "\n" +
594 1 : strprintf(_("The source code is available from %s.").translated,
595 1 : URL_SOURCE_CODE) +
596 1 : "\n" +
597 1 : "\n" +
598 2 : _("This is experimental software.").translated + "\n" +
599 2 : strprintf(_("Distributed under the MIT software license, see the accompanying file %s or %s").translated, "COPYING", "<https://opensource.org/licenses/MIT>") +
600 : "\n";
601 1 : }
602 :
603 : static bool fHaveGenesis = false;
604 640 : static Mutex g_genesis_wait_mutex;
605 640 : static std::condition_variable g_genesis_wait_cv;
606 :
607 193 : static void BlockNotifyGenesisWait(const CBlockIndex* pBlockIndex)
608 : {
609 193 : if (pBlockIndex != nullptr) {
610 : {
611 193 : LOCK(g_genesis_wait_mutex);
612 193 : fHaveGenesis = true;
613 193 : }
614 193 : g_genesis_wait_cv.notify_all();
615 193 : }
616 193 : }
617 :
618 : struct CImportingNow
619 : {
620 990 : CImportingNow() {
621 495 : assert(fImporting == false);
622 495 : fImporting = true;
623 990 : }
624 :
625 990 : ~CImportingNow() {
626 495 : assert(fImporting == true);
627 495 : fImporting = false;
628 990 : }
629 : };
630 :
631 :
632 : // If we're using -prune with -reindex, then delete block files that will be ignored by the
633 : // reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
634 : // is missing, do the same here to delete any later block files after a gap. Also delete all
635 : // rev files since they'll be rewritten by the reindex anyway. This ensures that vinfoBlockFile
636 : // is in sync with what's actually on disk by the time we start downloading, so that pruning
637 : // works correctly.
638 0 : static void CleanupBlockRevFiles()
639 : {
640 0 : std::map<std::string, fs::path> mapBlockFiles;
641 :
642 : // Glob all blk?????.dat and rev?????.dat files from the blocks directory.
643 : // Remove the rev files immediately and insert the blk file paths into an
644 : // ordered map keyed by block file index.
645 0 : LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune\n");
646 0 : fs::path blocksdir = GetBlocksDir();
647 0 : for (fs::directory_iterator it(blocksdir); it != fs::directory_iterator(); it++) {
648 0 : if (fs::is_regular_file(*it) &&
649 0 : it->path().filename().string().length() == 12 &&
650 0 : it->path().filename().string().substr(8,4) == ".dat")
651 : {
652 0 : if (it->path().filename().string().substr(0,3) == "blk")
653 0 : mapBlockFiles[it->path().filename().string().substr(3,5)] = it->path();
654 0 : else if (it->path().filename().string().substr(0,3) == "rev")
655 0 : remove(it->path());
656 : }
657 : }
658 :
659 : // Remove all block files that aren't part of a contiguous set starting at
660 : // zero by walking the ordered map (keys are block file indices) by
661 : // keeping a separate counter. Once we hit a gap (or if 0 doesn't exist)
662 : // start removing block files.
663 : int nContigCounter = 0;
664 0 : for (const std::pair<const std::string, fs::path>& item : mapBlockFiles) {
665 0 : if (atoi(item.first) == nContigCounter) {
666 0 : nContigCounter++;
667 0 : continue;
668 : }
669 0 : remove(item.second);
670 0 : }
671 0 : }
672 :
673 495 : static void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args)
674 : {
675 495 : const CChainParams& chainparams = Params();
676 495 : ScheduleBatchPriority();
677 :
678 : {
679 495 : CImportingNow imp;
680 :
681 : // -reindex
682 495 : if (fReindex) {
683 24 : int nFile = 0;
684 8 : while (true) {
685 16 : FlatFilePos pos(nFile, 0);
686 16 : if (!fs::exists(GetBlockPosFilename(pos)))
687 8 : break; // No block files left to reindex
688 8 : FILE *file = OpenBlockFile(pos, true);
689 8 : if (!file)
690 0 : break; // This error is logged in OpenBlockFile
691 8 : LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
692 8 : LoadExternalBlockFile(chainparams, file, &pos);
693 8 : if (ShutdownRequested()) {
694 0 : LogPrintf("Shutdown requested. Exit %s\n", __func__);
695 0 : return;
696 : }
697 8 : nFile++;
698 24 : }
699 8 : pblocktree->WriteReindexing(false);
700 8 : fReindex = false;
701 8 : LogPrintf("Reindexing finished\n");
702 : // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
703 8 : LoadGenesisBlock(chainparams);
704 8 : }
705 :
706 : // -loadblock=
707 496 : for (const fs::path& path : vImportFiles) {
708 1 : FILE *file = fsbridge::fopen(path, "rb");
709 1 : if (file) {
710 1 : LogPrintf("Importing blocks file %s...\n", path.string());
711 1 : LoadExternalBlockFile(chainparams, file);
712 1 : if (ShutdownRequested()) {
713 0 : LogPrintf("Shutdown requested. Exit %s\n", __func__);
714 0 : return;
715 : }
716 : } else {
717 0 : LogPrintf("Warning: Could not open blocks file %s\n", path.string());
718 : }
719 2 : }
720 :
721 : // scan for better chains in the block chain database, that are not yet connected in the active best chain
722 :
723 : // We can't hold cs_main during ActivateBestChain even though we're accessing
724 : // the chainman unique_ptrs since ABC requires us not to be holding cs_main, so retrieve
725 : // the relevant pointers before the ABC call.
726 1485 : for (CChainState* chainstate : WITH_LOCK(::cs_main, return chainman.GetAll())) {
727 495 : BlockValidationState state;
728 495 : if (!chainstate->ActivateBestChain(state, chainparams, nullptr)) {
729 0 : LogPrintf("Failed to connect best block (%s)\n", state.ToString());
730 0 : StartShutdown();
731 0 : return;
732 : }
733 495 : }
734 :
735 495 : if (args.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) {
736 0 : LogPrintf("Stopping after block import\n");
737 0 : StartShutdown();
738 0 : return;
739 : }
740 495 : } // End scope of CImportingNow
741 495 : chainman.ActiveChainstate().LoadMempool(args);
742 495 : }
743 :
744 : /** Sanity checks
745 : * Ensure that Bitcoin is running in a usable environment with all
746 : * necessary library support.
747 : */
748 530 : static bool InitSanityCheck()
749 : {
750 530 : if (!ECC_InitSanityCheck()) {
751 0 : return InitError(Untranslated("Elliptic curve cryptography sanity check failure. Aborting."));
752 : }
753 :
754 530 : if (!glibc_sanity_test() || !glibcxx_sanity_test())
755 0 : return false;
756 :
757 530 : if (!Random_SanityCheck()) {
758 0 : return InitError(Untranslated("OS cryptographic RNG sanity check failure. Aborting."));
759 : }
760 :
761 530 : return true;
762 530 : }
763 :
764 526 : static bool AppInitServers(const util::Ref& context, NodeContext& node)
765 : {
766 1052 : const ArgsManager& args = *Assert(node.args);
767 526 : RPCServer::OnStarted(&OnRPCStarted);
768 526 : RPCServer::OnStopped(&OnRPCStopped);
769 526 : if (!InitHTTPServer())
770 0 : return false;
771 526 : StartRPC();
772 526 : node.rpc_interruption_point = RpcInterruptionPoint;
773 526 : if (!StartHTTPRPC(context))
774 1 : return false;
775 525 : if (args.GetBoolArg("-rest", DEFAULT_REST_ENABLE)) StartREST(context);
776 525 : StartHTTPServer();
777 525 : return true;
778 526 : }
779 :
780 : // Parameter interaction based on rules
781 533 : void InitParameterInteraction(ArgsManager& args)
782 : {
783 : // when specifying an explicit binding address, you want to listen on it
784 : // even when -connect or -proxy is specified
785 533 : if (args.IsArgSet("-bind")) {
786 529 : if (args.SoftSetBoolArg("-listen", true))
787 526 : LogPrintf("%s: parameter interaction: -bind set -> setting -listen=1\n", __func__);
788 : }
789 533 : if (args.IsArgSet("-whitebind")) {
790 2 : if (args.SoftSetBoolArg("-listen", true))
791 1 : LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__);
792 : }
793 :
794 533 : if (args.IsArgSet("-connect")) {
795 : // when only connecting to trusted nodes, do not seed via DNS, or listen by default
796 1 : if (args.SoftSetBoolArg("-dnsseed", false))
797 0 : LogPrintf("%s: parameter interaction: -connect set -> setting -dnsseed=0\n", __func__);
798 1 : if (args.SoftSetBoolArg("-listen", false))
799 0 : LogPrintf("%s: parameter interaction: -connect set -> setting -listen=0\n", __func__);
800 : }
801 :
802 533 : if (args.IsArgSet("-proxy")) {
803 : // to protect privacy, do not listen by default if a default proxy server is specified
804 3 : if (args.SoftSetBoolArg("-listen", false))
805 0 : LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__);
806 : // to protect privacy, do not use UPNP when a proxy is set. The user may still specify -listen=1
807 : // to listen locally, so don't rely on this happening through -listen below.
808 3 : if (args.SoftSetBoolArg("-upnp", false))
809 0 : LogPrintf("%s: parameter interaction: -proxy set -> setting -upnp=0\n", __func__);
810 : // to protect privacy, do not discover addresses by default
811 3 : if (args.SoftSetBoolArg("-discover", false))
812 0 : LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__);
813 : }
814 :
815 533 : if (!args.GetBoolArg("-listen", DEFAULT_LISTEN)) {
816 : // do not map ports or try to retrieve public IP when not listening (pointless)
817 0 : if (args.SoftSetBoolArg("-upnp", false))
818 0 : LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__);
819 0 : if (args.SoftSetBoolArg("-discover", false))
820 0 : LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__);
821 0 : if (args.SoftSetBoolArg("-listenonion", false))
822 0 : LogPrintf("%s: parameter interaction: -listen=0 -> setting -listenonion=0\n", __func__);
823 : }
824 :
825 533 : if (args.IsArgSet("-externalip")) {
826 : // if an explicit public IP is specified, do not try to find others
827 0 : if (args.SoftSetBoolArg("-discover", false))
828 0 : LogPrintf("%s: parameter interaction: -externalip set -> setting -discover=0\n", __func__);
829 : }
830 :
831 : // disable whitelistrelay in blocksonly mode
832 533 : if (args.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) {
833 2 : if (args.SoftSetBoolArg("-whitelistrelay", false))
834 2 : LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistrelay=0\n", __func__);
835 : }
836 :
837 : // Forcing relay from whitelisted hosts implies we will accept relays from them in the first place.
838 533 : if (args.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) {
839 4 : if (args.SoftSetBoolArg("-whitelistrelay", true))
840 3 : LogPrintf("%s: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1\n", __func__);
841 : }
842 533 : }
843 :
844 : /**
845 : * Initialize global loggers.
846 : *
847 : * Note that this is called very early in the process lifetime, so you should be
848 : * careful about what global state you rely on here.
849 : */
850 994 : void InitLogging(const ArgsManager& args)
851 : {
852 994 : LogInstance().m_print_to_file = !args.IsArgNegated("-debuglogfile");
853 994 : LogInstance().m_file_path = AbsPathForConfigVal(args.GetArg("-debuglogfile", DEFAULT_DEBUGLOGFILE));
854 994 : LogInstance().m_print_to_console = args.GetBoolArg("-printtoconsole", !args.GetBoolArg("-daemon", false));
855 994 : LogInstance().m_log_timestamps = args.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS);
856 994 : LogInstance().m_log_time_micros = args.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS);
857 : #ifdef HAVE_THREAD_LOCAL
858 994 : LogInstance().m_log_threadnames = args.GetBoolArg("-logthreadnames", DEFAULT_LOGTHREADNAMES);
859 : #endif
860 :
861 994 : fLogIPs = args.GetBoolArg("-logips", DEFAULT_LOGIPS);
862 :
863 994 : std::string version_string = FormatFullVersion();
864 : #ifdef DEBUG
865 : version_string += " (debug build)";
866 : #else
867 994 : version_string += " (release build)";
868 : #endif
869 994 : LogPrintf(PACKAGE_NAME " version %s\n", version_string);
870 994 : }
871 :
872 : namespace { // Variables internal to initialization process only
873 :
874 : int nMaxConnections;
875 : int nUserMaxConnections;
876 : int nFD;
877 : ServiceFlags nLocalServices = ServiceFlags(NODE_NETWORK | NODE_NETWORK_LIMITED);
878 : int64_t peer_connect_timeout;
879 640 : std::set<BlockFilterType> g_enabled_filter_types;
880 :
881 : } // namespace
882 :
883 0 : [[noreturn]] static void new_handler_terminate()
884 : {
885 : // Rather than throwing std::bad-alloc if allocation fails, terminate
886 : // immediately to (try to) avoid chain corruption.
887 : // Since LogPrintf may itself allocate memory, set the handler directly
888 : // to terminate first.
889 0 : std::set_new_handler(std::terminate);
890 0 : LogPrintf("Error: Out of memory. Terminating.\n");
891 :
892 : // The log was successful, terminate now.
893 0 : std::terminate();
894 : };
895 :
896 533 : bool AppInitBasicSetup(ArgsManager& args)
897 : {
898 : // ********************************************************* Step 1: setup
899 : #ifdef _MSC_VER
900 : // Turn off Microsoft heap dump noise
901 : _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
902 : _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, 0));
903 : // Disable confusing "helpful" text message on abort, Ctrl-C
904 : _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
905 : #endif
906 : #ifdef WIN32
907 : // Enable heap terminate-on-corruption
908 : HeapSetInformation(nullptr, HeapEnableTerminationOnCorruption, nullptr, 0);
909 : #endif
910 :
911 533 : if (!SetupNetworking()) {
912 0 : return InitError(Untranslated("Initializing networking failed."));
913 : }
914 :
915 : #ifndef WIN32
916 533 : if (!args.GetBoolArg("-sysperms", false)) {
917 533 : umask(077);
918 533 : }
919 :
920 : // Clean shutdown on SIGTERM
921 533 : registerSignalHandler(SIGTERM, HandleSIGTERM);
922 533 : registerSignalHandler(SIGINT, HandleSIGTERM);
923 :
924 : // Reopen debug.log on SIGHUP
925 533 : registerSignalHandler(SIGHUP, HandleSIGHUP);
926 :
927 : // Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly
928 533 : signal(SIGPIPE, SIG_IGN);
929 : #else
930 : SetConsoleCtrlHandler(consoleCtrlHandler, true);
931 : #endif
932 :
933 533 : std::set_new_handler(new_handler_terminate);
934 :
935 533 : return true;
936 533 : }
937 :
938 994 : bool AppInitParameterInteraction(const ArgsManager& args)
939 : {
940 994 : const CChainParams& chainparams = Params();
941 : // ********************************************************* Step 2: parameter interactions
942 :
943 : // also see: InitParameterInteraction()
944 :
945 : // Error if network-specific options (-addnode, -connect, etc) are
946 : // specified in default section of config file, but not overridden
947 : // on the command line or in this network's section of the config file.
948 994 : std::string network = args.GetChainName();
949 994 : bilingual_str errors;
950 995 : for (const auto& arg : args.GetUnsuitableSectionOnlyArgs()) {
951 1 : errors += strprintf(_("Config setting for %s only applied on %s network when in [%s] section.") + Untranslated("\n"), arg, network, network);
952 0 : }
953 :
954 994 : if (!errors.empty()) {
955 1 : return InitError(errors);
956 : }
957 :
958 : // Warn if unrecognized section name are present in the config file.
959 993 : bilingual_str warnings;
960 995 : for (const auto& section : args.GetUnrecognizedSections()) {
961 2 : warnings += strprintf(Untranslated("%s:%i ") + _("Section [%s] is not recognized.") + Untranslated("\n"), section.m_file, section.m_line, section.m_name);
962 0 : }
963 :
964 993 : if (!warnings.empty()) {
965 1 : InitWarning(warnings);
966 : }
967 :
968 993 : if (!fs::is_directory(GetBlocksDir())) {
969 1 : return InitError(strprintf(_("Specified blocks directory \"%s\" does not exist."), args.GetArg("-blocksdir", "")));
970 : }
971 :
972 : // parse and validate enabled filter types
973 992 : std::string blockfilterindex_value = args.GetArg("-blockfilterindex", DEFAULT_BLOCKFILTERINDEX);
974 992 : if (blockfilterindex_value == "" || blockfilterindex_value == "1") {
975 4 : g_enabled_filter_types = AllBlockFilterTypes();
976 988 : } else if (blockfilterindex_value != "0") {
977 0 : const std::vector<std::string> names = args.GetArgs("-blockfilterindex");
978 0 : for (const auto& name : names) {
979 0 : BlockFilterType filter_type;
980 0 : if (!BlockFilterTypeByName(name, filter_type)) {
981 0 : return InitError(strprintf(_("Unknown -blockfilterindex value %s."), name));
982 : }
983 0 : g_enabled_filter_types.insert(filter_type);
984 0 : }
985 0 : }
986 :
987 : // Signal NODE_COMPACT_FILTERS if peerblockfilters and basic filters index are both enabled.
988 992 : if (args.GetBoolArg("-peerblockfilters", DEFAULT_PEERBLOCKFILTERS)) {
989 1 : if (g_enabled_filter_types.count(BlockFilterType::BASIC) != 1) {
990 0 : return InitError(_("Cannot set -peerblockfilters without -blockfilterindex."));
991 : }
992 :
993 1 : nLocalServices = ServiceFlags(nLocalServices | NODE_COMPACT_FILTERS);
994 1 : }
995 :
996 : // if using block pruning, then disallow txindex
997 992 : if (args.GetArg("-prune", 0)) {
998 5 : if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX))
999 0 : return InitError(_("Prune mode is incompatible with -txindex."));
1000 5 : if (!g_enabled_filter_types.empty()) {
1001 0 : return InitError(_("Prune mode is incompatible with -blockfilterindex."));
1002 : }
1003 : }
1004 :
1005 : // -bind and -whitebind can't be set when not listening
1006 992 : size_t nUserBind = args.GetArgs("-bind").size() + args.GetArgs("-whitebind").size();
1007 992 : if (nUserBind != 0 && !args.GetBoolArg("-listen", DEFAULT_LISTEN)) {
1008 0 : return InitError(Untranslated("Cannot set -bind or -whitebind together with -listen=0"));
1009 : }
1010 :
1011 : // Make sure enough file descriptors are available
1012 992 : int nBind = std::max(nUserBind, size_t(1));
1013 992 : nUserMaxConnections = args.GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
1014 992 : nMaxConnections = std::max(nUserMaxConnections, 0);
1015 :
1016 : // Trim requested connection counts, to fit into system limitations
1017 : // <int> in std::min<int>(...) to work around FreeBSD compilation issue described in #2695
1018 992 : nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS + MAX_ADDNODE_CONNECTIONS);
1019 : #ifdef USE_POLL
1020 : int fd_max = nFD;
1021 : #else
1022 : int fd_max = FD_SETSIZE;
1023 : #endif
1024 992 : nMaxConnections = std::max(std::min<int>(nMaxConnections, fd_max - nBind - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS), 0);
1025 992 : if (nFD < MIN_CORE_FILEDESCRIPTORS)
1026 0 : return InitError(_("Not enough file descriptors available."));
1027 992 : nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS, nMaxConnections);
1028 :
1029 992 : if (nMaxConnections < nUserMaxConnections)
1030 0 : InitWarning(strprintf(_("Reducing -maxconnections from %d to %d, because of system limitations."), nUserMaxConnections, nMaxConnections));
1031 :
1032 : // ********************************************************* Step 3: parameter-to-internal-flags
1033 992 : if (args.IsArgSet("-debug")) {
1034 : // Special-case: if -debug=0/-nodebug is set, turn off debugging messages
1035 992 : const std::vector<std::string> categories = args.GetArgs("-debug");
1036 :
1037 992 : if (std::none_of(categories.begin(), categories.end(),
1038 985 : [](std::string cat){return cat == "0" || cat == "none";})) {
1039 1977 : for (const auto& cat : categories) {
1040 985 : if (!LogInstance().EnableCategory(cat)) {
1041 0 : InitWarning(strprintf(_("Unsupported logging category %s=%s."), "-debug", cat));
1042 0 : }
1043 : }
1044 992 : }
1045 992 : }
1046 :
1047 : // Now remove the logging categories which were explicitly excluded
1048 2976 : for (const std::string& cat : args.GetArgs("-debugexclude")) {
1049 1984 : if (!LogInstance().DisableCategory(cat)) {
1050 0 : InitWarning(strprintf(_("Unsupported logging category %s=%s."), "-debugexclude", cat));
1051 0 : }
1052 : }
1053 :
1054 992 : fCheckBlockIndex = args.GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks());
1055 992 : fCheckpointsEnabled = args.GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED);
1056 :
1057 992 : hashAssumeValid = uint256S(args.GetArg("-assumevalid", chainparams.GetConsensus().defaultAssumeValid.GetHex()));
1058 992 : if (!hashAssumeValid.IsNull())
1059 426 : LogPrintf("Assuming ancestors of block %s have valid signatures.\n", hashAssumeValid.GetHex());
1060 : else
1061 566 : LogPrintf("Validating signatures for all blocks.\n");
1062 :
1063 992 : if (args.IsArgSet("-minimumchainwork")) {
1064 3 : const std::string minChainWorkStr = args.GetArg("-minimumchainwork", "");
1065 3 : if (!IsHexNumber(minChainWorkStr)) {
1066 0 : return InitError(strprintf(Untranslated("Invalid non-hex (%s) minimum chain work value specified"), minChainWorkStr));
1067 : }
1068 3 : nMinimumChainWork = UintToArith256(uint256S(minChainWorkStr));
1069 3 : } else {
1070 989 : nMinimumChainWork = UintToArith256(chainparams.GetConsensus().nMinimumChainWork);
1071 : }
1072 992 : LogPrintf("Setting nMinimumChainWork=%s\n", nMinimumChainWork.GetHex());
1073 992 : if (nMinimumChainWork < UintToArith256(chainparams.GetConsensus().nMinimumChainWork)) {
1074 0 : LogPrintf("Warning: nMinimumChainWork set below default value of %s\n", chainparams.GetConsensus().nMinimumChainWork.GetHex());
1075 0 : }
1076 :
1077 : // mempool limits
1078 992 : int64_t nMempoolSizeMax = args.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1079 992 : int64_t nMempoolSizeMin = args.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000 * 40;
1080 992 : if (nMempoolSizeMax < 0 || nMempoolSizeMax < nMempoolSizeMin)
1081 0 : return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(nMempoolSizeMin / 1000000.0)));
1082 : // incremental relay fee sets the minimum feerate increase necessary for BIP 125 replacement in the mempool
1083 : // and the amount the mempool min fee increases above the feerate of txs evicted due to mempool limiting.
1084 992 : if (args.IsArgSet("-incrementalrelayfee")) {
1085 0 : CAmount n = 0;
1086 0 : if (!ParseMoney(args.GetArg("-incrementalrelayfee", ""), n))
1087 0 : return InitError(AmountErrMsg("incrementalrelayfee", args.GetArg("-incrementalrelayfee", "")));
1088 0 : incrementalRelayFee = CFeeRate(n);
1089 0 : }
1090 :
1091 : // block pruning; get the amount of disk space (in MiB) to allot for block & undo files
1092 992 : int64_t nPruneArg = args.GetArg("-prune", 0);
1093 992 : if (nPruneArg < 0) {
1094 0 : return InitError(_("Prune cannot be configured with a negative value."));
1095 : }
1096 992 : nPruneTarget = (uint64_t) nPruneArg * 1024 * 1024;
1097 992 : if (nPruneArg == 1) { // manual pruning: -prune=1
1098 3 : LogPrintf("Block pruning enabled. Use RPC call pruneblockchain(height) to manually prune block and undo files.\n");
1099 3 : nPruneTarget = std::numeric_limits<uint64_t>::max();
1100 3 : fPruneMode = true;
1101 992 : } else if (nPruneTarget) {
1102 2 : if (nPruneTarget < MIN_DISK_SPACE_FOR_BLOCK_FILES) {
1103 0 : return InitError(strprintf(_("Prune configured below the minimum of %d MiB. Please use a higher number."), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
1104 : }
1105 2 : LogPrintf("Prune configured to target %u MiB on disk for block and undo files.\n", nPruneTarget / 1024 / 1024);
1106 2 : fPruneMode = true;
1107 2 : }
1108 :
1109 992 : nConnectTimeout = args.GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT);
1110 992 : if (nConnectTimeout <= 0) {
1111 0 : nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
1112 0 : }
1113 :
1114 992 : peer_connect_timeout = args.GetArg("-peertimeout", DEFAULT_PEER_CONNECT_TIMEOUT);
1115 992 : if (peer_connect_timeout <= 0) {
1116 0 : return InitError(Untranslated("peertimeout cannot be configured with a negative value."));
1117 : }
1118 :
1119 992 : if (args.IsArgSet("-minrelaytxfee")) {
1120 12 : CAmount n = 0;
1121 12 : if (!ParseMoney(args.GetArg("-minrelaytxfee", ""), n)) {
1122 0 : return InitError(AmountErrMsg("minrelaytxfee", args.GetArg("-minrelaytxfee", "")));
1123 : }
1124 : // High fee check is done afterward in CWallet::CreateWalletFromFile()
1125 12 : ::minRelayTxFee = CFeeRate(n);
1126 992 : } else if (incrementalRelayFee > ::minRelayTxFee) {
1127 : // Allow only setting incrementalRelayFee to control both
1128 0 : ::minRelayTxFee = incrementalRelayFee;
1129 0 : LogPrintf("Increasing minrelaytxfee to %s to match incrementalrelayfee\n",::minRelayTxFee.ToString());
1130 0 : }
1131 :
1132 : // Sanity check argument for min fee for including tx in block
1133 : // TODO: Harmonize which arguments need sanity checking and where that happens
1134 992 : if (args.IsArgSet("-blockmintxfee")) {
1135 0 : CAmount n = 0;
1136 0 : if (!ParseMoney(args.GetArg("-blockmintxfee", ""), n))
1137 0 : return InitError(AmountErrMsg("blockmintxfee", args.GetArg("-blockmintxfee", "")));
1138 0 : }
1139 :
1140 : // Feerate used to define dust. Shouldn't be changed lightly as old
1141 : // implementations may inadvertently create non-standard transactions
1142 992 : if (args.IsArgSet("-dustrelayfee")) {
1143 0 : CAmount n = 0;
1144 0 : if (!ParseMoney(args.GetArg("-dustrelayfee", ""), n))
1145 0 : return InitError(AmountErrMsg("dustrelayfee", args.GetArg("-dustrelayfee", "")));
1146 0 : dustRelayFee = CFeeRate(n);
1147 0 : }
1148 :
1149 992 : fRequireStandard = !args.GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard());
1150 992 : if (!chainparams.IsTestChain() && !fRequireStandard) {
1151 1 : return InitError(strprintf(Untranslated("acceptnonstdtxn is not currently supported for %s chain"), chainparams.NetworkIDString()));
1152 : }
1153 991 : nBytesPerSigOp = args.GetArg("-bytespersigop", nBytesPerSigOp);
1154 :
1155 991 : if (!g_wallet_init_interface.ParameterInteraction()) return false;
1156 :
1157 991 : fIsBareMultisigStd = args.GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG);
1158 991 : fAcceptDatacarrier = args.GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER);
1159 991 : nMaxDatacarrierBytes = args.GetArg("-datacarriersize", nMaxDatacarrierBytes);
1160 :
1161 : // Option to startup with mocktime set (used for regression testing):
1162 991 : SetMockTime(args.GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op
1163 :
1164 991 : if (args.GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS))
1165 1 : nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM);
1166 :
1167 991 : if (args.GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) < 0)
1168 0 : return InitError(Untranslated("rpcserialversion must be non-negative."));
1169 :
1170 991 : if (args.GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) > 1)
1171 0 : return InitError(Untranslated("Unknown rpcserialversion requested."));
1172 :
1173 991 : nMaxTipAge = args.GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE);
1174 :
1175 991 : return true;
1176 994 : }
1177 :
1178 1059 : static bool LockDataDirectory(bool probeOnly)
1179 : {
1180 : // Make sure only a single Bitcoin process is using the data directory.
1181 1059 : fs::path datadir = GetDataDir();
1182 1059 : if (!DirIsWritable(datadir)) {
1183 0 : return InitError(strprintf(_("Cannot write to data directory '%s'; check permissions."), datadir.string()));
1184 : }
1185 1059 : if (!LockDirectory(datadir, ".lock", probeOnly)) {
1186 1 : return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), datadir.string(), PACKAGE_NAME));
1187 : }
1188 1058 : return true;
1189 1059 : }
1190 :
1191 530 : bool AppInitSanityChecks()
1192 : {
1193 : // ********************************************************* Step 4: sanity checks
1194 :
1195 : // Initialize elliptic curve code
1196 530 : std::string sha256_algo = SHA256AutoDetect();
1197 530 : LogPrintf("Using the '%s' SHA256 implementation\n", sha256_algo);
1198 530 : RandomInit();
1199 530 : ECC_Start();
1200 530 : globalVerifyHandle.reset(new ECCVerifyHandle());
1201 :
1202 : // Sanity check
1203 530 : if (!InitSanityCheck())
1204 0 : return InitError(strprintf(_("Initialization sanity check failed. %s is shutting down."), PACKAGE_NAME));
1205 :
1206 : // Probe the data directory lock to give an early error message, if possible
1207 : // We cannot hold the data directory lock here, as the forking for daemon() hasn't yet happened,
1208 : // and a fork will cause weird behavior to it.
1209 530 : return LockDataDirectory(true);
1210 530 : }
1211 :
1212 529 : bool AppInitLockDataDirectory()
1213 : {
1214 : // After daemonization get the data directory lock again and hold on to it until exit
1215 : // This creates a slight window for a race condition to happen, however this condition is harmless: it
1216 : // will at most make us exit without printing a message to console.
1217 529 : if (!LockDataDirectory(false)) {
1218 : // Detailed error printed inside LockDataDirectory
1219 0 : return false;
1220 : }
1221 529 : return true;
1222 529 : }
1223 :
1224 529 : bool AppInitInterfaces(NodeContext& node)
1225 : {
1226 529 : node.chain = interfaces::MakeChain(node);
1227 : // Create client interfaces for wallets that are supposed to be loaded
1228 : // according to -wallet and -disablewallet options. This only constructs
1229 : // the interfaces, it doesn't load wallet data. Wallets actually get loaded
1230 : // when load() and start() interface methods are called below.
1231 529 : g_wallet_init_interface.Construct(node);
1232 529 : return true;
1233 : }
1234 :
1235 529 : bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
1236 : {
1237 1058 : const ArgsManager& args = *Assert(node.args);
1238 529 : const CChainParams& chainparams = Params();
1239 : // ********************************************************* Step 4a: application initialization
1240 529 : if (!CreatePidFile(args)) {
1241 : // Detailed error printed inside CreatePidFile().
1242 0 : return false;
1243 : }
1244 529 : if (LogInstance().m_print_to_file) {
1245 528 : if (args.GetBoolArg("-shrinkdebugfile", LogInstance().DefaultShrinkDebugFile())) {
1246 : // Do this first since it both loads a bunch of debug.log into memory,
1247 : // and because this needs to happen before any other debug.log printing
1248 0 : LogInstance().ShrinkDebugFile();
1249 0 : }
1250 : }
1251 529 : if (!LogInstance().StartLogging()) {
1252 4 : return InitError(strprintf(Untranslated("Could not open debug log file %s"),
1253 2 : LogInstance().m_file_path.string()));
1254 : }
1255 :
1256 527 : if (!LogInstance().m_log_timestamps)
1257 0 : LogPrintf("Startup time: %s\n", FormatISO8601DateTime(GetTime()));
1258 527 : LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
1259 527 : LogPrintf("Using data directory %s\n", GetDataDir().string());
1260 :
1261 : // Only log conf file usage message if conf file actually exists.
1262 527 : fs::path config_file_path = GetConfigFile(args.GetArg("-conf", BITCOIN_CONF_FILENAME));
1263 527 : if (fs::exists(config_file_path)) {
1264 527 : LogPrintf("Config file: %s\n", config_file_path.string());
1265 0 : } else if (args.IsArgSet("-conf")) {
1266 : // Warn if no conf file exists at path provided by user
1267 0 : InitWarning(strprintf(_("The specified config file %s does not exist\n"), config_file_path.string()));
1268 0 : } else {
1269 : // Not categorizing as "Warning" because it's the default behavior
1270 0 : LogPrintf("Config file: %s (not found, skipping)\n", config_file_path.string());
1271 : }
1272 :
1273 : // Log the config arguments to debug.log
1274 527 : args.LogArgs();
1275 :
1276 527 : LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD);
1277 :
1278 : // Warn about relative -datadir path.
1279 527 : if (args.IsArgSet("-datadir") && !fs::path(args.GetArg("-datadir", "")).is_absolute()) {
1280 0 : LogPrintf("Warning: relative datadir option '%s' specified, which will be interpreted relative to the " /* Continued */
1281 : "current working directory '%s'. This is fragile, because if bitcoin is started in the future "
1282 : "from a different location, it will be unable to locate the current data files. There could "
1283 : "also be data loss if bitcoin is started while in a temporary directory.\n",
1284 0 : args.GetArg("-datadir", ""), fs::current_path().string());
1285 0 : }
1286 :
1287 527 : InitSignatureCache();
1288 527 : InitScriptExecutionCache();
1289 :
1290 527 : int script_threads = args.GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
1291 527 : if (script_threads <= 0) {
1292 : // -par=0 means autodetect (number of cores - 1 script threads)
1293 : // -par=-n means "leave n cores free" (number of cores - n - 1 script threads)
1294 524 : script_threads += GetNumCores();
1295 524 : }
1296 :
1297 : // Subtract 1 because the main thread counts towards the par threads
1298 527 : script_threads = std::max(script_threads - 1, 0);
1299 :
1300 : // Number of script-checking threads <= MAX_SCRIPTCHECK_THREADS
1301 527 : script_threads = std::min(script_threads, MAX_SCRIPTCHECK_THREADS);
1302 :
1303 527 : LogPrintf("Script verification uses %d additional threads\n", script_threads);
1304 527 : if (script_threads >= 1) {
1305 524 : g_parallel_script_checks = true;
1306 2096 : for (int i = 0; i < script_threads; ++i) {
1307 3127 : threadGroup.create_thread([i]() { return ThreadScriptCheck(i); });
1308 : }
1309 524 : }
1310 :
1311 527 : assert(!node.scheduler);
1312 527 : node.scheduler = MakeUnique<CScheduler>();
1313 :
1314 : // Start the lightweight task scheduler thread
1315 1581 : threadGroup.create_thread([&] { TraceThread("scheduler", [&] { node.scheduler->serviceQueue(); }); });
1316 :
1317 : // Gather some entropy once per minute.
1318 1190 : node.scheduler->scheduleEvery([]{
1319 136 : RandAddPeriodic();
1320 663 : }, std::chrono::minutes{1});
1321 :
1322 527 : GetMainSignals().RegisterBackgroundSignalScheduler(*node.scheduler);
1323 :
1324 : /* Register RPC commands regardless of -server setting so they will be
1325 : * available in the GUI RPC console even if external calls are disabled.
1326 : */
1327 527 : RegisterAllCoreRPCCommands(tableRPC);
1328 1049 : for (const auto& client : node.chain_clients) {
1329 522 : client->registerRpcs();
1330 : }
1331 : #if ENABLE_ZMQ
1332 527 : RegisterZMQRPCCommands(tableRPC);
1333 : #endif
1334 :
1335 : /* Start the RPC server already. It will be started in "warmup" mode
1336 : * and not really process calls already (but it will signify connections
1337 : * that the server is there and will be ready later). Warmup mode will
1338 : * be disabled when initialisation is finished.
1339 : */
1340 527 : if (args.GetBoolArg("-server", false)) {
1341 526 : uiInterface.InitMessage_connect(SetRPCWarmupStatus);
1342 526 : if (!AppInitServers(context, node))
1343 1 : return InitError(_("Unable to start HTTP server. See debug log for details."));
1344 : }
1345 :
1346 : // ********************************************************* Step 5: verify wallet database integrity
1347 1045 : for (const auto& client : node.chain_clients) {
1348 521 : if (!client->verify()) {
1349 17 : return false;
1350 : }
1351 502 : }
1352 :
1353 : // ********************************************************* Step 6: network initialization
1354 : // Note that we absolutely cannot open any actual connections
1355 : // until the very end ("start node") as the UTXO/block state
1356 : // is not yet setup and may end up being set up twice if we
1357 : // need to reindex later.
1358 :
1359 507 : assert(!node.banman);
1360 507 : node.banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", &uiInterface, args.GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME));
1361 507 : assert(!node.connman);
1362 507 : node.connman = MakeUnique<CConnman>(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max()), args.GetBoolArg("-networkactive", true));
1363 :
1364 : // Make mempool generally available in the node context. For example the connection manager, wallet, or RPC threads,
1365 : // which are all started after this, may use it from the node context.
1366 507 : assert(!node.mempool);
1367 507 : node.mempool = MakeUnique<CTxMemPool>(&::feeEstimator);
1368 507 : if (node.mempool) {
1369 507 : int ratio = std::min<int>(std::max<int>(args.GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000);
1370 507 : if (ratio != 0) {
1371 504 : node.mempool->setSanityCheck(1.0 / ratio);
1372 : }
1373 507 : }
1374 :
1375 507 : assert(!node.chainman);
1376 507 : node.chainman = &g_chainman;
1377 1014 : ChainstateManager& chainman = *Assert(node.chainman);
1378 :
1379 507 : node.peerman.reset(new PeerManager(chainparams, *node.connman, node.banman.get(), *node.scheduler, chainman, *node.mempool));
1380 507 : RegisterValidationInterface(node.peerman.get());
1381 :
1382 : // sanitize comments per BIP-0014, format user agent and check total size
1383 507 : std::vector<std::string> uacomments;
1384 1029 : for (const std::string& cmt : args.GetArgs("-uacomment")) {
1385 522 : if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT))
1386 6 : return InitError(strprintf(_("User Agent comment (%s) contains unsafe characters."), cmt));
1387 516 : uacomments.push_back(cmt);
1388 516 : }
1389 501 : strSubVersion = FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, uacomments);
1390 501 : if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) {
1391 1 : return InitError(strprintf(_("Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments."),
1392 1 : strSubVersion.size(), MAX_SUBVERSION_LENGTH));
1393 : }
1394 :
1395 500 : if (args.IsArgSet("-onlynet")) {
1396 0 : std::set<enum Network> nets;
1397 0 : for (const std::string& snet : args.GetArgs("-onlynet")) {
1398 0 : enum Network net = ParseNetwork(snet);
1399 0 : if (net == NET_UNROUTABLE)
1400 2000 : return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet));
1401 0 : nets.insert(net);
1402 0 : }
1403 0 : for (int n = 0; n < NET_MAX; n++) {
1404 0 : enum Network net = (enum Network)n;
1405 0 : if (!nets.count(net))
1406 0 : SetReachable(net, false);
1407 0 : }
1408 0 : }
1409 :
1410 : // Check for host lookup allowed before parsing any network related parameters
1411 500 : fNameLookup = args.GetBoolArg("-dns", DEFAULT_NAME_LOOKUP);
1412 :
1413 500 : bool proxyRandomize = args.GetBoolArg("-proxyrandomize", DEFAULT_PROXYRANDOMIZE);
1414 : // -proxy sets a proxy for all outgoing network traffic
1415 : // -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default
1416 500 : std::string proxyArg = args.GetArg("-proxy", "");
1417 500 : SetReachable(NET_ONION, false);
1418 500 : if (proxyArg != "" && proxyArg != "0") {
1419 3 : CService proxyAddr;
1420 3 : if (!Lookup(proxyArg, proxyAddr, 9050, fNameLookup)) {
1421 0 : return InitError(strprintf(_("Invalid -proxy address or hostname: '%s'"), proxyArg));
1422 : }
1423 :
1424 3 : proxyType addrProxy = proxyType(proxyAddr, proxyRandomize);
1425 3 : if (!addrProxy.IsValid())
1426 0 : return InitError(strprintf(_("Invalid -proxy address or hostname: '%s'"), proxyArg));
1427 :
1428 3 : SetProxy(NET_IPV4, addrProxy);
1429 3 : SetProxy(NET_IPV6, addrProxy);
1430 3 : SetProxy(NET_ONION, addrProxy);
1431 3 : SetNameProxy(addrProxy);
1432 3 : SetReachable(NET_ONION, true); // by default, -proxy sets onion as reachable, unless -noonion later
1433 3 : }
1434 :
1435 : // -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses
1436 : // -noonion (or -onion=0) disables connecting to .onion entirely
1437 : // An empty string is used to not override the onion proxy (in which case it defaults to -proxy set above, or none)
1438 500 : std::string onionArg = args.GetArg("-onion", "");
1439 500 : if (onionArg != "") {
1440 1 : if (onionArg == "0") { // Handle -noonion/-onion=0
1441 0 : SetReachable(NET_ONION, false);
1442 : } else {
1443 1 : CService onionProxy;
1444 1 : if (!Lookup(onionArg, onionProxy, 9050, fNameLookup)) {
1445 0 : return InitError(strprintf(_("Invalid -onion address or hostname: '%s'"), onionArg));
1446 : }
1447 1 : proxyType addrOnion = proxyType(onionProxy, proxyRandomize);
1448 1 : if (!addrOnion.IsValid())
1449 0 : return InitError(strprintf(_("Invalid -onion address or hostname: '%s'"), onionArg));
1450 1 : SetProxy(NET_ONION, addrOnion);
1451 1 : SetReachable(NET_ONION, true);
1452 1 : }
1453 : }
1454 :
1455 : // see Step 2: parameter interactions for more information about these
1456 500 : fListen = args.GetBoolArg("-listen", DEFAULT_LISTEN);
1457 500 : fDiscover = args.GetBoolArg("-discover", true);
1458 500 : g_relay_txes = !args.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY);
1459 :
1460 500 : for (const std::string& strAddr : args.GetArgs("-externalip")) {
1461 0 : CService addrLocal;
1462 0 : if (Lookup(strAddr, addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid())
1463 0 : AddLocal(addrLocal, LOCAL_MANUAL);
1464 : else
1465 0 : return InitError(ResolveErrMsg("externalip", strAddr));
1466 0 : }
1467 :
1468 : // Read asmap file if configured
1469 500 : if (args.IsArgSet("-asmap")) {
1470 6 : fs::path asmap_path = fs::path(args.GetArg("-asmap", ""));
1471 6 : if (asmap_path.empty()) {
1472 4 : asmap_path = DEFAULT_ASMAP_FILENAME;
1473 : }
1474 6 : if (!asmap_path.is_absolute()) {
1475 5 : asmap_path = GetDataDir() / asmap_path;
1476 5 : }
1477 6 : if (!fs::exists(asmap_path)) {
1478 1 : InitError(strprintf(_("Could not find asmap file %s"), asmap_path));
1479 1 : return false;
1480 : }
1481 5 : std::vector<bool> asmap = CAddrMan::DecodeAsmap(asmap_path);
1482 5 : if (asmap.size() == 0) {
1483 1 : InitError(strprintf(_("Could not parse asmap file %s"), asmap_path));
1484 4958 : return false;
1485 : }
1486 4 : const uint256 asmap_version = SerializeHash(asmap);
1487 4 : node.connman->SetAsmap(std::move(asmap));
1488 4 : LogPrintf("Using asmap version %s for IP bucketing\n", asmap_version.ToString());
1489 6 : } else {
1490 494 : LogPrintf("Using /16 prefix for IP bucketing\n");
1491 : }
1492 :
1493 : #if ENABLE_ZMQ
1494 498 : g_zmq_notification_interface = CZMQNotificationInterface::Create();
1495 :
1496 498 : if (g_zmq_notification_interface) {
1497 2 : RegisterValidationInterface(g_zmq_notification_interface);
1498 : }
1499 : #endif
1500 : uint64_t nMaxOutboundLimit = 0; //unlimited unless -maxuploadtarget is set
1501 : uint64_t nMaxOutboundTimeframe = MAX_UPLOAD_TIMEFRAME;
1502 :
1503 498 : if (args.IsArgSet("-maxuploadtarget")) {
1504 2 : nMaxOutboundLimit = args.GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET) * 1024 * 1024;
1505 2 : }
1506 :
1507 : // ********************************************************* Step 7: load block chain
1508 :
1509 498 : fReindex = args.GetBoolArg("-reindex", false);
1510 498 : bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false);
1511 :
1512 : // cache size calculations
1513 498 : int64_t nTotalCache = (args.GetArg("-dbcache", nDefaultDbCache) << 20);
1514 498 : nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache
1515 498 : nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greater than nMaxDbcache
1516 498 : int64_t nBlockTreeDBCache = std::min(nTotalCache / 8, nMaxBlockDBCache << 20);
1517 498 : nTotalCache -= nBlockTreeDBCache;
1518 498 : int64_t nTxIndexCache = std::min(nTotalCache / 8, args.GetBoolArg("-txindex", DEFAULT_TXINDEX) ? nMaxTxIndexCache << 20 : 0);
1519 498 : nTotalCache -= nTxIndexCache;
1520 : int64_t filter_index_cache = 0;
1521 498 : if (!g_enabled_filter_types.empty()) {
1522 4 : size_t n_indexes = g_enabled_filter_types.size();
1523 4 : int64_t max_cache = std::min(nTotalCache / 8, max_filter_index_cache << 20);
1524 4 : filter_index_cache = max_cache / n_indexes;
1525 4 : nTotalCache -= filter_index_cache * n_indexes;
1526 4 : }
1527 498 : int64_t nCoinDBCache = std::min(nTotalCache / 2, (nTotalCache / 4) + (1 << 23)); // use 25%-50% of the remainder for disk cache
1528 498 : nCoinDBCache = std::min(nCoinDBCache, nMaxCoinsDBCache << 20); // cap total coins db cache
1529 498 : nTotalCache -= nCoinDBCache;
1530 : int64_t nCoinCacheUsage = nTotalCache; // the rest goes to in-memory cache
1531 498 : int64_t nMempoolSizeMax = args.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1532 498 : LogPrintf("Cache configuration:\n");
1533 498 : LogPrintf("* Using %.1f MiB for block index database\n", nBlockTreeDBCache * (1.0 / 1024 / 1024));
1534 498 : if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
1535 6 : LogPrintf("* Using %.1f MiB for transaction index database\n", nTxIndexCache * (1.0 / 1024 / 1024));
1536 6 : }
1537 502 : for (BlockFilterType filter_type : g_enabled_filter_types) {
1538 4 : LogPrintf("* Using %.1f MiB for %s block filter index database\n",
1539 4 : filter_index_cache * (1.0 / 1024 / 1024), BlockFilterTypeName(filter_type));
1540 0 : }
1541 498 : LogPrintf("* Using %.1f MiB for chain state database\n", nCoinDBCache * (1.0 / 1024 / 1024));
1542 498 : LogPrintf("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)\n", nCoinCacheUsage * (1.0 / 1024 / 1024), nMempoolSizeMax * (1.0 / 1024 / 1024));
1543 :
1544 1493 : bool fLoaded = false;
1545 995 : while (!fLoaded && !ShutdownRequested()) {
1546 498 : bool fReset = fReindex;
1547 1494 : auto is_coinsview_empty = [&](CChainState* chainstate) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
1548 996 : return fReset || fReindexChainState || chainstate->CoinsTip().GetBestBlock().IsNull();
1549 : };
1550 498 : bilingual_str strLoadError;
1551 :
1552 498 : uiInterface.InitMessage(_("Loading block index...").translated);
1553 :
1554 : do {
1555 498 : const int64_t load_block_index_start_time = GetTimeMillis();
1556 : try {
1557 498 : LOCK(cs_main);
1558 996 : chainman.InitializeChainstate(*Assert(node.mempool));
1559 498 : chainman.m_total_coinstip_cache = nCoinCacheUsage;
1560 498 : chainman.m_total_coinsdb_cache = nCoinDBCache;
1561 :
1562 498 : UnloadBlockIndex(node.mempool.get());
1563 :
1564 : // new CBlockTreeDB tries to delete the existing file, which
1565 : // fails if it's still open from the previous loop. Close it first:
1566 498 : pblocktree.reset();
1567 498 : pblocktree.reset(new CBlockTreeDB(nBlockTreeDBCache, false, fReset));
1568 :
1569 498 : if (fReset) {
1570 8 : pblocktree->WriteReindexing(true);
1571 : //If we're reindexing in prune mode, wipe away unusable block files and all undo data files
1572 8 : if (fPruneMode)
1573 0 : CleanupBlockRevFiles();
1574 : }
1575 :
1576 498 : if (ShutdownRequested()) break;
1577 :
1578 : // LoadBlockIndex will load fHavePruned if we've ever removed a
1579 : // block file from disk.
1580 : // Note that it also sets fReindex based on the disk flag!
1581 : // From here on out fReindex and fReset mean something different!
1582 498 : if (!chainman.LoadBlockIndex(chainparams)) {
1583 0 : if (ShutdownRequested()) break;
1584 0 : strLoadError = _("Error loading block database");
1585 0 : break;
1586 : }
1587 :
1588 : // If the loaded chain has a wrong genesis, bail out immediately
1589 : // (we're likely using a testnet datadir, or the other way around).
1590 805 : if (!chainman.BlockIndex().empty() &&
1591 307 : !LookupBlockIndex(chainparams.GetConsensus().hashGenesisBlock)) {
1592 0 : return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
1593 : }
1594 :
1595 : // Check for changed -prune state. What we are concerned about is a user who has pruned blocks
1596 : // in the past, but is now trying to run unpruned.
1597 498 : if (fHavePruned && !fPruneMode) {
1598 0 : strLoadError = _("You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain");
1599 0 : break;
1600 : }
1601 :
1602 : // At this point blocktree args are consistent with what's on disk.
1603 : // If we're not mid-reindex (based on disk + args), add a genesis block on disk
1604 : // (otherwise we use the one already on disk).
1605 : // This is called again in ThreadImport after the reindex completes.
1606 498 : if (!fReindex && !LoadGenesisBlock(chainparams)) {
1607 0 : strLoadError = _("Error initializing block database");
1608 0 : break;
1609 : }
1610 :
1611 : // At this point we're either in reindex or we've loaded a useful
1612 : // block tree into BlockIndex()!
1613 :
1614 1494 : bool failed_chainstate_init = false;
1615 :
1616 996 : for (CChainState* chainstate : chainman.GetAll()) {
1617 498 : LogPrintf("Initializing chainstate %s\n", chainstate->ToString());
1618 498 : chainstate->InitCoinsDB(
1619 498 : /* cache_size_bytes */ nCoinDBCache,
1620 : /* in_memory */ false,
1621 498 : /* should_wipe */ fReset || fReindexChainState);
1622 :
1623 498 : chainstate->CoinsErrorCatcher().AddReadErrCallback([]() {
1624 0 : uiInterface.ThreadSafeMessageBox(
1625 0 : _("Error reading from database, shutting down."),
1626 0 : "", CClientUIInterface::MSG_ERROR);
1627 0 : });
1628 :
1629 : // If necessary, upgrade from older database format.
1630 : // This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
1631 498 : if (!chainstate->CoinsDB().Upgrade()) {
1632 0 : strLoadError = _("Error upgrading chainstate database");
1633 : failed_chainstate_init = true;
1634 0 : break;
1635 : }
1636 :
1637 : // ReplayBlocks is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
1638 498 : if (!chainstate->ReplayBlocks(chainparams)) {
1639 0 : strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.");
1640 : failed_chainstate_init = true;
1641 0 : break;
1642 : }
1643 :
1644 : // The on-disk coinsdb is now in a good state, create the cache
1645 498 : chainstate->InitCoinsCache(nCoinCacheUsage);
1646 498 : assert(chainstate->CanFlushToDisk());
1647 :
1648 498 : if (!is_coinsview_empty(chainstate)) {
1649 : // LoadChainTip initializes the chain based on CoinsTip()'s best block
1650 305 : if (!chainstate->LoadChainTip(chainparams)) {
1651 0 : strLoadError = _("Error initializing block database");
1652 : failed_chainstate_init = true;
1653 0 : break; // out of the per-chainstate loop
1654 : }
1655 305 : assert(chainstate->m_chain.Tip() != nullptr);
1656 : }
1657 498 : }
1658 :
1659 498 : if (failed_chainstate_init) {
1660 0 : break; // out of the chainstate activation do-while
1661 : }
1662 996 : } catch (const std::exception& e) {
1663 0 : LogPrintf("%s\n", e.what());
1664 0 : strLoadError = _("Error opening block database");
1665 : break;
1666 0 : }
1667 :
1668 1494 : bool failed_rewind{false};
1669 : // Can't hold cs_main while calling RewindBlockIndex, so retrieve the relevant
1670 : // chainstates beforehand.
1671 1494 : for (CChainState* chainstate : WITH_LOCK(::cs_main, return chainman.GetAll())) {
1672 498 : if (!fReset) {
1673 : // Note that RewindBlockIndex MUST run even if we're about to -reindex-chainstate.
1674 : // It both disconnects blocks based on the chainstate, and drops block data in
1675 : // BlockIndex() based on lack of available witness data.
1676 490 : uiInterface.InitMessage(_("Rewinding blocks...").translated);
1677 490 : if (!chainstate->RewindBlockIndex(chainparams)) {
1678 0 : strLoadError = _(
1679 : "Unable to rewind the database to a pre-fork state. "
1680 : "You will need to redownload the blockchain");
1681 : failed_rewind = true;
1682 0 : break; // out of the per-chainstate loop
1683 : }
1684 : }
1685 498 : }
1686 :
1687 498 : if (failed_rewind) {
1688 0 : break; // out of the chainstate activation do-while
1689 : }
1690 :
1691 1493 : bool failed_verification = false;
1692 :
1693 : try {
1694 498 : LOCK(cs_main);
1695 :
1696 996 : for (CChainState* chainstate : chainman.GetAll()) {
1697 498 : if (!is_coinsview_empty(chainstate)) {
1698 305 : uiInterface.InitMessage(_("Verifying blocks...").translated);
1699 305 : if (fHavePruned && args.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) {
1700 0 : LogPrintf("Prune: pruned datadir may not have more than %d blocks; only checking available blocks\n",
1701 : MIN_BLOCKS_TO_KEEP);
1702 : }
1703 :
1704 305 : const CBlockIndex* tip = chainstate->m_chain.Tip();
1705 305 : RPCNotifyBlockChange(tip);
1706 305 : if (tip && tip->nTime > GetAdjustedTime() + 2 * 60 * 60) {
1707 0 : strLoadError = _("The block database contains a block which appears to be from the future. "
1708 : "This may be due to your computer's date and time being set incorrectly. "
1709 : "Only rebuild the block database if you are sure that your computer's date and time are correct");
1710 : failed_verification = true;
1711 0 : break;
1712 : }
1713 :
1714 : // Only verify the DB of the active chainstate. This is fixed in later
1715 : // work when we allow VerifyDB to be parameterized by chainstate.
1716 610 : if (&::ChainstateActive() == chainstate &&
1717 610 : !CVerifyDB().VerifyDB(
1718 305 : chainparams, &chainstate->CoinsDB(),
1719 305 : args.GetArg("-checklevel", DEFAULT_CHECKLEVEL),
1720 305 : args.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) {
1721 1 : strLoadError = _("Corrupted block database detected");
1722 : failed_verification = true;
1723 1 : break;
1724 : }
1725 304 : }
1726 497 : }
1727 498 : } catch (const std::exception& e) {
1728 0 : LogPrintf("%s\n", e.what());
1729 0 : strLoadError = _("Error opening block database");
1730 : failed_verification = true;
1731 : break;
1732 0 : }
1733 :
1734 498 : if (!failed_verification) {
1735 : fLoaded = true;
1736 497 : LogPrintf(" block index %15dms\n", GetTimeMillis() - load_block_index_start_time);
1737 497 : }
1738 498 : } while(false);
1739 :
1740 498 : if (!fLoaded && !ShutdownRequested()) {
1741 : // first suggest a reindex
1742 1 : if (!fReset) {
1743 1 : bool fRet = uiInterface.ThreadSafeQuestion(
1744 1 : strLoadError + Untranslated(".\n\n") + _("Do you want to rebuild the block database now?"),
1745 1 : strLoadError.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.",
1746 1 : "", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
1747 1 : if (fRet) {
1748 0 : fReindex = true;
1749 0 : AbortShutdown();
1750 : } else {
1751 1 : LogPrintf("Aborted block database rebuild. Exiting.\n");
1752 1 : return false;
1753 : }
1754 0 : } else {
1755 0 : return InitError(strLoadError);
1756 : }
1757 : }
1758 498 : }
1759 :
1760 : // As LoadBlockIndex can take several minutes, it's possible the user
1761 : // requested to kill the GUI during the last operation. If so, exit.
1762 : // As the program has not fully started yet, Shutdown() is possibly overkill.
1763 497 : if (ShutdownRequested()) {
1764 0 : LogPrintf("Shutdown requested. Exiting.\n");
1765 0 : return false;
1766 : }
1767 :
1768 497 : fs::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME;
1769 497 : CAutoFile est_filein(fsbridge::fopen(est_path, "rb"), SER_DISK, CLIENT_VERSION);
1770 : // Allowed to fail as this file IS missing on first startup.
1771 497 : if (!est_filein.IsNull())
1772 193 : ::feeEstimator.Read(est_filein);
1773 497 : fFeeEstimatesInitialized = true;
1774 :
1775 : // ********************************************************* Step 8: start indexers
1776 497 : if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
1777 6 : g_txindex = MakeUnique<TxIndex>(nTxIndexCache, false, fReindex);
1778 6 : g_txindex->Start();
1779 : }
1780 :
1781 501 : for (const auto& filter_type : g_enabled_filter_types) {
1782 4 : InitBlockFilterIndex(filter_type, filter_index_cache, false, fReindex);
1783 4 : GetBlockFilterIndex(filter_type)->Start();
1784 0 : }
1785 :
1786 : // ********************************************************* Step 9: load wallet
1787 989 : for (const auto& client : node.chain_clients) {
1788 492 : if (!client->load()) {
1789 2 : return false;
1790 : }
1791 490 : }
1792 :
1793 : // ********************************************************* Step 10: data directory maintenance
1794 :
1795 : // if pruning, unset the service bit and perform the initial blockstore prune
1796 : // after any wallet rescanning has taken place.
1797 495 : if (fPruneMode) {
1798 5 : LogPrintf("Unsetting NODE_NETWORK on prune mode\n");
1799 5 : nLocalServices = ServiceFlags(nLocalServices & ~NODE_NETWORK);
1800 5 : if (!fReindex) {
1801 5 : LOCK(cs_main);
1802 10 : for (CChainState* chainstate : chainman.GetAll()) {
1803 5 : uiInterface.InitMessage(_("Pruning blockstore...").translated);
1804 5 : chainstate->PruneAndFlush();
1805 : }
1806 5 : }
1807 : }
1808 :
1809 495 : if (chainparams.GetConsensus().SegwitHeight != std::numeric_limits<int>::max()) {
1810 : // Advertise witness capabilities.
1811 : // The option to not set NODE_WITNESS is only used in the tests and should be removed.
1812 494 : nLocalServices = ServiceFlags(nLocalServices | NODE_WITNESS);
1813 494 : }
1814 :
1815 : // ********************************************************* Step 11: import blocks
1816 :
1817 495 : if (!CheckDiskSpace(GetDataDir())) {
1818 0 : InitError(strprintf(_("Error: Disk space is low for %s"), GetDataDir()));
1819 0 : return false;
1820 : }
1821 495 : if (!CheckDiskSpace(GetBlocksDir())) {
1822 0 : InitError(strprintf(_("Error: Disk space is low for %s"), GetBlocksDir()));
1823 0 : return false;
1824 : }
1825 :
1826 : // Either install a handler to notify us when genesis activates, or set fHaveGenesis directly.
1827 : // No locking, as this happens before any background thread is started.
1828 495 : boost::signals2::connection block_notify_genesis_wait_connection;
1829 495 : if (::ChainActive().Tip() == nullptr) {
1830 193 : block_notify_genesis_wait_connection = uiInterface.NotifyBlockTip_connect(std::bind(BlockNotifyGenesisWait, std::placeholders::_2));
1831 193 : } else {
1832 302 : fHaveGenesis = true;
1833 : }
1834 :
1835 : #if HAVE_SYSTEM
1836 495 : const std::string block_notify = args.GetArg("-blocknotify", "");
1837 495 : if (!block_notify.empty()) {
1838 156 : uiInterface.NotifyBlockTip_connect([block_notify](SynchronizationState sync_state, const CBlockIndex* pBlockIndex) {
1839 113 : if (sync_state != SynchronizationState::POST_INIT || !pBlockIndex) return;
1840 112 : std::string command = block_notify;
1841 112 : boost::replace_all(command, "%s", pBlockIndex->GetBlockHash().GetHex());
1842 112 : std::thread t(runCommand, command);
1843 112 : t.detach(); // thread runs free
1844 113 : });
1845 1 : }
1846 : #endif
1847 :
1848 495 : std::vector<fs::path> vImportFiles;
1849 496 : for (const std::string& strFile : args.GetArgs("-loadblock")) {
1850 1 : vImportFiles.push_back(strFile);
1851 : }
1852 :
1853 9900 : g_load_block = std::thread(&TraceThread<std::function<void()>>, "loadblk", [=, &chainman, &args] {
1854 495 : ThreadImport(chainman, vImportFiles, args);
1855 495 : });
1856 :
1857 : // Wait for genesis block to be processed
1858 : {
1859 495 : WAIT_LOCK(g_genesis_wait_mutex, lock);
1860 : // We previously could hang here if StartShutdown() is called prior to
1861 : // ThreadImport getting started, so instead we just wait on a timer to
1862 : // check ShutdownRequested() regularly.
1863 681 : while (!fHaveGenesis && !ShutdownRequested()) {
1864 186 : g_genesis_wait_cv.wait_for(lock, std::chrono::milliseconds(500));
1865 : }
1866 495 : block_notify_genesis_wait_connection.disconnect();
1867 495 : }
1868 :
1869 495 : if (ShutdownRequested()) {
1870 0 : return false;
1871 : }
1872 :
1873 : // ********************************************************* Step 12: start node
1874 :
1875 495 : int chain_active_height;
1876 :
1877 : //// debug print
1878 : {
1879 495 : LOCK(cs_main);
1880 495 : LogPrintf("block tree size = %u\n", chainman.BlockIndex().size());
1881 495 : chain_active_height = chainman.ActiveChain().Height();
1882 495 : if (tip_info) {
1883 0 : tip_info->block_height = chain_active_height;
1884 0 : tip_info->block_time = chainman.ActiveChain().Tip() ? chainman.ActiveChain().Tip()->GetBlockTime() : Params().GenesisBlock().GetBlockTime();
1885 0 : tip_info->verification_progress = GuessVerificationProgress(Params().TxData(), chainman.ActiveChain().Tip());
1886 0 : }
1887 495 : if (tip_info && ::pindexBestHeader) {
1888 0 : tip_info->header_height = ::pindexBestHeader->nHeight;
1889 0 : tip_info->header_time = ::pindexBestHeader->GetBlockTime();
1890 0 : }
1891 495 : }
1892 495 : LogPrintf("nBestHeight = %d\n", chain_active_height);
1893 :
1894 495 : if (args.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION))
1895 0 : StartTorControl();
1896 :
1897 495 : Discover();
1898 :
1899 : // Map ports with UPnP
1900 495 : if (args.GetBoolArg("-upnp", DEFAULT_UPNP)) {
1901 0 : StartMapPort();
1902 : }
1903 :
1904 495 : CConnman::Options connOptions;
1905 495 : connOptions.nLocalServices = nLocalServices;
1906 495 : connOptions.nMaxConnections = nMaxConnections;
1907 495 : connOptions.m_max_outbound_full_relay = std::min(MAX_OUTBOUND_FULL_RELAY_CONNECTIONS, connOptions.nMaxConnections);
1908 495 : connOptions.m_max_outbound_block_relay = std::min(MAX_BLOCK_RELAY_ONLY_CONNECTIONS, connOptions.nMaxConnections-connOptions.m_max_outbound_full_relay);
1909 495 : connOptions.nMaxAddnode = MAX_ADDNODE_CONNECTIONS;
1910 495 : connOptions.nMaxFeeler = MAX_FEELER_CONNECTIONS;
1911 495 : connOptions.nBestHeight = chain_active_height;
1912 495 : connOptions.uiInterface = &uiInterface;
1913 495 : connOptions.m_banman = node.banman.get();
1914 495 : connOptions.m_msgproc = node.peerman.get();
1915 495 : connOptions.nSendBufferMaxSize = 1000 * args.GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER);
1916 495 : connOptions.nReceiveFloodSize = 1000 * args.GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER);
1917 495 : connOptions.m_added_nodes = args.GetArgs("-addnode");
1918 :
1919 495 : connOptions.nMaxOutboundTimeframe = nMaxOutboundTimeframe;
1920 495 : connOptions.nMaxOutboundLimit = nMaxOutboundLimit;
1921 495 : connOptions.m_peer_connect_timeout = peer_connect_timeout;
1922 :
1923 988 : for (const std::string& strBind : args.GetArgs("-bind")) {
1924 493 : CService addrBind;
1925 493 : if (!Lookup(strBind, addrBind, GetListenPort(), false)) {
1926 0 : return InitError(ResolveErrMsg("bind", strBind));
1927 : }
1928 493 : connOptions.vBinds.push_back(addrBind);
1929 493 : }
1930 497 : for (const std::string& strBind : args.GetArgs("-whitebind")) {
1931 2 : NetWhitebindPermissions whitebind;
1932 2 : bilingual_str error;
1933 2 : if (!NetWhitebindPermissions::TryParse(strBind, whitebind, error)) return InitError(error);
1934 1 : connOptions.vWhiteBinds.push_back(whitebind);
1935 2 : }
1936 :
1937 555 : for (const auto& net : args.GetArgs("-whitelist")) {
1938 61 : NetWhitelistPermissions subnet;
1939 61 : bilingual_str error;
1940 61 : if (!NetWhitelistPermissions::TryParse(net, subnet, error)) return InitError(error);
1941 59 : connOptions.vWhitelistedRange.push_back(subnet);
1942 61 : }
1943 :
1944 492 : connOptions.vSeedNodes = args.GetArgs("-seednode");
1945 :
1946 : // Initiate outbound connections unless connect=0
1947 492 : connOptions.m_use_addrman_outgoing = !args.IsArgSet("-connect");
1948 492 : if (!connOptions.m_use_addrman_outgoing) {
1949 1 : const auto connect = args.GetArgs("-connect");
1950 1 : if (connect.size() != 1 || connect[0] != "0") {
1951 1 : connOptions.m_specified_outgoing = connect;
1952 : }
1953 1 : }
1954 492 : if (!node.connman->Start(*node.scheduler, connOptions)) {
1955 0 : return false;
1956 : }
1957 :
1958 : // ********************************************************* Step 13: finished
1959 :
1960 492 : SetRPCWarmupFinished();
1961 492 : uiInterface.InitMessage(_("Done loading").translated);
1962 :
1963 979 : for (const auto& client : node.chain_clients) {
1964 487 : client->start(*node.scheduler);
1965 : }
1966 :
1967 492 : BanMan* banman = node.banman.get();
1968 987 : node.scheduler->scheduleEvery([banman]{
1969 3 : banman->DumpBanlist();
1970 495 : }, DUMP_BANS_INTERVAL);
1971 :
1972 : return true;
1973 529 : }
|