PIVX Core  5.6.99
P2P Digital Currency
init.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2021 The Bitcoin developers
3 // Copyright (c) 2014-2015 The Dash developers
4 // Copyright (c) 2011-2013 The PPCoin developers
5 // Copyright (c) 2013-2014 The NovaCoin Developers
6 // Copyright (c) 2014-2018 The BlackCoin Developers
7 // Copyright (c) 2015-2022 The PIVX Core developers
8 // Distributed under the MIT software license, see the accompanying
9 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
10 
11 #if defined(HAVE_CONFIG_H)
12 #include "config/pivx-config.h"
13 #endif
14 
15 #include "init.h"
16 
17 #include "activemasternode.h"
18 #include "addrman.h"
19 #include "amount.h"
20 #include "bls/bls_wrapper.h"
21 #include "checkpoints.h"
22 #include "compat/sanity.h"
23 #include "consensus/upgrades.h"
24 #include "fs.h"
25 #include "httpserver.h"
26 #include "httprpc.h"
27 #include "invalid.h"
28 #include "key.h"
29 #include "mapport.h"
30 #include "miner.h"
31 #include "netbase.h"
32 #include "net_processing.h"
33 #include "policy/feerate.h"
34 #include "policy/policy.h"
35 #include "rpc/register.h"
36 #include "rpc/server.h"
37 #include "script/sigcache.h"
38 #include "script/standard.h"
39 #include "scheduler.h"
40 #include "shutdown.h"
41 #include "spork.h"
42 #include "sporkdb.h"
43 #include "tiertwo/init.h"
44 #include "txdb.h"
45 #include "torcontrol.h"
46 #include "guiinterface.h"
47 #include "guiinterfaceutil.h"
48 #include "util/system.h"
49 #include "utilmoneystr.h"
50 #include "util/threadnames.h"
51 #include "validation.h"
52 #include "validationinterface.h"
53 #include "warnings.h"
54 
55 #ifdef ENABLE_WALLET
56 #include "wallet/init.h"
57 #include "wallet/wallet.h"
58 #include "wallet/rpcwallet.h"
59 #endif
60 
61 #include <atomic>
62 #include <fstream>
63 #include <stdint.h>
64 #include <stdio.h>
65 #include <memory>
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.hpp>
75 #include <boost/algorithm/string/split.hpp>
76 #include <boost/algorithm/string/replace.hpp>
77 #include <boost/thread.hpp>
78 
79 #if ENABLE_ZMQ
81 #endif
82 
83 
84 volatile bool fFeeEstimatesInitialized = false;
85 static const bool DEFAULT_PROXYRANDOMIZE = true;
86 static const bool DEFAULT_REST_ENABLE = false;
87 static const bool DEFAULT_DISABLE_SAFEMODE = false;
88 static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
89 
90 std::unique_ptr<CConnman> g_connman;
91 std::unique_ptr<PeerLogicValidation> peerLogic;
92 
93 #if ENABLE_ZMQ
94 static CZMQNotificationInterface* pzmqNotificationInterface = nullptr;
95 #endif
96 
97 #ifdef WIN32
98 // Win32 LevelDB doesn't use filedescriptors, and the ones used for
99 // accessing block files, don't count towards to fd_set size limit
100 // anyway.
101 #define MIN_CORE_FILEDESCRIPTORS 0
102 #else
103 #define MIN_CORE_FILEDESCRIPTORS 150
104 #endif
105 
106 static const char* DEFAULT_ASMAP_FILENAME="ip_asn.map";
107 
108 static const char* FEE_ESTIMATES_FILENAME = "fee_estimates.dat";
109 CClientUIInterface uiInterface; // Declared but not defined in guiinterface.h
110 
114 const char * const PIVX_PID_FILENAME = "pivx.pid";
115 
116 fs::path GetPidFile()
117 {
118  fs::path pathPidFile(gArgs.GetArg("-pid", PIVX_PID_FILENAME));
119  return AbsPathForConfigVal(pathPidFile);
120 }
121 
122 NODISCARD static bool CreatePidFile()
123 {
124  FILE* file = fsbridge::fopen(GetPidFile(), "w");
125  if (file) {
126  fprintf(file, "%d\n", getpid());
127  fclose(file);
128  return true;
129  } else {
130  return UIError(strprintf(_("Unable to create the PID file '%s': %s"), GetPidFile().string(), std::strerror(errno)));
131  }
132 }
133 
135 //
136 // Shutdown
137 //
138 
139 //
140 // Thread management and startup/shutdown:
141 //
142 // The network-processing threads are all part of a thread group
143 // created by AppInit() or the Qt main() function.
144 //
145 // A clean exit happens when StartShutdown() or the SIGTERM
146 // signal handler sets ShutdownRequested(), which triggers
147 // the DetectShutdownThread(), which interrupts the main thread group.
148 // DetectShutdownThread() then exits, which causes AppInit() to
149 // continue (it .joins the shutdown thread).
150 // Shutdown() is then
151 // called to clean up database connections, and stop other
152 // threads that should only be stopped after the main network-processing
153 // threads have exited.
154 //
155 // Shutdown for Qt is very similar, only it uses a QTimer to detect
156 // ShutdownRequested() getting set, and then does the normal Qt
157 // shutdown thing.
158 //
159 
161 {
162 public:
164  bool GetCoin(const COutPoint& outpoint, Coin& coin) const override
165  {
166  try {
167  return CCoinsViewBacked::GetCoin(outpoint, coin);
168  } catch (const std::runtime_error& e) {
169  uiInterface.ThreadSafeMessageBox(_("Error reading from database, shutting down."), "", CClientUIInterface::MSG_ERROR);
170  LogPrintf("Error reading from database: %s\n", e.what());
171  // Starting the shutdown sequence and returning false to the caller would be
172  // interpreted as 'entry not found' (as opposed to unable to read data), and
173  // could lead to invalid interpration. Just exit immediately, as we can't
174  // continue anyway, and all writes should be atomic.
175  abort();
176  }
177  }
178  // Writes do not need similar protection, as failure to write is handled by the caller.
179 };
180 
181 static std::unique_ptr<CCoinsViewErrorCatcher> pcoinscatcher;
182 static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
183 
184 static boost::thread_group threadGroup;
185 static CScheduler scheduler;
186 void Interrupt()
187 {
190  InterruptRPC();
191  InterruptREST();
195  if (g_connman)
196  g_connman->Interrupt();
197 }
198 
199 void Shutdown()
200 {
201  StartShutdown(); // Needed when we shutdown the wallet
202  LogPrintf("%s: In progress...\n", __func__);
203  static RecursiveMutex cs_Shutdown;
204  TRY_LOCK(cs_Shutdown, lockShutdown);
205  if (!lockShutdown)
206  return;
207 
212  util::ThreadRename("pivx-shutoff");
214  StopHTTPRPC();
215  StopREST();
216  StopRPC();
217  StopHTTPServer();
219 #ifdef ENABLE_WALLET
220  for (CWalletRef pwallet : vpwallets) {
221  pwallet->Flush(false);
222  }
223  GenerateBitcoins(false, nullptr, 0);
224 #endif
225  StopMapPort();
226 
227  // Because these depend on each-other, we make sure that neither can be
228  // using the other before destroying them.
230  if (g_connman) g_connman->Stop();
231 
232  StopTorControl();
233 
234  // After everything has been shut down, but before things get flushed, stop the
235  // CScheduler/checkqueue threadGroup
236  scheduler.stop();
237  threadGroup.interrupt_all();
238  threadGroup.join_all();
239 
240  // After the threads that potentially access these pointers have been stopped,
241  // destruct and reset all to nullptr.
242  g_connman.reset();
243  peerLogic.reset();
244 
245  DumpTierTwo();
246  if (::mempool.IsLoaded() && gArgs.GetBoolArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
247  DumpMempool(::mempool);
248  }
249 
251  fs::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME;
252  CAutoFile est_fileout(fsbridge::fopen(est_path, "wb"), SER_DISK, CLIENT_VERSION);
253  if (!est_fileout.IsNull())
254  mempool.WriteFeeEstimates(est_fileout);
255  else
256  LogPrintf("%s: Failed to write fee estimates to %s\n", __func__, est_path.string());
257  fFeeEstimatesInitialized = false;
258  }
259 
260  // FlushStateToDisk generates a SetBestChain callback, which we should avoid missing
261  if (pcoinsTip != nullptr) {
263  }
264 
265  // After there are no more peers/RPC left to give us new data which may generate
266  // CValidationInterface callbacks, flush them...
268 
269  // Any future callbacks will be dropped. This should absolutely be safe - if
270  // missing a callback results in an unrecoverable situation, unclean shutdown
271  // would too. The only reason to do the above flushes is to let the wallet catch
272  // up with our current chain to avoid any strange pruning edge cases and make
273  // next startup faster by avoiding rescan.
274 
275  {
276  LOCK(cs_main);
277  if (pcoinsTip != nullptr) {
279 
280  //record that client took the proper shutdown procedure
281  pblocktree->WriteFlag("shutdown", true);
282  }
283  pcoinsTip.reset();
284  pcoinscatcher.reset();
285  pcoinsdbview.reset();
286  pblocktree.reset();
287  zerocoinDB.reset();
288  accumulatorCache.reset();
289  pSporkDB.reset();
290  DeleteTierTwo();
291  }
292 #ifdef ENABLE_WALLET
293  for (CWalletRef pwallet : vpwallets) {
294  pwallet->Flush(true);
295  }
296 #endif
297 
298  // Tier two
300 
301 #if ENABLE_ZMQ
302  if (pzmqNotificationInterface) {
303  UnregisterValidationInterface(pzmqNotificationInterface);
304  delete pzmqNotificationInterface;
305  pzmqNotificationInterface = nullptr;
306  }
307 #endif
308 
309  // Disconnect all slots
312 
313 #ifndef WIN32
314  try {
315  if (!fs::remove(GetPidFile())) {
316  LogPrintf("%s: Unable to remove PID file: File does not exist\n", __func__);
317  }
318  } catch (const fs::filesystem_error& e) {
319  LogPrintf("%s: Unable to remove PID file: %s\n", __func__, e.what());
320  }
321 #endif
322 
323 #ifdef ENABLE_WALLET
324  for (CWalletRef pwallet : vpwallets) {
325  delete pwallet;
326  }
327  vpwallets.clear();
328 #endif
329  globalVerifyHandle.reset();
330  ECC_Stop();
331  LogPrintf("%s: done\n", __func__);
332 }
333 
337 void HandleSIGTERM(int)
338 {
339  StartShutdown();
340 }
341 
342 void HandleSIGHUP(int)
343 {
344  g_logger->m_reopen_file = true;
345 }
346 
347 #ifndef WIN32
348 static void registerSignalHandler(int signal, void(*handler)(int))
349 {
350  struct sigaction sa{};
351  sa.sa_handler = handler;
352  sigemptyset(&sa.sa_mask);
353  sa.sa_flags = 0;
354  sigaction(signal, &sa, nullptr);
355 }
356 #endif
357 
359 {
361 }
362 
364 {
366  // TODO: remove unused parameter fInitialDownload
367  RPCNotifyBlockChange(false, nullptr);
368  g_best_block_cv.notify_all();
369  LogPrint(BCLog::RPC, "RPC stopped.\n");
370 }
371 
372 void OnRPCPreCommand(const CRPCCommand& cmd)
373 {
374  // Observe safe mode
375  std::string strWarning = GetWarnings("rpc");
376  if (!strWarning.empty() && !gArgs.GetBoolArg("-disablesafemode", DEFAULT_DISABLE_SAFEMODE) &&
377  !cmd.okSafeMode)
378  throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, std::string("Safe mode: ") + strWarning);
379 }
380 
381 std::string HelpMessage(HelpMessageMode mode)
382 {
383  const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN);
384  const auto testnetBaseParams = CreateBaseChainParams(CBaseChainParams::TESTNET);
385  const auto defaultChainParams = CreateChainParams(CBaseChainParams::MAIN);
386  const auto testnetChainParams = CreateChainParams(CBaseChainParams::TESTNET);
387  const bool showDebug = gArgs.GetBoolArg("-help-debug", false);
388 
389  // When adding new options to the categories, please keep and ensure alphabetical ordering.
390  std::string strUsage = HelpMessageGroup("Options:");
391  strUsage += HelpMessageOpt("-?", "This help message");
392  strUsage += HelpMessageOpt("-version", "Print version and exit");
393  strUsage += HelpMessageOpt("-alertnotify=<cmd>", "Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)");
394  strUsage += HelpMessageOpt("-blocksdir=<dir>", "Specify directory to hold blocks subdirectory for *.dat files (default: <datadir>)");
395  strUsage += HelpMessageOpt("-blocknotify=<cmd>", "Execute command when the best block changes (%s in cmd is replaced by block hash)");
396  strUsage += HelpMessageOpt("-checkblocks=<n>", strprintf("How many blocks to check at startup (default: %u, 0 = all)", DEFAULT_CHECKBLOCKS));
397  strUsage += HelpMessageOpt("-checklevel=<n>", strprintf("How thorough the block verification of -checkblocks is (0-4, default: %u)", DEFAULT_CHECKLEVEL));
398 
399  strUsage += HelpMessageOpt("-conf=<file>", strprintf("Specify configuration file (default: %s)", PIVX_CONF_FILENAME));
400  if (mode == HMM_BITCOIND) {
401 #if !defined(WIN32)
402  strUsage += HelpMessageOpt("-daemon", "Run in the background as a daemon and accept commands");
403 #endif
404  }
405  strUsage += HelpMessageOpt("-datadir=<dir>", "Specify data directory");
406  if (showDebug) {
407  strUsage += HelpMessageOpt("-dbbatchsize", strprintf("Maximum database write batch size in bytes (default: %u)", nDefaultDbBatchSize));
408  }
409  strUsage += HelpMessageOpt("-paramsdir=<dir>", strprintf("Specify zk params directory (default: %s)", ZC_GetParamsDir().string()));
410  strUsage += HelpMessageOpt("-debuglogfile=<file>", strprintf("Specify location of debug log file: this can be an absolute path or a path relative to the data directory (default: %s)", DEFAULT_DEBUGLOGFILE));
411  strUsage += HelpMessageOpt("-disablesystemnotifications", strprintf("Disable OS notifications for incoming transactions (default: %u)", 0));
412  strUsage += HelpMessageOpt("-dbcache=<n>", strprintf("Set database cache size in megabytes (%d to %d, default: %d)", nMinDbCache, nMaxDbCache, nDefaultDbCache));
413  strUsage += HelpMessageOpt("-loadblock=<file>", "Imports blocks from external blk000??.dat file on startup");
414  strUsage += HelpMessageOpt("-maxreorg=<n>", strprintf("Set the Maximum reorg depth (default: %u)", DEFAULT_MAX_REORG_DEPTH));
415  strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf("Keep at most <n> unconnectable transactions in memory (default: %u)", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
416  strUsage += HelpMessageOpt("-maxmempool=<n>", strprintf("Keep the transaction memory pool below <n> megabytes (default: %u)", DEFAULT_MAX_MEMPOOL_SIZE));
417  strUsage += HelpMessageOpt("-mempoolexpiry=<n>", strprintf("Do not keep transactions in the mempool longer than <n> hours (default: %u)", DEFAULT_MEMPOOL_EXPIRY));
418  strUsage += HelpMessageOpt("-persistmempool", strprintf("Whether to save the mempool on shutdown and load on restart (default: %u)", DEFAULT_PERSIST_MEMPOOL));
419  strUsage += HelpMessageOpt("-par=<n>", strprintf("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)", -GetNumCores(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS));
420 #ifndef WIN32
421  strUsage += HelpMessageOpt("-pid=<file>", strprintf("Specify pid file (default: %s)", PIVX_PID_FILENAME));
422 #endif
423  strUsage += HelpMessageOpt("-reindex-chainstate", "Rebuild chain state from the currently indexed blocks");
424  strUsage += HelpMessageOpt("-reindex", "Rebuild block chain index from current blk000??.dat files on startup");
425  strUsage += HelpMessageOpt("-resync", "Delete blockchain folders and resync from scratch on startup");
426 #if !defined(WIN32)
427  strUsage += HelpMessageOpt("-sysperms", "Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)");
428 #endif
429  strUsage += HelpMessageOpt("-txindex", strprintf("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)", DEFAULT_TXINDEX));
430  strUsage += HelpMessageOpt("-forcestart", "Attempt to force blockchain corruption recovery on startup");
431 
432  strUsage += HelpMessageGroup("Connection options:");
433  strUsage += HelpMessageOpt("-addnode=<ip>", "Add a node to connect to and attempt to keep the connection open");
434  strUsage += HelpMessageOpt("-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));
435  strUsage += HelpMessageOpt("-banscore=<n>", strprintf("Threshold for disconnecting misbehaving peers (default: %u)", DEFAULT_BANSCORE_THRESHOLD));
436  strUsage += HelpMessageOpt("-bantime=<n>", strprintf("Number of seconds to keep misbehaving peers from reconnecting (default: %u)", DEFAULT_MISBEHAVING_BANTIME));
437  strUsage += HelpMessageOpt("-bind=<addr>", "Bind to given address and always listen on it. Use [host]:port notation for IPv6");
438  strUsage += HelpMessageOpt("-connect=<ip>", "Connect only to the specified node(s); -noconnect or -connect=0 alone to disable automatic connections");
439  strUsage += HelpMessageOpt("-discover", "Discover own IP address (default: 1 when listening and no -externalip)");
440  strUsage += HelpMessageOpt("-dns", strprintf("Allow DNS lookups for -addnode, -seednode and -connect (default: %u)", DEFAULT_NAME_LOOKUP));
441  strUsage += HelpMessageOpt("-dnsseed", "Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect/-noconnect)");
442  strUsage += HelpMessageOpt("-externalip=<ip>", "Specify your own public address");
443  strUsage += HelpMessageOpt("-forcednsseed", strprintf("Always query for peer addresses via DNS lookup (default: %u)", DEFAULT_FORCEDNSSEED));
444  strUsage += HelpMessageOpt("-listen", strprintf("Accept connections from outside (default: %u if no -proxy or -connect/-noconnect)", DEFAULT_LISTEN));
445  strUsage += HelpMessageOpt("-listenonion", strprintf("Automatically create Tor hidden service (default: %d)", DEFAULT_LISTEN_ONION));
446  strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf("Maintain at most <n> connections to peers (default: %u)", DEFAULT_MAX_PEER_CONNECTIONS));
447  strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXRECEIVEBUFFER));
448  strUsage += HelpMessageOpt("-maxsendbuffer=<n>", strprintf("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXSENDBUFFER));
449  strUsage += HelpMessageOpt("-onion=<ip:port>", strprintf("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)", "-proxy"));
450  strUsage += HelpMessageOpt("-onlynet=<net>", "Only connect to nodes in network <net> (ipv4, ipv6 or onion)");
451  strUsage += HelpMessageOpt("-permitbaremultisig", strprintf("Relay non-P2SH multisig (default: %u)", DEFAULT_PERMIT_BAREMULTISIG));
452  strUsage += HelpMessageOpt("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS));
453  strUsage += HelpMessageOpt("-port=<port>", strprintf("Listen for connections on <port> (default: %u or testnet: %u)", defaultChainParams->GetDefaultPort(), testnetChainParams->GetDefaultPort()));
454  strUsage += HelpMessageOpt("-proxy=<ip:port>", "Connect through SOCKS5 proxy");
455  strUsage += HelpMessageOpt("-proxyrandomize", strprintf("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)", DEFAULT_PROXYRANDOMIZE));
456  strUsage += HelpMessageOpt("-seednode=<ip>", "Connect to a node to retrieve peer addresses, and disconnect");
457  strUsage += HelpMessageOpt("-timeout=<n>", strprintf("Specify connection timeout in milliseconds (minimum: 1, default: %d)", DEFAULT_CONNECT_TIMEOUT));
458  strUsage += HelpMessageOpt("-torcontrol=<ip>:<port>", strprintf("Tor control port to use if onion listening enabled (default: %s)", DEFAULT_TOR_CONTROL));
459  strUsage += HelpMessageOpt("-torpassword=<pass>", "Tor control port password (default: empty)");
460  strUsage += HelpMessageOpt("-upnp", strprintf("Use UPnP to map the listening port (default: %u)", DEFAULT_UPNP));
461 #ifdef USE_NATPMP
462  strUsage += HelpMessageOpt("-natpmp", strprintf("Use NAT-PMP to map the listening port (default: %s)", DEFAULT_NATPMP ? "1 when listening and no -proxy" : "0"));
463 #endif // USE_NATPMP
464  strUsage += HelpMessageOpt("-whitebind=<addr>", "Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6");
465  strUsage += HelpMessageOpt("-whitelist=<netmask>", "Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times."
466  " Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway");
467 
468 #if ENABLE_WALLET
469  strUsage += GetWalletHelpString(showDebug);
470 #endif
471 
472  if (mode == HMM_BITCOIN_QT) {
473  strUsage += HelpMessageOpt("-windowtitle=<name>", "Wallet window title");
474  }
475 
476 #if ENABLE_ZMQ
477  strUsage += HelpMessageGroup("ZeroMQ notification options:");
478  strUsage += HelpMessageOpt("-zmqpubhashblock=<address>", "Enable publish hash block in <address>");
479  strUsage += HelpMessageOpt("-zmqpubhashtx=<address>", "Enable publish hash transaction in <address>");
480  strUsage += HelpMessageOpt("-zmqpubrawblock=<address>", "Enable publish raw block in <address>");
481  strUsage += HelpMessageOpt("-zmqpubrawtx=<address>", "Enable publish raw transaction in <address>");
482 #endif
483 
484  strUsage += HelpMessageGroup("Debugging/Testing options:");
485  strUsage += HelpMessageOpt("-uacomment=<cmt>", "Append comment to the user agent string");
486  if (showDebug) {
487  strUsage += HelpMessageOpt("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. Also sets -checkmempool (default: %u)", defaultChainParams->DefaultConsistencyChecks()));
488  strUsage += HelpMessageOpt("-checkmempool=<n>", strprintf("Run checks every <n> transactions (default: %u)", defaultChainParams->DefaultConsistencyChecks()));
489  strUsage += HelpMessageOpt("-checkpoints", strprintf("Only accept block chain matching built-in checkpoints (default: %u)", DEFAULT_CHECKPOINTS_ENABLED));
490  strUsage += HelpMessageOpt("-disablesafemode", strprintf("Disable safemode, override a real safe mode event (default: %u)", DEFAULT_DISABLE_SAFEMODE));
491  strUsage += HelpMessageOpt("-testsafemode", strprintf("Force safe mode (default: %u)", DEFAULT_TESTSAFEMODE));
492  strUsage += HelpMessageOpt("-deprecatedrpc=<method>", "Allows deprecated RPC method(s) to be used");
493  strUsage += HelpMessageOpt("-dropmessagestest=<n>", "Randomly drop 1 of every <n> network messages");
494  strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", "Randomly fuzz 1 of every <n> network messages");
495  strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", DEFAULT_STOPAFTERBLOCKIMPORT));
496  strUsage += HelpMessageOpt("-limitancestorcount=<n>", strprintf("Do not accept transactions if number of in-mempool ancestors is <n> or more (default: %u)", DEFAULT_ANCESTOR_LIMIT));
497  strUsage += HelpMessageOpt("-limitancestorsize=<n>", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds <n> kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT));
498  strUsage += HelpMessageOpt("-limitdescendantcount=<n>", strprintf("Do not accept transactions if any ancestor would have <n> or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT));
499  strUsage += HelpMessageOpt("-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));
500  strUsage += HelpMessageOpt("-sporkkey=<privkey>", "Enable spork administration functionality with the appropriate private key.");
501  strUsage += HelpMessageOpt("-nuparams=upgradeName:activationHeight", "Use given activation height for specified network upgrade (regtest-only)");
502  }
503  strUsage += HelpMessageOpt("-debug=<category>", strprintf("Output debugging information (default: %u, supplying <category> is optional)", 0) + ". " +
504  "If <category> is not supplied, output all debugging information. <category> can be: " + ListLogCategories() + ".");
505  strUsage += HelpMessageOpt("-debugexclude=<category>", "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.");
506  if (showDebug)
507  strUsage += HelpMessageOpt("-nodebug", "Turn off debugging messages, same as -debug=0");
508 
509  strUsage += HelpMessageOpt("-help-debug", "Show all debugging options (usage: --help -help-debug)");
510  strUsage += HelpMessageOpt("-logips", strprintf("Include IP addresses in debug output (default: %u)", DEFAULT_LOGIPS));
511  strUsage += HelpMessageOpt("-logtimestamps", strprintf("Prepend debug output with timestamp (default: %u)", DEFAULT_LOGTIMESTAMPS));
512  strUsage += HelpMessageOpt("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS));
513  if (showDebug) {
514  strUsage += HelpMessageOpt("-mocktime=<n>", "Replace actual time with <n> seconds since epoch (default: 0)");
515  strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit size of signature cache to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE));
516  }
517  strUsage += HelpMessageOpt("-maxtipage=<n>", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE));
518  strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf("Fees (in %s/Kb) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)", CURRENCY_UNIT, FormatMoney(::minRelayTxFee.GetFeePerK())));
519  strUsage += HelpMessageOpt("-printtoconsole", strprintf("Send trace/debug info to console instead of debug.log file (default: %u)", 0));
520  if (showDebug) {
521  strUsage += HelpMessageOpt("-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)));
522  strUsage += HelpMessageOpt("-printpriority", strprintf("Log transaction fee per kB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY));
523  }
524  strUsage += HelpMessageOpt("-shrinkdebugfile", "Shrink debug.log file on client startup (default: 1 when no -debug)");
525  AppendParamsHelpMessages(strUsage, showDebug);
526 
527  strUsage += GetTierTwoHelpString(showDebug);
528 
529  strUsage += HelpMessageGroup("Node relay options:");
530  if (showDebug) {
531  strUsage += HelpMessageOpt("-acceptnonstdtxn",
532  strprintf("Relay and mine \"non-standard\" transactions (%sdefault: %u)",
533  "testnet/regtest only; ",
534  !CreateChainParams(CBaseChainParams::TESTNET)->RequireStandard()));
535  }
536  strUsage += HelpMessageOpt("-datacarrier", strprintf("Relay and mine data carrier transactions (default: %u)", DEFAULT_ACCEPT_DATACARRIER));
537  strUsage += HelpMessageOpt("-datacarriersize", strprintf("Maximum size of data in data carrier transactions we relay and mine (default: %u)", MAX_OP_RETURN_RELAY));
538  if (showDebug) {
539  strUsage += HelpMessageOpt("-blockversion=<n>", "Override block version to test forking scenarios");
540  }
541 
542  strUsage += HelpMessageGroup("Block creation options:");
543  strUsage += HelpMessageOpt("-blockmaxsize=<n>", strprintf("Set maximum block size in bytes (default: %d)", DEFAULT_BLOCK_MAX_SIZE));
544  if (showDebug)
545  strUsage += HelpMessageOpt("-blockversion=<n>", "Override block version to test forking scenarios");
546 
547  strUsage += HelpMessageGroup("RPC server options:");
548  strUsage += HelpMessageOpt("-server", "Accept command line and JSON-RPC commands");
549  strUsage += HelpMessageOpt("-rest", strprintf("Accept public REST requests (default: %u)", DEFAULT_REST_ENABLE));
550  strUsage += HelpMessageOpt("-rpcbind=<addr>", "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)");
551  strUsage += HelpMessageOpt("-rpccookiefile=<loc>", "Location of the auth cookie (default: data dir)");
552  strUsage += HelpMessageOpt("-rpcuser=<user>", "Username for JSON-RPC connections");
553  strUsage += HelpMessageOpt("-rpcpassword=<pw>", "Password for JSON-RPC connections");
554  strUsage += HelpMessageOpt("-rpcauth=<userpw>", "Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. The client then connects normally using the rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This option can be specified multiple times");
555  strUsage += HelpMessageOpt("-rpcport=<port>", strprintf("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort()));
556  strUsage += HelpMessageOpt("-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");
557  strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf("Set the number of threads to service RPC calls (default: %d)", DEFAULT_HTTP_THREADS));
558  if (showDebug) {
559  strUsage += HelpMessageOpt("-rpcworkqueue=<n>", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE));
560  strUsage += HelpMessageOpt("-rpcservertimeout=<n>", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT));
561  }
562 
563  strUsage += HelpMessageOpt("-blockspamfilter=<n>", strprintf("Use block spam filter (default: %u)", DEFAULT_BLOCK_SPAM_FILTER));
564  strUsage += HelpMessageOpt("-blockspamfiltermaxsize=<n>", strprintf("Maximum size of the list of indexes in the block spam filter (default: %u)", DEFAULT_BLOCK_SPAM_FILTER_MAX_SIZE));
565  strUsage += HelpMessageOpt("-blockspamfiltermaxavg=<n>", strprintf("Maximum average size of an index occurrence in the block spam filter (default: %u)", DEFAULT_BLOCK_SPAM_FILTER_MAX_AVG));
566 
567  return strUsage;
568 }
569 
570 std::string LicenseInfo()
571 {
572  return FormatParagraph(strprintf(_("Copyright (C) 2009-%i The Bitcoin Core Developers"), COPYRIGHT_YEAR)) + "\n" +
573  "\n" +
574  FormatParagraph(strprintf(_("Copyright (C) 2014-%i The Dash Core Developers"), COPYRIGHT_YEAR)) + "\n" +
575  "\n" +
576  FormatParagraph(strprintf(_("Copyright (C) 2015-%i The %s Developers"), COPYRIGHT_YEAR, PACKAGE_NAME)) + "\n" +
577  "\n" +
578  FormatParagraph(_("This is experimental software.")) + "\n" +
579  "\n" +
580  FormatParagraph(_("Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.")) + "\n" +
581  "\n" +
582  FormatParagraph(_("This product includes UPnP software written by Thomas Bernard.")) +
583  "\n";
584 }
585 
586 static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex)
587 {
588 
589  if (initialSync || !pBlockIndex)
590  return;
591 
592  std::string strCmd = gArgs.GetArg("-blocknotify", "");
593 
594  if (!strCmd.empty()) {
595  boost::replace_all(strCmd, "%s", pBlockIndex->GetBlockHash().GetHex());
596  std::thread t(runCommand, strCmd);
597  t.detach(); // thread runs free
598  }
599 }
600 
602 
603 static bool fHaveGenesis = false;
604 static std::mutex cs_GenesisWait;
605 static std::condition_variable condvar_GenesisWait;
606 
607 static void BlockNotifyGenesisWait(bool, const CBlockIndex *pBlockIndex)
608 {
609  if (pBlockIndex != nullptr) {
610  {
611  std::unique_lock<std::mutex> lock_GenesisWait(cs_GenesisWait);
612  fHaveGenesis = true;
613  }
614  condvar_GenesisWait.notify_all();
615  }
616 }
617 
619 
620 
623  {
624  assert(fImporting == false);
625  fImporting = true;
626  }
627 
629  {
630  assert(fImporting == true);
631  fImporting = false;
632  }
633 };
634 
635 void ThreadImport(const std::vector<fs::path>& vImportFiles)
636 {
637  util::ThreadRename("pivx-loadblk");
638  CImportingNow imp;
640 
641  // -reindex
642  if (fReindex) {
643  int nFile = 0;
644  while (true) {
645  FlatFilePos pos(nFile, 0);
646  if (!fs::exists(GetBlockPosFilename(pos)))
647  break; // No block files left to reindex
648  FILE* file = OpenBlockFile(pos, true);
649  if (!file)
650  break; // This error is logged in OpenBlockFile
651  LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
652  LoadExternalBlockFile(file, &pos);
653  nFile++;
654  }
655  pblocktree->WriteReindexing(false);
656  fReindex = false;
657  LogPrintf("Reindexing finished\n");
658  // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
659  if (!LoadGenesisBlock()) {
660  throw std::runtime_error("Error initializing block database");
661  }
662  }
663 
664  // hardcoded $DATADIR/bootstrap.dat
665  fs::path pathBootstrap = GetDataDir() / "bootstrap.dat";
666  if (fs::exists(pathBootstrap)) {
667  FILE* file = fsbridge::fopen(pathBootstrap, "rb");
668  if (file) {
669  fs::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
670  LogPrintf("Importing bootstrap.dat...\n");
671  LoadExternalBlockFile(file);
672  RenameOver(pathBootstrap, pathBootstrapOld);
673  } else {
674  LogPrintf("Warning: Could not open bootstrap file %s\n", pathBootstrap.string());
675  }
676  }
677 
678  // -loadblock=
679  for (const fs::path& path : vImportFiles) {
680  FILE* file = fsbridge::fopen(path, "rb");
681  if (file) {
682  LogPrintf("Importing blocks file %s...\n", path.string());
683  LoadExternalBlockFile(file);
684  } else {
685  LogPrintf("Warning: Could not open blocks file %s\n", path.string());
686  }
687  }
688 
689  if (gArgs.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) {
690  LogPrintf("Stopping after block import\n");
691  StartShutdown();
692  }
693 
694  // scan for better chains in the block chain database, that are not yet connected in the active best chain
695  CValidationState state;
696  if (!ActivateBestChain(state)) {
697  LogPrintf("Failed to connect best block\n");
698  StartShutdown();
699  }
700 
701  // tier two
703 
704  if (gArgs.GetBoolArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
705  LoadMempool(::mempool);
706  }
708 }
709 
714 bool InitSanityCheck(void)
715 {
716  if (!ECC_InitSanityCheck()) {
717  UIError(_("Elliptic curve cryptography sanity check failure. Aborting."));
718  return false;
719  }
720 
721  if (!glibc_sanity_test() || !glibcxx_sanity_test()) {
722  return false;
723  }
724 
725  if (!Random_SanityCheck()) {
726  UIError(_("OS cryptographic RNG sanity check failure. Aborting."));
727  return false;
728  }
729 
730  if (!BLSInit()) {
731  return false;
732  }
733 
734  return true;
735 }
736 
737 static void LoadSaplingParams()
738 {
739  struct timeval tv_start{}, tv_end{};
740  float elapsed;
741  gettimeofday(&tv_start, nullptr);
742 
743  try {
744  initZKSNARKS();
745  } catch (std::runtime_error &e) {
746  std::string strError = strprintf(_("Cannot find the Sapling parameters in the following directory:\n%s"), ZC_GetParamsDir());
747  std::string strErrorPosix = strprintf(_("Please run the included %s script and then restart."), "install-params.sh");
748  std::string strErrorWin = strprintf(_("Please copy the included params files to the %s directory."), ZC_GetParamsDir());
749  uiInterface.ThreadSafeMessageBox(strError + "\n"
750 #ifndef WIN32
751  + strErrorPosix,
752 #else
753  + strErrorWin,
754 #endif
756  StartShutdown();
757  return;
758  }
759 
760  gettimeofday(&tv_end, nullptr);
761  elapsed = float(tv_end.tv_sec-tv_start.tv_sec) + (tv_end.tv_usec-tv_start.tv_usec)/float(1000000);
762  LogPrintf("Loaded Sapling parameters in %fs seconds.\n", elapsed);
763 }
764 
766 {
770  if (!InitHTTPServer())
771  return false;
772  if (!StartRPC())
773  return false;
774  if (!StartHTTPRPC())
775  return false;
776  if (gArgs.GetBoolArg("-rest", DEFAULT_REST_ENABLE) && !StartREST())
777  return false;
778  if (!StartHTTPServer())
779  return false;
780  return true;
781 }
782 
783 [[noreturn]] static void new_handler_terminate()
784 {
785  // Rather than throwing std::bad-alloc if allocation fails, terminate
786  // immediately to (try to) avoid chain corruption.
787  // Since LogPrintf may itself allocate memory, set the handler directly
788  // to terminate first.
789  std::set_new_handler(std::terminate);
790  LogPrintf("Error: Out of memory. Terminating.\n");
791 
792  // The log was successful, terminate now.
793  std::terminate();
794 }
795 
796 namespace { // Variables internal to initialization process only
797 
798  ServiceFlags nRelevantServices = NODE_NETWORK;
799  int nMaxConnections;
800  int nUserMaxConnections;
801  int nFD;
802  ServiceFlags nLocalServices = NODE_NETWORK;
803 }
804 
806 {
807 // ********************************************************* Step 1: setup
808 #ifdef _MSC_VER
809  // Turn off Microsoft heap dump noise
810  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
811  _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, 0));
812 #endif
813 #if _MSC_VER >= 1400
814  // Disable confusing "helpful" text message on abort, Ctrl-C
815  _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
816 #endif
817 #ifdef WIN32
818  // Enable Data Execution Prevention (DEP)
819 // Minimum supported OS versions: WinXP SP3, WinVista >= SP1, Win Server 2008
820 // A failure is non-critical and needs no further attention!
821 #ifndef PROCESS_DEP_ENABLE
822 // We define this here, because GCCs winbase.h limits this to _WIN32_WINNT >= 0x0601 (Windows 7),
823 // which is not correct. Can be removed, when GCCs winbase.h is fixed!
824 #define PROCESS_DEP_ENABLE 0x00000001
825 #endif
826  typedef BOOL(WINAPI * PSETPROCDEPPOL)(DWORD);
827  PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy");
828  if (setProcDEPPol != nullptr) setProcDEPPol(PROCESS_DEP_ENABLE);
829 #endif
830 
831  if (!SetupNetworking())
832  return UIError(_("Error: Initializing networking failed"));
833 
834 #ifndef WIN32
835  if (!gArgs.GetBoolArg("-sysperms", false)) {
836  umask(077);
837  }
838 
839  // Clean shutdown on SIGTERMx
840  registerSignalHandler(SIGTERM, HandleSIGTERM);
841  registerSignalHandler(SIGINT, HandleSIGTERM);
842 
843  // Reopen debug.log on SIGHUP
844  registerSignalHandler(SIGHUP, HandleSIGHUP);
845 
846  // Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly
847  signal(SIGPIPE, SIG_IGN);
848 #endif
849 
850  std::set_new_handler(new_handler_terminate);
851 
852  return true;
853 }
854 
855 // Parameter interaction based on rules
857 {
858  if (gArgs.IsArgSet("-bind") || gArgs.IsArgSet("-whitebind")) {
859  // when specifying an explicit binding address, you want to listen on it
860  // even when -connect or -proxy is specified
861  if (gArgs.SoftSetBoolArg("-listen", true))
862  LogPrintf("%s : parameter interaction: -bind or -whitebind set -> setting -listen=1\n", __func__);
863  }
864 
865  if (gArgs.IsArgSet("-connect")) {
866  // when only connecting to trusted nodes, do not seed via DNS, or listen by default
867  if (gArgs.SoftSetBoolArg("-dnsseed", false))
868  LogPrintf("%s : parameter interaction: -connect set -> setting -dnsseed=0\n", __func__);
869  if (gArgs.SoftSetBoolArg("-listen", false))
870  LogPrintf("%s : parameter interaction: -connect set -> setting -listen=0\n", __func__);
871  }
872 
873  if (gArgs.IsArgSet("-proxy")) {
874  // to protect privacy, do not listen by default if a default proxy server is specified
875  if (gArgs.SoftSetBoolArg("-listen", false))
876  LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__);
877  // to protect privacy, do not use map ports when a proxy is set. The user may still specify -listen=1
878  // to listen locally, so don't rely on this happening through -listen below.
879  if (gArgs.SoftSetBoolArg("-upnp", false))
880  LogPrintf("%s: parameter interaction: -proxy set -> setting -upnp=0\n", __func__);
881  if (gArgs.SoftSetBoolArg("-natpmp", false)) {
882  LogPrintf("%s: parameter interaction: -proxy set -> setting -natpmp=0\n", __func__);
883  }
884  // to protect privacy, do not discover addresses by default
885  if (gArgs.SoftSetBoolArg("-discover", false))
886  LogPrintf("%s : parameter interaction: -proxy set -> setting -discover=0\n", __func__);
887  }
888 
889  if (!gArgs.GetBoolArg("-listen", DEFAULT_LISTEN)) {
890  // do not map ports or try to retrieve public IP when not listening (pointless)
891  if (gArgs.SoftSetBoolArg("-upnp", false))
892  LogPrintf("%s : parameter interaction: -listen=0 -> setting -upnp=0\n", __func__);
893  if (gArgs.SoftSetBoolArg("-natpmp", false)) {
894  LogPrintf("%s: parameter interaction: -listen=0 -> setting -natpmp=0\n", __func__);
895  }
896  if (gArgs.SoftSetBoolArg("-discover", false))
897  LogPrintf("%s : parameter interaction: -listen=0 -> setting -discover=0\n", __func__);
898  if (gArgs.SoftSetBoolArg("-listenonion", false))
899  LogPrintf("%s : parameter interaction: -listen=0 -> setting -listenonion=0\n", __func__);
900  }
901 
902  if (gArgs.IsArgSet("-externalip")) {
903  // if an explicit public IP is specified, do not try to find others
904  if (gArgs.SoftSetBoolArg("-discover", false))
905  LogPrintf("%s : parameter interaction: -externalip set -> setting -discover=0\n", __func__);
906  }
907 }
908 
910 {
911  if (gArgs.IsArgSet("-nuparams")) {
912  // Allow overriding network upgrade parameters for testing
913  if (Params().NetworkIDString() != "regtest") {
914  return UIError(_("Network upgrade parameters may only be overridden on regtest."));
915  }
916  for (const std::string& strDeployment : gArgs.GetArgs("-nuparams")) {
917  std::vector<std::string> vDeploymentParams;
918  boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":"));
919  if (vDeploymentParams.size() != 2) {
920  return UIError(strprintf(_("Network upgrade parameters malformed, expecting %s"), "hexBranchId:activationHeight"));
921  }
922  int nActivationHeight;
923  if (!ParseInt32(vDeploymentParams[1], &nActivationHeight)) {
924  return UIError(strprintf(_("Invalid activation height (%s)"), vDeploymentParams[1]));
925  }
926  bool found = false;
927  // Exclude base network from upgrades
928  for (auto j = Consensus::BASE_NETWORK + 1; j < Consensus::MAX_NETWORK_UPGRADES; ++j) {
929  if (vDeploymentParams[0] == NetworkUpgradeInfo[j].strName) {
931  found = true;
932  LogPrintf("Setting network upgrade activation parameters for %s to height=%d\n", vDeploymentParams[0], nActivationHeight);
933  break;
934  }
935  }
936  if (!found) {
937  return UIError(strprintf(_("Invalid network upgrade (%s)"), vDeploymentParams[0]));
938  }
939  }
940  }
941  return true;
942 }
943 
944 static std::string ResolveErrMsg(const char * const optname, const std::string& strBind)
945 {
946  return strprintf(_("Cannot resolve -%s address: '%s'"), optname, strBind);
947 }
948 
950 {
951  g_logger->m_print_to_file = !gArgs.IsArgNegated("-debuglogfile");
953 
954  // Add newlines to the logfile to distinguish this execution from the last
955  // one; called before console logging is set up, so this is only sent to
956  // debug.log.
957  LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
958 
959  g_logger->m_print_to_console = gArgs.GetBoolArg("-printtoconsole", !gArgs.GetBoolArg("-daemon", false));
960  g_logger->m_log_timestamps = gArgs.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS);
961  g_logger->m_log_time_micros = gArgs.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS);
962 
963  fLogIPs = gArgs.GetBoolArg("-logips", DEFAULT_LOGIPS);
964 
965  std::string version_string = FormatFullVersion();
966 #ifdef DEBUG
967  version_string += " (debug build)";
968 #else
969  version_string += " (release build)";
970 #endif
971  LogPrintf("PIVX version %s\n", version_string);
972 }
973 
975 {
976  // ********************************************************* Step 2: parameter interactions
977 
978  if (!fs::is_directory(GetBlocksDir())) {
979  return UIError(strprintf(_("Specified blocks directory \"%s\" does not exist."), gArgs.GetArg("-blocksdir", "").c_str()));
980  }
981 
982  // Make sure enough file descriptors are available
983 
984  // -bind and -whitebind can't be set when not listening
985  size_t nUserBind =
986  (gArgs.IsArgSet("-bind") ? gArgs.GetArgs("-bind").size() : 0) +
987  (gArgs.IsArgSet("-whitebind") ? gArgs.GetArgs("-whitebind").size() : 0);
988  if (nUserBind != 0 && !gArgs.GetBoolArg("-listen", DEFAULT_LISTEN)) {
989  return UIError(strprintf(_("Cannot set %s or %s together with %s"), "-bind", "-whitebind", "-listen=0"));
990  }
991 
992  // Make sure enough file descriptors are available
993  int nBind = std::max(nUserBind, size_t(1));
994  nUserMaxConnections = gArgs.GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
995  nMaxConnections = std::max(nUserMaxConnections, 0);
996 
997  // Trim requested connection counts, to fit into system limitations
998  nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS + MAX_ADDNODE_CONNECTIONS);
999 #ifdef USE_POLL
1000  int fd_max = nFD;
1001 #else
1002  int fd_max = FD_SETSIZE;
1003 #endif
1004  nMaxConnections = std::max(std::min<int>(nMaxConnections, fd_max - nBind - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS), 0);
1005  if (nFD < MIN_CORE_FILEDESCRIPTORS)
1006  return UIError(_("Not enough file descriptors available."));
1007  nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS, nMaxConnections);
1008 
1009  // ********************************************************* Step 3: parameter-to-internal-flags
1010 
1011  // Special-case: if -debug=0/-nodebug is set, turn off debugging messages
1012  const std::vector<std::string>& categories = gArgs.GetArgs("-debug");
1013 
1014  if (!(gArgs.GetBoolArg("-nodebug", false) ||
1015  find(categories.begin(), categories.end(), std::string("0")) != categories.end())) {
1016  for (const auto& cat : categories) {
1017  if (!g_logger->EnableCategory(cat)) {
1018  UIWarning(strprintf(_("Unsupported logging category %s=%s."), "-debug", cat));
1019  }
1020  }
1021  }
1022 
1023  // Now remove the logging categories which were explicitly excluded
1024  for (const std::string& cat : gArgs.GetArgs("-debugexclude")) {
1025  if (!g_logger->DisableCategory(cat)) {
1026  UIWarning(strprintf(_("Unsupported logging category %s=%s."), "-debugexclude", cat));
1027  }
1028  }
1029 
1030  // Check for -debugnet
1031  if (gArgs.GetBoolArg("-debugnet", false))
1032  UIWarning(strprintf(_("Warning: Unsupported argument %s ignored, use %s."), "-debugnet", "-debug=net"));
1033  // Check for -socks - as this is a privacy risk to continue, exit here
1034  if (gArgs.IsArgSet("-socks"))
1035  return UIError(
1036  strprintf(_("Error: Unsupported argument %s found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported."), "-socks"));
1037  // Check for -tor - as this is a privacy risk to continue, exit here
1038  if (gArgs.GetBoolArg("-tor", false))
1039  return UIError(strprintf(_("Error: Unsupported argument %s found, use %s."), "-tor", "-onion"));
1040  // Check level must be 4 for zerocoin checks
1041  if (gArgs.IsArgSet("-checklevel"))
1042  return UIError(strprintf(_("Error: Unsupported argument %s found. Checklevel must be level 4."), "-checklevel"));
1043  // Exit early if -masternode=1 and -listen=0
1044  if (gArgs.GetBoolArg("-masternode", DEFAULT_MASTERNODE) && !gArgs.GetBoolArg("-listen", DEFAULT_LISTEN))
1045  return UIError(strprintf(_("Error: %s must be true if %s is set."), "-listen", "-masternode"));
1046  if (gArgs.GetBoolArg("-benchmark", false))
1047  UIWarning(strprintf(_("Warning: Unsupported argument %s ignored, use %s"), "-benchmark", "-debug=bench."));
1048 
1049  // Checkmempool and checkblockindex default to true in regtest mode
1050  int ratio = std::min<int>(
1051  std::max<int>(gArgs.GetArg("-checkmempool", Params().DefaultConsistencyChecks() ? 1 : 0), 0), 1000000);
1052  if (ratio != 0) {
1053  mempool.setSanityCheck(1.0 / ratio);
1054  }
1055  fCheckBlockIndex = gArgs.GetBoolArg("-checkblockindex", Params().DefaultConsistencyChecks());
1056  Checkpoints::fEnabled = gArgs.GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED);
1057 
1058  // -mempoollimit limits
1059  int64_t nMempoolSizeLimit = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1060  int64_t nMempoolDescendantSizeLimit = gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000;
1061  if (nMempoolSizeLimit < 0 || nMempoolSizeLimit < nMempoolDescendantSizeLimit * 40)
1062  return UIError(strprintf(_("Error: %s must be at least %d MB"), "-maxmempool",
1063  gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) / 25));
1064 
1065  // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
1066  nScriptCheckThreads = gArgs.GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
1067  if (nScriptCheckThreads <= 0)
1069  if (nScriptCheckThreads <= 1)
1070  nScriptCheckThreads = 0;
1071  else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS)
1072  nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS;
1073 
1074  setvbuf(stdout, nullptr, _IOLBF, 0);
1075 
1076 #ifndef ENABLE_WALLET
1077  if (gArgs.SoftSetBoolArg("-staking", false))
1078  LogPrintf("AppInit2 : parameter interaction: wallet functionality not enabled -> setting -staking=0\n");
1079 #endif
1080 
1081  nConnectTimeout = gArgs.GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT);
1082  if (nConnectTimeout <= 0)
1083  nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
1084 
1085  // Fee-per-kilobyte amount required for mempool acceptance and relay
1086  // If you are mining, be careful setting this:
1087  // if you set it to zero then
1088  // a transaction spammer can cheaply fill blocks using
1089  // 0-fee transactions. It should be set above the real
1090  // cost to you of processing a transaction.
1091  if (gArgs.IsArgSet("-minrelaytxfee")) {
1092  CAmount n = 0;
1093  if (!ParseMoney(gArgs.GetArg("-minrelaytxfee", ""), n)) {
1094  return UIError(AmountErrMsg("minrelaytxfee", gArgs.GetArg("-minrelaytxfee", "")));
1095  }
1096  // High fee check is done afterward in CWallet::ParameterInteraction()
1098  }
1099 
1100  const CChainParams& chainparams = Params();
1101  fRequireStandard = !gArgs.GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard());
1102  if (!chainparams.IsTestChain() && !fRequireStandard)
1103  return UIError(strprintf("%s is not currently supported for %s chain", "-acceptnonstdtxn", chainparams.NetworkIDString()));
1104 
1105  // Feerate used to define dust. Shouldn't be changed lightly as old
1106  // implementations may inadvertently create non-standard transactions
1107  if (gArgs.IsArgSet("-dustrelayfee")) {
1108  CAmount n = 0;
1109  if (!ParseMoney(gArgs.GetArg("-dustrelayfee", ""), n) || 0 == n)
1110  return UIError(AmountErrMsg("dustrelayfee", gArgs.GetArg("-dustrelayfee", "")));
1111  dustRelayFee = CFeeRate(n);
1112  }
1113 
1114 #ifdef ENABLE_WALLET
1116  return false;
1117 #endif // ENABLE_WALLET
1118 
1119  fIsBareMultisigStd = gArgs.GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG);
1120  nMaxDatacarrierBytes = gArgs.GetArg("-datacarriersize", nMaxDatacarrierBytes);
1121 
1122  // Option to startup with mocktime set (used for regression testing):
1123  if (Params().IsRegTestNet()) {
1124  SetMockTime(gArgs.GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op
1125  }
1126 
1127  if (gArgs.GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS))
1128  nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM);
1129 
1130  nMaxTipAge = gArgs.GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE);
1131 
1132  if (!InitNUParams())
1133  return false;
1134 
1135  return true;
1136 }
1137 
1138 static bool LockDataDirectory(bool probeOnly)
1139 {
1140  // Make sure only a single PIVX process is using the data directory.
1141  fs::path datadir = GetDataDir();
1142  if (!DirIsWritable(datadir)) {
1143  return UIError(strprintf(_("Cannot write to data directory '%s'; check permissions."), datadir.string()));
1144  }
1145  if (!LockDirectory(datadir, ".lock", probeOnly)) {
1146  return UIError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), datadir.string(), PACKAGE_NAME));
1147  }
1148  return true;
1149 }
1150 
1152 {
1153  // ********************************************************* Step 4: sanity checks
1154 
1155  // Initialize elliptic curve code
1156  RandomInit();
1157  ECC_Start();
1158  globalVerifyHandle.reset(new ECCVerifyHandle());
1159 
1160  // Sanity check
1161  if (!InitSanityCheck())
1162  return UIError(strprintf(_("Initialization sanity check failed. %s is shutting down."), PACKAGE_NAME));
1163 
1164  // Probe the data directory lock to give an early error message, if possible
1165  return LockDataDirectory(true);
1166 }
1167 
1169 {
1170  // ********************************************************* Step 4a: application initialization
1171  // After daemonization get the data directory lock again and hold on to it until exit
1172  // This creates a slight window for a race condition to happen, however this condition is harmless: it
1173  // will at most make us exit without printing a message to console.
1174  if (!LockDataDirectory(false)) {
1175  // Detailed error printed inside LockDataDirectory
1176  return false;
1177  }
1178 
1179 #ifndef WIN32
1180  if (!CreatePidFile()) {
1181  // Detailed error printed inside CreatePidFile().
1182  return false;
1183  }
1184 #endif
1185  if (g_logger->m_print_to_file) {
1186  if (gArgs.GetBoolArg("-shrinkdebugfile", g_logger->DefaultShrinkDebugFile()))
1188  if (!g_logger->OpenDebugLog())
1189  return UIError(strprintf(_("Could not open debug log file %s"), g_logger->m_file_path.string()));
1190  }
1191 #ifdef ENABLE_WALLET
1192  LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
1193 #endif
1194  if (!g_logger->m_log_timestamps)
1195  LogPrintf("Startup time: %s\n", FormatISO8601DateTime(GetTime()));
1196  LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
1197  LogPrintf("Using data directory %s\n", GetDataDir().string());
1198  LogPrintf("Using config file %s\n", GetConfigFile(gArgs.GetArg("-conf", PIVX_CONF_FILENAME)).string());
1199  LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD);
1200  std::ostringstream strErrors;
1201 
1202  // Warn about relative -datadir path.
1203  if (gArgs.IsArgSet("-datadir") && !fs::path(gArgs.GetArg("-datadir", "")).is_absolute()) {
1204  LogPrintf("Warning: relative datadir option '%s' specified, which will be interpreted relative to the " /* Continued */
1205  "current working directory '%s'. This is fragile because if PIVX is started in the future " /* Continued */
1206  "from a different location. It will be unable to locate the current data files. There could " /* Continued */
1207  "also be data loss if PIVX is started while in a temporary directory.\n",
1208  gArgs.GetArg("-datadir", ""), fs::current_path().string());
1209  }
1210 
1212 
1213  LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads);
1214  if (nScriptCheckThreads) {
1215  for (int i = 0; i < nScriptCheckThreads - 1; i++)
1216  threadGroup.create_thread(&ThreadScriptCheck);
1217  }
1218 
1219  if (gArgs.IsArgSet("-sporkkey")) // spork priv key
1220  {
1221  if (!sporkManager.SetPrivKey(gArgs.GetArg("-sporkkey", "")))
1222  return UIError(_("Unable to sign spork message, wrong key?"));
1223  }
1224 
1225  // Start the lightweight task scheduler thread
1226  CScheduler::Function serviceLoop = std::bind(&CScheduler::serviceQueue, &scheduler);
1227  threadGroup.create_thread(std::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop));
1228 
1229  // Gather some entropy once per minute.
1231  RandAddPeriodic();
1232  }, 60000);
1233 
1235 
1236  // Initialize Sapling circuit parameters
1237  LoadSaplingParams();
1238 
1239  /* Register RPC commands regardless of -server setting so they will be
1240  * available in the GUI RPC console even if external calls are disabled.
1241  */
1242  RegisterAllCoreRPCCommands(tableRPC);
1243 #ifdef ENABLE_WALLET
1245 #endif
1246 
1247  /* Start the RPC server already. It will be started in "warmup" mode
1248  * and not really process calls already (but it will signify connections
1249  * that the server is there and will be ready later). Warmup mode will
1250  * be disabled when initialisation is finished.
1251  */
1252  if (gArgs.GetBoolArg("-server", false)) {
1254  if (!AppInitServers())
1255  return UIError(_("Unable to start HTTP server. See debug log for details."));
1256  }
1257 
1258  if (gArgs.GetBoolArg("-resync", false)) {
1259  uiInterface.InitMessage(_("Preparing for resync..."));
1260  // Delete the local blockchain folders to force a resync from scratch to get a consistent blockchain-state
1261  fs::path blocksDir = GetBlocksDir();
1262  fs::path chainstateDir = GetDataDir() / "chainstate";
1263  fs::path sporksDir = GetDataDir() / "sporks";
1264  fs::path zerocoinDir = GetDataDir() / "zerocoin";
1265  fs::path evoDir = GetDataDir() / "evodb";
1266 
1267  LogPrintf("Deleting blockchain folders blocks, chainstate, sporks, zerocoin and evodb\n");
1268  std::vector<fs::path> removeDirs{blocksDir, chainstateDir, sporksDir, zerocoinDir, evoDir};
1269  // We delete in 5 individual steps in case one of the folder is missing already
1270  try {
1271  for (const auto& dir : removeDirs) {
1272  if (fs::exists(dir)) {
1273  fs::remove_all(dir);
1274  LogPrintf("-resync: folder deleted: %s\n", dir.string().c_str());
1275  }
1276  }
1277  } catch (const fs::filesystem_error& error) {
1278  LogPrintf("Failed to delete blockchain folders %s\n", error.what());
1279  }
1280  }
1281 
1282 // ********************************************************* Step 5: Verify wallet database integrity
1283 #ifdef ENABLE_WALLET
1284  if (!WalletVerify()) {
1285  return false;
1286  }
1287 #endif
1288 
1289  // ********************************************************* Step 6: network initialization
1290  // Note that we absolutely cannot open any actual connections
1291  // until the very end ("start node") as the UTXO/block state
1292  // is not yet setup and may end up being set up twice if we
1293  // need to reindex later.
1294 
1295  assert(!g_connman);
1296  g_connman = std::make_unique<CConnman>(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max()));
1297  CConnman& connman = *g_connman;
1298 
1299  peerLogic.reset(new PeerLogicValidation(&connman));
1301 
1302  // sanitize comments per BIP-0014, format user agent and check total size
1303  std::vector<std::string> uacomments;
1304  for (const std::string& cmt : gArgs.GetArgs("-uacomment")) {
1305  if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT))
1306  return UIError(strprintf(_("User Agent comment (%s) contains unsafe characters."), cmt));
1307  uacomments.push_back(cmt);
1308  }
1309 
1310  // format user agent, check total size
1311  strSubVersion = FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, uacomments);
1312  if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) {
1313  return UIError(strprintf(_("Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of %s."),
1314  strSubVersion.size(), MAX_SUBVERSION_LENGTH, "-uacomment"));
1315  }
1316 
1317  if (gArgs.IsArgSet("-onlynet")) {
1318  std::set<enum Network> nets;
1319  for (const std::string& snet : gArgs.GetArgs("-onlynet")) {
1320  enum Network net = ParseNetwork(snet);
1321  if (net == NET_UNROUTABLE)
1322  return UIError(strprintf(_("Unknown network specified in %s: '%s'"), "-onlynet", snet));
1323  nets.insert(net);
1324  }
1325  for (int n = 0; n < NET_MAX; n++) {
1326  enum Network net = (enum Network)n;
1327  if (!nets.count(net))
1328  SetReachable(net, false);
1329  }
1330  }
1331 
1332  // Check for host lookup allowed before parsing any network related parameters
1333  fNameLookup = gArgs.GetBoolArg("-dns", DEFAULT_NAME_LOOKUP);
1334 
1335  bool proxyRandomize = gArgs.GetBoolArg("-proxyrandomize", DEFAULT_PROXYRANDOMIZE);
1336  // -proxy sets a proxy for all outgoing network traffic
1337  // -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default
1338  std::string proxyArg = gArgs.GetArg("-proxy", "");
1339  SetReachable(NET_ONION, false);
1340  if (!proxyArg.empty() && proxyArg != "0") {
1341  CService proxyAddr;
1342  if (!Lookup(proxyArg, proxyAddr, 9050, fNameLookup)) {
1343  return UIError(strprintf(_("%s Invalid %s address or hostname: '%s'"), "Lookup():", "-proxy", proxyArg));
1344  }
1345 
1346  proxyType addrProxy = proxyType(proxyAddr, proxyRandomize);
1347  if (!addrProxy.IsValid())
1348  return UIError(strprintf(_("%s Invalid %s address or hostname: '%s'"), "isValid():", "-proxy", proxyArg));
1349 
1350  SetProxy(NET_IPV4, addrProxy);
1351  SetProxy(NET_IPV6, addrProxy);
1352  SetProxy(NET_ONION, addrProxy);
1353  SetNameProxy(addrProxy);
1354  SetReachable(NET_ONION, true); // by default, -proxy sets onion as reachable, unless -noonion later
1355  }
1356 
1357  // -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses
1358  // -noonion (or -onion=0) disables connecting to .onion entirely
1359  // An empty string is used to not override the onion proxy (in which case it defaults to -proxy set above, or none)
1360  std::string onionArg = gArgs.GetArg("-onion", "");
1361  if (!onionArg.empty()) {
1362  if (onionArg == "0") { // Handle -noonion/-onion=0
1363  SetReachable(NET_ONION, false);
1364  } else {
1365  CService onionProxy;
1366  if (!Lookup(onionArg, onionProxy, 9050, fNameLookup)) {
1367  return UIError(strprintf(_("%s Invalid %s address or hostname: '%s'"), "Lookup():", "-onion", onionArg));
1368  }
1369  proxyType addrOnion = proxyType(onionProxy, proxyRandomize);
1370  if (!addrOnion.IsValid())
1371  return UIError(strprintf(_("%s Invalid %s address or hostname: '%s'"), "isValid():", "-onion", onionArg));
1372  SetProxy(NET_ONION, addrOnion);
1373  SetReachable(NET_ONION, true);
1374  }
1375  }
1376 
1377  // see Step 2: parameter interactions for more information about these
1378  fListen = gArgs.GetBoolArg("-listen", DEFAULT_LISTEN);
1379  fDiscover = gArgs.GetBoolArg("-discover", true);
1380 
1381  for (const std::string& strAddr : gArgs.GetArgs("-externalip")) {
1382  CService addrLocal;
1383  if (Lookup(strAddr, addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid())
1384  AddLocal(addrLocal, LOCAL_MANUAL);
1385  else
1386  return UIError(ResolveErrMsg("externalip", strAddr));
1387  }
1388 
1389  // Read asmap file if configured
1390  if (gArgs.IsArgSet("-asmap")) {
1391  fs::path asmap_path = fs::path(gArgs.GetArg("-asmap", ""));
1392  if (asmap_path.empty()) {
1393  asmap_path = DEFAULT_ASMAP_FILENAME;
1394  }
1395  if (!asmap_path.is_absolute()) {
1396  asmap_path = GetDataDir() / asmap_path;
1397  }
1398  if (!fs::exists(asmap_path)) {
1399  UIError(strprintf(_("Could not find asmap file %s"), asmap_path));
1400  return false;
1401  }
1402  std::vector<bool> asmap = CAddrMan::DecodeAsmap(asmap_path);
1403  if (asmap.size() == 0) {
1404  UIError(strprintf(_("Could not parse asmap file %s"), asmap_path));
1405  return false;
1406  }
1407  const uint256 asmap_version = SerializeHash(asmap);
1408  connman.SetAsmap(std::move(asmap));
1409  LogPrintf("Using asmap version %s for IP bucketing\n", asmap_version.ToString());
1410  } else {
1411  LogPrintf("Using /16 prefix for IP bucketing\n");
1412  }
1413 
1414  // Warn if network-specific options (-addnode, -connect, etc) are
1415  // specified in default section of config file, but not overridden
1416  // on the command line or in this network's section of the config file.
1418 
1419 #if ENABLE_ZMQ
1420  pzmqNotificationInterface = CZMQNotificationInterface::Create();
1421 
1422  if (pzmqNotificationInterface) {
1423  RegisterValidationInterface(pzmqNotificationInterface);
1424  }
1425 #endif
1426 
1428 
1429  // ********************************************************* Step 7: load block chain
1430 
1431  fReindex = gArgs.GetBoolArg("-reindex", false);
1432  bool fReindexChainState = gArgs.GetBoolArg("-reindex-chainstate", false);
1433 
1434  // cache size calculations
1435  int64_t nTotalCache = (gArgs.GetArg("-dbcache", nDefaultDbCache) << 20);
1436  nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache
1437  nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greater than nMaxDbcache
1438  int64_t nBlockTreeDBCache = nTotalCache / 8;
1439  nBlockTreeDBCache = std::min(nBlockTreeDBCache, (gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX) ? nMaxBlockDBAndTxIndexCache : nMaxBlockDBCache) << 20);
1440  nTotalCache -= nBlockTreeDBCache;
1441  int64_t nCoinDBCache = std::min(nTotalCache / 2, (nTotalCache / 4) + (1 << 23)); // use 25%-50% of the remainder for disk cache
1442  nCoinDBCache = std::min(nCoinDBCache, nMaxCoinsDBCache << 20); // cap total coins db cache
1443  nTotalCache -= nCoinDBCache;
1444  nCoinCacheUsage = nTotalCache; // the rest goes to in-memory cache
1445  LogPrintf("Cache configuration:\n");
1446  LogPrintf("* Using %.1fMiB for block index database\n", nBlockTreeDBCache * (1.0 / 1024 / 1024));
1447  LogPrintf("* Using %.1fMiB for chain state database\n", nCoinDBCache * (1.0 / 1024 / 1024));
1448  LogPrintf("* Using %.1fMiB for in-memory UTXO set\n", nCoinCacheUsage * (1.0 / 1024 / 1024));
1449 
1450  const CChainParams& chainparams = Params();
1451  const Consensus::Params& consensus = chainparams.GetConsensus();
1452 
1453  bool fLoaded = false;
1454  while (!fLoaded && !ShutdownRequested()) {
1455  bool fReset = fReindex;
1456  std::string strLoadError;
1457 
1458  LOCK(cs_main);
1459 
1460  do {
1461  const int64_t load_block_index_start_time = GetTimeMillis();
1462 
1463  try {
1464  UnloadBlockIndex();
1465  pcoinsTip.reset();
1466  pcoinsdbview.reset();
1467  pcoinscatcher.reset();
1468  pblocktree.reset(new CBlockTreeDB(nBlockTreeDBCache, false, fReset));
1469 
1470  //PIVX specific: zerocoin and spork DB's
1471  zerocoinDB.reset(new CZerocoinDB(0, false, fReindex));
1472  pSporkDB.reset(new CSporkDB(0, false, false));
1473  accumulatorCache.reset(new AccumulatorCache(zerocoinDB.get()));
1474 
1476 
1477  if (fReset) {
1478  pblocktree->WriteReindexing(true);
1479  }
1480 
1481  // End loop if shutdown was requested
1482  if (ShutdownRequested()) break;
1483 
1484  // PIVX: load previous sessions sporks if we have them.
1485  uiInterface.InitMessage(_("Loading sporks..."));
1487 
1488  // LoadBlockIndex will load fTxIndex from the db, or set it if
1489  // we're reindexing. It will also load fHavePruned if we've
1490  // ever removed a block file from disk.
1491  // Note that it also sets fReindex based on the disk flag!
1492  // From here on out fReindex and fReset mean something different!
1493  uiInterface.InitMessage(_("Loading block index..."));
1494  std::string strBlockIndexError;
1495  if (!LoadBlockIndex(strBlockIndexError)) {
1496  if (ShutdownRequested()) break;
1497  strLoadError = _("Error loading block database");
1498  strLoadError = strprintf("%s : %s", strLoadError, strBlockIndexError);
1499  break;
1500  }
1501 
1502  // If the loaded chain has a wrong genesis, bail out immediately
1503  // (we're likely using a testnet datadir, or the other way around).
1504  if (!mapBlockIndex.empty() && !LookupBlockIndex(consensus.hashGenesisBlock)) {
1505  return UIError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
1506  }
1507 
1508  // Check for changed -txindex state
1509  if (fTxIndex != gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
1510  strLoadError = strprintf(_("You need to rebuild the database using %s to change %s"), "-reindex-chainstate", "-txindex");
1511  break;
1512  }
1513 
1514  // At this point blocktree args are consistent with what's on disk.
1515  // If we're not mid-reindex (based on disk + args), add a genesis block on disk.
1516  // This is called again in ThreadImport in the reindex completes.
1517  if (!fReindex && !LoadGenesisBlock()) {
1518  strLoadError = _("Error initializing block database");
1519  break;
1520  }
1521 
1522  // At this point we're either in reindex or we've loaded a useful
1523  // block tree into mapBlockIndex!
1524 
1525  pcoinsdbview.reset(new CCoinsViewDB(nCoinDBCache, false, fReset || fReindexChainState));
1526  pcoinscatcher.reset(new CCoinsViewErrorCatcher(pcoinsdbview.get()));
1527 
1528  // If necessary, upgrade from older database format.
1529  // This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
1530  uiInterface.InitMessage(_("Upgrading coins database if needed..."));
1531  // If necessary, upgrade from older database format.
1532  if (!pcoinsdbview->Upgrade()) {
1533  strLoadError = _("Error upgrading chainstate database");
1534  break;
1535  }
1536 
1537  // ReplayBlocks is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
1538  if (!ReplayBlocks(chainparams, pcoinsdbview.get())) {
1539  strLoadError = strprintf(_("Unable to replay blocks. You will need to rebuild the database using %s."), "-reindex");
1540  break;
1541  }
1542 
1543  // The on-disk coinsdb is now in a good state, create the cache
1544  pcoinsTip.reset(new CCoinsViewCache(pcoinscatcher.get()));
1545 
1547 
1548  bool is_coinsview_empty = fReset || fReindexChainState || pcoinsTip->GetBestBlock().IsNull();
1549  if (!is_coinsview_empty) {
1550  // LoadChainTip sets chainActive based on pcoinsTip's best block
1551  if (!LoadChainTip(chainparams)) {
1552  strLoadError = _("Error initializing block database");
1553  break;
1554  }
1555  assert(chainActive.Tip() != nullptr);
1556  }
1557 
1558  if (Params().NetworkIDString() == CBaseChainParams::MAIN) {
1559  // Prune zerocoin invalid outs if they were improperly stored in the coins database
1560  int chainHeight = chainActive.Height();
1561  bool fZerocoinActive = chainHeight > 0 && consensus.NetworkUpgradeActive(chainHeight, Consensus::UPGRADE_ZC);
1562 
1563  uiInterface.InitMessage(_("Loading/Pruning invalid outputs..."));
1564  if (fZerocoinActive) {
1565  if (!pcoinsTip->PruneInvalidEntries()) {
1566  strLoadError = _("System error while flushing the chainstate after pruning invalid entries. Possible corrupt database.");
1567  break;
1568  }
1569  MoneySupply.Update(pcoinsTip->GetTotalAmount(), chainHeight);
1570  // No need to keep the invalid outs in memory. Clear the map 100 blocks after the last invalid UTXO
1571  if (chainHeight > consensus.height_last_invalid_UTXO + 100) {
1573  }
1574  } else {
1575  // Populate list of invalid/fraudulent outpoints that are banned from the chain
1576  // They will not be added to coins view
1578  }
1579  }
1580 
1581  if (!is_coinsview_empty) {
1582  uiInterface.InitMessage(_("Verifying blocks..."));
1583  CBlockIndex *tip = chainActive.Tip();
1584  RPCNotifyBlockChange(true, tip);
1585  if (tip && tip->nTime > GetAdjustedTime() + 2 * 60 * 60) {
1586  strLoadError = _("The block database contains a block which appears to be from the future. "
1587  "This may be due to your computer's date and time being set incorrectly. "
1588  "Only rebuild the block database if you are sure that your computer's date and time are correct");
1589  break;
1590  }
1591 
1592  if (!CVerifyDB().VerifyDB(pcoinsdbview.get(), gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL),
1593  gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) {
1594  strLoadError = _("Corrupted block database detected");
1595  break;
1596  }
1597  }
1598  } catch (const std::exception& e) {
1599  LogPrintf("%s\n", e.what());
1600  strLoadError = _("Error opening block database");
1601  break;
1602  }
1603 
1604  fLoaded = true;
1605  LogPrintf(" block index %15dms\n", GetTimeMillis() - load_block_index_start_time);
1606  } while (false);
1607 
1608  if (!fLoaded && !ShutdownRequested()) {
1609  // first suggest a reindex
1610  if (!fReset) {
1611  bool fRet = uiInterface.ThreadSafeMessageBox(
1612  strLoadError + ".\n\n" + _("Do you want to rebuild the block database now?"),
1614  if (fRet) {
1615  fReindex = true;
1616  AbortShutdown();
1617  } else {
1618  LogPrintf("Aborted block database rebuild. Exiting.\n");
1619  return false;
1620  }
1621  } else {
1622  return UIError(strLoadError);
1623  }
1624  }
1625  }
1626 
1627  // As LoadBlockIndex can take several minutes, it's possible the user
1628  // requested to kill the GUI during the last operation. If so, exit.
1629  // As the program has not fully started yet, Shutdown() is possibly overkill.
1630  if (ShutdownRequested()) {
1631  LogPrintf("Shutdown requested. Exiting.\n");
1632  return false;
1633  }
1634 
1635  fs::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME;
1636  CAutoFile est_filein(fsbridge::fopen(est_path, "rb"), SER_DISK, CLIENT_VERSION);
1637  // Allowed to fail as this file IS missing on first startup.
1638  if (!est_filein.IsNull())
1639  mempool.ReadFeeEstimates(est_filein);
1640  fFeeEstimatesInitialized = true;
1641 
1642 // ********************************************************* Step 8: Backup and Load wallet
1643 #ifdef ENABLE_WALLET
1644  if (!InitLoadWallet())
1645  return false;
1646 #else
1647  LogPrintf("No wallet compiled in!\n");
1648 #endif
1649  // ********************************************************* Step 9: import blocks
1650 
1651  if (!CheckDiskSpace(GetDataDir())) {
1652  UIError(strprintf(_("Error: Disk space is low for %s"), GetDataDir()));
1653  return false;
1654  }
1655  if (!CheckDiskSpace(GetBlocksDir())) {
1656  UIError(strprintf(_("Error: Disk space is low for %s"), GetBlocksDir()));
1657  return false;
1658  }
1659 
1660  // Either install a handler to notify us when genesis activates, or set fHaveGenesis directly.
1661  // No locking, as this happens before any background thread is started.
1662  if (chainActive.Tip() == nullptr) {
1663  uiInterface.NotifyBlockTip.connect(BlockNotifyGenesisWait);
1664  } else {
1665  fHaveGenesis = true;
1666  }
1667 
1668  if (gArgs.IsArgSet("-blocknotify"))
1669  uiInterface.NotifyBlockTip.connect(BlockNotifyCallback);
1670 
1671  // update g_best_block if needed
1672  {
1674  if (g_best_block.IsNull() && chainActive.Tip()) {
1675  CBlockIndex* tip = chainActive.Tip();
1676  g_best_block = tip->GetBlockHash();
1678  g_best_block_cv.notify_all();
1679  }
1680  }
1681 
1682  std::vector<fs::path> vImportFiles;
1683  for (const std::string& strFile : gArgs.GetArgs("-loadblock")) {
1684  vImportFiles.emplace_back(strFile);
1685  }
1686  threadGroup.create_thread(std::bind(&ThreadImport, vImportFiles));
1687 
1688  // Wait for genesis block to be processed
1689  LogPrintf("Waiting for genesis block to be imported...\n");
1690  {
1691  std::unique_lock<std::mutex> lockG(cs_GenesisWait);
1692  // We previously could hang here if StartShutdown() is called prior to
1693  // ThreadImport getting started, so instead we just wait on a timer to
1694  // check ShutdownRequested() regularly.
1695  while (!fHaveGenesis && !ShutdownRequested()) {
1696  condvar_GenesisWait.wait_for(lockG, std::chrono::milliseconds(500));
1697  }
1698  uiInterface.NotifyBlockTip.disconnect(BlockNotifyGenesisWait);
1699  }
1700 
1701  if (ShutdownRequested()) {
1702  return false;
1703  }
1704 
1705  int chain_active_height;
1706 
1708  {
1709  LOCK(cs_main);
1710  chain_active_height = chainActive.Height();
1711  LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
1712  }
1713  LogPrintf("chainActive.Height() = %d\n", chain_active_height);
1714 
1715  // Update money supply
1716  if (!fReindex && !fReindexChainState) {
1717  uiInterface.InitMessage(_("Calculating money supply..."));
1718  MoneySupply.Update(pcoinsTip->GetTotalAmount(), chain_active_height);
1719  }
1720 
1721 
1722  // ********************************************************* Step 10: setup layer 2 data
1723 
1724  bool load_cache_files = !(fReindex || fReindexChainState);
1725  {
1726  LOCK(cs_main);
1727  // was blocks/chainstate deleted?
1728  if (chainActive.Tip() == nullptr) {
1729  load_cache_files = false;
1730  }
1731  }
1732 
1733  LoadTierTwo(chain_active_height, load_cache_files);
1735 
1736  // set the mode of budget voting for this node
1737  SetBudgetFinMode(gArgs.GetArg("-budgetvotemode", "auto"));
1738 
1739  // Start tier two threads and jobs
1741 
1742  if (ShutdownRequested()) {
1743  LogPrintf("Shutdown requested. Exiting.\n");
1744  return false;
1745  }
1746 
1747  // ********************************************************* Step 11: start node
1748 
1749  if (!strErrors.str().empty())
1750  return UIError(strErrors.str());
1751 
1752 #ifdef ENABLE_WALLET
1753  {
1754  int idx = 0;
1755  for (CWalletRef pwallet : vpwallets) {
1756  LogPrintf("Wallet %d\n", idx++);
1757  LOCK(pwallet->cs_wallet);
1758  LogPrintf("setKeyPool.size() = %u\n", pwallet->GetKeyPoolSize());
1759  LogPrintf("mapWallet.size() = %u\n", pwallet->mapWallet.size());
1760  LogPrintf("mapAddressBook.size() = %u\n", pwallet->GetAddressBookSize());
1761  }
1762  }
1763 #endif
1764 
1765  if (gArgs.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION))
1766  StartTorControl();
1767 
1768  Discover();
1769 
1770  // Map ports with UPnP or NAT-PMP
1771  StartMapPort(gArgs.GetBoolArg("-upnp", DEFAULT_UPNP), gArgs.GetBoolArg("-natpmp", DEFAULT_NATPMP));
1772 
1773  CConnman::Options connOptions;
1774  connOptions.nLocalServices = nLocalServices;
1775  connOptions.nRelevantServices = nRelevantServices;
1776  connOptions.nMaxConnections = nMaxConnections;
1777  connOptions.nMaxOutbound = std::min(MAX_OUTBOUND_CONNECTIONS, connOptions.nMaxConnections);
1778  connOptions.nMaxAddnode = MAX_ADDNODE_CONNECTIONS;
1779  connOptions.nMaxFeeler = 1;
1780  connOptions.nBestHeight = chain_active_height;
1781  connOptions.uiInterface = &uiInterface;
1782  connOptions.m_msgproc = peerLogic.get();
1783  connOptions.nSendBufferMaxSize = 1000*gArgs.GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER);
1784  connOptions.nReceiveFloodSize = 1000*gArgs.GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER);
1785  connOptions.m_added_nodes = gArgs.GetArgs("-addnode");
1786 
1787  if (gArgs.IsArgSet("-bind")) {
1788  for (const std::string& strBind : gArgs.GetArgs("-bind")) {
1789  CService addrBind;
1790  if (!Lookup(strBind, addrBind, GetListenPort(), false)) {
1791  return UIError(ResolveErrMsg("bind", strBind));
1792  }
1793  connOptions.vBinds.emplace_back(addrBind);
1794  }
1795  }
1796  if (gArgs.IsArgSet("-whitebind")) {
1797  for (const std::string& strBind : gArgs.GetArgs("-whitebind")) {
1798  CService addrBind;
1799  if (!Lookup(strBind, addrBind, 0, false)) {
1800  return UIError(ResolveErrMsg("whitebind", strBind));
1801  }
1802  if (addrBind.GetPort() == 0) {
1803  return UIError(strprintf(_("Need to specify a port with %s: '%s'"), "-whitebind", strBind));
1804  }
1805  connOptions.vWhiteBinds.emplace_back(addrBind);
1806  }
1807  }
1808 
1809  for (const auto& net : gArgs.GetArgs("-whitelist")) {
1810  CSubNet subnet;
1811  LookupSubNet(net, subnet);
1812  if (!subnet.IsValid())
1813  return UIError(strprintf(_("Invalid netmask specified in %s: '%s'"), "-whitelist", net));
1814  connOptions.vWhitelistedRange.emplace_back(subnet);
1815  }
1816 
1817  connOptions.vSeedNodes = gArgs.GetArgs("-seednode");
1818 
1819  // Initiate outbound connections unless connect=0
1820  connOptions.m_use_addrman_outgoing = !gArgs.IsArgSet("-connect");
1821  if (!connOptions.m_use_addrman_outgoing) {
1822  const auto connect = gArgs.GetArgs("-connect");
1823  if (connect.size() != 1 || connect[0] != "0") {
1824  connOptions.m_specified_outgoing = connect;
1825  }
1826  }
1827  if (!connman.Start(scheduler, connOptions)) {
1828  return false;
1829  }
1830 
1831 #ifdef ENABLE_WALLET
1832  // Generate coins in the background (disabled on mainnet. use only wallet 0)
1833  if (!vpwallets.empty())
1834  GenerateBitcoins(gArgs.GetBoolArg("-gen", DEFAULT_GENERATE), vpwallets[0], gArgs.GetArg("-genproclimit", DEFAULT_GENERATE_PROCLIMIT));
1835 #endif
1836 
1837 #ifdef ENABLE_WALLET
1838  uiInterface.InitMessage(_("Reaccepting wallet transactions..."));
1839  for (CWalletRef pwallet : vpwallets) {
1840  pwallet->postInitProcess(scheduler);
1841  }
1842  // StakeMiner thread disabled by default on regtest
1843  if (!vpwallets.empty() && gArgs.GetBoolArg("-staking", !Params().IsRegTestNet() && DEFAULT_STAKING)) {
1844  threadGroup.create_thread(std::bind(&ThreadStakeMinter));
1845  }
1846 #endif
1847 
1848  // Enable active MN
1849  if (!InitActiveMN()) return false;
1850 
1851  // ********************************************************* Step 12: finished
1852 
1854  uiInterface.InitMessage(_("Done loading"));
1855 
1856  return true;
1857 }
int64_t CAmount
Amount in PIV (Can be negative)
Definition: amount.h:13
#define NODISCARD
Definition: attributes.h:18
void RPCNotifyBlockChange(bool fInitialDownload, const CBlockIndex *pindex)
Definition: blockchain.cpp:274
bool BLSInit()
void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight)
Allows modifying the network upgrade regtest parameters.
const CChainParams & Params()
Return the currently selected parameters.
std::unique_ptr< CChainParams > CreateChainParams(const std::string &chain)
Creates and returns a std::unique_ptr<CChainParams> of the chosen chain.
std::unique_ptr< CBaseChainParams > CreateBaseChainParams(const std::string &chain)
Creates and returns a std::unique_ptr<CBaseChainParams> of the chosen chain.
void AppendParamsHelpMessages(std::string &strUsage, bool debugHelp)
Append the help messages for the chainparams options to the parameter string.
bool IsArgNegated(const std::string &strArg) const
Return true if the argument was originally passed as a negated option, i.e.
Definition: system.cpp:431
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: system.cpp:406
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:425
void WarnForSectionOnlyArgs()
Log warnings for options in m_section_only_args when they are specified in the default section but no...
Definition: system.cpp:338
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:449
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
Definition: system.cpp:481
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:465
bool OpenDebugLog()
Definition: logging.cpp:36
bool DefaultShrinkDebugFile() const
Definition: logging.cpp:87
fs::path m_file_path
Definition: logging.h:99
bool m_log_time_micros
Definition: logging.h:97
void EnableCategory(LogFlags flag)
Definition: logging.cpp:56
bool m_log_timestamps
Definition: logging.h:96
std::atomic< bool > m_reopen_file
Definition: logging.h:100
void ShrinkDebugFile()
Definition: logging.cpp:241
bool m_print_to_file
Definition: logging.h:94
bool m_print_to_console
Definition: logging.h:93
void DisableCategory(LogFlags flag)
Definition: logging.cpp:69
static std::vector< bool > DecodeAsmap(fs::path path)
Definition: addrman.cpp:633
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:452
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
Definition: streams.h:501
static const std::string TESTNET
static const std::string MAIN
Chain name strings.
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:139
uint32_t nTime
Definition: chain.h:196
uint256 GetBlockHash() const
Definition: chain.h:215
int64_t GetBlockTime() const
Definition: chain.h:216
Access to the block database (blocks/index/)
Definition: txdb.h:128
CBlockIndex * Tip(bool fProofOfStake=false) const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:405
int Height() const
Return the maximal height in the chain.
Definition: chain.h:450
CChainParams defines various tweakable parameters of a given instance of the PIVX system.
Definition: chainparams.h:43
std::string NetworkIDString() const
Return the network string.
Definition: chainparams.h:91
bool RequireStandard() const
Policy: Filter transactions that do not match well-defined patterns.
Definition: chainparams.h:78
bool IsTestChain() const
If this chain is exclusively used for testing.
Definition: chainparams.h:82
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:72
Signals for UI communication.
Definition: guiinterface.h:32
boost::signals2::signal< void(const std::string &message)> InitMessage
Progress message during initialization.
Definition: guiinterface.h:87
boost::signals2::signal< bool(const std::string &message, const std::string &caption, unsigned int style), boost::signals2::last_value< bool > > ThreadSafeMessageBox
Show message box.
Definition: guiinterface.h:84
boost::signals2::signal< void(bool fInitialDownload, const CBlockIndex *newTip)> NotifyBlockTip
New block has been accepted.
Definition: guiinterface.h:105
CCoinsView backed by another CCoinsView.
Definition: coins.h:250
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:34
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:283
CCoinsView backed by the LevelDB coin database (chainstate/)
Definition: txdb.h:71
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: init.cpp:164
CCoinsViewErrorCatcher(CCoinsView *view)
Definition: init.cpp:163
Abstract view on the open txout dataset.
Definition: coins.h:201
Definition: net.h:145
void SetAsmap(std::vector< bool > asmap)
Definition: net.h:373
bool Start(CScheduler &scheduler, const Options &options)
Definition: net.cpp:2208
Fee rate in PIV per kilobyte: CAmount / kB.
Definition: feerate.h:20
CAmount GetFeePerK() const
Definition: feerate.h:29
void UnregisterBackgroundSignalScheduler()
Unregister a CScheduler to give callbacks which should run in the background - these callbacks will n...
void RegisterBackgroundSignalScheduler(CScheduler &scheduler)
Register a CScheduler to give callbacks which should run in the background (may only be called once)
void FlushBackgroundCallbacks()
Call any remaining callbacks on the calling thread.
void Update(const CAmount &_nSupply, int _nHeight)
Definition: moneysupply.h:24
bool IsValid() const
Definition: netaddress.cpp:418
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:72
bool okSafeMode
Definition: server.h:139
void serviceQueue()
Definition: scheduler.cpp:22
void stop(bool drain=false)
Definition: scheduler.cpp:73
std::function< void(void)> Function
Definition: scheduler.h:45
void scheduleEvery(Function f, int64_t deltaMilliSeconds)
Definition: scheduler.cpp:105
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:484
uint16_t GetPort() const
Definition: netaddress.cpp:882
void LoadSporksFromDB()
Definition: spork.cpp:47
bool SetPrivKey(std::string strPrivKey)
Definition: spork.cpp:265
bool IsValid() const
bool ReadFeeEstimates(CAutoFile &filein)
Definition: txmempool.cpp:1226
bool WriteFeeEstimates(CAutoFile &fileout) const
Write/Read estimates to disk.
Definition: txmempool.cpp:1212
void AddTransactionsUpdated(unsigned int n)
Definition: txmempool.cpp:357
void setSanityCheck(double dFrequency=1.0)
Definition: txmempool.h:527
void SetIsLoaded(bool loaded)
Sets the current loaded state.
Definition: txmempool.cpp:1503
bool IsLoaded() const
Definition: txmempool.cpp:1497
Capture information about block/transaction validation.
Definition: validation.h:24
RAII wrapper for VerifyDB: Verify consistency of the block and coin databases.
Definition: validation.h:335
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,...
Definition: wallet.h:577
static CZMQNotificationInterface * Create()
Zerocoin database (zerocoin/)
Definition: txdb.h:152
A UTXO entry.
Definition: coins.h:32
Users of this module must hold an ECCVerifyHandle.
Definition: pubkey.h:273
std::string ToString() const
Definition: uint256.cpp:65
bool IsNull() const
Definition: uint256.h:36
std::string GetHex() const
Definition: uint256.cpp:21
bool IsValid() const
Definition: netbase.h:35
256-bit opaque blob.
Definition: uint256.h:138
std::string FormatSubVersion(const std::string &name, int nClientVersion, const std::vector< std::string > &comments)
Format the subversion field according to BIP 14 spec (https://github.com/bitcoin/bips/blob/master/bip...
std::string FormatFullVersion()
const std::string CLIENT_NAME
const std::string CURRENCY_UNIT
Definition: feerate.cpp:11
bool glibc_sanity_test()
bool glibcxx_sanity_test()
uint256 SerializeHash(const T &obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
Compute the 256-bit hash of an object's serialization.
Definition: hash.h:289
void InterruptHTTPRPC()
Interrupt HTTP RPC subsystem.
Definition: httprpc.cpp:241
void StopHTTPRPC()
Stop HTTP RPC subsystem.
Definition: httprpc.cpp:246
bool StartHTTPRPC()
Start HTTP RPC subsystem.
Definition: httprpc.cpp:224
void StopREST()
Stop HTTP REST subsystem.
Definition: rest.cpp:588
bool StartREST()
Start HTTP REST subsystem.
Definition: rest.cpp:577
void InterruptREST()
Interrupt RPC REST subsystem.
Definition: rest.cpp:584
void InterruptHTTPServer()
Interrupt HTTP server threads.
Definition: httpserver.cpp:444
bool InitHTTPServer()
Initialize HTTP server.
Definition: httpserver.cpp:356
bool StartHTTPServer()
Start HTTP server.
Definition: httpserver.cpp:431
void StopHTTPServer()
Stop HTTP server.
Definition: httpserver.cpp:455
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:90
bool AppInitServers()
Definition: init.cpp:765
#define MIN_CORE_FILEDESCRIPTORS
Definition: init.cpp:103
void InitParameterInteraction()
Parameter interaction: change current parameters depending on various rules.
Definition: init.cpp:856
CClientUIInterface uiInterface
Definition: init.cpp:109
bool AppInitMain()
Bitcoin core main initialization.
Definition: init.cpp:1168
std::string HelpMessage(HelpMessageMode mode)
Help for options shared between UI and daemon (for -help)
Definition: init.cpp:381
volatile bool fFeeEstimatesInitialized
Definition: init.cpp:84
void HandleSIGHUP(int)
Definition: init.cpp:342
const char *const PIVX_PID_FILENAME
The PID file facilities.
Definition: init.cpp:114
bool InitSanityCheck(void)
Sanity checks Ensure that PIVX is running in a usable environment with all necessary library support.
Definition: init.cpp:714
void OnRPCPreCommand(const CRPCCommand &cmd)
Definition: init.cpp:372
bool AppInitParameterInteraction()
Initialization: parameter interaction.
Definition: init.cpp:974
bool InitNUParams()
Definition: init.cpp:909
bool AppInitBasicSetup()
Initialize PIVX core: Basic context setup.
Definition: init.cpp:805
bool AppInitSanityChecks()
Initialization sanity checks: ecc init, sanity checks, dir lock.
Definition: init.cpp:1151
void InitLogging()
Initialize the logging infrastructure.
Definition: init.cpp:949
fs::path GetPidFile()
Definition: init.cpp:116
void OnRPCStarted()
Definition: init.cpp:358
void Interrupt()
Interrupt threads.
Definition: init.cpp:186
void Shutdown()
Definition: init.cpp:199
std::string LicenseInfo()
Returns licensing information (for -version)
Definition: init.cpp:570
void HandleSIGTERM(int)
Signal handlers are very limited in what they are allowed to do, so:
Definition: init.cpp:337
void OnRPCStopped()
Definition: init.cpp:363
void ThreadImport(const std::vector< fs::path > &vImportFiles)
Definition: init.cpp:635
std::unique_ptr< PeerLogicValidation > peerLogic
Definition: init.cpp:91
HelpMessageMode
The help message mode determines what help message to show.
Definition: init.h:53
@ HMM_BITCOIN_QT
Definition: init.h:55
@ HMM_BITCOIND
Definition: init.h:54
bool ECC_InitSanityCheck()
Check that required EC support is available at runtime.
Definition: key.cpp:336
void ECC_Start()
Initialize the elliptic curve support.
Definition: key.cpp:344
void ECC_Stop()
Deinitialize the elliptic curve support.
Definition: key.cpp:361
@ LOCK
Definition: lockunlock.h:16
BCLog::Logger *const g_logger
NOTE: the logger instances is leaked on exit.
Definition: logging.cpp:26
bool fLogIPs
Definition: logging.cpp:28
const char *const DEFAULT_DEBUGLOGFILE
Definition: logging.cpp:11
std::string ListLogCategories()
Returns a string with the supported log categories.
Definition: logging.cpp:148
#define LogPrint(category,...)
Definition: logging.h:163
void StartMapPort(bool use_upnp, bool use_natpmp)
Definition: mapport.cpp:327
void StopMapPort()
Definition: mapport.cpp:335
void InterruptMapPort()
Definition: mapport.cpp:331
@ RPC
Definition: logging.h:48
UpgradeIndex
Index into Params.vUpgrades and NetworkUpgradeInfo.
Definition: params.h:26
@ BASE_NETWORK
Definition: params.h:27
@ MAX_NETWORK_UPGRADES
Definition: params.h:44
@ UPGRADE_ZC
Definition: params.h:30
void OnPreCommand(std::function< void(const CRPCCommand &)> slot)
Definition: server.cpp:58
void OnStarted(std::function< void()> slot)
Definition: server.cpp:48
void OnStopped(std::function< void()> slot)
Definition: server.cpp:53
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:23
bool LoadOutpoints()
Definition: invalid.cpp:27
std::set< COutPoint > setInvalidOutPoints
Definition: invalid.cpp:14
void ThreadRename(std::string &&)
Rename a thread both in terms of an internal (in-memory) name as well as its system thread name.
Definition: threadnames.cpp:62
uint16_t GetListenPort()
Definition: net.cpp:104
bool fDiscover
Definition: net.cpp:89
bool fListen
Definition: net.cpp:90
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
Definition: net.cpp:94
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
Definition: net.cpp:245
bool AddLocal(const CService &addr, int nScore)
Definition: net.cpp:206
void Discover()
Definition: net.cpp:2101
@ LOCAL_MANUAL
Definition: net.h:539
RecursiveMutex cs_main
Global state.
Definition: validation.cpp:80
Network
A network type.
Definition: netaddress.h:44
@ NET_MAX
Dummy value to indicate the number of NET_* constants.
Definition: netaddress.h:68
@ NET_ONION
TOR (v2 or v3)
Definition: netaddress.h:55
@ NET_IPV6
IPv6.
Definition: netaddress.h:52
@ NET_IPV4
IPv4.
Definition: netaddress.h:49
@ NET_UNROUTABLE
Addresses from these networks are not publicly routable on the global Internet.
Definition: netaddress.h:46
enum Network ParseNetwork(std::string net)
Definition: netbase.cpp:46
bool Lookup(const std::string &name, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
Definition: netbase.cpp:177
bool fNameLookup
Definition: netbase.cpp:40
bool LookupSubNet(const std::string &strSubnet, CSubNet &ret)
Definition: netbase.cpp:673
int nConnectTimeout
Definition: netbase.cpp:39
bool SetNameProxy(const proxyType &addrProxy)
Definition: netbase.cpp:615
bool SetProxy(enum Network net, const proxyType &addrProxy)
Definition: netbase.cpp:595
#define PACKAGE_NAME
Definition: pivx-config.h:366
#define COPYRIGHT_YEAR
Definition: pivx-config.h:27
bool fIsBareMultisigStd
Definition: policy.cpp:17
CFeeRate dustRelayFee
Definition: policy.cpp:19
ServiceFlags
nServices flags
Definition: protocol.h:312
@ NODE_BLOOM
Definition: protocol.h:321
@ NODE_NETWORK
Definition: protocol.h:318
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:581
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:647
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:716
uint64_t GetRand(uint64_t nMax) noexcept
Definition: random.cpp:586
bool(* handler)(HTTPRequest *req, const std::string &strReq)
Definition: rest.cpp:565
UniValue JSONRPCError(int code, const std::string &message)
Definition: protocol.cpp:53
@ RPC_FORBIDDEN_BY_SAFE_MODE
std::exception thrown in command handling
Definition: protocol.h:42
void RegisterWalletRPCCommands(CRPCTable &tableRPC)
Definition: rpcwallet.cpp:4853
@ SER_DISK
Definition: serialize.h:175
void SetRPCWarmupFinished()
Definition: server.cpp:362
void StopRPC()
Definition: server.cpp:343
void InterruptRPC()
Definition: server.cpp:336
bool StartRPC()
Definition: server.cpp:328
void SetRPCWarmupStatus(const std::string &newStatus)
Set the RPC warmup status.
Definition: server.cpp:356
CRPCTable tableRPC
Definition: server.cpp:565
bool ShutdownRequested()
Definition: shutdown.cpp:22
void StartShutdown()
Definition: shutdown.cpp:14
void AbortShutdown()
Definition: shutdown.cpp:18
void InitSignatureCache()
Definition: sigcache.cpp:74
CSporkManager sporkManager
Definition: spork.cpp:29
unsigned nMaxDatacarrierBytes
Definition: standard.cpp:14
std::vector< CSubNet > vWhitelistedRange
Definition: net.h:170
unsigned int nReceiveFloodSize
Definition: net.h:167
CClientUIInterface * uiInterface
Definition: net.h:164
int nMaxOutbound
Definition: net.h:160
int nBestHeight
Definition: net.h:163
int nMaxFeeler
Definition: net.h:162
std::vector< std::string > m_specified_outgoing
Definition: net.h:173
NetEventsInterface * m_msgproc
Definition: net.h:165
int nMaxConnections
Definition: net.h:159
ServiceFlags nLocalServices
Definition: net.h:157
std::vector< std::string > m_added_nodes
Definition: net.h:174
std::vector< CService > vWhiteBinds
Definition: net.h:171
std::vector< CService > vBinds
Definition: net.h:171
ServiceFlags nRelevantServices
Definition: net.h:158
unsigned int nSendBufferMaxSize
Definition: net.h:166
std::vector< std::string > vSeedNodes
Definition: net.h:169
bool m_use_addrman_outgoing
Definition: net.h:172
int nMaxAddnode
Definition: net.h:161
~CImportingNow()
Definition: init.cpp:628
CImportingNow()
Definition: init.cpp:622
Parameters that influence chain consensus.
Definition: params.h:171
uint256 hashGenesisBlock
Definition: params.h:172
bool NetworkUpgradeActive(int nHeight, Consensus::UpgradeIndex idx) const
Returns true if the given network upgrade is active as of the given block height.
Definition: params.cpp:12
int height_last_invalid_UTXO
Definition: params.h:204
#define TRY_LOCK(cs, name)
Definition: sync.h:224
fs::path GetDefaultDataDir()
Definition: system.cpp:533
fs::path AbsPathForConfigVal(const fs::path &path, bool net_specific)
Definition: system.cpp:853
const char *const PIVX_CONF_FILENAME
Definition: system.cpp:81
void initZKSNARKS()
Definition: system.cpp:624
bool DirIsWritable(const fs::path &directory)
Definition: system.cpp:140
bool RenameOver(fs::path src, fs::path dest)
Definition: system.cpp:875
bool SetupNetworking()
Definition: system.cpp:1070
const fs::path & ZC_GetParamsDir()
Definition: system.cpp:596
int RaiseFileDescriptorLimit(int nMinFD)
this function tries to raise the file descriptor limit to the requested number.
Definition: system.cpp:950
const fs::path & GetDataDir(bool fNetSpecific)
Definition: system.cpp:724
int ScheduleBatchPriority(void)
On platforms that support it, tell the kernel the calling thread is CPU-intensive and non-interactive...
Definition: system.cpp:1101
ArgsManager gArgs
Definition: system.cpp:89
fs::path GetConfigFile(const std::string &confPath)
Definition: system.cpp:770
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Definition: system.cpp:499
bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes)
Definition: system.cpp:93
bool LockDirectory(const fs::path &directory, const std::string &lockfile_name, bool probe_only)
Definition: system.cpp:110
const fs::path & GetBlocksDir()
Definition: system.cpp:696
void runCommand(std::string strCommand)
Definition: system.cpp:1031
int GetNumCores()
Return the number of cores available on the current system.
Definition: system.cpp:1095
std::string HelpMessageOpt(const std::string &option, const std::string &message)
Format a string to be used as option description in help messages.
Definition: system.cpp:503
bool error(const char *fmt, const Args &... args)
Definition: system.h:77
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a Optional result.
Definition: system.h:65
bool InitActiveMN()
Initialize the active Masternode manager.
Definition: init.cpp:215
void InterruptTierTwo()
Interrupt tier two threads.
Definition: init.cpp:332
void ResetTierTwoInterfaces()
Resets the interfaces objects.
Definition: init.cpp:51
std::string GetTierTwoHelpString(bool showDebug)
Definition: init.cpp:27
void SetBudgetFinMode(const std::string &mode)
Definition: init.cpp:209
void InitTierTwoChainTip()
Initialize chain tip.
Definition: init.cpp:80
void RegisterTierTwoValidationInterface()
Register all tier two objects.
Definition: init.cpp:193
void InitTierTwoInterfaces()
Init the interfaces objects.
Definition: init.cpp:45
void InitTierTwoPreChainLoad(bool fReindex)
Inits the tier two global objects.
Definition: init.cpp:65
void StopTierTwoThreads()
Stops tier two workers.
Definition: init.cpp:320
bool LoadTierTwo(int chain_active_height, bool load_cache_files)
Loads from disk all the tier two related objects.
Definition: init.cpp:100
void StartTierTwoThreadsAndScheduleJobs(boost::thread_group &threadGroup, CScheduler &scheduler)
Starts tier two threads and jobs.
Definition: init.cpp:303
void DeleteTierTwo()
Cleans manager and worker objects pointers.
Definition: init.cpp:325
void DumpTierTwo()
Dump tier two managers to disk.
Definition: init.cpp:200
void InitTierTwoPostCoinsCacheLoad(CScheduler *scheduler)
Inits the tier two global objects that require access to the coins tip cache.
Definition: init.cpp:74
int64_t GetAdjustedTime()
Definition: timedata.cpp:36
#define strprintf
Definition: tinyformat.h:1056
const std::string DEFAULT_TOR_CONTROL
Default control port.
Definition: torcontrol.cpp:33
void StartTorControl()
Definition: torcontrol.cpp:744
void InterruptTorControl()
Definition: torcontrol.cpp:761
void StopTorControl()
Definition: torcontrol.cpp:771
const struct NUInfo NetworkUpgradeInfo[Consensus::MAX_NETWORK_UPGRADES]
General information about each network upgrade.
Definition: upgrades.cpp:15
bool ParseMoney(const std::string &str, CAmount &nRet)
std::string FormatMoney(const CAmount &n, bool fPlus)
Money parsing/formatting utilities.
std::string FormatParagraph(const std::string in, size_t width, size_t indent)
Format a paragraph of text to a fixed width, adding spaces for indentation to any added line.
bool ParseInt32(const std::string &str, int32_t *out)
Convert string to signed 32-bit integer with strict parse error feedback.
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
@ SAFE_CHARS_UA_COMMENT
BIP-0014 subset.
int64_t GetTimeMillis()
Returns the system time (not mockable)
Definition: utiltime.cpp:61
void SetMockTime(int64_t nMockTimeIn)
For testing.
Definition: utiltime.cpp:51
int64_t GetTime()
DEPRECATED Use either GetSystemTimeInSeconds (not mockable) or GetTime<T> (mockable)
Definition: utiltime.cpp:27
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
Definition: utiltime.cpp:102
void FlushStateToDisk()
Flush all state, indexes and buffers to disk.
bool LoadGenesisBlock()
Ensures we have a genesis block in the block tree, possibly writing one to disk.
std::unique_ptr< CBlockTreeDB > pblocktree
Global variable that points to the active block tree (protected by cs_main)
Definition: validation.cpp:207
bool fCheckBlockIndex
Definition: validation.cpp:98
std::unique_ptr< CZerocoinDB > zerocoinDB
Global variable that points to the zerocoin database (protected by cs_main)
Definition: validation.cpp:208
std::condition_variable g_best_block_cv
Definition: validation.cpp:89
int nScriptCheckThreads
Definition: validation.cpp:93
std::unique_ptr< CSporkDB > pSporkDB
Global variable that points to the spork database (protected by cs_main)
Definition: validation.cpp:209
CMoneySupply MoneySupply
Definition: validation.cpp:114
bool LoadBlockIndex(std::string &strError)
Load the block tree and coins database from disk, initializing state if we're running with -reindex.
bool DumpMempool(const CTxMemPool &pool)
Dump the mempool to disk.
CTxMemPool mempool(::minRelayTxFee)
bool LoadMempool(CTxMemPool &pool)
Load the mempool from disk.
CFeeRate minRelayTxFee
Fees smaller than this (in upiv) are considered zero fee (for relaying, mining and transaction creati...
Definition: validation.cpp:108
bool fTxIndex
Definition: validation.cpp:96
bool ActivateBestChain(CValidationState &state, std::shared_ptr< const CBlock > pblock)
Make the best chain active, in multiple steps.
std::unique_ptr< CCoinsViewCache > pcoinsTip
Global variable that points to the active CCoinsView (protected by cs_main)
Definition: validation.cpp:206
int64_t g_best_block_time
Definition: validation.cpp:91
std::atomic< bool > fImporting
Definition: validation.cpp:94
BlockMap mapBlockIndex
Definition: validation.cpp:82
void ThreadScriptCheck()
Run an instance of the script checking thread.
Mutex g_best_block_mutex
Definition: validation.cpp:88
fs::path GetBlockPosFilename(const FlatFilePos &pos)
Translation to a filesystem path.
bool LoadChainTip(const CChainParams &chainparams)
Update the chain tip based on database information.
FILE * OpenBlockFile(const FlatFilePos &pos, bool fReadOnly)
Open a block file (blk?????.dat)
size_t nCoinCacheUsage
Definition: validation.cpp:99
std::unique_ptr< CCoinsViewDB > pcoinsdbview
Global variable that points to the coins database (protected by cs_main)
Definition: validation.cpp:205
bool LoadExternalBlockFile(FILE *fileIn, FlatFilePos *dbp)
Import blocks from an external file.
void UnloadBlockIndex()
Unload database information.
bool ReplayBlocks(const CChainParams &params, CCoinsView *view)
Replay blocks that aren't fully applied to the database.
std::atomic< bool > fReindex
Definition: validation.cpp:95
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:84
std::unique_ptr< AccumulatorCache > accumulatorCache
In-memory cache for the zerocoin accumulators.
Definition: validation.cpp:210
uint256 g_best_block
Definition: validation.cpp:90
bool fRequireStandard
Definition: validation.cpp:97
int64_t nMaxTipAge
Definition: validation.cpp:102
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: validation.h:345
CMainSignals & GetMainSignals()
void UnregisterValidationInterface(CValidationInterface *pwalletIn)
Unregister a wallet from core.
void UnregisterAllValidationInterfaces()
Unregister all wallets from core.
void RegisterValidationInterface(CValidationInterface *pwalletIn)
Register a wallet to receive updates from core.
bool WalletVerify()
Responsible for reading and validating the -wallet arguments and verifying the wallet database.
Definition: init.cpp:143
std::string GetWalletHelpString(bool showDebug)
Return the wallets help message.
Definition: init.cpp:17
bool InitLoadWallet()
Load wallet databases.
Definition: init.cpp:208
bool WalletParameterInteraction()
Wallets parameter interaction.
Definition: init.cpp:53
std::vector< CWalletRef > vpwallets
Definition: wallet.cpp:33
CScheduler scheduler
boost::thread_group threadGroup
std::string GetWarnings(const std::string &strFor)
Definition: warnings.cpp:47