Merge branch 'dev' of github.com:VerusCoin/VerusCoin into dev
[VerusCoin.git] / src / init.cpp
CommitLineData
69d605f4 1// Copyright (c) 2009-2010 Satoshi Nakamoto
f914f1a7 2// Copyright (c) 2009-2014 The Bitcoin Core developers
c5b390b6 3// Distributed under the MIT software license, see the accompanying
bc909a7a 4// file COPYING or https://www.opensource.org/licenses/mit-license.php .
5350ea41 5
35b8af92 6#if defined(HAVE_CONFIG_H)
f3967bcc 7#include "config/bitcoin-config.h"
35b8af92
CF
8#endif
9
663224c2 10#include "init.h"
2902ac7c 11#include "crypto/common.h"
42181656 12#include "primitives/block.h"
51ed9ec9 13#include "addrman.h"
eda37330 14#include "amount.h"
51ed9ec9 15#include "checkpoints.h"
611116d4 16#include "compat/sanity.h"
b174b7e3 17#include "consensus/upgrades.h"
da29ecbc 18#include "consensus/validation.h"
afd64f76
WL
19#include "httpserver.h"
20#include "httprpc.h"
4a09e1df 21#include "key.h"
20c3ac51 22#include "notarisationdb.h"
93bd00a0
JG
23#ifdef ENABLE_MINING
24#include "key_io.h"
25#endif
a9a37c8b 26#include "main.h"
a6df7ab5 27#include "metrics.h"
d247a5d1 28#include "miner.h"
51ed9ec9 29#include "net.h"
4519a766 30#include "rpc/server.h"
9f0c14b2 31#include "rpc/pbaasrpc.h"
a9496b08 32#include "rpc/register.h"
2aa63292 33#include "script/standard.h"
3a788721 34#include "script/sigcache.h"
ddd0acd3 35#include "scheduler.h"
51ed9ec9 36#include "txdb.h"
eb5f63fe 37#include "torcontrol.h"
ed6d0b5f 38#include "ui_interface.h"
51ed9ec9 39#include "util.h"
ad49c256 40#include "utilmoneystr.h"
cbb2cf55 41#include "validationinterface.h"
48ba56cd 42#ifdef ENABLE_WALLET
8ffd63af 43#include "key_io.h"
50c72f23
JS
44#include "wallet/wallet.h"
45#include "wallet/walletdb.h"
48ba56cd 46#endif
51ed9ec9 47#include <stdint.h>
283e405c 48#include <stdio.h>
69d605f4 49
9cb1ec9c 50#ifndef _WIN32
ed6d0b5f 51#include <signal.h>
52d3a481 52#endif
5f2e76b8 53
b174b7e3 54#include <boost/algorithm/string/classification.hpp>
51ed9ec9 55#include <boost/algorithm/string/predicate.hpp>
e9dd83f0 56#include <boost/algorithm/string/replace.hpp>
b174b7e3 57#include <boost/algorithm/string/split.hpp>
36cba8f1 58#include <boost/bind.hpp>
51ed9ec9 59#include <boost/filesystem.hpp>
36cba8f1 60#include <boost/function.hpp>
51ed9ec9 61#include <boost/interprocess/sync/file_lock.hpp>
ad49c256 62#include <boost/thread.hpp>
51ed9ec9
BD
63#include <openssl/crypto.h>
64
fee88353 65#include <libsnark/common/profiling.hpp>
d66877af 66
f200002c
JG
67#if ENABLE_ZMQ
68#include "zmq/zmqnotificationinterface.h"
69#endif
70
99eb947a
S
71#if ENABLE_PROTON
72#include "amqp/amqpnotificationinterface.h"
73#endif
74
acfcdb94
SB
75#include "librustzcash.h"
76
00d1980b 77using namespace std;
69d605f4 78
b39e1bdb 79extern void ThreadSendAlert();
1a608050 80extern int32_t KOMODO_LOADINGBLOCKS;
a8a4e37b 81extern bool VERUS_MINTBLOCKS;
3613db08 82extern std::string VERUS_CHEATCATCHER;
b39e1bdb 83
2dc35992 84ZCJoinSplit* pzcashParams = NULL;
4f1c3798 85
48ba56cd 86#ifdef ENABLE_WALLET
20a11ffa 87CWallet* pwalletMain = NULL;
48ba56cd 88#endif
94064710 89bool fFeeEstimatesInitialized = false;
e8ef3da7 90
f200002c
JG
91#if ENABLE_ZMQ
92static CZMQNotificationInterface* pzmqNotificationInterface = NULL;
93#endif
94
99eb947a
S
95#if ENABLE_PROTON
96static AMQPNotificationInterface* pAMQPNotificationInterface = NULL;
97#endif
98
ba29a559 99#ifdef WIN32
df22af00 100// Win32 LevelDB doesn't use file descriptors, and the ones used for
7e6d23b1 101// accessing block files don't count towards the fd_set size limit
ba29a559
PW
102// anyway.
103#define MIN_CORE_FILEDESCRIPTORS 0
104#else
105#define MIN_CORE_FILEDESCRIPTORS 150
106#endif
107
c5b390b6 108/** Used to pass flags to the Bind() function */
c73323ee 109enum BindFlags {
29e214aa
PK
110 BF_NONE = 0,
111 BF_EXPLICIT = (1U << 0),
dc942e6f
PW
112 BF_REPORT_ERROR = (1U << 1),
113 BF_WHITELIST = (1U << 2),
c73323ee
PK
114};
115
171ca774 116static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat";
b74dcb3b 117CClientUIInterface uiInterface; // Declared but not defined in ui_interface.h
4751d07e 118
69d605f4
WL
119//////////////////////////////////////////////////////////////////////////////
120//
121// Shutdown
122//
123
b31499ec
GA
124//
125// Thread management and startup/shutdown:
126//
127// The network-processing threads are all part of a thread group
07cf4264 128// created by AppInit().
b31499ec
GA
129//
130// A clean exit happens when StartShutdown() or the SIGTERM
131// signal handler sets fRequestShutdown, which triggers
132// the DetectShutdownThread(), which interrupts the main thread group.
133// DetectShutdownThread() then exits, which causes AppInit() to
134// continue (it .joins the shutdown thread).
135// Shutdown() is then
136// called to clean up database connections, and stop other
137// threads that should only be stopped after the main network-processing
138// threads have exited.
139//
140// Note that if running -daemon the parent process returns from AppInit2
141// before adding any threads to the threadGroup, so .join_all() returns
142// immediately and the parent exits from main().
143//
b31499ec 144
bf673640 145std::atomic<bool> fRequestShutdown(false);
69d605f4 146
9247134e
PK
147void StartShutdown()
148{
b31499ec 149 fRequestShutdown = true;
9247134e 150}
723035bb
GA
151bool ShutdownRequested()
152{
153 return fRequestShutdown;
154}
9247134e 155
13cdce43
PW
156class CCoinsViewErrorCatcher : public CCoinsViewBacked
157{
158public:
159 CCoinsViewErrorCatcher(CCoinsView* view) : CCoinsViewBacked(view) {}
160 bool GetCoins(const uint256 &txid, CCoins &coins) const {
161 try {
162 return CCoinsViewBacked::GetCoins(txid, coins);
163 } catch(const std::runtime_error& e) {
164 uiInterface.ThreadSafeMessageBox(_("Error reading from database, shutting down."), "", CClientUIInterface::MSG_ERROR);
165 LogPrintf("Error reading from database: %s\n", e.what());
166 // Starting the shutdown sequence and returning false to the caller would be
167 // interpreted as 'entry not found' (as opposed to unable to read data), and
c0692346 168 // could lead to invalid interpretation. Just exit immediately, as we can't
13cdce43
PW
169 // continue anyway, and all writes should be atomic.
170 abort();
171 }
172 }
173 // Writes do not need similar protection, as failure to write is handled by the caller.
174};
175
20a11ffa 176static CCoinsViewDB *pcoinsdbview = NULL;
13cdce43 177static CCoinsViewErrorCatcher *pcoinscatcher = NULL;
3d02d0f6 178static boost::scoped_ptr<ECCVerifyHandle> globalVerifyHandle;
ae8bfd12 179
afd64f76
WL
180void Interrupt(boost::thread_group& threadGroup)
181{
182 InterruptHTTPServer();
183 InterruptHTTPRPC();
184 InterruptRPC();
185 InterruptREST();
975dc649 186 InterruptTorControl();
afd64f76
WL
187 threadGroup.interrupt_all();
188}
189
b31499ec 190void Shutdown()
69d605f4 191{
00d1980b 192 LogPrintf("%s: In progress...\n", __func__);
69d605f4 193 static CCriticalSection cs_Shutdown;
b31499ec 194 TRY_LOCK(cs_Shutdown, lockShutdown);
00d1980b
PK
195 if (!lockShutdown)
196 return;
96931d6f 197
94064710
WL
198 /// Note: Shutdown() must be able to handle cases in which AppInit2() failed part of the way,
199 /// for example if the data directory was found to be locked.
200 /// Be sure that anything that writes files or flushes caches only does this if the respective
201 /// module was initialized.
76a77528 202 RenameThread("verus-shutoff");
319b1160 203 mempool.AddTransactionsUpdated(1);
afd64f76
WL
204
205 StopHTTPRPC();
206 StopREST();
207 StopRPC();
208 StopHTTPServer();
4a85e067 209#ifdef ENABLE_WALLET
b0730874 210 if (pwalletMain)
2bb1c877 211 pwalletMain->Flush(false);
8e8b6d70 212#endif
f8f61a6d 213
8e8b6d70 214#ifdef ENABLE_MINING
88d014d0 215#ifdef ENABLE_WALLET
c8b74258 216 GenerateBitcoins(false, NULL, 0);
88d014d0 217#else
8e8b6d70 218 GenerateBitcoins(false, 0);
88d014d0 219#endif
48ba56cd 220#endif
f8f61a6d 221
21eb5ada 222 StopNode();
eb5f63fe 223 StopTorControl();
b2864d2f 224 UnregisterNodeSignals(GetNodeSignals());
171ca774 225
94064710 226 if (fFeeEstimatesInitialized)
09c744c2
PW
227 {
228 boost::filesystem::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME;
229 CAutoFile est_fileout(fopen(est_path.string().c_str(), "wb"), SER_DISK, CLIENT_VERSION);
a8738238 230 if (!est_fileout.IsNull())
09c744c2
PW
231 mempool.WriteFeeEstimates(est_fileout);
232 else
233 LogPrintf("%s: Failed to write fee estimates to %s\n", __func__, est_path.string());
94064710 234 fFeeEstimatesInitialized = false;
09c744c2 235 }
171ca774 236
69d605f4 237 {
b31499ec 238 LOCK(cs_main);
51ce901a
PW
239 if (pcoinsTip != NULL) {
240 FlushStateToDisk();
241 }
00d1980b
PK
242 delete pcoinsTip;
243 pcoinsTip = NULL;
13cdce43
PW
244 delete pcoinscatcher;
245 pcoinscatcher = NULL;
00d1980b
PK
246 delete pcoinsdbview;
247 pcoinsdbview = NULL;
248 delete pblocktree;
249 pblocktree = NULL;
69d605f4 250 }
48ba56cd 251#ifdef ENABLE_WALLET
b0730874 252 if (pwalletMain)
2bb1c877 253 pwalletMain->Flush(true);
48ba56cd 254#endif
f200002c
JG
255
256#if ENABLE_ZMQ
257 if (pzmqNotificationInterface) {
258 UnregisterValidationInterface(pzmqNotificationInterface);
f200002c
JG
259 delete pzmqNotificationInterface;
260 pzmqNotificationInterface = NULL;
261 }
262#endif
263
99eb947a
S
264#if ENABLE_PROTON
265 if (pAMQPNotificationInterface) {
266 UnregisterValidationInterface(pAMQPNotificationInterface);
267 delete pAMQPNotificationInterface;
268 pAMQPNotificationInterface = NULL;
269 }
270#endif
271
d6712db3 272#ifndef WIN32
ffdda4e8
AW
273 try {
274 boost::filesystem::remove(GetPidFile());
275 } catch (const boost::filesystem::filesystem_error& e) {
276 LogPrintf("%s: Unable to remove pidfile: %s\n", __func__, e.what());
277 }
d6712db3 278#endif
a96d1139 279 UnregisterAllValidationInterfaces();
48ba56cd 280#ifdef ENABLE_WALLET
20a11ffa
PK
281 delete pwalletMain;
282 pwalletMain = NULL;
48ba56cd 283#endif
7ee82c43
SB
284 delete pzcashParams;
285 pzcashParams = NULL;
3d02d0f6 286 globalVerifyHandle.reset();
a56054be 287 ECC_Stop();
00d1980b 288 LogPrintf("%s: done\n", __func__);
69d605f4
WL
289}
290
c5b390b6
MF
291/**
292 * Signal handlers are very limited in what they are allowed to do, so:
293 */
69d605f4
WL
294void HandleSIGTERM(int)
295{
296 fRequestShutdown = true;
297}
298
9af080c3
MH
299void HandleSIGHUP(int)
300{
301 fReopenDebugLog = true;
302}
69d605f4 303
ac7c7ab9
PW
304bool static InitError(const std::string &str)
305{
49d57125 306 uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR);
ac7c7ab9 307 return false;
ac7c7ab9
PW
308}
309
310bool static InitWarning(const std::string &str)
311{
49d57125 312 uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING);
ac7c7ab9
PW
313 return true;
314}
315
29e214aa 316bool static Bind(const CService &addr, unsigned int flags) {
c73323ee 317 if (!(flags & BF_EXPLICIT) && IsLimited(addr))
8f10a288
PW
318 return false;
319 std::string strError;
8d657a65 320 if (!BindListenPort(addr, strError, (flags & BF_WHITELIST) != 0)) {
c73323ee 321 if (flags & BF_REPORT_ERROR)
587f929c
PW
322 return InitError(strError);
323 return false;
324 }
8f10a288
PW
325 return true;
326}
327
4401b2d7
EL
328void OnRPCStopped()
329{
330 cvBlockChange.notify_all();
331 LogPrint("rpc", "RPC stopped.\n");
332}
333
334void OnRPCPreCommand(const CRPCCommand& cmd)
335{
4401b2d7
EL
336 // Observe safe mode
337 string strWarning = GetWarnings("rpc");
338 if (strWarning != "" && !GetBoolArg("-disablesafemode", false) &&
339 !cmd.okSafeMode)
340 throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning);
341}
342
1020f599 343std::string HelpMessage(HelpMessageMode mode)
9f5b11e6 344{
94cd7051 345 const bool showDebug = GetBoolArg("-help-debug", false);
1fdb9fa3 346
1020f599 347 // When adding new options to the categories, please keep and ensure alphabetical ordering.
c938fb1f 348 // Do not translate _(...) -help-debug options, many technical terms, and only a very small audience, so is unnecessary stress to translators
94cd7051 349
1fdb9fa3
LV
350 string strUsage = HelpMessageGroup(_("Options:"));
351 strUsage += HelpMessageOpt("-?", _("This help message"));
4d9c7fe6 352 strUsage += HelpMessageOpt("-alerts", strprintf(_("Receive and display P2P network alerts (default: %u)"), DEFAULT_ALERTS));
1fdb9fa3
LV
353 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)"));
354 strUsage += HelpMessageOpt("-blocknotify=<cmd>", _("Execute command when the best block changes (%s in cmd is replaced by block hash)"));
355 strUsage += HelpMessageOpt("-checkblocks=<n>", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 288));
356 strUsage += HelpMessageOpt("-checklevel=<n>", strprintf(_("How thorough the block verification of -checkblocks is (0-4, default: %u)"), 3));
5166804f 357 strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "komodo.conf"));
1020f599 358 if (mode == HMM_BITCOIND)
7398f4a7
CL
359 {
360#if !defined(WIN32)
1fdb9fa3 361 strUsage += HelpMessageOpt("-daemon", _("Run in the background as a daemon and accept commands"));
7398f4a7
CL
362#endif
363 }
1fdb9fa3 364 strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
9064d73b 365 strUsage += HelpMessageOpt("-exportdir=<dir>", _("Specify directory to be used when exporting data"));
1fdb9fa3
LV
366 strUsage += HelpMessageOpt("-dbcache=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache));
367 strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file") + " " + _("on startup"));
368 strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
31afbcc5 369 strUsage += HelpMessageOpt("-mempooltxinputlimit=<n>", _("[DEPRECATED FROM OVERWINTER] Set the maximum number of transparent inputs in a transaction that the mempool will accept (default: 0 = no limit applied)"));
1fdb9fa3
LV
370 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)"),
371 -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS));
9cb1ec9c 372#ifndef _WIN32
5915430d 373 strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), "verusd.pid"));
d6712db3 374#endif
fc44231c
WL
375 strUsage += HelpMessageOpt("-prune=<n>", strprintf(_("Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. "
376 "Warning: Reverting this setting requires re-downloading the entire blockchain. "
377 "(default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)"), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
a1d0ec44 378 strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current blk000??.dat files on startup"));
bdd5b587 379#if !defined(WIN32)
1fdb9fa3 380 strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)"));
bdd5b587 381#endif
1fdb9fa3 382 strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0));
8b78a819
T
383 strUsage += HelpMessageOpt("-addressindex", strprintf(_("Maintain a full address index, used to query for the balance, txids and unspent outputs for addresses (default: %u)"), DEFAULT_ADDRESSINDEX));
384 strUsage += HelpMessageOpt("-timestampindex", strprintf(_("Maintain a timestamp index for block hashes, used to query blocks hashes by a range of timestamps (default: %u)"), DEFAULT_TIMESTAMPINDEX));
385 strUsage += HelpMessageOpt("-spentindex", strprintf(_("Maintain a full spent index, used to query the spending txid and input index for an outpoint (default: %u)"), DEFAULT_SPENTINDEX));
1fdb9fa3
LV
386 strUsage += HelpMessageGroup(_("Connection options:"));
387 strUsage += HelpMessageOpt("-addnode=<ip>", _("Add a node to connect to and attempt to keep the connection open"));
388 strUsage += HelpMessageOpt("-banscore=<n>", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100));
389 strUsage += HelpMessageOpt("-bantime=<n>", strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400));
390 strUsage += HelpMessageOpt("-bind=<addr>", _("Bind to given address and always listen on it. Use [host]:port notation for IPv6"));
391 strUsage += HelpMessageOpt("-connect=<ip>", _("Connect only to the specified node(s)"));
392 strUsage += HelpMessageOpt("-discover", _("Discover own IP addresses (default: 1 when listening and no -externalip or -proxy)"));
393 strUsage += HelpMessageOpt("-dns", _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)"));
394 strUsage += HelpMessageOpt("-dnsseed", _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)"));
395 strUsage += HelpMessageOpt("-externalip=<ip>", _("Specify your own public address"));
396 strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0));
397 strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect)"));
eb5f63fe 398 strUsage += HelpMessageOpt("-listenonion", strprintf(_("Automatically create Tor hidden service (default: %d)"), DEFAULT_LISTEN_ONION));
8a5ae3c7 399 strUsage += HelpMessageOpt("-maxconnections=<n>", strprintf(_("Maintain at most <n> connections to peers (default: %u)"), DEFAULT_MAX_PEER_CONNECTIONS));
1fdb9fa3
LV
400 strUsage += HelpMessageOpt("-maxreceivebuffer=<n>", strprintf(_("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)"), 5000));
401 strUsage += HelpMessageOpt("-maxsendbuffer=<n>", strprintf(_("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)"), 1000));
402 strUsage += HelpMessageOpt("-onion=<ip:port>", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy"));
403 strUsage += HelpMessageOpt("-onlynet=<net>", _("Only connect to nodes in network <net> (ipv4, ipv6 or onion)"));
404 strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), 1));
0a284eca 405 strUsage += HelpMessageOpt("-peerbloomfilters", strprintf(_("Support filtering of blocks and transaction with Bloom filters (default: %u)"), 1));
b976ce7c 406 if (showDebug)
0a284eca 407 strUsage += HelpMessageOpt("-enforcenodebloom", strprintf("Enforce minimum protocol version to limit use of Bloom filters (default: %u)", 0));
1799af96 408 strUsage += HelpMessageOpt("-port=<port>", strprintf(_("Listen for connections on <port> (default: %u or testnet: %u)"), 7770, 17770));
1fdb9fa3 409 strUsage += HelpMessageOpt("-proxy=<ip:port>", _("Connect through SOCKS5 proxy"));
67a79493 410 strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), 1));
1fdb9fa3
LV
411 strUsage += HelpMessageOpt("-seednode=<ip>", _("Connect to a node to retrieve peer addresses, and disconnect"));
412 strUsage += HelpMessageOpt("-timeout=<n>", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT));
eb5f63fe 413 strUsage += HelpMessageOpt("-torcontrol=<ip>:<port>", strprintf(_("Tor control port to use if onion listening enabled (default: %s)"), DEFAULT_TOR_CONTROL));
975dc649 414 strUsage += HelpMessageOpt("-torpassword=<pass>", _("Tor control port password (default: empty)"));
1fdb9fa3
LV
415 strUsage += HelpMessageOpt("-whitebind=<addr>", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6"));
416 strUsage += HelpMessageOpt("-whitelist=<netmask>", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") +
417 " " + _("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"));
7398f4a7
CL
418
419#ifdef ENABLE_WALLET
1fdb9fa3
LV
420 strUsage += HelpMessageGroup(_("Wallet options:"));
421 strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
422 strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), 100));
5969bd8f 423 strUsage += HelpMessageOpt("-migration", _("Enable the Sprout to Sapling migration"));
8ffd63af 424 strUsage += HelpMessageOpt("-migrationdestaddress=<zaddr>", _("Set the Sapling migration address"));
94cd7051 425 if (showDebug)
091b2116
RN
426 strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)",
427 CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK())));
428 strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"),
429 CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK())));
430 strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup"));
1fdb9fa3
LV
431 strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup"));
432 strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0));
433 strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1));
77ed59df 434 strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET));
8865f4b6 435 strUsage += HelpMessageOpt("-txexpirydelta", strprintf(_("Set the number of blocks after which a transaction that has not been mined will become invalid (min: %u, default: %u (pre-Blossom) or %u (post-Blossom))"), TX_EXPIRING_SOON_THRESHOLD + 1, DEFAULT_PRE_BLOSSOM_TX_EXPIRY_DELTA, DEFAULT_POST_BLOSSOM_TX_EXPIRY_DELTA));
091b2116
RN
436 strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction; setting this too low may abort large transactions (default: %s)"),
437 CURRENCY_UNIT, FormatMoney(maxTxFee)));
1fdb9fa3
LV
438 strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup"));
439 strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat"));
6f252627 440 strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), true));
1fdb9fa3
LV
441 strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)"));
442 strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") +
443 " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)"));
7398f4a7
CL
444#endif
445
f200002c
JG
446#if ENABLE_ZMQ
447 strUsage += HelpMessageGroup(_("ZeroMQ notification options:"));
448 strUsage += HelpMessageOpt("-zmqpubhashblock=<address>", _("Enable publish hash block in <address>"));
57c6ef01 449 strUsage += HelpMessageOpt("-zmqpubhashtx=<address>", _("Enable publish hash transaction in <address>"));
f200002c 450 strUsage += HelpMessageOpt("-zmqpubrawblock=<address>", _("Enable publish raw block in <address>"));
57c6ef01 451 strUsage += HelpMessageOpt("-zmqpubrawtx=<address>", _("Enable publish raw transaction in <address>"));
7398f4a7
CL
452#endif
453
99eb947a
S
454#if ENABLE_PROTON
455 strUsage += HelpMessageGroup(_("AMQP 1.0 notification options:"));
456 strUsage += HelpMessageOpt("-amqppubhashblock=<address>", _("Enable publish hash block in <address>"));
457 strUsage += HelpMessageOpt("-amqppubhashtx=<address>", _("Enable publish hash transaction in <address>"));
458 strUsage += HelpMessageOpt("-amqppubrawblock=<address>", _("Enable publish raw block in <address>"));
459 strUsage += HelpMessageOpt("-amqppubrawtx=<address>", _("Enable publish raw transaction in <address>"));
460#endif
461
1fdb9fa3 462 strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
94cd7051 463 if (showDebug)
7398f4a7 464 {
bfa832c7 465 strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", 1));
94cd7051
WL
466 strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)", 100));
467 strUsage += HelpMessageOpt("-disablesafemode", strprintf("Disable safemode, override a real safe mode event (default: %u)", 0));
468 strUsage += HelpMessageOpt("-testsafemode", strprintf("Force safe mode (default: %u)", 0));
469 strUsage += HelpMessageOpt("-dropmessagestest=<n>", "Randomly drop 1 of every <n> network messages");
470 strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", "Randomly fuzz 1 of every <n> network messages");
471 strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", 1));
472 strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0));
b174b7e3 473 strUsage += HelpMessageOpt("-nuparams=hexBranchId:activationHeight", "Use given activation height for specified network upgrade (regtest-only)");
7398f4a7 474 }
a659991a 475 string debugCategories = "addrman, alert, bench, coindb, db, estimatefee, http, libevent, lock, mempool, net, partitioncheck, pow, proxy, prune, "
65fd8eb1 476 "rand, reindex, rpc, selectcoins, tor, zmq, zrpc, zrpcunsafe (implies zrpc)"; // Don't translate these
1fdb9fa3 477 strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
53e9a6a0 478 _("If <category> is not supplied or if <category> = 1, output all debugging information.") + " " + _("<category> can be:") + " " + debugCategories + ".");
1f015f6a 479 strUsage += HelpMessageOpt("-experimentalfeatures", _("Enable use of experimental features"));
1fdb9fa3
LV
480 strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)"));
481 strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), 0));
482 strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1));
94cd7051 483 if (showDebug)
3b570559 484 {
94cd7051 485 strUsage += HelpMessageOpt("-limitfreerelay=<n>", strprintf("Continuously rate-limit free transactions to <n>*1000 bytes per minute (default: %u)", 15));
a5150a15 486 strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", 0));
3a788721 487 strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit size of signature cache to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE));
29aaf13b 488 strUsage += HelpMessageOpt("-maxtipage=<n>", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE));
3b570559 489 }
091b2116
RN
490 strUsage += HelpMessageOpt("-minrelaytxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for relaying (default: %s)"),
491 CURRENCY_UNIT, FormatMoney(::minRelayTxFee.GetFeePerK())));
1fdb9fa3 492 strUsage += HelpMessageOpt("-printtoconsole", _("Send trace/debug info to console instead of debug.log file"));
94cd7051 493 if (showDebug)
3b570559 494 {
94cd7051
WL
495 strUsage += HelpMessageOpt("-printpriority", strprintf("Log transaction priority and fee per kB when mining blocks (default: %u)", 0));
496 strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", 1));
497 strUsage += HelpMessageOpt("-regtest", "Enter regression test mode, which uses a special chain in which blocks can be solved instantly. "
498 "This is intended for regression testing tools and app development.");
3b570559 499 }
5ae7b70a 500 // strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)"));
1fdb9fa3
LV
501 strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
502
503 strUsage += HelpMessageGroup(_("Node relay options:"));
504 strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1));
505 strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY));
506
507 strUsage += HelpMessageGroup(_("Block creation options:"));
508 strUsage += HelpMessageOpt("-blockminsize=<n>", strprintf(_("Set minimum block size in bytes (default: %u)"), 0));
509 strUsage += HelpMessageOpt("-blockmaxsize=<n>", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE));
510 strUsage += HelpMessageOpt("-blockprioritysize=<n>", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE));
fbbd3cc6
PK
511 if (GetBoolArg("-help-debug", false))
512 strUsage += HelpMessageOpt("-blockversion=<n>", strprintf("Override block version to test forking scenarios (default: %d)", (int)CBlock::CURRENT_VERSION));
1fdb9fa3 513
78ba3472
JG
514#ifdef ENABLE_MINING
515 strUsage += HelpMessageGroup(_("Mining options:"));
5f63373e 516 strUsage += HelpMessageOpt("-mint", strprintf(_("Mint/stake coins automatically (default: %u)"), 0));
517 strUsage += HelpMessageOpt("-gen", strprintf(_("Mine/generate coins (default: %u)"), 0));
518 strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf(_("Set the number of threads for coin mining if enabled (-1 = all cores, default: %d)"), 0));
78ba3472
JG
519 strUsage += HelpMessageOpt("-equihashsolver=<name>", _("Specify the Equihash solver to be used if enabled (default: \"default\")"));
520 strUsage += HelpMessageOpt("-mineraddress=<addr>", _("Send mined coins to a specific single address"));
f49bcdf9
JG
521 strUsage += HelpMessageOpt("-minetolocalwallet", strprintf(
522 _("Require that mined blocks use a coinbase address in the local wallet (default: %u)"),
523 #ifdef ENABLE_WALLET
524 1
525 #else
526 0
527 #endif
528 ));
78ba3472 529#endif
1fdb9fa3
LV
530
531 strUsage += HelpMessageGroup(_("RPC server options:"));
532 strUsage += HelpMessageOpt("-server", _("Accept command line and JSON-RPC commands"));
533 strUsage += HelpMessageOpt("-rest", strprintf(_("Accept public REST requests (default: %u)"), 0));
534 strUsage += HelpMessageOpt("-rpcbind=<addr>", _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)"));
535 strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
536 strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
1785f62b 537 strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 7771, 17771));
1fdb9fa3 538 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"));
9fb5b94e
WL
539 strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), DEFAULT_HTTP_THREADS));
540 if (showDebug) {
541 strUsage += HelpMessageOpt("-rpcworkqueue=<n>", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE));
89bccddc 542 strUsage += HelpMessageOpt("-rpcservertimeout=<n>", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT));
9fb5b94e 543 }
008fccfa
S
544
545 // Disabled until we can lock notes and also tune performance of libsnark which by default uses multiple threads
546 //strUsage += HelpMessageOpt("-rpcasyncthreads=<n>", strprintf(_("Set the number of threads to service Async RPC calls (default: %d)"), 1));
1fdb9fa3 547
07cf4264 548 if (mode == HMM_BITCOIND) {
18f656d2 549 strUsage += HelpMessageGroup(_("Metrics Options (only if -daemon and -printtoconsole are not set):"));
0076a80a
JG
550 strUsage += HelpMessageOpt("-showmetrics", _("Show metrics on stdout (default: 1 if running in a console, 0 otherwise)"));
551 strUsage += HelpMessageOpt("-metricsui", _("Set to 1 for a persistent metrics screen, 0 for sequential metrics output (default: 1 if running in a console, 0 otherwise)"));
552 strUsage += HelpMessageOpt("-metricsrefreshtime", strprintf(_("Number of seconds between metrics refreshes (default: %u if running in a console, %u otherwise)"), 1, 600));
f7547079
LV
553 }
554
9f5b11e6
WL
555 return strUsage;
556}
557
c7b6117d
JG
558static void BlockNotifyCallback(const uint256& hashNewTip)
559{
560 std::string strCmd = GetArg("-blocknotify", "");
561
562 boost::replace_all(strCmd, "%s", hashNewTip.GetHex());
563 boost::thread t(runCommand, strCmd); // thread runs free
564}
565
7a5b7535
PW
566struct CImportingNow
567{
568 CImportingNow() {
569 assert(fImporting == false);
570 fImporting = true;
571 }
572
573 ~CImportingNow() {
574 assert(fImporting == true);
575 fImporting = false;
576 }
577};
578
f9ec3f0f 579
580// If we're using -prune with -reindex, then delete block files that will be ignored by the
581// reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
6cb70ca4
AW
582// is missing, do the same here to delete any later block files after a gap. Also delete all
583// rev files since they'll be rewritten by the reindex anyway. This ensures that vinfoBlockFile
584// is in sync with what's actually on disk by the time we start downloading, so that pruning
585// works correctly.
586void CleanupBlockRevFiles()
f9ec3f0f 587{
6cb70ca4
AW
588 using namespace boost::filesystem;
589 map<string, path> mapBlockFiles;
590
591 // Glob all blk?????.dat and rev?????.dat files from the blocks directory.
592 // Remove the rev files immediately and insert the blk file paths into an
593 // ordered map keyed by block file index.
594 LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune\n");
595 path blocksdir = GetDataDir() / "blocks";
596 for (directory_iterator it(blocksdir); it != directory_iterator(); it++) {
597 if (is_regular_file(*it) &&
598 it->path().filename().string().length() == 12 &&
599 it->path().filename().string().substr(8,4) == ".dat")
600 {
601 if (it->path().filename().string().substr(0,3) == "blk")
602 mapBlockFiles[it->path().filename().string().substr(3,5)] = it->path();
603 else if (it->path().filename().string().substr(0,3) == "rev")
604 remove(it->path());
605 }
606 }
e4a1e28c 607 path komodostate = GetDataDir() / "komodostate";
608 remove(komodostate);
888cf827 609 path minerids = GetDataDir() / "minerids";
610 remove(minerids);
6cb70ca4
AW
611 // Remove all block files that aren't part of a contiguous set starting at
612 // zero by walking the ordered map (keys are block file indices) by
613 // keeping a separate counter. Once we hit a gap (or if 0 doesn't exist)
614 // start removing block files.
615 int nContigCounter = 0;
616 BOOST_FOREACH(const PAIRTYPE(string, path)& item, mapBlockFiles) {
617 if (atoi(item.first) == nContigCounter) {
618 nContigCounter++;
619 continue;
f9ec3f0f 620 }
6cb70ca4 621 remove(item.second);
f9ec3f0f 622 }
623}
624
21eb5ada
GA
625void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
626{
44b2d060 627 const CChainParams& chainparams = Params();
7662d72b 628 RenameThread("zcash-loadblk");
7fea4846
PW
629 // -reindex
630 if (fReindex) {
631 CImportingNow imp;
632 int nFile = 0;
21eb5ada 633 while (true) {
a8a4b967 634 CDiskBlockPos pos(nFile, 0);
ec7eb0fa
SD
635 if (!boost::filesystem::exists(GetBlockPosFilename(pos, "blk")))
636 break; // No block files left to reindex
7fea4846
PW
637 FILE *file = OpenBlockFile(pos, true);
638 if (!file)
ec7eb0fa 639 break; // This error is logged in OpenBlockFile
881a85a2 640 LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
44b2d060 641 LoadExternalBlockFile(chainparams, file, &pos);
7fea4846
PW
642 nFile++;
643 }
21eb5ada
GA
644 pblocktree->WriteReindexing(false);
645 fReindex = false;
881a85a2 646 LogPrintf("Reindexing finished\n");
21eb5ada 647 // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
44b2d060 648 InitBlockIndex(chainparams);
1a608050 649 KOMODO_LOADINGBLOCKS = 0;
7a5b7535
PW
650 }
651
652 // hardcoded $DATADIR/bootstrap.dat
a3241998
CF
653 boost::filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat";
654 if (boost::filesystem::exists(pathBootstrap)) {
7a5b7535
PW
655 FILE *file = fopen(pathBootstrap.string().c_str(), "rb");
656 if (file) {
7fea4846 657 CImportingNow imp;
a3241998 658 boost::filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
881a85a2 659 LogPrintf("Importing bootstrap.dat...\n");
44b2d060 660 LoadExternalBlockFile(chainparams, file);
7a5b7535 661 RenameOver(pathBootstrap, pathBootstrapOld);
d54e819f
WL
662 } else {
663 LogPrintf("Warning: Could not open bootstrap file %s\n", pathBootstrap.string());
7a5b7535
PW
664 }
665 }
666
7fea4846 667 // -loadblock=
db954a65 668 BOOST_FOREACH(const boost::filesystem::path& path, vImportFiles) {
7fea4846
PW
669 FILE *file = fopen(path.string().c_str(), "rb");
670 if (file) {
671 CImportingNow imp;
d54e819f 672 LogPrintf("Importing blocks file %s...\n", path.string());
44b2d060 673 LoadExternalBlockFile(chainparams, file);
d54e819f
WL
674 } else {
675 LogPrintf("Warning: Could not open blocks file %s\n", path.string());
7fea4846
PW
676 }
677 }
1569353b
WL
678
679 if (GetBoolArg("-stopafterblockimport", false)) {
680 LogPrintf("Stopping after block import\n");
681 StartShutdown();
682 }
7a5b7535
PW
683}
684
3ff68c50
JG
685void ThreadNotifyRecentlyAdded()
686{
687 while (true) {
688 // Run the notifier on an integer second in the steady clock.
689 auto now = std::chrono::steady_clock::now().time_since_epoch();
690 auto nextFire = std::chrono::duration_cast<std::chrono::seconds>(
691 now + std::chrono::seconds(1));
692 std::this_thread::sleep_until(
693 std::chrono::time_point<std::chrono::steady_clock>(nextFire));
694
695 boost::this_thread::interruption_point();
696
697 mempool.NotifyRecentlyAdded();
698 }
699}
700
4a09e1df
AP
701/** Sanity checks
702 * Ensure that Bitcoin is running in a usable environment with all
703 * necessary library support.
704 */
705bool InitSanityCheck(void)
706{
707 if(!ECC_InitSanityCheck()) {
3d02d0f6 708 InitError("Elliptic curve cryptography sanity check failure. Aborting.");
4a09e1df
AP
709 return false;
710 }
92a62207
CF
711 if (!glibc_sanity_test() || !glibcxx_sanity_test())
712 return false;
4a09e1df
AP
713
714 return true;
715}
716
4f1c3798 717
acfcdb94
SB
718static void ZC_LoadParams(
719 const CChainParams& chainparams
720)
4f1c3798
SB
721{
722 struct timeval tv_start, tv_end;
723 float elapsed;
724
27e3f362
SB
725 boost::filesystem::path pk_path = ZC_GetParamsDir() / "sprout-proving.key";
726 boost::filesystem::path vk_path = ZC_GetParamsDir() / "sprout-verifying.key";
198dfd3c
SB
727 boost::filesystem::path sapling_spend = ZC_GetParamsDir() / "sapling-spend.params";
728 boost::filesystem::path sapling_output = ZC_GetParamsDir() / "sapling-output.params";
729 boost::filesystem::path sprout_groth16 = ZC_GetParamsDir() / "sprout-groth16.params";
4f1c3798 730
acfcdb94
SB
731 if (!(
732 boost::filesystem::exists(pk_path) &&
733 boost::filesystem::exists(vk_path) &&
198dfd3c
SB
734 boost::filesystem::exists(sapling_spend) &&
735 boost::filesystem::exists(sapling_output) &&
736 boost::filesystem::exists(sprout_groth16)
acfcdb94 737 )) {
bddf4079
JG
738 uiInterface.ThreadSafeMessageBox(strprintf(
739 _("Cannot find the Zcash network parameters in the following directory:\n"
740 "%s\n"
5915430d 741 "Please run 'fetch-params' or './zcutil/fetch-params.sh' and then restart."),
bddf4079
JG
742 ZC_GetParamsDir()),
743 "", CClientUIInterface::MSG_ERROR);
744 StartShutdown();
745 return;
746 }
747
f4091941 748 LogPrintf("Loading verifying key from %s\n", vk_path.string().c_str());
4f1c3798 749 gettimeofday(&tv_start, 0);
2dc35992 750
1a9543d0 751 pzcashParams = ZCJoinSplit::Prepared(vk_path.string(), pk_path.string());
2dc35992 752
4f1c3798
SB
753 gettimeofday(&tv_end, 0);
754 elapsed = float(tv_end.tv_sec-tv_start.tv_sec) + (tv_end.tv_usec-tv_start.tv_usec)/float(1000000);
f4091941 755 LogPrintf("Loaded verifying key in %fs seconds.\n", elapsed);
acfcdb94 756
ee3fa702
JG
757 static_assert(
758 sizeof(boost::filesystem::path::value_type) == sizeof(codeunit),
759 "librustzcash not configured correctly");
760 auto sapling_spend_str = sapling_spend.native();
761 auto sapling_output_str = sapling_output.native();
762 auto sprout_groth16_str = sprout_groth16.native();
763
764 LogPrintf("Loading Sapling (Spend) parameters from %s\n", sapling_spend.string().c_str());
765 LogPrintf("Loading Sapling (Output) parameters from %s\n", sapling_output.string().c_str());
766 LogPrintf("Loading Sapling (Sprout Groth16) parameters from %s\n", sprout_groth16.string().c_str());
198dfd3c
SB
767 gettimeofday(&tv_start, 0);
768
769 librustzcash_init_zksnark_params(
ee3fa702
JG
770 reinterpret_cast<const codeunit*>(sapling_spend_str.c_str()),
771 sapling_spend_str.length(),
198dfd3c 772 "8270785a1a0d0bc77196f000ee6d221c9c9894f55307bd9357c3f0105d31ca63991ab91324160d8f53e2bbd3c2633a6eb8bdf5205d822e7f3f73edac51b2b70c",
ee3fa702
JG
773 reinterpret_cast<const codeunit*>(sapling_output_str.c_str()),
774 sapling_output_str.length(),
198dfd3c 775 "657e3d38dbb5cb5e7dd2970e8b03d69b4787dd907285b5a7f0790dcc8072f60bf593b32cc2d1c030e00ff5ae64bf84c5c3beb84ddc841d48264b4a171744d028",
ee3fa702
JG
776 reinterpret_cast<const codeunit*>(sprout_groth16_str.c_str()),
777 sprout_groth16_str.length(),
198dfd3c
SB
778 "e9b238411bd6c0ec4791e9d04245ec350c9c5744f5610dfcce4365d5ca49dfefd5054e371842b3f88fa1b9d7e8e075249b3ebabd167fa8b0f3161292d36c180a"
779 );
780
781 gettimeofday(&tv_end, 0);
782 elapsed = float(tv_end.tv_sec-tv_start.tv_sec) + (tv_end.tv_usec-tv_start.tv_usec)/float(1000000);
783 LogPrintf("Loaded Sapling parameters in %fs seconds.\n", elapsed);
4f1c3798
SB
784}
785
afd64f76
WL
786bool AppInitServers(boost::thread_group& threadGroup)
787{
788 RPCServer::OnStopped(&OnRPCStopped);
789 RPCServer::OnPreCommand(&OnRPCPreCommand);
116503c0 790 if (!InitHTTPServer())
afd64f76
WL
791 return false;
792 if (!StartRPC())
793 return false;
794 if (!StartHTTPRPC())
795 return false;
796 if (GetBoolArg("-rest", false) && !StartREST())
797 return false;
c7f77e28 798 if (!StartHTTPServer())
116503c0 799 return false;
afd64f76
WL
800 return true;
801}
802
9f5b11e6
WL
803/** Initialize bitcoin.
804 * @pre Parameters should be parsed and config file should be read.
805 */
df35158a 806extern int32_t KOMODO_REWIND;
807
b2a98c42 808bool AppInitNetworking()
69d605f4 809{
7d80d2e3 810 // ********************************************************* Step 1: setup
69d605f4 811#ifdef _MSC_VER
814efd6f 812 // Turn off Microsoft heap dump noise
69d605f4
WL
813 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
814 _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
815#endif
816#if _MSC_VER >= 1400
814efd6f 817 // Disable confusing "helpful" text message on abort, Ctrl-C
69d605f4
WL
818 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
819#endif
9cb1ec9c 820#ifdef _WIN32
3d88c9b4
PK
821 // Enable Data Execution Prevention (DEP)
822 // Minimum supported OS versions: WinXP SP3, WinVista >= SP1, Win Server 2008
823 // A failure is non-critical and needs no further attention!
824#ifndef PROCESS_DEP_ENABLE
f65dddc7
PK
825 // We define this here, because GCCs winbase.h limits this to _WIN32_WINNT >= 0x0601 (Windows 7),
826 // which is not correct. Can be removed, when GCCs winbase.h is fixed!
3d88c9b4
PK
827#define PROCESS_DEP_ENABLE 0x00000001
828#endif
829 typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD);
830 PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy");
831 if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE);
69d605f4 832#endif
bdd5b587 833
167b6231
WL
834 if (!SetupNetworking())
835 return InitError("Error: Initializing networking failed");
b2a98c42
MT
836
837 return true;
838}
167b6231 839
b2a98c42
MT
840bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
841{
9cb1ec9c 842#ifndef _WIN32
bdd5b587
RS
843 if (GetBoolArg("-sysperms", false)) {
844#ifdef ENABLE_WALLET
845 if (!GetBoolArg("-disablewallet", false))
846 return InitError("Error: -sysperms is not allowed in combination with enabled wallet functionality");
847#endif
848 } else {
849 umask(077);
850 }
3d88c9b4 851
69d605f4
WL
852 // Clean shutdown on SIGTERM
853 struct sigaction sa;
854 sa.sa_handler = HandleSIGTERM;
855 sigemptyset(&sa.sa_mask);
856 sa.sa_flags = 0;
857 sigaction(SIGTERM, &sa, NULL);
858 sigaction(SIGINT, &sa, NULL);
9af080c3
MH
859
860 // Reopen debug.log on SIGHUP
861 struct sigaction sa_hup;
862 sa_hup.sa_handler = HandleSIGHUP;
863 sigemptyset(&sa_hup.sa_mask);
864 sa_hup.sa_flags = 0;
865 sigaction(SIGHUP, &sa_hup, NULL);
b34255b7 866
7ed4d40c 867 // Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly
b34255b7 868 signal(SIGPIPE, SIG_IGN);
69d605f4
WL
869#endif
870
c10b69eb
CF
871 std::set_new_handler(new_handler_terminate);
872
7d80d2e3 873 // ********************************************************* Step 2: parameter interactions
4e382177 874 const CChainParams& chainparams = Params();
13f90318 875
1f015f6a
JG
876 // Set this early so that experimental features are correctly enabled/disabled
877 fExperimentalMode = GetBoolArg("-experimentalfeatures", false);
878
b8eb3775
JG
879 // Fail early if user has set experimental options without the global flag
880 if (!fExperimentalMode) {
881 if (mapArgs.count("-developerencryptwallet")) {
882 return InitError(_("Wallet encryption requires -experimentalfeatures."));
4c1a8884
S
883 } else if (mapArgs.count("-developersetpoolsizezero")) {
884 return InitError(_("Setting the size of shielded pools to zero requires -experimentalfeatures."));
885 } else if (mapArgs.count("-paymentdisclosure")) {
45232b19 886 return InitError(_("Payment disclosure requires -experimentalfeatures."));
553a5c1a
JG
887 } else if (mapArgs.count("-zmergetoaddress")) {
888 return InitError(_("RPC method z_mergetoaddress requires -experimentalfeatures."));
685c0ab0
SB
889 } else if (mapArgs.count("-savesproutr1cs")) {
890 return InitError(_("Saving the Sprout R1CS requires -experimentalfeatures."));
45232b19 891 }
b8eb3775
JG
892 }
893
eadcd0c8
MC
894 // Set this early so that parameter interactions go to console
895 fPrintToConsole = GetBoolArg("-printtoconsole", false);
896 fLogTimestamps = GetBoolArg("-logtimestamps", true);
897 fLogIPs = GetBoolArg("-logips", false);
7d80d2e3 898
8550bcfe
AW
899 LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
900 LogPrintf("Zcash version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
901
13f90318
PK
902 // when specifying an explicit binding address, you want to listen on it
903 // even when -connect or -proxy is specified
904 if (mapArgs.count("-bind")) {
905 if (SoftSetBoolArg("-listen", true))
906 LogPrintf("%s: parameter interaction: -bind set -> setting -listen=1\n", __func__);
907 }
908 if (mapArgs.count("-whitebind")) {
df966d1b 909 if (SoftSetBoolArg("-listen", true))
13f90318 910 LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__);
587f929c 911 }
7d80d2e3 912
f161a2c2 913 if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) {
587f929c 914 // when only connecting to trusted nodes, do not seed via DNS, or listen by default
df966d1b 915 if (SoftSetBoolArg("-dnsseed", false))
13f90318 916 LogPrintf("%s: parameter interaction: -connect set -> setting -dnsseed=0\n", __func__);
df966d1b 917 if (SoftSetBoolArg("-listen", false))
13f90318 918 LogPrintf("%s: parameter interaction: -connect set -> setting -listen=0\n", __func__);
587f929c
PW
919 }
920
921 if (mapArgs.count("-proxy")) {
df966d1b
PK
922 // to protect privacy, do not listen by default if a default proxy server is specified
923 if (SoftSetBoolArg("-listen", false))
13f90318 924 LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__);
845c86d1
GM
925 // to protect privacy, do not discover addresses by default
926 if (SoftSetBoolArg("-discover", false))
13f90318 927 LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__);
587f929c
PW
928 }
929
13f90318 930 if (!GetBoolArg("-listen", DEFAULT_LISTEN)) {
506a2185 931 // do not try to retrieve public IP when not listening (pointless)
df966d1b 932 if (SoftSetBoolArg("-discover", false))
13f90318 933 LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__);
eb5f63fe
WL
934 if (SoftSetBoolArg("-listenonion", false))
935 LogPrintf("%s: parameter interaction: -listen=0 -> setting -listenonion=0\n", __func__);
7d80d2e3
PW
936 }
937
587f929c
PW
938 if (mapArgs.count("-externalip")) {
939 // if an explicit public IP is specified, do not try to find others
df966d1b 940 if (SoftSetBoolArg("-discover", false))
13f90318 941 LogPrintf("%s: parameter interaction: -externalip set -> setting -discover=0\n", __func__);
587f929c
PW
942 }
943
3260b4c0 944 if (GetBoolArg("-salvagewallet", false)) {
eed1785f 945 // Rewrite just private keys: rescan to find transactions
df966d1b 946 if (SoftSetBoolArg("-rescan", true))
13f90318 947 LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__);
eed1785f
GA
948 }
949
518f3bda
JG
950 // -zapwallettx implies a rescan
951 if (GetBoolArg("-zapwallettxes", false)) {
952 if (SoftSetBoolArg("-rescan", true))
13f90318 953 LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n", __func__);
518f3bda
JG
954 }
955
ba29a559 956 // Make sure enough file descriptors are available
dc942e6f 957 int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1);
8a5ae3c7 958 nMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
03f49808 959 nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0);
ba29a559
PW
960 int nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS);
961 if (nFD < MIN_CORE_FILEDESCRIPTORS)
962 return InitError(_("Not enough file descriptors available."));
963 if (nFD - MIN_CORE_FILEDESCRIPTORS < nMaxConnections)
964 nMaxConnections = nFD - MIN_CORE_FILEDESCRIPTORS;
965
f9ec3f0f 966 // if using block pruning, then disable txindex
967 // also disable the wallet (for now, until SPV support is implemented in wallet)
968 if (GetArg("-prune", 0)) {
b2c00e54 969 if (GetBoolArg("-txindex", true))
f9ec3f0f 970 return InitError(_("Prune mode is incompatible with -txindex."));
971#ifdef ENABLE_WALLET
972 if (!GetBoolArg("-disablewallet", false)) {
973 if (SoftSetBoolArg("-disablewallet", true))
974 LogPrintf("%s : parameter interaction: -prune -> setting -disablewallet=1\n", __func__);
975 else
976 return InitError(_("Can't run with a wallet in prune mode."));
977 }
978#endif
979 }
980
7d80d2e3
PW
981 // ********************************************************* Step 3: parameter-to-internal-flags
982
3b570559
PK
983 fDebug = !mapMultiArgs["-debug"].empty();
984 // Special-case: if -debug=0/-nodebug is set, turn off debugging messages
985 const vector<string>& categories = mapMultiArgs["-debug"];
986 if (GetBoolArg("-nodebug", false) || find(categories.begin(), categories.end(), string("0")) != categories.end())
987 fDebug = false;
988
3307124a
S
989 // Special case: if debug=zrpcunsafe, implies debug=zrpc, so add it to debug categories
990 if (find(categories.begin(), categories.end(), string("zrpcunsafe")) != categories.end()) {
991 if (find(categories.begin(), categories.end(), string("zrpc")) == categories.end()) {
43b67537 992 LogPrintf("%s: parameter interaction: setting -debug=zrpcunsafe -> -debug=zrpc\n", __func__);
3307124a
S
993 vector<string>& v = mapMultiArgs["-debug"];
994 v.push_back("zrpc");
995 }
996 }
997
00d1980b 998 // Check for -debugnet
3b570559 999 if (GetBoolArg("-debugnet", false))
00d1980b 1000 InitWarning(_("Warning: Unsupported argument -debugnet ignored, use -debug=net."));
a339a37b
PK
1001 // Check for -socks - as this is a privacy risk to continue, exit here
1002 if (mapArgs.count("-socks"))
1003 return InitError(_("Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported."));
1c750dbd
PK
1004 // Check for -tor - as this is a privacy risk to continue, exit here
1005 if (GetBoolArg("-tor", false))
1006 return InitError(_("Error: Unsupported argument -tor found, use -onion."));
3b570559 1007
d70bc52e
PW
1008 if (GetBoolArg("-benchmark", false))
1009 InitWarning(_("Warning: Unsupported argument -benchmark ignored, use -debug=bench."));
1010
3fcfbc8a 1011 // Checkmempool and checkblockindex default to true in regtest mode
934fd197
PW
1012 int ratio = std::min<int>(std::max<int>(GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000);
1013 if (ratio != 0) {
1014 mempool.setSanityCheck(1.0 / ratio);
1015 }
4e382177 1016 fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks());
a8cdaf5c 1017 fCheckpointsEnabled = GetBoolArg("-checkpoints", true);
d07eaba1 1018
f9cae832 1019 // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
5409404d 1020 nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
ebd7e8bf 1021 if (nScriptCheckThreads <= 0)
da1357e6 1022 nScriptCheckThreads += GetNumCores();
69e07747 1023 if (nScriptCheckThreads <= 1)
f9cae832
PW
1024 nScriptCheckThreads = 0;
1025 else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS)
1026 nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS;
1027
8b9adca4 1028 fServer = GetBoolArg("-server", false);
f9ec3f0f 1029
1030 // block pruning; get the amount of disk space (in MB) to allot for block & undo files
1031 int64_t nSignedPruneTarget = GetArg("-prune", 0) * 1024 * 1024;
1032 if (nSignedPruneTarget < 0) {
1033 return InitError(_("Prune cannot be configured with a negative value."));
1034 }
1035 nPruneTarget = (uint64_t) nSignedPruneTarget;
1036 if (nPruneTarget) {
1037 if (nPruneTarget < MIN_DISK_SPACE_FOR_BLOCK_FILES) {
1038 return InitError(strprintf(_("Prune configured below the minimum of %d MB. Please use a higher number."), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
1039 }
1040 LogPrintf("Prune configured to target %uMiB on disk for block and undo files.\n", nPruneTarget / 1024 / 1024);
1041 fPruneMode = true;
1042 }
1043
a9496b08 1044 RegisterAllCoreRPCCommands(tableRPC);
48ba56cd 1045#ifdef ENABLE_WALLET
e6b7e3dc 1046 bool fDisableWallet = GetBoolArg("-disablewallet", false);
34aca1b0 1047 if (!fDisableWallet)
a9496b08 1048 RegisterWalletRPCCommands(tableRPC);
48ba56cd 1049#endif
69d605f4 1050
de10efd1
PK
1051 nConnectTimeout = GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT);
1052 if (nConnectTimeout <= 0)
1053 nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
7d80d2e3 1054
000dc551
GA
1055 // Fee-per-kilobyte amount considered the same as "free"
1056 // If you are mining, be careful setting this:
1057 // if you set it to zero then
1058 // a transaction spammer can cheaply fill blocks using
1059 // 1-satoshi-fee transactions. It should be set above the real
1060 // cost to you of processing a transaction.
000dc551
GA
1061 if (mapArgs.count("-minrelaytxfee"))
1062 {
a372168e 1063 CAmount n = 0;
000dc551 1064 if (ParseMoney(mapArgs["-minrelaytxfee"], n) && n > 0)
13fc83c7 1065 ::minRelayTxFee = CFeeRate(n);
000dc551 1066 else
7d9d134b 1067 return InitError(strprintf(_("Invalid amount for -minrelaytxfee=<amount>: '%s'"), mapArgs["-minrelaytxfee"]));
000dc551 1068 }
7d80d2e3 1069
cd7fa8bb 1070#ifdef ENABLE_WALLET
13fc83c7
GA
1071 if (mapArgs.count("-mintxfee"))
1072 {
a372168e 1073 CAmount n = 0;
13fc83c7
GA
1074 if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0)
1075 CWallet::minTxFee = CFeeRate(n);
1076 else
1077 return InitError(strprintf(_("Invalid amount for -mintxfee=<amount>: '%s'"), mapArgs["-mintxfee"]));
1078 }
7d80d2e3
PW
1079 if (mapArgs.count("-paytxfee"))
1080 {
a372168e 1081 CAmount nFeePerK = 0;
c6cb21d1 1082 if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK))
7d9d134b 1083 return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"]));
c6cb21d1 1084 if (nFeePerK > nHighTransactionFeeWarning)
e6bc9c35 1085 InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
c6cb21d1 1086 payTxFee = CFeeRate(nFeePerK, 1000);
13fc83c7 1087 if (payTxFee < ::minRelayTxFee)
b33d1f5e
GA
1088 {
1089 return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
13fc83c7 1090 mapArgs["-paytxfee"], ::minRelayTxFee.ToString()));
b33d1f5e 1091 }
7d80d2e3 1092 }
aa279d61
GM
1093 if (mapArgs.count("-maxtxfee"))
1094 {
1095 CAmount nMaxFee = 0;
1096 if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee))
1097 return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s'"), mapArgs["-maptxfee"]));
1098 if (nMaxFee > nHighTransactionMaxFeeWarning)
1099 InitWarning(_("Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction."));
1100 maxTxFee = nMaxFee;
1101 if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee)
1102 {
1103 return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
1104 mapArgs["-maxtxfee"], ::minRelayTxFee.ToString()));
1105 }
1106 }
77ed59df 1107 nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET);
8865f4b6 1108 if (mapArgs.count("-txexpirydelta")) {
82c291b6 1109 int64_t expiryDelta = atoi64(mapArgs["-txexpirydelta"]);
8865f4b6
EOW
1110 uint32_t minExpiryDelta = TX_EXPIRING_SOON_THRESHOLD + 1;
1111 if (expiryDelta < minExpiryDelta) {
1112 return InitError(strprintf(_("Invalid value for -txexpirydelta='%u' (must be least %u)"), expiryDelta, minExpiryDelta));
1113 }
1114 expiryDeltaArg = expiryDelta;
f8cd79c2 1115 }
472b4c5d
AM
1116 bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", true);
1117 fSendFreeTransactions = GetBoolArg("-sendfreetransactions", false);
7d80d2e3 1118
7d4dda76 1119 std::string strWalletFile = GetArg("-wallet", "wallet.dat");
8ffd63af
E
1120 // Check Sapling migration address if set and is a valid Sapling address
1121 if (mapArgs.count("-migrationdestaddress")) {
1122 std::string migrationDestAddress = mapArgs["-migrationdestaddress"];
1123 libzcash::PaymentAddress address = DecodePaymentAddress(migrationDestAddress);
1124 if (boost::get<libzcash::SaplingPaymentAddress>(&address) == nullptr) {
1125 return InitError(_("-migrationdestaddress must be a valid Sapling address."));
1126 }
1127 }
3da434a2
JG
1128#endif // ENABLE_WALLET
1129
472b4c5d 1130 fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", true);
2aa63292 1131 nMaxDatacarrierBytes = GetArg("-datacarriersize", nMaxDatacarrierBytes);
3da434a2 1132
4d9c7fe6
WL
1133 fAlerts = GetBoolArg("-alerts", DEFAULT_ALERTS);
1134
abb0e8cc
GA
1135 // Option to startup with mocktime set (used for regression testing):
1136 SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op
1137
8bc44613
MC
1138 if (GetBoolArg("-peerbloomfilters", true))
1139 nLocalServices |= NODE_BLOOM;
1140
29aaf13b
WL
1141 nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE);
1142
8e8b6d70
JG
1143#ifdef ENABLE_MINING
1144 if (mapArgs.count("-mineraddress")) {
b6be3e88
JG
1145 CTxDestination addr = DecodeDestination(mapArgs["-mineraddress"]);
1146 if (!IsValidDestination(addr)) {
8e8b6d70
JG
1147 return InitError(strprintf(
1148 _("Invalid address for -mineraddress=<addr>: '%s' (must be a transparent address)"),
1149 mapArgs["-mineraddress"]));
1150 }
1151 }
1152#endif
1153
da6d9391
S
1154 // Default value of 0 for mempooltxinputlimit means no limit is applied
1155 if (mapArgs.count("-mempooltxinputlimit")) {
1156 int64_t limit = GetArg("-mempooltxinputlimit", 0);
1157 if (limit < 0) {
1158 return InitError(_("Mempool limit on transparent inputs to a transaction cannot be negative"));
1159 } else if (limit > 0) {
1160 LogPrintf("Mempool configured to reject transactions with greater than %lld transparent inputs\n", limit);
1161 }
1162 }
1163
b174b7e3
JG
1164 if (!mapMultiArgs["-nuparams"].empty()) {
1165 // Allow overriding network upgrade parameters for testing
1166 if (Params().NetworkIDString() != "regtest") {
1167 return InitError("Network upgrade parameters may only be overridden on regtest.");
1168 }
1169 const vector<string>& deployments = mapMultiArgs["-nuparams"];
1170 for (auto i : deployments) {
1171 std::vector<std::string> vDeploymentParams;
1172 boost::split(vDeploymentParams, i, boost::is_any_of(":"));
1173 if (vDeploymentParams.size() != 2) {
1174 return InitError("Network upgrade parameters malformed, expecting hexBranchId:activationHeight");
1175 }
1176 int nActivationHeight;
1177 if (!ParseInt32(vDeploymentParams[1], &nActivationHeight)) {
1178 return InitError(strprintf("Invalid nActivationHeight (%s)", vDeploymentParams[1]));
1179 }
1180 bool found = false;
1181 // Exclude Sprout from upgrades
1182 for (auto i = Consensus::BASE_SPROUT + 1; i < Consensus::MAX_NETWORK_UPGRADES; ++i)
1183 {
1184 if (vDeploymentParams[0].compare(HexInt(NetworkUpgradeInfo[i].nBranchId)) == 0) {
1185 UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex(i), nActivationHeight);
1186 found = true;
1187 LogPrintf("Setting network upgrade activation parameters for %s to height=%d\n", vDeploymentParams[0], nActivationHeight);
1188 break;
1189 }
1190 }
1191 if (!found) {
1192 return InitError(strprintf("Invalid network upgrade (%s)", vDeploymentParams[0]));
1193 }
1194 }
1195 }
da6d9391 1196
7d80d2e3 1197 // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
20a11ffa 1198
f4091941 1199 // Initialize libsodium
2902ac7c 1200 if (init_and_check_sodium() == -1) {
f4091941
SB
1201 return false;
1202 }
1203
a56054be
PW
1204 // Initialize elliptic curve code
1205 ECC_Start();
3d02d0f6 1206 globalVerifyHandle.reset(new ECCVerifyHandle());
a56054be 1207
42181656 1208 // set the hash algorithm to use for this chain
1209 extern uint32_t ASSETCHAINS_ALGO, ASSETCHAINS_VERUSHASH;
1210 if (ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASH)
5296a850 1211 {
4dcb64c0
MT
1212 // initialize VerusHash
1213 CVerusHash::init();
1214 CVerusHashV2::init();
12217420 1215 CBlockHeader::SetVerusV2Hash();
d5040cb1 1216 if (strcmp(ASSETCHAINS_SYMBOL,"VRSC") == 0)
1217 {
ec1c84a0 1218 CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV2, 310000);
d5040cb1 1219 }
1220 else
1221 {
ec1c84a0
MT
1222 CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV2, 1);
1223 CConstVerusSolutionVector::activationHeight.SetActivationHeight(CActivationHeight::SOLUTION_VERUSV3, 1);
d5040cb1 1224 }
5296a850 1225 }
42181656 1226
4a09e1df
AP
1227 // Sanity check
1228 if (!InitSanityCheck())
2e500f50 1229 return InitError(_("Initialization sanity check failed. Komodo is shutting down."));
7d80d2e3 1230
22bb0490 1231 std::string strDataDir = GetDataDir().string();
48ba56cd 1232#ifdef ENABLE_WALLET
674cb304
NS
1233 // Wallet file must be a plain filename without a directory
1234 if (strWalletFile != boost::filesystem::basename(strWalletFile) + boost::filesystem::extension(strWalletFile))
7d9d134b 1235 return InitError(strprintf(_("Wallet %s resides outside data directory %s"), strWalletFile, strDataDir));
48ba56cd 1236#endif
7d80d2e3
PW
1237 // Make sure only a single Bitcoin process is using the data directory.
1238 boost::filesystem::path pathLockFile = GetDataDir() / ".lock";
1239 FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
1240 if (file) fclose(file);
ffdda4e8
AW
1241
1242 try {
1243 static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
1244 if (!lock.try_lock())
2e500f50 1245 return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Komodo is probably already running."), strDataDir));
ffdda4e8 1246 } catch(const boost::interprocess::interprocess_exception& e) {
2e500f50 1247 return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Komodo is probably already running.") + " %s.", strDataDir, e.what()));
ffdda4e8
AW
1248 }
1249
9cb1ec9c 1250#ifndef _WIN32
d6712db3
WL
1251 CreatePidFile(GetPidFile(), getpid());
1252#endif
7f1de3fe 1253 if (GetBoolArg("-shrinkdebugfile", !fDebug))
69d605f4 1254 ShrinkDebugFile();
881a85a2 1255 LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
2e500f50 1256 LogPrintf("Komodo version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
8550bcfe
AW
1257
1258 if (fPrintToDebugLog)
1259 OpenDebugLog();
881a85a2 1260 LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
d0a2e2eb
WL
1261#ifdef ENABLE_WALLET
1262 LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
1263#endif
dcb14198 1264 if (!fLogTimestamps)
7d9d134b
WL
1265 LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()));
1266 LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
1267 LogPrintf("Using data directory %s\n", strDataDir);
5bd02cf7 1268 LogPrintf("Using config file %s\n", GetConfigFile().string());
881a85a2 1269 LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
7d80d2e3 1270 std::ostringstream strErrors;
69d605f4 1271
9bdec760 1272 LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads);
f9cae832 1273 if (nScriptCheckThreads) {
f9cae832 1274 for (int i=0; i<nScriptCheckThreads-1; i++)
21eb5ada 1275 threadGroup.create_thread(&ThreadScriptCheck);
f9cae832
PW
1276 }
1277
ddd0acd3
GA
1278 // Start the lightweight task scheduler thread
1279 CScheduler::Function serviceLoop = boost::bind(&CScheduler::serviceQueue, &scheduler);
1280 threadGroup.create_thread(boost::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop));
1281
000499ae
JG
1282 // Count uptime
1283 MarkStartTime();
1284
d35172fb 1285 if ((chainparams.NetworkIDString() != "regtest") &&
deadcdc5 1286 GetBoolArg("-showmetrics", 0) &&
d35172fb 1287 !fPrintToConsole && !GetBoolArg("-daemon", false)) {
a6df7ab5 1288 // Start the persistent metrics interface
4ace963c 1289 ConnectMetricsScreen();
a6df7ab5
JG
1290 threadGroup.create_thread(&ThreadShowMetricsScreen);
1291 }
1292
f4091941
SB
1293 // These must be disabled for now, they are buggy and we probably don't
1294 // want any of libsnark's profiling in production anyway.
1295 libsnark::inhibit_profiling_info = true;
1296 libsnark::inhibit_profiling_counters = true;
1297
226a6b32 1298 // Initialize Zcash circuit parameters
acfcdb94 1299 ZC_LoadParams(chainparams);
226a6b32 1300
685c0ab0
SB
1301 if (GetBoolArg("-savesproutr1cs", false)) {
1302 boost::filesystem::path r1cs_path = ZC_GetParamsDir() / "r1cs";
1303
1304 LogPrintf("Saving Sprout R1CS to %s\n", r1cs_path.string());
1305
1306 pzcashParams->saveR1CS(r1cs_path.string());
1307 }
1308
af82884a
DK
1309 /* Start the RPC server already. It will be started in "warmup" mode
1310 * and not really process calls already (but it will signify connections
1311 * that the server is there and will be ready later). Warmup mode will
1312 * be disabled when initialisation is finished.
1313 */
1314 if (fServer)
1315 {
1316 uiInterface.InitMessage.connect(SetRPCWarmupStatus);
afd64f76
WL
1317 if (!AppInitServers(threadGroup))
1318 return InitError(_("Unable to start HTTP server. See debug log for details."));
af82884a
DK
1319 }
1320
51ed9ec9 1321 int64_t nStart;
7d80d2e3 1322
06494cab 1323 // ********************************************************* Step 5: verify wallet database integrity
48ba56cd 1324#ifdef ENABLE_WALLET
e6b7e3dc 1325 if (!fDisableWallet) {
8a6894ca 1326 LogPrintf("Using wallet %s\n", strWalletFile);
f9ee7a03 1327 uiInterface.InitMessage(_("Verifying wallet..."));
eed1785f 1328
2bb1c877
JS
1329 std::string warningString;
1330 std::string errorString;
db954a65 1331
2bb1c877
JS
1332 if (!CWallet::Verify(strWalletFile, warningString, errorString))
1333 return false;
db954a65 1334
2bb1c877
JS
1335 if (!warningString.empty())
1336 InitWarning(warningString);
1337 if (!errorString.empty())
1338 return InitError(warningString);
db954a65 1339
e6b7e3dc 1340 } // (!fDisableWallet)
48ba56cd 1341#endif // ENABLE_WALLET
eed1785f 1342 // ********************************************************* Step 6: network initialization
7d80d2e3 1343
501da250 1344 RegisterNodeSignals(GetNodeSignals());
0e4b3175 1345
3c1db170
M
1346 // sanitize comments per BIP-0014, format user agent and check total size
1347 std::vector<string> uacomments;
1348 BOOST_FOREACH(string cmt, mapMultiArgs["-uacomment"])
1349 {
1350 if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT))
1351 return InitError(strprintf("User Agent comment (%s) contains unsafe characters.", cmt));
1352 uacomments.push_back(SanitizeString(cmt, SAFE_CHARS_UA_COMMENT));
1353 }
1354 strSubVersion = FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, uacomments);
2bc62dc4
PR
1355 if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) {
1356 return InitError(strprintf("Total length of network version string %i exceeds maximum of %i characters. Reduce the number and/or size of uacomments.",
1357 strSubVersion.size(), MAX_SUBVERSION_LENGTH));
1358 }
1359
7d80d2e3
PW
1360 if (mapArgs.count("-onlynet")) {
1361 std::set<enum Network> nets;
db954a65 1362 BOOST_FOREACH(const std::string& snet, mapMultiArgs["-onlynet"]) {
7d80d2e3
PW
1363 enum Network net = ParseNetwork(snet);
1364 if (net == NET_UNROUTABLE)
7d9d134b 1365 return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet));
7d80d2e3
PW
1366 nets.insert(net);
1367 }
1368 for (int n = 0; n < NET_MAX; n++) {
1369 enum Network net = (enum Network)n;
1370 if (!nets.count(net))
1371 SetLimited(net);
1372 }
1373 }
1374
dc942e6f
PW
1375 if (mapArgs.count("-whitelist")) {
1376 BOOST_FOREACH(const std::string& net, mapMultiArgs["-whitelist"]) {
1377 CSubNet subnet(net);
1378 if (!subnet.IsValid())
1379 return InitError(strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net));
1380 CNode::AddWhitelistedRange(subnet);
1381 }
1382 }
1383
8d9719e0
WL
1384 bool proxyRandomize = GetBoolArg("-proxyrandomize", true);
1385 // -proxy sets a proxy for all outgoing network traffic
1386 // -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default
1387 std::string proxyArg = GetArg("-proxy", "");
a05be280 1388 SetLimited(NET_TOR);
8d9719e0
WL
1389 if (proxyArg != "" && proxyArg != "0") {
1390 proxyType addrProxy = proxyType(CService(proxyArg, 9050), proxyRandomize);
587f929c 1391 if (!addrProxy.IsValid())
8d9719e0 1392 return InitError(strprintf(_("Invalid -proxy address: '%s'"), proxyArg));
587f929c 1393
3c777141
GM
1394 SetProxy(NET_IPV4, addrProxy);
1395 SetProxy(NET_IPV6, addrProxy);
8d9719e0 1396 SetProxy(NET_TOR, addrProxy);
0127a9be 1397 SetNameProxy(addrProxy);
a05be280 1398 SetLimited(NET_TOR, false); // by default, -proxy sets onion as reachable, unless -noonion later
54ce3bad
PW
1399 }
1400
8d9719e0
WL
1401 // -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses
1402 // -noonion (or -onion=0) disables connecting to .onion entirely
1403 // An empty string is used to not override the onion proxy (in which case it defaults to -proxy set above, or none)
1404 std::string onionArg = GetArg("-onion", "");
1405 if (onionArg != "") {
1406 if (onionArg == "0") { // Handle -noonion/-onion=0
a05be280 1407 SetLimited(NET_TOR); // set onions as unreachable
8d9719e0
WL
1408 } else {
1409 proxyType addrOnion = proxyType(CService(onionArg, 9050), proxyRandomize);
1410 if (!addrOnion.IsValid())
1411 return InitError(strprintf(_("Invalid -onion address: '%s'"), onionArg));
1412 SetProxy(NET_TOR, addrOnion);
a05be280 1413 SetLimited(NET_TOR, false);
8d9719e0 1414 }
587f929c
PW
1415 }
1416
1417 // see Step 2: parameter interactions for more information about these
56b07d2d 1418 fListen = GetBoolArg("-listen", DEFAULT_LISTEN);
587f929c
PW
1419 fDiscover = GetBoolArg("-discover", true);
1420 fNameLookup = GetBoolArg("-dns", true);
928d3a01 1421
7d80d2e3 1422 bool fBound = false;
53a08815 1423 if (fListen) {
dc942e6f 1424 if (mapArgs.count("-bind") || mapArgs.count("-whitebind")) {
db954a65 1425 BOOST_FOREACH(const std::string& strBind, mapMultiArgs["-bind"]) {
7d80d2e3
PW
1426 CService addrBind;
1427 if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false))
7d9d134b 1428 return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind));
c73323ee 1429 fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR));
7d80d2e3 1430 }
db954a65 1431 BOOST_FOREACH(const std::string& strBind, mapMultiArgs["-whitebind"]) {
dc942e6f
PW
1432 CService addrBind;
1433 if (!Lookup(strBind.c_str(), addrBind, 0, false))
1434 return InitError(strprintf(_("Cannot resolve -whitebind address: '%s'"), strBind));
1435 if (addrBind.GetPort() == 0)
1436 return InitError(strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind));
1437 fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST));
1438 }
c73323ee
PK
1439 }
1440 else {
7d80d2e3
PW
1441 struct in_addr inaddr_any;
1442 inaddr_any.s_addr = INADDR_ANY;
c73323ee 1443 fBound |= Bind(CService(in6addr_any, GetListenPort()), BF_NONE);
c73323ee 1444 fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE);
7d80d2e3
PW
1445 }
1446 if (!fBound)
587f929c 1447 return InitError(_("Failed to listen on any port. Use -listen=0 if you want this."));
928d3a01
JG
1448 }
1449
c73323ee 1450 if (mapArgs.count("-externalip")) {
db954a65 1451 BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-externalip"]) {
7d80d2e3
PW
1452 CService addrLocal(strAddr, GetListenPort(), fNameLookup);
1453 if (!addrLocal.IsValid())
7d9d134b 1454 return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr));
7d80d2e3
PW
1455 AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL);
1456 }
1457 }
1458
db954a65 1459 BOOST_FOREACH(const std::string& strDest, mapMultiArgs["-seednode"])
587f929c
PW
1460 AddOneShot(strDest);
1461
f200002c
JG
1462#if ENABLE_ZMQ
1463 pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs);
1464
1465 if (pzmqNotificationInterface) {
f200002c
JG
1466 RegisterValidationInterface(pzmqNotificationInterface);
1467 }
1468#endif
1469
99eb947a
S
1470#if ENABLE_PROTON
1471 pAMQPNotificationInterface = AMQPNotificationInterface::CreateWithArguments(mapArgs);
1472
1473 if (pAMQPNotificationInterface) {
1474
1475 // AMQP support is currently an experimental feature, so fail if user configured AMQP notifications
1476 // without enabling experimental features.
1477 if (!fExperimentalMode) {
1478 return InitError(_("AMQP support requires -experimentalfeatures."));
1479 }
1480
1481 RegisterValidationInterface(pAMQPNotificationInterface);
1482 }
1483#endif
1484
729b1806 1485 // ********************************************************* Step 7: load block chain
7d80d2e3 1486
3260b4c0 1487 fReindex = GetBoolArg("-reindex", false);
7fea4846 1488
f4445f99 1489 // Upgrading to 0.8; hard-link the old blknnnn.dat files into /blocks/
a3241998
CF
1490 boost::filesystem::path blocksDir = GetDataDir() / "blocks";
1491 if (!boost::filesystem::exists(blocksDir))
f4445f99 1492 {
a3241998 1493 boost::filesystem::create_directories(blocksDir);
f4445f99
GA
1494 bool linked = false;
1495 for (unsigned int i = 1; i < 10000; i++) {
a3241998
CF
1496 boost::filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i);
1497 if (!boost::filesystem::exists(source)) break;
1498 boost::filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1);
f4445f99 1499 try {
a3241998 1500 boost::filesystem::create_hard_link(source, dest);
7d9d134b 1501 LogPrintf("Hardlinked %s -> %s\n", source.string(), dest.string());
f4445f99 1502 linked = true;
a3241998 1503 } catch (const boost::filesystem::filesystem_error& e) {
f4445f99
GA
1504 // Note: hardlink creation failing is not a disaster, it just means
1505 // blocks will get re-downloaded from peers.
5262fde0 1506 LogPrintf("Error hardlinking blk%04u.dat: %s\n", i, e.what());
f4445f99
GA
1507 break;
1508 }
1509 }
1510 if (linked)
1511 {
1512 fReindex = true;
1513 }
1514 }
1515
8b78a819
T
1516 // block tree db settings
1517 int dbMaxOpenFiles = GetArg("-dbmaxopenfiles", DEFAULT_DB_MAX_OPEN_FILES);
1518 bool dbCompression = GetBoolArg("-dbcompression", DEFAULT_DB_COMPRESSION);
1519
1520 LogPrintf("Block index database configuration:\n");
1521 LogPrintf("* Using %d max open files\n", dbMaxOpenFiles);
1522 LogPrintf("* Compression is %s\n", dbCompression ? "enabled" : "disabled");
1523
1c83b0a3 1524 // cache size calculations
b3ed4236
PW
1525 int64_t nTotalCache = (GetArg("-dbcache", nDefaultDbCache) << 20);
1526 nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache
1527 nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greated than nMaxDbcache
1528 int64_t nBlockTreeDBCache = nTotalCache / 8;
8b78a819
T
1529
1530 if (GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX) || GetBoolArg("-spentindex", DEFAULT_SPENTINDEX)) {
1531 // enable 3/4 of the cache if addressindex and/or spentindex is enabled
1532 nBlockTreeDBCache = nTotalCache * 3 / 4;
1533 } else {
1534 if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", false)) {
1535 nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB
1536 }
1537 }
1c83b0a3 1538 nTotalCache -= nBlockTreeDBCache;
b3ed4236 1539 int64_t nCoinDBCache = std::min(nTotalCache / 2, (nTotalCache / 4) + (1 << 23)); // use 25%-50% of the remainder for disk cache
1c83b0a3 1540 nTotalCache -= nCoinDBCache;
b3ed4236
PW
1541 nCoinCacheUsage = nTotalCache; // the rest goes to in-memory cache
1542 LogPrintf("Cache configuration:\n");
8b78a819 1543 LogPrintf("* Max cache setting possible %.1fMiB\n", nMaxDbCache);
b3ed4236
PW
1544 LogPrintf("* Using %.1fMiB for block index database\n", nBlockTreeDBCache * (1.0 / 1024 / 1024));
1545 LogPrintf("* Using %.1fMiB for chain state database\n", nCoinDBCache * (1.0 / 1024 / 1024));
1546 LogPrintf("* Using %.1fMiB for in-memory UTXO set\n", nCoinCacheUsage * (1.0 / 1024 / 1024));
1c83b0a3 1547
37b14d06 1548 if ( fReindex == 0 )
1549 {
88d014d0 1550 bool checkval,fAddressIndex,fSpentIndex,fTimeStampIndex;
37b14d06 1551 pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex, dbCompression, dbMaxOpenFiles);
88d014d0 1552
37b14d06 1553 fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
1554 pblocktree->ReadFlag("addressindex", checkval);
1555 if ( checkval != fAddressIndex )
1556 {
1557 pblocktree->WriteFlag("addressindex", fAddressIndex);
1558 fprintf(stderr,"set addressindex, will reindex. sorry will take a while.\n");
1559 fReindex = true;
1560 }
88d014d0 1561
37b14d06 1562 fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
1563 pblocktree->ReadFlag("spentindex", checkval);
1564 if ( checkval != fSpentIndex )
1565 {
1566 pblocktree->WriteFlag("spentindex", fSpentIndex);
1567 fprintf(stderr,"set spentindex, will reindex. sorry will take a while.\n");
1568 fReindex = true;
1569 }
88d014d0 1570
88d014d0 1571 pblocktree->ReadFlag("timestampindex", checkval);
6a71051c 1572 bool defaultState = DEFAULT_TIMESTAMPINDEX ? DEFAULT_TIMESTAMPINDEX : checkval;
1573 fTimeStampIndex = GetBoolArg("-timestampindex", defaultState);
88d014d0 1574 if (checkval != fTimeStampIndex)
1575 {
6a71051c 1576 pblocktree->WriteFlag("timestampindex", fTimeStampIndex);
88d014d0 1577 fprintf(stderr,"set timestamp index, will reindex. sorry will take a while.\n");
1578 fReindex = true;
1579 }
1580
88d014d0 1581 pblocktree->ReadFlag("insightexplorer", checkval);
6a71051c 1582 defaultState = DEFAULT_INSIGHTEXPLORER ? DEFAULT_INSIGHTEXPLORER : checkval;
1583 fInsightExplorer = GetBoolArg("-insightexplorer", defaultState);
88d014d0 1584 if (checkval != fInsightExplorer)
1585 {
1586 pblocktree->WriteFlag("insightexplorer", fInsightExplorer);
1587 fprintf(stderr,"set main indexes, will reindex. sorry will take a while.\n");
1588 fReindex = true;
1589 }
37b14d06 1590 }
1591
66856b2b
DH
1592 bool clearWitnessCaches = false;
1593
f7f3a96b
PW
1594 bool fLoaded = false;
1595 while (!fLoaded) {
1596 bool fReset = fReindex;
1597 std::string strLoadError;
bb41a87d 1598
f7f3a96b 1599 uiInterface.InitMessage(_("Loading block index..."));
ae8bfd12 1600
f7f3a96b
PW
1601 nStart = GetTimeMillis();
1602 do {
1603 try {
1604 UnloadBlockIndex();
1605 delete pcoinsTip;
1606 delete pcoinsdbview;
13cdce43 1607 delete pcoinscatcher;
f7f3a96b 1608 delete pblocktree;
20c3ac51 1609 delete pnotarisations;
f7f3a96b 1610
8b78a819 1611 pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex, dbCompression, dbMaxOpenFiles);
f7f3a96b 1612 pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
13cdce43
PW
1613 pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview);
1614 pcoinsTip = new CCoinsViewCache(pcoinscatcher);
20c3ac51
SS
1615 pnotarisations = new NotarisationDB(100*1024*1024, false, fReindex);
1616
f7f3a96b 1617
f9ec3f0f 1618 if (fReindex) {
f7f3a96b 1619 pblocktree->WriteReindexing(true);
6cb70ca4 1620 //If we're reindexing in prune mode, wipe away unusable block files and all undo data files
f9ec3f0f 1621 if (fPruneMode)
6cb70ca4 1622 CleanupBlockRevFiles();
f9ec3f0f 1623 }
f7f3a96b
PW
1624
1625 if (!LoadBlockIndex()) {
1626 strLoadError = _("Error loading block database");
1627 break;
1628 }
1629
5d274c99
PW
1630 // If the loaded chain has a wrong genesis, bail out immediately
1631 // (we're likely using a testnet datadir, or the other way around).
4e382177 1632 if (!mapBlockIndex.empty() && mapBlockIndex.count(chainparams.GetConsensus().hashGenesisBlock) == 0)
5d274c99
PW
1633 return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
1634
f7f3a96b 1635 // Initialize the block index (no-op if non-empty database was already loaded)
44b2d060 1636 if (!InitBlockIndex(chainparams)) {
f7f3a96b
PW
1637 strLoadError = _("Error initializing block database");
1638 break;
1639 }
1a608050 1640 KOMODO_LOADINGBLOCKS = 0;
067a6092 1641 // Check for changed -txindex state
b2c00e54 1642 if (fTxIndex != GetBoolArg("-txindex", true)) {
067a6092
PW
1643 strLoadError = _("You need to rebuild the database using -reindex to change -txindex");
1644 break;
1645 }
1646
6cf0e50b
LR
1647 // Check for changed -insightexplorer state
1648 if (fInsightExplorer != GetBoolArg("-insightexplorer", false)) {
1649 strLoadError = _("You need to rebuild the database using -reindex to change -insightexplorer");
1650 break;
1651 }
1652
f9ec3f0f 1653 // Check for changed -prune state. What we are concerned about is a user who has pruned blocks
1654 // in the past, but is now trying to run unpruned.
1655 if (fHavePruned && !fPruneMode) {
1656 strLoadError = _("You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain");
1657 break;
1658 }
1659
89f20450 1660 if (!fReindex) {
5009136d 1661 uiInterface.InitMessage(_("Rewinding blocks if needed..."));
66856b2b 1662 if (!RewindBlockIndex(chainparams, clearWitnessCaches)) {
9e851450 1663 strLoadError = _("Unable to rewind the database to a pre-upgrade state. You will need to redownload the blockchain");
89f20450
PW
1664 break;
1665 }
1666 }
1667
e1ca89df 1668 uiInterface.InitMessage(_("Verifying blocks..."));
f9ec3f0f 1669 if (fHavePruned && GetArg("-checkblocks", 288) > MIN_BLOCKS_TO_KEEP) {
1670 LogPrintf("Prune: pruned datadir may not have more than %d blocks; -checkblocks=%d may fail\n",
1671 MIN_BLOCKS_TO_KEEP, GetArg("-checkblocks", 288));
1672 }
b3df07a0 1673 if ( KOMODO_REWIND == 0 )
df35158a 1674 {
88d014d0 1675 if (!CVerifyDB().VerifyDB(Params(), pcoinsdbview, GetArg("-checklevel", 3),
df35158a 1676 GetArg("-checkblocks", 288))) {
1677 strLoadError = _("Corrupted block database detected");
1678 break;
1679 }
f7f3a96b 1680 }
27df4123 1681 } catch (const std::exception& e) {
881a85a2 1682 if (fDebug) LogPrintf("%s\n", e.what());
f7f3a96b
PW
1683 strLoadError = _("Error opening block database");
1684 break;
1685 }
1f355b66 1686
f7f3a96b
PW
1687 fLoaded = true;
1688 } while(false);
1689
1690 if (!fLoaded) {
1691 // first suggest a reindex
1692 if (!fReset) {
1693 bool fRet = uiInterface.ThreadSafeMessageBox(
d3b5faf9 1694 strLoadError + ".\n\n" + _("error in HDD data, might just need to update to latest, if that doesnt work, then you need to resync"),
f7f3a96b
PW
1695 "", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
1696 if (fRet) {
1697 fReindex = true;
1698 fRequestShutdown = false;
1699 } else {
881a85a2 1700 LogPrintf("Aborted block database rebuild. Exiting.\n");
f7f3a96b
PW
1701 return false;
1702 }
1703 } else {
1704 return InitError(strLoadError);
1705 }
1706 }
1707 }
1a608050 1708 KOMODO_LOADINGBLOCKS = 0;
871c3557 1709
46469d0f
PK
1710 // As LoadBlockIndex can take several minutes, it's possible the user
1711 // requested to kill the GUI during the last operation. If so, exit.
871c3557
B
1712 // As the program has not fully started yet, Shutdown() is possibly overkill.
1713 if (fRequestShutdown)
1714 {
881a85a2 1715 LogPrintf("Shutdown requested. Exiting.\n");
871c3557
B
1716 return false;
1717 }
f48742c2 1718 LogPrintf(" block index %15dms\n", GetTimeMillis() - nStart);
69d605f4 1719
171ca774 1720 boost::filesystem::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME;
eee030f6 1721 CAutoFile est_filein(fopen(est_path.string().c_str(), "rb"), SER_DISK, CLIENT_VERSION);
00d1980b 1722 // Allowed to fail as this file IS missing on first startup.
a8738238 1723 if (!est_filein.IsNull())
171ca774 1724 mempool.ReadFeeEstimates(est_filein);
94064710 1725 fFeeEstimatesInitialized = true;
171ca774 1726
d66877af 1727
eed1785f 1728 // ********************************************************* Step 8: load wallet
48ba56cd 1729#ifdef ENABLE_WALLET
e6b7e3dc
JG
1730 if (fDisableWallet) {
1731 pwalletMain = NULL;
1732 LogPrintf("Wallet disabled!\n");
1733 } else {
77cbd462
CL
1734
1735 // needed to restore wallet transaction meta data after -zapwallettxes
1736 std::vector<CWalletTx> vWtx;
1737
518f3bda
JG
1738 if (GetBoolArg("-zapwallettxes", false)) {
1739 uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
1740
1741 pwalletMain = new CWallet(strWalletFile);
77cbd462 1742 DBErrors nZapWalletRet = pwalletMain->ZapWalletTx(vWtx);
518f3bda
JG
1743 if (nZapWalletRet != DB_LOAD_OK) {
1744 uiInterface.InitMessage(_("Error loading wallet.dat: Wallet corrupted"));
1745 return false;
1746 }
1747
1748 delete pwalletMain;
1749 pwalletMain = NULL;
1750 }
1751
f9ee7a03 1752 uiInterface.InitMessage(_("Loading wallet..."));
bb41a87d 1753
f9ee7a03
JG
1754 nStart = GetTimeMillis();
1755 bool fFirstRun = true;
1756 pwalletMain = new CWallet(strWalletFile);
1757 DBErrors nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun);
1758 if (nLoadWalletRet != DB_LOAD_OK)
eed1785f 1759 {
f9ee7a03
JG
1760 if (nLoadWalletRet == DB_CORRUPT)
1761 strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n";
1762 else if (nLoadWalletRet == DB_NONCRITICAL_ERROR)
1763 {
1764 string msg(_("Warning: error reading wallet.dat! All keys read correctly, but transaction data"
1765 " or address book entries might be missing or incorrect."));
1766 InitWarning(msg);
1767 }
1768 else if (nLoadWalletRet == DB_TOO_NEW)
810f6366 1769 strErrors << _("Error loading wallet.dat: Wallet requires newer version of Komodo") << "\n";
f9ee7a03
JG
1770 else if (nLoadWalletRet == DB_NEED_REWRITE)
1771 {
d2c1e4a8 1772 strErrors << _("Wallet needed to be rewritten: restart Zcash to complete") << "\n";
7d9d134b 1773 LogPrintf("%s", strErrors.str());
f9ee7a03
JG
1774 return InitError(strErrors.str());
1775 }
1776 else
1777 strErrors << _("Error loading wallet.dat") << "\n";
eed1785f 1778 }
f9ee7a03
JG
1779
1780 if (GetBoolArg("-upgradewallet", fFirstRun))
d764d916 1781 {
f9ee7a03
JG
1782 int nMaxVersion = GetArg("-upgradewallet", 0);
1783 if (nMaxVersion == 0) // the -upgradewallet without argument case
1784 {
1785 LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
1786 nMaxVersion = CLIENT_VERSION;
1787 pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
1788 }
1789 else
1790 LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
1791 if (nMaxVersion < pwalletMain->GetVersion())
1792 strErrors << _("Cannot downgrade wallet") << "\n";
1793 pwalletMain->SetMaxVersion(nMaxVersion);
d764d916 1794 }
439e1497 1795
c58dae6c
JG
1796 if (!pwalletMain->HaveHDSeed())
1797 {
1f561f32
JG
1798 // We can't set the new HD seed until the wallet is decrypted.
1799 // https://github.com/zcash/zcash/issues/3607
1800 if (!pwalletMain->IsCrypted()) {
1801 // generate a new HD seed
1802 pwalletMain->GenerateNewSeed();
1803 }
c58dae6c
JG
1804 }
1805
8ffd63af
E
1806 // Set sapling migration status
1807 pwalletMain->fSaplingMigrationEnabled = GetBoolArg("-migration", false);
1808
f9ee7a03 1809 if (fFirstRun)
439e1497 1810 {
f9ee7a03 1811 // Create new keyUser and set as default key
f9ee7a03
JG
1812 CPubKey newDefaultKey;
1813 if (pwalletMain->GetKeyFromPool(newDefaultKey)) {
1814 pwalletMain->SetDefaultKey(newDefaultKey);
1815 if (!pwalletMain->SetAddressBook(pwalletMain->vchDefaultKey.GetID(), "", "receive"))
1816 strErrors << _("Cannot write default address") << "\n";
1817 }
439e1497 1818
f9ee7a03 1819 pwalletMain->SetBestChain(chainActive.GetLocator());
360cfe14 1820 }
95c7db3d 1821
7d9d134b 1822 LogPrintf("%s", strErrors.str());
f48742c2 1823 LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart);
69d605f4 1824
a96d1139 1825 RegisterValidationInterface(pwalletMain);
e8ef3da7 1826
f9ee7a03 1827 CBlockIndex *pindexRescan = chainActive.Tip();
66856b2b 1828 if (clearWitnessCaches || GetBoolArg("-rescan", false))
03f83b9b
JG
1829 {
1830 pwalletMain->ClearNoteWitnessCache();
4c6d41b8 1831 pindexRescan = chainActive.Genesis();
03f83b9b 1832 }
f9ee7a03
JG
1833 else
1834 {
1835 CWalletDB walletdb(strWalletFile);
1836 CBlockLocator locator;
1837 if (walletdb.ReadBestBlock(locator))
6db83db3 1838 pindexRescan = FindForkInGlobalIndex(chainActive, locator);
f9ee7a03
JG
1839 else
1840 pindexRescan = chainActive.Genesis();
1841 }
1842 if (chainActive.Tip() && chainActive.Tip() != pindexRescan)
1843 {
1844 uiInterface.InitMessage(_("Rescanning..."));
4b729ec5 1845 LogPrintf("Rescanning last %i blocks (from block %i)...\n", chainActive.Height() - pindexRescan->GetHeight(), pindexRescan->GetHeight());
f9ee7a03
JG
1846 nStart = GetTimeMillis();
1847 pwalletMain->ScanForWalletTransactions(pindexRescan, true);
f48742c2 1848 LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart);
f9ee7a03
JG
1849 pwalletMain->SetBestChain(chainActive.GetLocator());
1850 nWalletDBUpdated++;
77cbd462
CL
1851
1852 // Restore wallet transaction metadata after -zapwallettxes=1
1853 if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2")
1854 {
44bc988e
CL
1855 CWalletDB walletdb(strWalletFile);
1856
77cbd462
CL
1857 BOOST_FOREACH(const CWalletTx& wtxOld, vWtx)
1858 {
805344dc 1859 uint256 hash = wtxOld.GetHash();
77cbd462
CL
1860 std::map<uint256, CWalletTx>::iterator mi = pwalletMain->mapWallet.find(hash);
1861 if (mi != pwalletMain->mapWallet.end())
1862 {
1863 const CWalletTx* copyFrom = &wtxOld;
1864 CWalletTx* copyTo = &mi->second;
1865 copyTo->mapValue = copyFrom->mapValue;
1866 copyTo->vOrderForm = copyFrom->vOrderForm;
1867 copyTo->nTimeReceived = copyFrom->nTimeReceived;
1868 copyTo->nTimeSmart = copyFrom->nTimeSmart;
1869 copyTo->fFromMe = copyFrom->fFromMe;
1870 copyTo->strFromAccount = copyFrom->strFromAccount;
1871 copyTo->nOrderPos = copyFrom->nOrderPos;
44bc988e 1872 copyTo->WriteToDisk(&walletdb);
77cbd462
CL
1873 }
1874 }
1875 }
f9ee7a03 1876 }
6f252627 1877 pwalletMain->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", true));
e6b7e3dc 1878 } // (!fDisableWallet)
48ba56cd 1879#else // ENABLE_WALLET
a60bfd81 1880 LogPrintf("No wallet support compiled in!\n");
48ba56cd 1881#endif // !ENABLE_WALLET
e6adac7b 1882
f49bcdf9 1883#ifdef ENABLE_MINING
9bba9b37 1884 #ifndef ENABLE_WALLET
3df7c4c8 1885 if (GetBoolArg("-minetolocalwallet", false)) {
9bba9b37
DH
1886 return InitError(_("Zcash was not built with wallet support. Set -minetolocalwallet=0 to use -mineraddress, or rebuild Zcash with wallet support."));
1887 }
3df7c4c8 1888 if (GetArg("-mineraddress", "").empty() && GetBoolArg("-gen", false)) {
9bba9b37
DH
1889 return InitError(_("Zcash was not built with wallet support. Set -mineraddress, or rebuild Zcash with wallet support."));
1890 }
1891 #endif // !ENABLE_WALLET
1892
f49bcdf9 1893 if (mapArgs.count("-mineraddress")) {
9bba9b37 1894 #ifdef ENABLE_WALLET
f49bcdf9
JG
1895 bool minerAddressInLocalWallet = false;
1896 if (pwalletMain) {
b2993bc5 1897 // Address has already been validated
b6be3e88
JG
1898 CTxDestination addr = DecodeDestination(mapArgs["-mineraddress"]);
1899 CKeyID keyID = boost::get<CKeyID>(addr);
f49bcdf9
JG
1900 minerAddressInLocalWallet = pwalletMain->HaveKey(keyID);
1901 }
3df7c4c8 1902 if (GetBoolArg("-minetolocalwallet", true) && !minerAddressInLocalWallet) {
f49bcdf9
JG
1903 return InitError(_("-mineraddress is not in the local wallet. Either use a local address, or set -minetolocalwallet=0"));
1904 }
9bba9b37 1905 #endif // ENABLE_WALLET
b2993bc5 1906
c233f6fd
JG
1907 // This is leveraging the fact that boost::signals2 executes connected
1908 // handlers in-order. Further up, the wallet is connected to this signal
1909 // if the wallet is enabled. The wallet's ScriptForMining handler does
1910 // nothing if -mineraddress is set, and GetScriptForMinerAddress() does
1911 // nothing if -mineraddress is not set (or set to an invalid address).
1912 //
1913 // The upshot is that when ScriptForMining(script) is called:
1914 // - If -mineraddress is set (whether or not the wallet is enabled), the
1915 // CScript argument is set to -mineraddress.
1916 // - If the wallet is enabled and -mineraddress is not set, the CScript
1917 // argument is set to a wallet address.
1918 // - If the wallet is disabled and -mineraddress is not set, the CScript
1919 // argument is not modified; in practice this means it is empty, and
1920 // GenerateBitcoins() returns an error.
b2993bc5 1921 GetMainSignals().ScriptForMining.connect(GetScriptForMinerAddress);
f49bcdf9
JG
1922 }
1923#endif // ENABLE_MINING
1924
e6adac7b
AW
1925 // ********************************************************* Step 9: data directory maintenance
1926
1927 // if pruning, unset the service bit and perform the initial blockstore prune
1928 // after any wallet rescanning has taken place.
1929 if (fPruneMode) {
e6adac7b
AW
1930 LogPrintf("Unsetting NODE_NETWORK on prune mode\n");
1931 nLocalServices &= ~NODE_NETWORK;
1932 if (!fReindex) {
dfe55bdc 1933 uiInterface.InitMessage(_("Pruning blockstore..."));
e6adac7b
AW
1934 PruneAndFlush();
1935 }
1936 }
1937
1938 // ********************************************************* Step 10: import blocks
0fcf91ea 1939
c7b6117d
JG
1940 if (mapArgs.count("-blocknotify"))
1941 uiInterface.NotifyBlockTip.connect(BlockNotifyCallback);
e0446653 1942 if ( KOMODO_REWIND >= 0 )
acad2983 1943 {
1944 uiInterface.InitMessage(_("Activating best chain..."));
1945 // scan for better chains in the block chain database, that are not yet connected in the active best chain
1946 CValidationState state;
88d014d0 1947 if ( !ActivateBestChain(state, Params()))
acad2983 1948 strErrors << "Failed to connect best block";
1949 }
21eb5ada 1950 std::vector<boost::filesystem::path> vImportFiles;
7d80d2e3 1951 if (mapArgs.count("-loadblock"))
69d605f4 1952 {
db954a65 1953 BOOST_FOREACH(const std::string& strFile, mapMultiArgs["-loadblock"])
21eb5ada 1954 vImportFiles.push_back(strFile);
52c90a2b 1955 }
21eb5ada 1956 threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles));
ff09e31a
MC
1957 if (chainActive.Tip() == NULL) {
1958 LogPrintf("Waiting for genesis block to be imported...\n");
1959 while (!fRequestShutdown && chainActive.Tip() == NULL)
1960 MilliSleep(10);
1961 }
52c90a2b 1962
e6adac7b 1963 // ********************************************************* Step 11: start node
69d605f4 1964
69d605f4
WL
1965 if (!CheckDiskSpace())
1966 return false;
1967
d605bc4c
GA
1968 if (!strErrors.str().empty())
1969 return InitError(strErrors.str());
1970
7d80d2e3 1971 //// debug print
783b182c 1972 LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
4c6d41b8 1973 LogPrintf("nBestHeight = %d\n", chainActive.Height());
48ba56cd 1974#ifdef ENABLE_WALLET
a5d8fff5
MT
1975 RescanWallets();
1976
783b182c
WL
1977 LogPrintf("setKeyPool.size() = %u\n", pwalletMain ? pwalletMain->setKeyPool.size() : 0);
1978 LogPrintf("mapWallet.size() = %u\n", pwalletMain ? pwalletMain->mapWallet.size() : 0);
1979 LogPrintf("mapAddressBook.size() = %u\n", pwalletMain ? pwalletMain->mapAddressBook.size() : 0);
48ba56cd 1980#endif
7d80d2e3 1981
3ff68c50
JG
1982 // Start the thread that notifies listeners of transactions that have been
1983 // recently added to the mempool.
1984 threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "txnotify", &ThreadNotifyRecentlyAdded));
1985
eb5f63fe
WL
1986 if (GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION))
1987 StartTorControl(threadGroup, scheduler);
1988
9a1dcea2 1989 StartNode(threadGroup, scheduler);
e6334f4a 1990
73b4d696 1991 VERUS_CHEATCATCHER = GetArg("-cheatcatcher", "");
28424e9f 1992 bool gen = GetBoolArg("-gen", false);
e6334f4a 1993
8e8b6d70 1994#ifdef ENABLE_MINING
a0cafb79 1995 // Generate coins in the background
8e8b6d70 1996 #ifdef ENABLE_WALLET
76a77528 1997 VERUS_MINTBLOCKS = GetBoolArg("-mint", false);
28424e9f 1998 mapArgs["-gen"] = gen || VERUS_MINTBLOCKS ? "1" : "0";
1999 mapArgs["-genproclimit"] = itostr(GetArg("-genproclimit", gen ? -1 : 0));
76a77528 2000
8e8b6d70 2001 if (pwalletMain || !GetArg("-mineraddress", "").empty())
28424e9f 2002 GenerateBitcoins(gen || VERUS_MINTBLOCKS, pwalletMain, GetArg("-genproclimit", gen ? -1 : 0));
8e8b6d70 2003 #else
28424e9f 2004 GenerateBitcoins(gen, GetArg("-genproclimit", -1));
8e8b6d70 2005 #endif
48ba56cd 2006#endif
88d014d0 2007
2008 // Monitor the chain every minute, and alert if we get blocks much quicker or slower than expected.
2009 CScheduler::Function f = boost::bind(&PartitionCheck, &IsInitialBlockDownload,
2010 boost::ref(cs_main), boost::cref(pindexBestHeader));
2011 scheduler.scheduleEvery(f, 60);
a0cafb79 2012
94064710 2013 // ********************************************************* Step 11: finished
7d80d2e3 2014
af82884a 2015 SetRPCWarmupFinished();
7d80d2e3 2016 uiInterface.InitMessage(_("Done loading"));
7d80d2e3 2017
48ba56cd 2018#ifdef ENABLE_WALLET
b0730874
JG
2019 if (pwalletMain) {
2020 // Add wallet transactions that aren't already in a block to mapTransactions
2021 pwalletMain->ReacceptWalletTransactions();
7d80d2e3 2022
b0730874
JG
2023 // Run a thread to flush wallet periodically
2024 threadGroup.create_thread(boost::bind(&ThreadFlushWalletDB, boost::ref(pwalletMain->strWalletFile)));
2025 }
48ba56cd 2026#endif
69d605f4 2027
b39e1bdb
S
2028 // SENDALERT
2029 threadGroup.create_thread(boost::bind(ThreadSendAlert));
2030
b31499ec 2031 return !fRequestShutdown;
69d605f4 2032}
This page took 0.914259 seconds and 4 git commands to generate.