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