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