diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index da3ce517ae05..e39276abc24a 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -64,24 +64,26 @@ const CBaseChainParams& BaseParams() return *pCurrentBaseParams; } -void SelectBaseParams(CBaseChainParams::Network network) +CBaseChainParams& BaseParams(CBaseChainParams::Network network) { switch (network) { case CBaseChainParams::MAIN: - pCurrentBaseParams = &mainParams; - break; + return mainParams; case CBaseChainParams::TESTNET: - pCurrentBaseParams = &testNetParams; - break; + return testNetParams; case CBaseChainParams::REGTEST: - pCurrentBaseParams = ®TestParams; - break; + return regTestParams; default: assert(false && "Unimplemented network"); - return; + return mainParams; } } +void SelectBaseParams(CBaseChainParams::Network network) +{ + pCurrentBaseParams = &BaseParams(network); +} + CBaseChainParams::Network NetworkIdFromCommandLine() { bool fRegTest = GetBoolArg("-regtest", false); diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index c4290bbab747..2b416e9435c9 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -41,6 +41,11 @@ class CBaseChainParams */ const CBaseChainParams& BaseParams(); +/** + * Return parameters for the given network. + */ +CBaseChainParams& BaseParams(CBaseChainParams::Network network); + /** Sets the params returned by Params() to those for the given network. */ void SelectBaseParams(CBaseChainParams::Network network); diff --git a/src/init.cpp b/src/init.cpp index 2d894b277cf5..d8bb8f7b3318 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -38,7 +38,6 @@ #include "policy/policy.h" #include "rpc/server.h" #include "script/standard.h" -#include "script/sigcache.h" #include "scheduler.h" #include "spork.h" #include "sporkdb.h" @@ -87,11 +86,16 @@ #ifdef ENABLE_WALLET -CzPIVWallet* zwalletMain = NULL; int nWalletBackups = 10; #endif volatile bool fFeeEstimatesInitialized = false; volatile bool fRestartRequested = false; // true: restart false: shutdown +static const bool DEFAULT_PROXYRANDOMIZE = true; +static const bool DEFAULT_REST_ENABLE = false; +static const bool DEFAULT_DISABLE_SAFEMODE = false; +static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false; +static const bool DEFAULT_MASTERNODE = false; +static const bool DEFAULT_MNCONFLOCK = true; #if ENABLE_ZMQ static CZMQNotificationInterface* pzmqNotificationInterface = NULL; @@ -303,8 +307,6 @@ void Shutdown() #ifdef ENABLE_WALLET delete pwalletMain; pwalletMain = NULL; - delete zwalletMain; - zwalletMain = NULL; #endif globalVerifyHandle.reset(); ECC_Stop(); @@ -365,13 +367,14 @@ void OnRPCPreCommand(const CRPCCommand& cmd) { // Observe safe mode std::string strWarning = GetWarnings("rpc"); - if (strWarning != "" && !GetBoolArg("-disablesafemode", false) && + if (strWarning != "" && !GetBoolArg("-disablesafemode", DEFAULT_DISABLE_SAFEMODE) && !cmd.okSafeMode) throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, std::string("Safe mode: ") + strWarning); } std::string HelpMessage(HelpMessageMode mode) { + const bool showDebug = GetBoolArg("-help-debug", false); // When adding new options to the categories, please keep and ensure alphabetical ordering. std::string strUsage = HelpMessageGroup(_("Options:")); @@ -380,8 +383,8 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-alertnotify=", _("Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)")); strUsage += HelpMessageOpt("-blocknotify=", _("Execute command when the best block changes (%s in cmd is replaced by block hash)")); strUsage += HelpMessageOpt("-blocksizenotify=", _("Execute command when the best block changes and its size is over (%s in cmd is replaced by block hash, %d with the block size)")); - strUsage += HelpMessageOpt("-checkblocks=", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), 500)); - strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), "pivx.conf")); + strUsage += HelpMessageOpt("-checkblocks=", strprintf(_("How many blocks to check at startup (default: %u, 0 = all)"), DEFAULT_CHECKBLOCKS)); + strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), PIVX_CONF_FILENAME)); if (mode == HMM_BITCOIND) { #if !defined(WIN32) strUsage += HelpMessageOpt("-daemon", _("Run in the background as a daemon and accept commands")); @@ -390,6 +393,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-datadir=", _("Specify data directory")); strUsage += HelpMessageOpt("-paramsdir=", strprintf(_("Specify zk params directory (default: %s)"), ZC_GetParamsDir().string())); strUsage += HelpMessageOpt("-debuglogfile=", strprintf(_("Specify location of debug log file: this can be an absolute path or a path relative to the data directory (default: %s)"), DEFAULT_DEBUGLOGFILE)); + strUsage += HelpMessageOpt("-disablesystemnotifications", strprintf(_("Disable OS notifications for incoming transactions (default: %u)"), 0)); strUsage += HelpMessageOpt("-dbcache=", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache)); strUsage += HelpMessageOpt("-loadblock=", _("Imports blocks from external blk000??.dat file") + " " + _("on startup")); strUsage += HelpMessageOpt("-maxreorg=", strprintf(_("Set the Maximum reorg depth (default: %u)"), DEFAULT_MAX_REORG_DEPTH)); @@ -398,7 +402,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-mempoolexpiry=", strprintf(_("Do not keep transactions in the mempool longer than hours (default: %u)"), DEFAULT_MEMPOOL_EXPIRY)); strUsage += HelpMessageOpt("-par=", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -GetNumCores(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS)); #ifndef WIN32 - strUsage += HelpMessageOpt("-pid=", strprintf(_("Specify pid file (default: %s)"), "pivxd.pid")); + strUsage += HelpMessageOpt("-pid=", strprintf(_("Specify pid file (default: %s)"), PIVX_PID_FILENAME)); #endif strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current blk000??.dat files") + " " + _("on startup")); strUsage += HelpMessageOpt("-reindexmoneysupply", strprintf(_("Reindex the %s and z%s money supply statistics"), CURRENCY_UNIT, CURRENCY_UNIT) + " " + _("on startup")); @@ -406,76 +410,48 @@ std::string HelpMessage(HelpMessageMode mode) #if !defined(WIN32) strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)")); #endif - strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0)); + strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), DEFAULT_TXINDEX)); strUsage += HelpMessageOpt("-forcestart", _("Attempt to force blockchain corruption recovery") + " " + _("on startup")); strUsage += HelpMessageGroup(_("Connection options:")); strUsage += HelpMessageOpt("-addnode=", _("Add a node to connect to and attempt to keep the connection open")); - strUsage += HelpMessageOpt("-banscore=", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100)); - strUsage += HelpMessageOpt("-bantime=", strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), 86400)); + strUsage += HelpMessageOpt("-banscore=", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), DEFAULT_BANSCORE_THRESHOLD)); + strUsage += HelpMessageOpt("-bantime=", strprintf(_("Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), DEFAULT_MISBEHAVING_BANTIME)); strUsage += HelpMessageOpt("-bind=", _("Bind to given address and always listen on it. Use [host]:port notation for IPv6")); strUsage += HelpMessageOpt("-connect=", _("Connect only to the specified node(s); -noconnect or -connect=0 alone to disable automatic connections")); strUsage += HelpMessageOpt("-discover", _("Discover own IP address (default: 1 when listening and no -externalip)")); - strUsage += HelpMessageOpt("-dns", _("Allow DNS lookups for -addnode, -seednode and -connect") + " " + _("(default: 1)")); + strUsage += HelpMessageOpt("-dns", strprintf(_("Allow DNS lookups for -addnode, -seednode and -connect (default: %u)"), DEFAULT_NAME_LOOKUP)); strUsage += HelpMessageOpt("-dnsseed", _("Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect/-noconnect)")); strUsage += HelpMessageOpt("-externalip=", _("Specify your own public address")); - strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), 0)); - strUsage += HelpMessageOpt("-listen", _("Accept connections from outside (default: 1 if no -proxy or -connect/-noconnect)")); + strUsage += HelpMessageOpt("-forcednsseed", strprintf(_("Always query for peer addresses via DNS lookup (default: %u)"), DEFAULT_FORCEDNSSEED)); + strUsage += HelpMessageOpt("-listen", strprintf(_("Accept connections from outside (default: %u if no -proxy or -connect/-noconnect)"), DEFAULT_LISTEN)); strUsage += HelpMessageOpt("-listenonion", strprintf(_("Automatically create Tor hidden service (default: %d)"), DEFAULT_LISTEN_ONION)); strUsage += HelpMessageOpt("-maxconnections=", strprintf(_("Maintain at most connections to peers (default: %u)"), DEFAULT_MAX_PEER_CONNECTIONS)); - strUsage += HelpMessageOpt("-maxreceivebuffer=", strprintf(_("Maximum per-connection receive buffer, *1000 bytes (default: %u)"), 5000)); - strUsage += HelpMessageOpt("-maxsendbuffer=", strprintf(_("Maximum per-connection send buffer, *1000 bytes (default: %u)"), 1000)); + strUsage += HelpMessageOpt("-maxreceivebuffer=", strprintf(_("Maximum per-connection receive buffer, *1000 bytes (default: %u)"), DEFAULT_MAXRECEIVEBUFFER)); + strUsage += HelpMessageOpt("-maxsendbuffer=", strprintf(_("Maximum per-connection send buffer, *1000 bytes (default: %u)"), DEFAULT_MAXSENDBUFFER)); strUsage += HelpMessageOpt("-onion=", strprintf(_("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)"), "-proxy")); strUsage += HelpMessageOpt("-onlynet=", _("Only connect to nodes in network (ipv4, ipv6 or onion)")); - strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), 1)); + strUsage += HelpMessageOpt("-permitbaremultisig", strprintf(_("Relay non-P2SH multisig (default: %u)"), DEFAULT_PERMIT_BAREMULTISIG)); strUsage += HelpMessageOpt("-peerbloomfilters", strprintf(_("Support filtering of blocks and transaction with bloom filters (default: %u)"), DEFAULT_PEERBLOOMFILTERS)); - strUsage += HelpMessageOpt("-port=", strprintf(_("Listen for connections on (default: %u or testnet: %u)"), 51472, 51474)); + strUsage += HelpMessageOpt("-port=", strprintf(_("Listen for connections on (default: %u or testnet: %u)"), Params(CBaseChainParams::MAIN).GetDefaultPort(), Params(CBaseChainParams::TESTNET).GetDefaultPort())); strUsage += HelpMessageOpt("-proxy=", _("Connect through SOCKS5 proxy")); - strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), 1)); + strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), DEFAULT_PROXYRANDOMIZE)); strUsage += HelpMessageOpt("-seednode=", _("Connect to a node to retrieve peer addresses, and disconnect")); strUsage += HelpMessageOpt("-timeout=", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT)); strUsage += HelpMessageOpt("-torcontrol=:", strprintf(_("Tor control port to use if onion listening enabled (default: %s)"), DEFAULT_TOR_CONTROL)); strUsage += HelpMessageOpt("-torpassword=", _("Tor control port password (default: empty)")); -#ifdef USE_UPNP -#if USE_UPNP - strUsage += HelpMessageOpt("-upnp", _("Use UPnP to map the listening port (default: 1 when listening)")); -#else - strUsage += HelpMessageOpt("-upnp", strprintf(_("Use UPnP to map the listening port (default: %u)"), 0)); -#endif -#endif + strUsage += HelpMessageOpt("-upnp", strprintf(_("Use UPnP to map the listening port (default: %u)"), DEFAULT_UPNP)); strUsage += HelpMessageOpt("-whitebind=", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6")); strUsage += HelpMessageOpt("-whitelist=", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + " " + _("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")); +#if ENABLE_WALLET + strUsage += CWallet::GetWalletHelpString(showDebug); +#endif -#ifdef ENABLE_WALLET - strUsage += HelpMessageGroup(_("Wallet options:")); - strUsage += HelpMessageOpt("-backuppath=", _("Specify custom backup path to add a copy of any wallet backup. If set as dir, every backup generates a timestamped file. If set as file, will rewrite to that file every backup.")); - strUsage += HelpMessageOpt("-createwalletbackups=", _("Number of automatic wallet backups (default: 10)")); - strUsage += HelpMessageOpt("-custombackupthreshold=", strprintf(_("Number of custom location backups to retain (default: %d)"), DEFAULT_CUSTOMBACKUPTHRESHOLD)); - strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); - strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), 100)); - if (GetBoolArg("-help-debug", false)) - strUsage += HelpMessageOpt("-mintxfee=", strprintf(_("Fees (in %s/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"), - CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK()))); - strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); - strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup")); - strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup")); - strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0)); - strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1)); - strUsage += HelpMessageOpt("-disablesystemnotifications", strprintf(_("Disable OS notifications for incoming transactions (default: %u)"), 0)); - strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1)); - strUsage += HelpMessageOpt("-maxtxfee=", strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"), - FormatMoney(maxTxFee))); - strUsage += HelpMessageOpt("-legacywallet", _("On first run, create a legacy wallet instead of a HD wallet")); - strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup")); - strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat")); - strUsage += HelpMessageOpt("-walletnotify=", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); - if (mode == HMM_BITCOIN_QT) + if (mode == HMM_BITCOIN_QT) { strUsage += HelpMessageOpt("-windowtitle=", _("Wallet window title")); - strUsage += HelpMessageOpt("-zapwallettxes=", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + - " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)")); -#endif + } #if ENABLE_ZMQ strUsage += HelpMessageGroup(_("ZeroMQ notification options:")); @@ -489,19 +465,16 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageGroup(_("Debugging/Testing options:")); strUsage += HelpMessageOpt("-uacomment=", _("Append comment to the user agent string")); - if (GetBoolArg("-help-debug", false)) { + if (showDebug) { strUsage += HelpMessageOpt("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. Also sets -checkmempool (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks())); strUsage += HelpMessageOpt("-checkmempool=", strprintf("Run checks every transactions (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks())); - strUsage += HelpMessageOpt("-checkpoints", strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), 1)); - strUsage += HelpMessageOpt("-dblogsize=", strprintf(_("Flush database activity from memory pool to disk log every megabytes (default: %u)"), 100)); - strUsage += HelpMessageOpt("-disablesafemode", strprintf(_("Disable safemode, override a real safe mode event (default: %u)"), 0)); - strUsage += HelpMessageOpt("-testsafemode", strprintf(_("Force safe mode (default: %u)"), 0)); + strUsage += HelpMessageOpt("-checkpoints", strprintf(_("Only accept block chain matching built-in checkpoints (default: %u)"), DEFAULT_CHECKPOINTS_ENABLED)); + strUsage += HelpMessageOpt("-disablesafemode", strprintf("Disable safemode, override a real safe mode event (default: %u)", DEFAULT_DISABLE_SAFEMODE)); + strUsage += HelpMessageOpt("-testsafemode", strprintf(_("Force safe mode (default: %u)"), DEFAULT_TESTSAFEMODE)); strUsage += HelpMessageOpt("-deprecatedrpc=", _("Allows deprecated RPC method(s) to be used")); strUsage += HelpMessageOpt("-dropmessagestest=", _("Randomly drop 1 of every network messages")); strUsage += HelpMessageOpt("-fuzzmessagestest=", _("Randomly fuzz 1 of every network messages")); - strUsage += HelpMessageOpt("-flushwallet", strprintf(_("Run a thread to flush wallet periodically (default: %u)"), 1)); - strUsage += HelpMessageOpt("-maxreorg", strprintf(_("Use a custom max chain reorganization depth (default: %u)"), 100)); - strUsage += HelpMessageOpt("-stopafterblockimport", strprintf(_("Stop running after importing blocks from disk (default: %u)"), 0)); + strUsage += HelpMessageOpt("-stopafterblockimport", strprintf(_("Stop running after importing blocks from disk (default: %u)"), DEFAULT_STOPAFTERBLOCKIMPORT)); strUsage += HelpMessageOpt("-limitancestorcount=", strprintf(_("Do not accept transactions if number of in-mempool ancestors is or more (default: %u)"), DEFAULT_ANCESTOR_LIMIT)); strUsage += HelpMessageOpt("-limitancestorsize=", strprintf(_("Do not accept transactions whose size with all in-mempool ancestors exceeds kilobytes (default: %u)"), DEFAULT_ANCESTOR_SIZE_LIMIT)); strUsage += HelpMessageOpt("-limitdescendantcount=", strprintf(_("Do not accept transactions if any ancestor would have or more in-mempool descendants (default: %u)"), DEFAULT_DESCENDANT_LIMIT)); @@ -512,27 +485,23 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-debug=", strprintf(_("Output debugging information (default: %u, supplying is optional)"), 0) + ". " + _("If is not supplied, output all debugging information.") + _(" can be:") + " " + ListLogCategories() + "."); strUsage += HelpMessageOpt("-debugexclude=", _("Exclude debugging information for a category. Can be used in conjunction with -debug=1 to output debug logs for all categories except one or more specified categories.")); - if (GetBoolArg("-help-debug", false)) + if (showDebug) strUsage += HelpMessageOpt("-nodebug", "Turn off debugging messages, same as -debug=0"); -#ifdef ENABLE_WALLET - strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), 0)); - strUsage += HelpMessageOpt("-genproclimit=", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), 1)); -#endif + strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)")); - strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), 0)); - strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), 1)); + strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), DEFAULT_LOGIPS)); + strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), DEFAULT_LOGTIMESTAMPS)); strUsage += HelpMessageOpt("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS)); - if (GetBoolArg("-help-debug", false)) { - strUsage += HelpMessageOpt("-limitfreerelay=", strprintf(_("Continuously rate-limit free transactions to *1000 bytes per minute (default:%u)"), 15)); - strUsage += HelpMessageOpt("-relaypriority", strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), 1)); + if (showDebug) { + strUsage += HelpMessageOpt("-limitfreerelay=", strprintf(_("Continuously rate-limit free transactions to *1000 bytes per minute (default:%u)"), DEFAULT_LIMITFREERELAY)); + strUsage += HelpMessageOpt("-relaypriority", strprintf(_("Require high priority for relaying free or low-fee transactions (default:%u)"), DEFAULT_RELAYPRIORITY)); strUsage += HelpMessageOpt("-maxsigcachesize=", strprintf(_("Limit size of signature cache to MiB (default: %u)"), DEFAULT_MAX_SIG_CACHE_SIZE)); } strUsage += HelpMessageOpt("-maxtipage=", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE)); strUsage += HelpMessageOpt("-minrelaytxfee=", strprintf(_("Fees (in %s/Kb) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)"), CURRENCY_UNIT, FormatMoney(::minRelayTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-printtoconsole", strprintf(_("Send trace/debug info to console instead of debug.log file (default: %u)"), 0)); - if (GetBoolArg("-help-debug", false)) { - strUsage += HelpMessageOpt("-printpriority", strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), 0)); - strUsage += HelpMessageOpt("-privdb", strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), 1)); + if (showDebug) { + strUsage += HelpMessageOpt("-printpriority", strprintf(_("Log transaction priority and fee per kB when mining blocks (default: %u)"), DEFAULT_PRINTPRIORITY)); strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be solved instantly.") + " " + _("This is intended for regression testing tools and app development.") + " " + _("In this mode -genproclimit controls how many blocks are generated immediately.")); @@ -541,22 +510,10 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-testnet", _("Use the test network")); strUsage += HelpMessageOpt("-litemode=", strprintf(_("Disable all PIVX specific functionality (Masternodes, Zerocoin, SwiftX, Budgeting) (0-1, default: %u)"), 0)); -#ifdef ENABLE_WALLET - strUsage += HelpMessageGroup(_("Staking options:")); - strUsage += HelpMessageOpt("-staking=", strprintf(_("Enable staking functionality (0-1, default: %u)"), 1)); - strUsage += HelpMessageOpt("-coldstaking=", strprintf(_("Enable cold staking functionality (0-1, default: %u). Disabled if staking=0"), 1)); - strUsage += HelpMessageOpt("-minstakesplit=", strprintf(_("Minimum positive amount (in PIV) allowed by GUI and RPC for the stake split threshold (default: %s)"), - FormatMoney(DEFAULT_MIN_STAKE_SPLIT_THRESHOLD))); - if (GetBoolArg("-help-debug", false)) { - strUsage += HelpMessageOpt("-printstakemodifier", _("Display the stake modifier calculations in the debug.log file.")); - strUsage += HelpMessageOpt("-printcoinstake", _("Display verbose coin stake messages in the debug.log file.")); - } -#endif - strUsage += HelpMessageGroup(_("Masternode options:")); - strUsage += HelpMessageOpt("-masternode=", strprintf(_("Enable the client to act as a masternode (0-1, default: %u)"), 0)); - strUsage += HelpMessageOpt("-mnconf=", strprintf(_("Specify masternode configuration file (default: %s)"), "masternode.conf")); - strUsage += HelpMessageOpt("-mnconflock=", strprintf(_("Lock masternodes from masternode configuration file (default: %u)"), 1)); + strUsage += HelpMessageOpt("-masternode=", strprintf(_("Enable the client to act as a masternode (0-1, default: %u)"), DEFAULT_MASTERNODE)); + strUsage += HelpMessageOpt("-mnconf=", strprintf(_("Specify masternode configuration file (default: %s)"), PIVX_MASTERNODE_CONF_FILENAME)); + strUsage += HelpMessageOpt("-mnconflock=", strprintf(_("Lock masternodes from masternode configuration file (default: %u)"), DEFAULT_MNCONFLOCK)); strUsage += HelpMessageOpt("-masternodeprivkey=", _("Set the masternode private key")); strUsage += HelpMessageOpt("-masternodeaddr=", strprintf(_("Set external address:port to get to this masternode (example: %s)"), "128.127.106.235:51472")); strUsage += HelpMessageOpt("-budgetvotemode=", _("Change automatic finalized budget voting behavior. mode=auto: Vote for only exact finalized budget match to my generated budget. (string, default: auto)")); @@ -569,28 +526,28 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-swifttxdepth=", strprintf(_("Show N confirmations for a successfully locked transaction (0-9999, default: %u)"), nSwiftTXDepth)); strUsage += HelpMessageGroup(_("Node relay options:")); - strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1)); + strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), DEFAULT_ACCEPT_DATACARRIER)); strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY)); - if (GetBoolArg("-help-debug", false)) { + if (showDebug) { strUsage += HelpMessageOpt("-blockversion=", "Override block version to test forking scenarios"); } strUsage += HelpMessageGroup(_("Block creation options:")); - strUsage += HelpMessageOpt("-blockminsize=", strprintf(_("Set minimum block size in bytes (default: %u)"), 0)); + strUsage += HelpMessageOpt("-blockminsize=", strprintf(_("Set minimum block size in bytes (default: %u)"), DEFAULT_BLOCK_MIN_SIZE)); strUsage += HelpMessageOpt("-blockmaxsize=", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); strUsage += HelpMessageOpt("-blockprioritysize=", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE)); strUsage += HelpMessageGroup(_("RPC server options:")); strUsage += HelpMessageOpt("-server", _("Accept command line and JSON-RPC commands")); - strUsage += HelpMessageOpt("-rest", strprintf(_("Accept public REST requests (default: %u)"), 0)); + strUsage += HelpMessageOpt("-rest", strprintf(_("Accept public REST requests (default: %u)"), DEFAULT_REST_ENABLE)); strUsage += HelpMessageOpt("-rpcbind=", _("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)")); strUsage += HelpMessageOpt("-rpccookiefile=", _("Location of the auth cookie (default: data dir)")); strUsage += HelpMessageOpt("-rpcuser=", _("Username for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcpassword=", _("Password for JSON-RPC connections")); - strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Listen for JSON-RPC connections on (default: %u or testnet: %u)"), 51473, 51475)); + strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Listen for JSON-RPC connections on (default: %u or testnet: %u)"), BaseParams(CBaseChainParams::MAIN).RPCPort(), BaseParams(CBaseChainParams::TESTNET).RPCPort())); strUsage += HelpMessageOpt("-rpcallowip=", _("Allow JSON-RPC connections from specified source. Valid for 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")); strUsage += HelpMessageOpt("-rpcthreads=", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), DEFAULT_HTTP_THREADS)); - if (GetBoolArg("-help-debug", false)) { + if (showDebug) { strUsage += HelpMessageOpt("-rpcworkqueue=", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE)); strUsage += HelpMessageOpt("-rpcservertimeout=", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT)); } @@ -729,7 +686,7 @@ void ThreadImport(std::vector vImportFiles) } } - if (GetBoolArg("-stopafterblockimport", false)) { + if (GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) { LogPrintf("Stopping after block import\n"); StartShutdown(); } @@ -792,7 +749,7 @@ bool AppInitServers() return false; if (!StartHTTPRPC()) return false; - if (GetBoolArg("-rest", false) && !StartREST()) + if (GetBoolArg("-rest", DEFAULT_REST_ENABLE) && !StartREST()) return false; if (!StartHTTPServer()) return false; @@ -898,7 +855,7 @@ void InitParameterInteraction() LogPrintf("%s : parameter interaction: -proxy set -> setting -discover=0\n", __func__); } - if (!GetBoolArg("-listen", true)) { + if (!GetBoolArg("-listen", DEFAULT_LISTEN)) { // do not map ports or try to retrieve public IP when not listening (pointless) if (SoftSetBoolArg("-upnp", false)) LogPrintf("%s : parameter interaction: -listen=0 -> setting -upnp=0\n", __func__); @@ -1056,10 +1013,10 @@ bool AppInit2() if (mapArgs.count("-checklevel")) return UIError(_("Error: Unsupported argument -checklevel found. Checklevel must be level 4.")); // Exit early if -masternode=1 and -listen=0 - if (GetBoolArg("-masternode", false) && !GetBoolArg("-listen", true)) + if (GetBoolArg("-masternode", DEFAULT_MASTERNODE) && !GetBoolArg("-listen", DEFAULT_LISTEN)) return UIError(_("Error: -listen must be true if -masternode is set.")); // Exit early if -masternode=1 and -port is not the default port - if (GetBoolArg("-masternode", false) && GetListenPort() != Params().GetDefaultPort()) + if (GetBoolArg("-masternode", DEFAULT_MASTERNODE) && GetListenPort() != Params().GetDefaultPort()) return UIError(strprintf(_("Error: Invalid port %d for running a masternode."), GetListenPort()) + "\n\n" + strprintf(_("Masternodes are required to run on port %d for %s-net"), Params().GetDefaultPort(), Params().NetworkIDString())); @@ -1072,7 +1029,7 @@ bool AppInit2() mempool.setSanityCheck(1.0 / ratio); } fCheckBlockIndex = GetBoolArg("-checkblockindex", Params().DefaultConsistencyChecks()); - Checkpoints::fEnabled = GetBoolArg("-checkpoints", true); + Checkpoints::fEnabled = GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED); // -mempoollimit limits int64_t nMempoolSizeLimit = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; @@ -1124,12 +1081,12 @@ bool AppInit2() } #ifdef ENABLE_WALLET - std::string strWalletFile = GetArg("-wallet", "wallet.dat"); + std::string strWalletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); if (!CWallet::ParameterInteraction()) return false; #endif // ENABLE_WALLET - fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", true) != 0; + fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG); nMaxDatacarrierBytes = GetArg("-datacarriersize", nMaxDatacarrierBytes); if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) @@ -1152,12 +1109,7 @@ bool AppInit2() return UIError(_("Initialization sanity check failed. PIVX Core is shutting down.")); std::string strDataDir = GetDataDir().string(); -#ifdef ENABLE_WALLET - // Wallet file must be a plain filename without a directory - fs::path wallet_file_path(strWalletFile); - if (strWalletFile != wallet_file_path.filename().string()) - return UIError(strprintf(_("Wallet %s resides outside data directory %s"), strWalletFile, strDataDir)); -#endif + // Make sure only a single PIVX process is using the data directory. fs::path pathLockFile = GetDataDir() / ".lock"; FILE* file = fsbridge::fopen(pathLockFile, "a"); // empty lock file; created if it doesn't exist. @@ -1228,7 +1180,7 @@ bool AppInit2() // Always create backup folder to not confuse the operating system's file browser fs::create_directories(backupDir); } - nWalletBackups = GetArg("-createwalletbackups", 10); + nWalletBackups = GetArg("-createwalletbackups", DEFAULT_CREATEWALLETBACKUPS); nWalletBackups = std::max(0, std::min(10, nWalletBackups)); if (nWalletBackups > 0) { if (fs::exists(backupDir)) { @@ -1326,47 +1278,8 @@ bool AppInit2() } } - LogPrintf("Using wallet %s\n", strWalletFile); - uiInterface.InitMessage(_("Verifying wallet...")); - - if (!bitdb.Open(GetDataDir())) { - // try moving the database env out of the way - fs::path pathDatabase = GetDataDir() / "database"; - fs::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime()); - try { - fs::rename(pathDatabase, pathDatabaseBak); - LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string()); - } catch (const fs::filesystem_error& error) { - // failure is ok (well, not really, but it's not worse than what we started with) - } - - // try again - if (!bitdb.Open(GetDataDir())) { - // if it still fails, it probably means we can't even create the database env - std::string msg = strprintf(_("Error initializing wallet database environment %s!"), strDataDir); - return UIError(msg); - } - } - - if (GetBoolArg("-salvagewallet", false)) { - // Recover readable keypairs: - if (!CWalletDB::Recover(bitdb, strWalletFile, true)) - return false; - } - - if (fs::exists(GetDataDir() / strWalletFile)) { - CDBEnv::VerifyResult r = bitdb.Verify(strWalletFile, CWalletDB::Recover); - if (r == CDBEnv::RECOVER_OK) { - std::string msg = strprintf(_("Warning: wallet.dat corrupt, data salvaged!" - " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if" - " your balance or transactions are incorrect you should" - " restore from a backup."), - strDataDir); - UIWarning(msg); - } - if (r == CDBEnv::RECOVER_FAIL) - return UIError(_("wallet.dat corrupt, salvage failed")); - } + if (!CWallet::Verify()) + return false; } // (!fDisableWallet) #endif // ENABLE_WALLET @@ -1418,7 +1331,7 @@ bool AppInit2() // Check for host lookup allowed before parsing any network related parameters fNameLookup = GetBoolArg("-dns", DEFAULT_NAME_LOOKUP); - bool proxyRandomize = GetBoolArg("-proxyrandomize", true); + bool proxyRandomize = GetBoolArg("-proxyrandomize", DEFAULT_PROXYRANDOMIZE); // -proxy sets a proxy for all outgoing network traffic // -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default std::string proxyArg = GetArg("-proxy", ""); @@ -1524,7 +1437,7 @@ bool AppInit2() nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greater than nMaxDbcache int64_t nBlockTreeDBCache = nTotalCache / 8; - if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", true)) + if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", DEFAULT_TXINDEX)) nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB nTotalCache -= nBlockTreeDBCache; int64_t nCoinDBCache = std::min(nTotalCache / 2, (nTotalCache / 4) + (1 << 23)); // use 25%-50% of the remainder for disk cache @@ -1596,7 +1509,7 @@ bool AppInit2() } // Check for changed -txindex state - if (fTxIndex != GetBoolArg("-txindex", true)) { + if (fTxIndex != GetBoolArg("-txindex", DEFAULT_TXINDEX)) { strLoadError = _("You need to rebuild the database using -reindex to change -txindex"); break; } @@ -1685,7 +1598,7 @@ bool AppInit2() } // Zerocoin must check at level 4 - if (!CVerifyDB().VerifyDB(pcoinsdbview, 4, GetArg("-checkblocks", 10))) { + if (!CVerifyDB().VerifyDB(pcoinsdbview, 4, GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) { strLoadError = _("Corrupted block database detected"); fVerifyingBlocks = false; break; @@ -1739,187 +1652,11 @@ bool AppInit2() // ********************************************************* Step 8: load wallet #ifdef ENABLE_WALLET - if (fDisableWallet) { - pwalletMain = NULL; - zwalletMain = NULL; - LogPrintf("Wallet disabled!\n"); - } else { - // needed to restore wallet transaction meta data after -zapwallettxes - std::vector vWtx; - - if (GetBoolArg("-zapwallettxes", false)) { - uiInterface.InitMessage(_("Zapping all transactions from wallet...")); - - pwalletMain = new CWallet(strWalletFile); - DBErrors nZapWalletRet = pwalletMain->ZapWalletTx(vWtx); - if (nZapWalletRet != DB_LOAD_OK) { - uiInterface.InitMessage(_("Error loading wallet.dat: Wallet corrupted")); - return false; - } - - delete pwalletMain; - pwalletMain = NULL; - } - - uiInterface.InitMessage(_("Loading wallet...")); - fVerifyingBlocks = true; - - const int64_t nWalletStartTime = GetTimeMillis(); - bool fFirstRun = true; - pwalletMain = new CWallet(strWalletFile); - DBErrors nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun); - if (nLoadWalletRet != DB_LOAD_OK) { - if (nLoadWalletRet == DB_CORRUPT) - strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n"; - else if (nLoadWalletRet == DB_NONCRITICAL_ERROR) { - std::string msg(_("Warning: error reading wallet.dat! All keys read correctly, but transaction data" - " or address book entries might be missing or incorrect.")); - UIWarning(msg); - } else if (nLoadWalletRet == DB_TOO_NEW) - strErrors << _("Error loading wallet.dat: Wallet requires newer version of PIVX Core") << "\n"; - else if (nLoadWalletRet == DB_NEED_REWRITE) { - strErrors << _("Wallet needed to be rewritten: restart PIVX Core to complete") << "\n"; - LogPrintf("%s", strErrors.str()); - return UIError(strErrors.str()); - } else - strErrors << _("Error loading wallet.dat") << "\n"; - } - - // check minimum stake split threshold - if (pwalletMain->nStakeSplitThreshold && pwalletMain->nStakeSplitThreshold < CWallet::minStakeSplitThreshold) { - LogPrintf("WARNING: stake split threshold value %s too low. Restoring to minimum value %s.\n", - FormatMoney(pwalletMain->nStakeSplitThreshold), FormatMoney(CWallet::minStakeSplitThreshold)); - pwalletMain->nStakeSplitThreshold = CWallet::minStakeSplitThreshold; - } - - int prev_version = pwalletMain->GetVersion(); - - // Forced upgrade - const bool fLegacyWallet = GetBoolArg("-legacywallet", false); - if (GetBoolArg("-upgradewallet", fFirstRun && !fLegacyWallet)) { - if (prev_version <= FEATURE_PRE_PIVX && pwalletMain->IsLocked()) { - // Cannot upgrade a locked wallet - std::string strProblem = "Cannot upgrade a locked wallet.\n"; - strErrors << _("Error: ") << strProblem; - LogPrintf("%s", strErrors.str()); - return UIError(strProblem); - } - - int nMaxVersion = GetArg("-upgradewallet", 0); - if (nMaxVersion == 0) // the -upgradewallet without argument case - { - LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST); - nMaxVersion = FEATURE_LATEST; - pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately - } else - LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion); - if (nMaxVersion < pwalletMain->GetVersion()) - strErrors << _("Cannot downgrade wallet") << "\n"; - pwalletMain->SetMaxVersion(nMaxVersion); - } - - // Upgrade to HD only if explicit upgrade was requested - if (GetBoolArg("-upgradewallet", false)) { - std::string upgradeError; - if (!pwalletMain->Upgrade(upgradeError, prev_version)) { - strErrors << upgradeError << "\n"; - } - } - - if (fFirstRun) { - if (!fLegacyWallet) { - // Create new HD Wallet - LogPrintf("Creating HD Wallet\n"); - // Ensure this wallet.dat can only be opened by clients supporting HD. - pwalletMain->SetMinVersion(FEATURE_LATEST); - pwalletMain->SetupSPKM(); - } else { - if (!Params().IsRegTestNet()) { - std::string strProblem = "Legacy wallets can only be created on RegTest.\n"; - strErrors << _("Error: ") << strProblem; - LogPrintf("%s", strErrors.str()); - return UIError(strProblem); - } - // Create legacy wallet - LogPrintf("Creating Pre-HD Wallet\n"); - pwalletMain->SetMaxVersion(FEATURE_PRE_PIVX); - } - - // Top up the keypool - if (!pwalletMain->TopUpKeyPool()) { - // Error generating keys - UIError(_("Unable to generate initial key") += "\n"); - return error("%s %s", __func__ , "Unable to generate initial key"); - } - - pwalletMain->SetBestChain(chainActive.GetLocator()); - } - - LogPrintf("Init errors: %s\n", strErrors.str()); - LogPrintf("Wallet completed loading in %15dms\n", GetTimeMillis() - nWalletStartTime); - zwalletMain = new CzPIVWallet(pwalletMain); - pwalletMain->setZWallet(zwalletMain); - - RegisterValidationInterface(pwalletMain); - - CBlockIndex* pindexRescan = chainActive.Tip(); - if (GetBoolArg("-rescan", false)) - pindexRescan = chainActive.Genesis(); - else { - CWalletDB walletdb(strWalletFile); - CBlockLocator locator; - if (walletdb.ReadBestBlock(locator)) - pindexRescan = FindForkInGlobalIndex(chainActive, locator); - else - pindexRescan = chainActive.Genesis(); - } - if (chainActive.Tip() && chainActive.Tip() != pindexRescan) { - uiInterface.InitMessage(_("Rescanning...")); - LogPrintf("Rescanning last %i blocks (from block %i)...\n", chainActive.Height() - pindexRescan->nHeight, pindexRescan->nHeight); - const int64_t nWalletRescanTime = GetTimeMillis(); - if (pwalletMain->ScanForWalletTransactions(pindexRescan, true, true) == -1) { - return error("Shutdown requested over the txs scan. Exiting."); - } - LogPrintf("Rescan completed in %15dms\n", GetTimeMillis() - nWalletRescanTime); - pwalletMain->SetBestChain(chainActive.GetLocator()); - CWalletDB::IncrementUpdateCounter(); - - // Restore wallet transaction metadata after -zapwallettxes=1 - if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2") { - CWalletDB walletdb(strWalletFile); - for (const CWalletTx& wtxOld : vWtx) { - uint256 hash = wtxOld.GetHash(); - std::map::iterator mi = pwalletMain->mapWallet.find(hash); - if (mi != pwalletMain->mapWallet.end()) { - const CWalletTx* copyFrom = &wtxOld; - CWalletTx* copyTo = &mi->second; - copyTo->mapValue = copyFrom->mapValue; - copyTo->vOrderForm = copyFrom->vOrderForm; - copyTo->nTimeReceived = copyFrom->nTimeReceived; - copyTo->nTimeSmart = copyFrom->nTimeSmart; - copyTo->fFromMe = copyFrom->fFromMe; - copyTo->strFromAccount = copyFrom->strFromAccount; - copyTo->nOrderPos = copyFrom->nOrderPos; - walletdb.WriteTx(*copyTo); - } - } - } - } - fVerifyingBlocks = false; - - if (!zwalletMain->GetMasterSeed().IsNull()) { - //Inititalize zPIVWallet - uiInterface.InitMessage(_("Syncing zPIV wallet...")); - - //Load zerocoin mint hashes to memory - pwalletMain->zpivTracker->Init(); - zwalletMain->LoadMintPoolFromDB(); - zwalletMain->SyncWithChain(); - } - } // (!fDisableWallet) -#else // ENABLE_WALLET + if (!CWallet::InitLoadWallet()) + return false; +#else LogPrintf("No wallet compiled in!\n"); -#endif // !ENABLE_WALLET +#endif // ********************************************************* Step 9: import blocks if (!CheckDiskSpace()) @@ -2020,7 +1757,7 @@ bool AppInit2() LogPrintf("file format is unknown or invalid, please fix it manually\n"); } - fMasterNode = GetBoolArg("-masternode", false); + fMasterNode = GetBoolArg("-masternode", DEFAULT_MASTERNODE); if ((fMasterNode || masternodeConfig.getCount() > -1) && fTxIndex == false) { return UIError("Enabling Masternode support requires turning on transaction indexing." @@ -2073,7 +1810,7 @@ bool AppInit2() //get the mode of budget voting for this masternode strBudgetMode = GetArg("-budgetvotemode", "auto"); - if (GetBoolArg("-mnconflock", true) && pwalletMain) { + if (GetBoolArg("-mnconflock", DEFAULT_MNCONFLOCK) && pwalletMain) { LOCK(pwalletMain->cs_wallet); LogPrintf("Locking Masternodes:\n"); uint256 mnTxHash; @@ -2133,7 +1870,7 @@ bool AppInit2() #ifdef ENABLE_WALLET // Generate coins in the background if (pwalletMain) - GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1)); + GenerateBitcoins(GetBoolArg("-gen", DEFAULT_GENERATE), pwalletMain, GetArg("-genproclimit", DEFAULT_GENERATE_PROCLIMIT)); #endif // ********************************************************* Step 12: finished @@ -2143,14 +1880,10 @@ bool AppInit2() #ifdef ENABLE_WALLET if (pwalletMain) { - // Add wallet transactions that aren't already in a block to mapTransactions - pwalletMain->ReacceptWalletTransactions(/*fFirstLoad*/true); - - // Run a thread to flush wallet periodically - threadGroup.create_thread(boost::bind(&ThreadFlushWalletDB, boost::ref(pwalletMain->strWalletFile))); + pwalletMain->postInitProcess(threadGroup); // StakeMiner thread disabled by default on regtest - if (GetBoolArg("-staking", !Params().IsRegTestNet())) { + if (GetBoolArg("-staking", !Params().IsRegTestNet() && DEFAULT_STAKING)) { threadGroup.create_thread(boost::bind(&ThreadStakeMinter)); } } diff --git a/src/init.h b/src/init.h index 492f0aa2e387..aa2d5407c754 100644 --- a/src/init.h +++ b/src/init.h @@ -18,8 +18,6 @@ namespace boost class thread_group; } // namespace boost -extern CzPIVWallet* zwalletMain; - void StartShutdown(); bool ShutdownRequested(); /** Interrupt threads */ diff --git a/src/main.cpp b/src/main.cpp index de7e4ce63f9f..b8935a3d385d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -93,7 +93,6 @@ int nScriptCheckThreads = 0; std::atomic fImporting{false}; std::atomic fReindex{false}; bool fTxIndex = true; -bool fIsBareMultisigStd = true; bool fCheckBlockIndex = false; bool fVerifyingBlocks = false; size_t nCoinCacheUsage = 5000 * 300; @@ -1030,7 +1029,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C strprintf("%d < %d", nFees, txMinFee)); // Require that free transactions have sufficient priority to be mined in the next block. - if (!hasZcSpendInputs && GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainHeight + 1))) { + if (!hasZcSpendInputs && GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainHeight + 1))) { return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority"); } @@ -1050,7 +1049,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C nLastTime = nNow; // -limitfreerelay unit is thousand-bytes-per-minute // At default rate it would take over a month to fill 1GB - if (dFreeCount >= GetArg("-limitfreerelay", 30) * 10 * 1000) + if (dFreeCount >= GetArg("-limitfreerelay", DEFAULT_LIMITFREERELAY) * 10 * 1000) return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "rate limited free transaction"); LogPrint(BCLog::MEMPOOL, "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount + nSize); dFreeCount += nSize; @@ -1282,7 +1281,7 @@ bool AcceptableInputs(CTxMemPool& pool, CValidationState& state, const CTransact if (mempoolRejectFee > 0 && nFees < mempoolRejectFee) { return state.DoS(0, error("%s : insuffiecient fee: %d < %d", __func__, nFees, mempoolRejectFee), REJECT_INSUFFICIENTFEE, "mempool min fee not met", false); - } else if (GetBoolArg("-relaypriority", true) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainActive.Height() + 1))) { + } else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainActive.Height() + 1))) { // Require that free transactions have sufficient priority to be mined in the next block. return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority"); } @@ -1303,7 +1302,7 @@ bool AcceptableInputs(CTxMemPool& pool, CValidationState& state, const CTransact nLastTime = nNow; // -limitfreerelay unit is thousand-bytes-per-minute // At default rate it would take over a month to fill 1GB - if (dFreeCount >= GetArg("-limitfreerelay", 30) * 10 * 1000) + if (dFreeCount >= GetArg("-limitfreerelay", DEFAULT_LIMITFREERELAY) * 10 * 1000) return state.DoS(0, error("AcceptableInputs : free transaction rejected by rate limiter"), REJECT_INSUFFICIENTFEE, "rate limited free transaction"); LogPrint(BCLog::MEMPOOL, "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount + nSize); @@ -1699,7 +1698,7 @@ void Misbehaving(NodeId pnode, int howmuch) EXCLUSIVE_LOCKS_REQUIRED(cs_main) return; state->nMisbehavior += howmuch; - int banscore = GetArg("-banscore", 100); + int banscore = GetArg("-banscore", DEFAULT_BANSCORE_THRESHOLD); if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore) { LogPrintf("Misbehaving: %s (%d -> %d) BAN THRESHOLD EXCEEDED\n", state->name, state->nMisbehavior - howmuch, state->nMisbehavior); state->fShouldBan = true; @@ -4870,7 +4869,7 @@ std::string GetWarnings(std::string strFor) if (!CLIENT_VERSION_IS_RELEASE) strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for staking or merchant applications!"); - if (GetBoolArg("-testsafemode", false)) + if (GetBoolArg("-testsafemode", DEFAULT_TESTSAFEMODE)) strStatusBar = strRPC = "testsafemode enabled"; // Misc warnings like out of disk space and clock is wrong diff --git a/src/main.h b/src/main.h index 88b8c869dcac..aa60e55d3f5a 100644 --- a/src/main.h +++ b/src/main.h @@ -65,17 +65,30 @@ struct CNodeStateStats; static const unsigned int DEFAULT_ANCESTOR_LIMIT = 25; /** Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors */ static const unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT = 101; +/** Default for -banscore */ +static const int DEFAULT_BANSCORE_THRESHOLD = 100; /** Default for -limitdescendantcount, max number of in-mempool descendants */ static const unsigned int DEFAULT_DESCENDANT_LIMIT = 25; /** Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants */ static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT = 101; /** Default for -mempoolexpiry, expiration time for mempool transactions in hours */ static const unsigned int DEFAULT_MEMPOOL_EXPIRY = 72; +/** Default for -txindex */ +static const bool DEFAULT_TXINDEX = true; +static const bool DEFAULT_CHECKPOINTS_ENABLED = true; +/** Default for -testsafemode */ +static const bool DEFAULT_TESTSAFEMODE = false; +/** Default for -relaypriority */ +static const bool DEFAULT_RELAYPRIORITY = true; +/** Default for -limitfeerelay */ +static const unsigned int DEFAULT_LIMITFREERELAY = 30; /** The maximum size for transactions we're willing to relay/mine */ static const unsigned int MAX_STANDARD_TX_SIZE = 100000; static const unsigned int MAX_ZEROCOIN_TX_SIZE = 150000; /** Default for -maxorphantx, maximum number of orphan transactions kept in memory */ static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS = 100; +/** Default for -checkblocks */ +static const signed int DEFAULT_CHECKBLOCKS = 10; /** The maximum size of a blk?????.dat file (since 0.8) */ static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB /** The pre-allocation chunk size for blk?????.dat files (since 0.8) */ @@ -149,7 +162,6 @@ extern std::atomic fImporting; extern std::atomic fReindex; extern int nScriptCheckThreads; extern bool fTxIndex; -extern bool fIsBareMultisigStd; extern bool fCheckBlockIndex; extern size_t nCoinCacheUsage; extern CFeeRate minRelayTxFee; diff --git a/src/miner.cpp b/src/miner.cpp index 56d72999786a..54f3c6f3f257 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -229,7 +229,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, // Priority order to process transactions std::list vOrphan; // list memory doesn't move std::map > mapDependers; - bool fPrintPriority = GetBoolArg("-printpriority", false); + bool fPrintPriority = GetBoolArg("-printpriority", DEFAULT_PRINTPRIORITY); // This vector will be sorted into a priority queue: std::vector vecPriority; diff --git a/src/miner.h b/src/miner.h index 644c6e54ac94..3f60490d7bc7 100644 --- a/src/miner.h +++ b/src/miner.h @@ -18,6 +18,8 @@ class CReserveKey; class CScript; class CWallet; +static const bool DEFAULT_PRINTPRIORITY = false; + struct CBlockTemplate; /** Generate a new block, without valid proof-of-work */ diff --git a/src/net.cpp b/src/net.cpp index dd58b5b71b7a..868324319f1f 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -592,7 +592,7 @@ void CNode::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t banti banEntry.banReason = banReason; if (bantimeoffset <= 0) { - bantimeoffset = GetArg("-bantime", 60*60*24); // Default 24-hour ban + bantimeoffset = GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME); // Default 24-hour ban sinceUnixEpoch = false; } banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime() )+bantimeoffset; @@ -1452,7 +1452,7 @@ void ThreadDNSAddressSeed() { // goal: only query DNS seeds if address need is acute if ((addrman.size() > 0) && - (!GetBoolArg("-forcednsseed", false))) { + (!GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) { MilliSleep(11 * 1000); LOCK(cs_vNodes); @@ -2325,8 +2325,8 @@ bool CAddrDB::Read(CAddrMan& addr, CDataStream& ssPeers) return true; } -unsigned int ReceiveFloodSize() { return 1000 * GetArg("-maxreceivebuffer", 5 * 1000); } -unsigned int SendBufferSize() { return 1000 * GetArg("-maxsendbuffer", 1 * 1000); } +unsigned int ReceiveFloodSize() { return 1000 * GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER); } +unsigned int SendBufferSize() { return 1000 * GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER); } CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fInboundIn) : ssSend(SER_NETWORK, INIT_PROTO_VERSION), diff --git a/src/net.h b/src/net.h index 05fd32894c90..d5f23556aa13 100644 --- a/src/net.h +++ b/src/net.h @@ -74,6 +74,13 @@ static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125; static const ServiceFlags REQUIRED_SERVICES = NODE_NETWORK; +static const bool DEFAULT_FORCEDNSSEED = false; +static const size_t DEFAULT_MAXRECEIVEBUFFER = 5 * 1000; +static const size_t DEFAULT_MAXSENDBUFFER = 1 * 1000; + +// NOTE: When adjusting this, update rpcnet:setban's help ("24h") +static const unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban + unsigned int ReceiveFloodSize(); unsigned int SendBufferSize(); diff --git a/src/pivx-cli.cpp b/src/pivx-cli.cpp index 485d84019a13..187c99a43dd1 100644 --- a/src/pivx-cli.cpp +++ b/src/pivx-cli.cpp @@ -24,7 +24,7 @@ #define _(x) std::string(x) /* Keep the _() around in case gettext or such will be used later to translate non-UI */ - +static const char DEFAULT_RPCCONNECT[] = "127.0.0.1"; static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900; std::string HelpMessageCli() @@ -32,12 +32,12 @@ std::string HelpMessageCli() std::string strUsage; strUsage += HelpMessageGroup(_("Options:")); strUsage += HelpMessageOpt("-?", _("This help message")); - strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), "pivx.conf")); + strUsage += HelpMessageOpt("-conf=", strprintf(_("Specify configuration file (default: %s)"), PIVX_CONF_FILENAME)); strUsage += HelpMessageOpt("-datadir=", _("Specify data directory")); strUsage += HelpMessageOpt("-testnet", _("Use the test network")); strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be " "solved instantly. This is intended for regression testing tools and app development.")); - strUsage += HelpMessageOpt("-rpcconnect=", strprintf(_("Send commands to node running on (default: %s)"), "127.0.0.1")); + strUsage += HelpMessageOpt("-rpcconnect=", strprintf(_("Send commands to node running on (default: %s)"), DEFAULT_RPCCONNECT)); strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Connect to JSON-RPC on (default: %u or testnet: %u)"), 51473, 51475)); strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start")); strUsage += HelpMessageOpt("-rpcuser=", _("Username for JSON-RPC connections")); @@ -142,7 +142,7 @@ static void http_request_done(struct evhttp_request *req, void *ctx) UniValue CallRPC(const std::string& strMethod, const UniValue& params) { - std::string host = GetArg("-rpcconnect", "127.0.0.1"); + std::string host = GetArg("-rpcconnect", DEFAULT_RPCCONNECT); int port = GetArg("-rpcport", BaseParams().RPCPort()); // Create event base diff --git a/src/policy/policy.cpp b/src/policy/policy.cpp index 05ab68e0b8aa..fe5b3456ecfb 100644 --- a/src/policy/policy.cpp +++ b/src/policy/policy.cpp @@ -15,6 +15,8 @@ #include +bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG; + /** * Check transaction inputs to mitigate two * potential denial-of-service attacks: @@ -51,7 +53,7 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) if (m < 1 || m > n) return false; } else if (whichType == TX_NULL_DATA && - (!GetBoolArg("-datacarrier", true) || scriptPubKey.size() > nMaxDatacarrierBytes)) + (!GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER) || scriptPubKey.size() > nMaxDatacarrierBytes)) return false; return whichType != TX_NONSTANDARD; diff --git a/src/policy/policy.h b/src/policy/policy.h index cb001b4f5b8d..914b6adc7518 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -24,6 +24,10 @@ static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 50000; static const unsigned int MAX_P2SH_SIGOPS = 15; /** Default for -maxmempool, maximum megabytes of mempool memory usage */ static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300; +/** Default for -permitbaremultisig */ +static const bool DEFAULT_PERMIT_BAREMULTISIG = true; +extern bool fIsBareMultisigStd; + /** * Standard script verification flags that standard transactions will comply * with. However scripts violating these flags may still be present in valid diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index cd20476af5d0..af85e33de71e 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -180,7 +180,7 @@ bool Intro::pickDataDirectory() dataDir = settings.value("strDataDir", dataDir).toString(); - if (!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", false)) { + if (!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || GetBoolArg("-choosedatadir", DEFAULT_CHOOSE_DATADIR)) { // If current default data directory does not exist, let the user choose one Intro intro; intro.setDataDirectory(dataDir); diff --git a/src/qt/pivx.cpp b/src/qt/pivx.cpp index ef465d263a34..8a7da7cd29c9 100644 --- a/src/qt/pivx.cpp +++ b/src/qt/pivx.cpp @@ -666,7 +666,7 @@ int main(int argc, char* argv[]) bool ret = true; #ifdef ENABLE_WALLET // Check if the wallet exists or need to be created - std::string strWalletFile = GetArg("-wallet", "wallet.dat"); + std::string strWalletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); std::string strDataDir = GetDataDir().string(); // Wallet file must be a plain filename without a directory fs::path wallet_file_path(strWalletFile); diff --git a/src/qt/pivx/settings/settingsinformationwidget.cpp b/src/qt/pivx/settings/settingsinformationwidget.cpp index 2abe7af7e927..f08a10aa6d0b 100644 --- a/src/qt/pivx/settings/settingsinformationwidget.cpp +++ b/src/qt/pivx/settings/settingsinformationwidget.cpp @@ -89,7 +89,7 @@ SettingsInformationWidget::SettingsInformationWidget(PIVXGUI* _window,QWidget *p #ifdef ENABLE_WALLET // Wallet data -- remove it with if it's needed ui->labelInfoBerkeley->setText(DbEnv::version(0, 0, 0)); - ui->labelInfoDataDir->setText(QString::fromStdString(GetDataDir().string() + QDir::separator().toLatin1() + GetArg("-wallet", "wallet.dat"))); + ui->labelInfoDataDir->setText(QString::fromStdString(GetDataDir().string() + QDir::separator().toLatin1() + GetArg("-wallet", DEFAULT_WALLET_DAT))); #else ui->labelInfoBerkeley->setText(tr("No information")); #endif diff --git a/src/qt/pivx/topbar.cpp b/src/qt/pivx/topbar.cpp index 5d40db9ff537..389fa3f25613 100644 --- a/src/qt/pivx/topbar.cpp +++ b/src/qt/pivx/topbar.cpp @@ -677,7 +677,7 @@ void TopBar::updateHDState(const bool& upgraded, const QString& upgradeError) } } else { inform(tr("Wallet upgraded successfully, but no backup created.") + "\n" + - tr("WARNING: remember to make a copy of your wallet.dat file!")); + tr("WARNING: remember to make a copy of your wallet file!")); } } else { warn(tr("Upgrade Wallet Error"), upgradeError); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 18b339400b25..3d29a0937bd6 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -299,7 +299,7 @@ RPCConsole::RPCConsole(QWidget* parent) : QDialog(parent, Qt::WindowSystemMenuHi } ui->berkeleyDBVersion->setText(DbEnv::version(0, 0, 0)); - ui->wallet_path->setText(QString::fromStdString(GetDataDir().string() + QDir::separator().toLatin1() + GetArg("-wallet", "wallet.dat"))); + ui->wallet_path->setText(QString::fromStdString(GetDataDir().string() + QDir::separator().toLatin1() + GetArg("-wallet", DEFAULT_WALLET_DAT))); #else ui->label_berkeleyDBVersion->hide(); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 61a8959c0ce7..0e147fb656ee 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -754,7 +754,7 @@ UniValue getstakingstatus(const JSONRPCRequest& request) LOCK2(cs_main, &pwalletMain->cs_wallet); UniValue obj(UniValue::VOBJ); obj.push_back(Pair("staking_status", pwalletMain->pStakerStatus->IsActive())); - obj.push_back(Pair("staking_enabled", GetBoolArg("-staking", true))); + obj.push_back(Pair("staking_enabled", GetBoolArg("-staking", DEFAULT_STAKING))); bool fColdStaking = GetBoolArg("-coldstaking", true); obj.push_back(Pair("coldstaking_enabled", fColdStaking)); obj.push_back(Pair("haveconnections", !vNodes.empty())); diff --git a/src/script/standard.cpp b/src/script/standard.cpp index 16c78cffc972..2bf1fdf3b85b 100644 --- a/src/script/standard.cpp +++ b/src/script/standard.cpp @@ -328,4 +328,4 @@ CScript GetScriptForMultisig(int nRequired, const std::vector& keys) bool IsValidDestination(const CTxDestination& dest) { return dest.which() != 0; -} \ No newline at end of file +} diff --git a/src/script/standard.h b/src/script/standard.h index 7f8602038714..95048dee7c2a 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -14,6 +14,8 @@ #include +static const bool DEFAULT_ACCEPT_DATACARRIER = true; + class CKeyID; class CScript; diff --git a/src/util.cpp b/src/util.cpp index dff7bc87489a..b794562254a4 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -85,6 +85,10 @@ #include #include +const char * const PIVX_CONF_FILENAME = "pivx.conf"; +const char * const PIVX_PID_FILENAME = "pivx.pid"; +const char * const PIVX_MASTERNODE_CONF_FILENAME = "masternode.conf"; + // PIVX only features // Masternode @@ -448,13 +452,13 @@ void ClearDatadirCache() fs::path GetConfigFile() { - fs::path pathConfigFile(GetArg("-conf", "pivx.conf")); + fs::path pathConfigFile(GetArg("-conf", PIVX_CONF_FILENAME)); return AbsPathForConfigVal(pathConfigFile, false); } fs::path GetMasternodeConfigFile() { - fs::path pathConfigFile(GetArg("-mnconf", "masternode.conf")); + fs::path pathConfigFile(GetArg("-mnconf", PIVX_MASTERNODE_CONF_FILENAME)); return AbsPathForConfigVal(pathConfigFile); } @@ -497,7 +501,7 @@ fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific) #ifndef WIN32 fs::path GetPidFile() { - fs::path pathPidFile(GetArg("-pid", "pivxd.pid")); + fs::path pathPidFile(GetArg("-pid", PIVX_PID_FILENAME)); return AbsPathForConfigVal(pathPidFile); } diff --git a/src/util.h b/src/util.h index 17f850457a8d..5f9373c4d5f8 100644 --- a/src/util.h +++ b/src/util.h @@ -33,6 +33,9 @@ #include #include // for boost::thread_interrupted +extern const char * const PIVX_CONF_FILENAME; +extern const char * const PIVX_PID_FILENAME; +extern const char * const PIVX_MASTERNODE_CONF_FILENAME; extern const char * const DEFAULT_DEBUGLOGFILE; //PIVX only features diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index a7573ad0753e..af3d4469b174 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -81,7 +81,7 @@ bool CDBEnv::Open(const fs::path& pathIn) LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string()); unsigned int nEnvFlags = 0; - if (GetBoolArg("-privdb", true)) + if (GetBoolArg("-privdb", DEFAULT_WALLET_PRIVDB)) nEnvFlags |= DB_PRIVATE; dbenv->set_lg_dir(pathLogDir.string().c_str()); diff --git a/src/wallet/db.h b/src/wallet/db.h index 3ddcce4f553f..f7b7d6a00919 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -25,6 +25,9 @@ class COutPoint; struct CBlockLocator; +static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100; +static const bool DEFAULT_WALLET_PRIVDB = true; + class CDBEnv { private: diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 7b35308332f1..469bfdf76349 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2839,7 +2839,7 @@ UniValue backupwallet(const JSONRPCRequest& request) if (request.fHelp || request.params.size() != 1) throw std::runtime_error( "backupwallet \"destination\"\n" - "\nSafely copies wallet.dat to destination, which can be a directory or a path with filename.\n" + "\nSafely copies wallet file to destination, which can be a directory or a path with filename.\n" "\nArguments:\n" "1. \"destination\" (string) The destination directory or file\n" @@ -4328,7 +4328,7 @@ UniValue resetmintzerocoin(const JSONRPCRequest& request) if (request.fHelp || request.params.size() > 1) throw std::runtime_error( "resetmintzerocoin ( fullscan )\n" - "\nScan the blockchain for all of the zerocoins that are held in the wallet.dat.\n" + "\nScan the blockchain for all of the zerocoins that are held in the wallet database.\n" "Update any meta-data that is incorrect. Archive any mints that are not able to be found.\n" + HelpRequiringPassphrase() + "\n" @@ -4388,7 +4388,7 @@ UniValue resetspentzerocoin(const JSONRPCRequest& request) if (request.fHelp || request.params.size() != 0) throw std::runtime_error( "resetspentzerocoin\n" - "\nScan the blockchain for all of the zerocoins that are held in the wallet.dat.\n" + "\nScan the blockchain for all of the zerocoins that are held in the wallet database.\n" "Reset mints that are considered spent that did not make it into the blockchain.\n" "\nResult:\n" @@ -4507,7 +4507,7 @@ UniValue exportzerocoins(const JSONRPCRequest& request) if(request.fHelp || request.params.empty() || request.params.size() > 2) throw std::runtime_error( "exportzerocoins include_spent ( denomination )\n" - "\nExports zerocoin mints that are held by this wallet.dat\n" + + "\nExports zerocoin mints that are held by the current wallet file\n" + HelpRequiringPassphrase() + "\n" "\nArguments:\n" @@ -4585,7 +4585,7 @@ UniValue importzerocoins(const JSONRPCRequest& request) "importzerocoins importdata \n" "\n[{\"d\":denomination,\"p\":\"pubcoin_hex\",\"s\":\"serial_hex\",\"r\":\"randomness_hex\",\"t\":\"txid\",\"h\":height, \"u\":used},{\"d\":...}]\n" "\nImport zerocoin mints.\n" - "Adds raw zerocoin mints to the wallet.dat\n" + "Adds raw zerocoin mints to the wallet.\n" "Note it is recommended to use the json export created from the exportzerocoins RPC call\n" + HelpRequiringPassphrase() + "\n" @@ -4808,7 +4808,7 @@ UniValue generatemintlist(const JSONRPCRequest& request) int nCount = request.params[0].get_int(); int nRange = request.params[1].get_int(); - CzPIVWallet* zwallet = pwalletMain->zwalletMain; + CzPIVWallet* zwallet = pwalletMain->getZWallet(); UniValue arrRet(UniValue::VARR); for (int i = nCount; i < nCount + nRange; i++) { @@ -4837,7 +4837,7 @@ UniValue dzpivstate(const JSONRPCRequest& request) { "\nExamples\n" + HelpExampleCli("mintpoolstatus", "") + HelpExampleRpc("mintpoolstatus", "")); - CzPIVWallet* zwallet = pwalletMain->zwalletMain; + CzPIVWallet* zwallet = pwalletMain->getZWallet(); UniValue obj(UniValue::VOBJ); int nCount, nCountLastUsed; zwallet->GetState(nCount, nCountLastUsed); @@ -4906,7 +4906,7 @@ UniValue searchdzpiv(const JSONRPCRequest& request) int nThreads = request.params[2].get_int(); - CzPIVWallet* zwallet = pwalletMain->zwalletMain; + CzPIVWallet* zwallet = pwalletMain->getZWallet(); boost::thread_group* dzpivThreads = new boost::thread_group(); int nRangePerThread = nRange / nThreads; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 09ea088401ac..98096fb2c9d3 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -30,10 +30,12 @@ CWallet* pwalletMain = nullptr; CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; unsigned int nTxConfirmTarget = 1; -bool bSpendZeroConfChange = true; bool bdisableSystemnotifications = false; // Those bubbles can be annoying and slow down the UI when you get lots of trx bool fSendFreeTransactions = false; bool fPayAtLeastCustomFee = true; +bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE; + +const char * DEFAULT_WALLET_DAT = "wallet.dat"; /** * Fees smaller than this (in upiv) are considered zero fee (for transaction creation) @@ -312,7 +314,7 @@ bool CWallet::Lock() { LOCK(cs_KeyStore); vMasterKey.clear(); - if (zwalletMain) zwalletMain->Lock(); + if (zwallet) zwallet->Lock(); } NotifyStatusChanged(this); @@ -370,14 +372,14 @@ bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn) vMasterKey = vMasterKeyIn; fDecryptionThoroughlyChecked = true; - if (zwalletMain) { + if (zwallet) { uint256 hashSeed; if (CWalletDB(strWalletFile).ReadCurrentSeedHash(hashSeed)) { uint256 nSeed; if (!GetDeterministicSeed(hashSeed, nSeed)) { return error("Failed to read zPIV seed from DB. Wallet is probably corrupt."); } - zwalletMain->SetMasterSeed(nSeed, false); + zwallet->SetMasterSeed(nSeed, false); } } } @@ -581,14 +583,13 @@ bool CWallet::ParameterInteraction() return UIError(AmountErrMsg("minstakesplit", mapArgs["-minstakesplit"])); } nTxConfirmTarget = GetArg("-txconfirmtarget", 1); - bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", false); + bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); bdisableSystemnotifications = GetBoolArg("-disablesystemnotifications", false); - fSendFreeTransactions = GetBoolArg("-sendfreetransactions", false); + fSendFreeTransactions = GetBoolArg("-sendfreetransactions", DEFAULT_SEND_FREE_TRANSACTIONS); return true; } - //////// End Init //////////// const CKeyingMaterial& CWallet::GetEncryptionKey() const @@ -1677,6 +1678,61 @@ std::set CWalletTx::GetConflicts() const return result; } +bool CWallet::Verify() +{ + std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); + std::string strDataDir = GetDataDir().string(); + + // Wallet file must be a plain filename without a directory + fs::path wallet_file_path(walletFile); + if (walletFile != wallet_file_path.filename().string()) + return UIError(strprintf(_("Wallet %s resides outside data directory %s"), walletFile, strDataDir)); + + LogPrintf("Using wallet %s\n", walletFile); + uiInterface.InitMessage(_("Verifying wallet...")); + + if (!bitdb.Open(GetDataDir())) { + // try moving the database env out of the way + fs::path pathDatabase = GetDataDir() / "database"; + fs::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime()); + try { + fs::rename(pathDatabase, pathDatabaseBak); + LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string()); + } catch (const fs::filesystem_error& error) { + // failure is ok (well, not really, but it's not worse than what we started with) + } + + // try again + if (!bitdb.Open(GetDataDir())) { + // if it still fails, it probably means we can't even create the database env + return UIError(strprintf(_("Error initializing wallet database environment %s!"), strDataDir)); + } + } + + if (GetBoolArg("-salvagewallet", false)) { + // Recover readable keypairs: + if (!CWalletDB::Recover(bitdb, walletFile, true)) + return false; + } + + if (fs::exists(GetDataDir() / walletFile)) { + CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover); + if (r == CDBEnv::RECOVER_OK) { + UIWarning(strprintf(_("Warning: wallet file corrupt, data salvaged!" + " Original %s saved as %s in %s; if" + " your balance or transactions are incorrect you should" + " restore from a backup."), + walletFile, "wallet.{timestamp}.bak", strDataDir)); + } + if (r == CDBEnv::RECOVER_FAIL) + return UIError(strprintf(_("%s corrupt, salvage failed"), walletFile)); + } + + return true; +} + + + void CWallet::ResendWalletTransactions() { // Do this infrequently and randomly to avoid giving away @@ -2183,7 +2239,7 @@ static void ApproximateBestSubset(std::vector* pCoins) { const bool fIncludeCold = (sporkManager.IsSporkActive(SPORK_17_COLDSTAKING_ENFORCEMENT) && - GetBoolArg("-coldstaking", true)); + GetBoolArg("-coldstaking", DEFAULT_COLDSTAKING)); return AvailableCoins(pCoins, nullptr, // coin control @@ -3774,6 +3830,258 @@ bool CWallet::MultiSend() */ } +std::string CWallet::GetWalletHelpString(bool showDebug) +{ + std::string strUsage = HelpMessageGroup(_("Wallet options:")); + strUsage += HelpMessageOpt("-backuppath=", _("Specify custom backup path to add a copy of any wallet backup. If set as dir, every backup generates a timestamped file. If set as file, will rewrite to that file every backup.")); + strUsage += HelpMessageOpt("-createwalletbackups=", strprintf(_("Number of automatic wallet backups (default: %d)"), DEFAULT_CREATEWALLETBACKUPS)); + strUsage += HelpMessageOpt("-custombackupthreshold=", strprintf(_("Number of custom location backups to retain (default: %d)"), DEFAULT_CUSTOMBACKUPTHRESHOLD)); + strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); + strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), DEFAULT_KEYPOOL_SIZE)); + strUsage += HelpMessageOpt("-legacywallet", _("On first run, create a legacy wallet instead of a HD wallet")); + strUsage += HelpMessageOpt("-maxtxfee=", strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"), FormatMoney(maxTxFee))); + strUsage += HelpMessageOpt("-mintxfee=", strprintf(_("Fees (in %s/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"), CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup")); + strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet file") + " " + _("on startup")); + strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); + strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); + strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1)); + strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup")); + strUsage += HelpMessageOpt("-wallet=", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT)); + strUsage += HelpMessageOpt("-walletnotify=", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); + strUsage += HelpMessageOpt("-zapwallettxes=", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + + " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)")); + strUsage += HelpMessageGroup(_("Mining/Staking options:")); + strUsage += HelpMessageOpt("-coldstaking=", strprintf(_("Enable cold staking functionality (0-1, default: %u). Disabled if staking=0"), DEFAULT_COLDSTAKING)); + strUsage += HelpMessageOpt("-gen", strprintf(_("Generate coins (default: %u)"), DEFAULT_GENERATE)); + strUsage += HelpMessageOpt("-genproclimit=", strprintf(_("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)"), DEFAULT_GENERATE_PROCLIMIT)); + strUsage += HelpMessageOpt("-minstakesplit=", strprintf(_("Minimum positive amount (in PIV) allowed by GUI and RPC for the stake split threshold (default: %s)"), FormatMoney(DEFAULT_MIN_STAKE_SPLIT_THRESHOLD))); + strUsage += HelpMessageOpt("-staking=", strprintf(_("Enable staking functionality (0-1, default: %u)"), DEFAULT_STAKING)); + if (showDebug) { + strUsage += HelpMessageGroup(_("Wallet debugging/testing options:")); + strUsage += HelpMessageOpt("-dblogsize=", strprintf(_("Flush database activity from memory pool to disk log every megabytes (default: %u)"), DEFAULT_WALLET_DBLOGSIZE)); + strUsage += HelpMessageOpt("-flushwallet", strprintf(_("Run a thread to flush wallet periodically (default: %u)"), DEFAULT_FLUSHWALLET)); + strUsage += HelpMessageOpt("-printcoinstake", _("Display verbose coin stake messages in the debug.log file.")); + strUsage += HelpMessageOpt("-printstakemodifier", _("Display the stake modifier calculations in the debug.log file.")); + strUsage += HelpMessageOpt("-privdb", strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), DEFAULT_WALLET_PRIVDB)); + } + + return strUsage; +} + +CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) +{ + // needed to restore wallet transaction meta data after -zapwallettxes + std::vector vWtx; + + if (GetBoolArg("-zapwallettxes", false)) { + uiInterface.InitMessage(_("Zapping all transactions from wallet...")); + + CWallet *tempWallet = new CWallet(walletFile); + DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); + if (nZapWalletRet != DB_LOAD_OK) { + UIError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); + return nullptr; + } + + delete tempWallet; + tempWallet = nullptr; + } + + uiInterface.InitMessage(_("Loading wallet...")); + fVerifyingBlocks = true; + + int64_t nStart = GetTimeMillis(); + bool fFirstRun = true; + CWallet *walletInstance = new CWallet(walletFile); + DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); + if (nLoadWalletRet != DB_LOAD_OK) { + if (nLoadWalletRet == DB_CORRUPT) { + UIError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); + return nullptr; + } else if (nLoadWalletRet == DB_NONCRITICAL_ERROR) { + UIWarning(strprintf(_("Warning: error reading %s! All keys read correctly, but transaction data" + " or address book entries might be missing or incorrect."), walletFile)); + } else if (nLoadWalletRet == DB_TOO_NEW) { + UIError(strprintf(_("Error loading %s: Wallet requires newer version of PIVX Core"), walletFile)); + return nullptr; + } else if (nLoadWalletRet == DB_NEED_REWRITE) { + UIError(_("Wallet needed to be rewritten: restart PIVX Core to complete")); + return nullptr; + } else { + UIError(strprintf(_("Error loading %s\n"), walletFile)); + return nullptr; + } + } + + // check minimum stake split threshold + if (walletInstance->nStakeSplitThreshold && walletInstance->nStakeSplitThreshold < CWallet::minStakeSplitThreshold) { + LogPrintf("WARNING: stake split threshold value %s too low. Restoring to minimum value %s.\n", + FormatMoney(walletInstance->nStakeSplitThreshold), FormatMoney(CWallet::minStakeSplitThreshold)); + walletInstance->nStakeSplitThreshold = CWallet::minStakeSplitThreshold; + } + + int prev_version = walletInstance->GetVersion(); + + // Forced upgrade + const bool fLegacyWallet = GetBoolArg("-legacywallet", false); + if (GetBoolArg("-upgradewallet", fFirstRun && !fLegacyWallet)) { + if (prev_version <= FEATURE_PRE_PIVX && walletInstance->IsLocked()) { + // Cannot upgrade a locked wallet + UIError("Cannot upgrade a locked wallet."); + return nullptr; + } + + int nMaxVersion = GetArg("-upgradewallet", 0); + if (nMaxVersion == 0) // the -upgradewallet without argument case + { + LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST); + nMaxVersion = FEATURE_LATEST; + walletInstance->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately + } else + LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion); + if (nMaxVersion < walletInstance->GetVersion()) { + UIError("Cannot downgrade wallet\n"); + return nullptr; + } + walletInstance->SetMaxVersion(nMaxVersion); + } + + // Upgrade to HD only if explicit upgrade was requested + if (GetBoolArg("-upgradewallet", false)) { + std::string upgradeError; + if (!walletInstance->Upgrade(upgradeError, prev_version)) { + UIError(upgradeError); + return nullptr; + } + } + + if (fFirstRun) { + if (!fLegacyWallet) { + // Create new HD Wallet + LogPrintf("Creating HD Wallet\n"); + // Ensure this wallet can only be opened by clients supporting HD. + walletInstance->SetMinVersion(FEATURE_LATEST); + walletInstance->SetupSPKM(); + } else { + if (!Params().IsRegTestNet()) { + UIError("Legacy wallets can only be created on RegTest."); + return nullptr; + } + // Create legacy wallet + LogPrintf("Creating Pre-HD Wallet\n"); + walletInstance->SetMaxVersion(FEATURE_PRE_PIVX); + } + + // Top up the keypool + if (!walletInstance->TopUpKeyPool()) { + // Error generating keys + UIError("Unable to generate initial key!"); + return nullptr; + } + + walletInstance->SetBestChain(chainActive.GetLocator()); + } + + LogPrintf("Wallet completed loading in %15dms\n", GetTimeMillis() - nStart); + + CzPIVWallet* zwalletInstance = new CzPIVWallet(walletInstance); + walletInstance->setZWallet(zwalletInstance); + + RegisterValidationInterface(walletInstance); + + CBlockIndex* pindexRescan = chainActive.Tip(); + if (GetBoolArg("-rescan", false)) + pindexRescan = chainActive.Genesis(); + else { + CWalletDB walletdb(walletFile); + CBlockLocator locator; + if (walletdb.ReadBestBlock(locator)) + pindexRescan = FindForkInGlobalIndex(chainActive, locator); + else + pindexRescan = chainActive.Genesis(); + } + if (chainActive.Tip() && chainActive.Tip() != pindexRescan) { + uiInterface.InitMessage(_("Rescanning...")); + LogPrintf("Rescanning last %i blocks (from block %i)...\n", chainActive.Height() - pindexRescan->nHeight, pindexRescan->nHeight); + const int64_t nWalletRescanTime = GetTimeMillis(); + if (walletInstance->ScanForWalletTransactions(pindexRescan, true, true) == -1) { + UIError(_("Shutdown requested over the txs scan. Exiting.")); + return nullptr; + } + LogPrintf("Rescan completed in %15dms\n", GetTimeMillis() - nWalletRescanTime); + walletInstance->SetBestChain(chainActive.GetLocator()); + CWalletDB::IncrementUpdateCounter(); + + // Restore wallet transaction metadata after -zapwallettxes=1 + if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2") { + CWalletDB walletdb(walletFile); + for (const CWalletTx& wtxOld : vWtx) { + uint256 hash = wtxOld.GetHash(); + std::map::iterator mi = walletInstance->mapWallet.find(hash); + if (mi != walletInstance->mapWallet.end()) { + const CWalletTx* copyFrom = &wtxOld; + CWalletTx* copyTo = &mi->second; + copyTo->mapValue = copyFrom->mapValue; + copyTo->vOrderForm = copyFrom->vOrderForm; + copyTo->nTimeReceived = copyFrom->nTimeReceived; + copyTo->nTimeSmart = copyFrom->nTimeSmart; + copyTo->fFromMe = copyFrom->fFromMe; + copyTo->strFromAccount = copyFrom->strFromAccount; + copyTo->nOrderPos = copyFrom->nOrderPos; + walletdb.WriteTx(*copyTo); + } + } + } + } + fVerifyingBlocks = false; + + if (!zwalletInstance->GetMasterSeed().IsNull()) { + //Inititalize zPIVWallet + uiInterface.InitMessage(_("Syncing zPIV wallet...")); + + //Load zerocoin mint hashes to memory + walletInstance->zpivTracker->Init(); + zwalletInstance->LoadMintPoolFromDB(); + zwalletInstance->SyncWithChain(); + } + + return walletInstance; +} + +bool CWallet::InitLoadWallet() +{ + if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { + pwalletMain = nullptr; + LogPrintf("Wallet disabled!\n"); + return true; + } + + std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); + + CWallet * const pwallet = CreateWalletFromFile(walletFile); + if (!pwallet) { + return false; + } + pwalletMain = pwallet; + + return true; +} + +std::atomic CWallet::fFlushThreadRunning(false); + +void CWallet::postInitProcess(boost::thread_group& threadGroup) +{ + // Add wallet transactions that aren't already in a block to mapTransactions + ReacceptWalletTransactions(/*fFirstLoad*/true); + + // Run a thread to flush wallet periodically + if (!CWallet::fFlushThreadRunning.exchange(true)) { + threadGroup.create_thread(ThreadFlushWalletDB); + } +} + CKeyPool::CKeyPool() { nTime = GetTime(); @@ -3905,7 +4213,7 @@ bool CMerkleTx::IsTransactionLockTimedOut() const std::string CWallet::GetUniqueWalletBackupName() const { - return strprintf("wallet.dat%s", DateTimeStrFormat(".%Y-%m-%d-%H-%M", GetTime())); + return strprintf("%s%s", strWalletFile, DateTimeStrFormat(".%Y-%m-%d-%H-%M", GetTime())); } CWallet::CWallet() @@ -3923,6 +4231,7 @@ CWallet::CWallet(std::string strWalletFileIn) CWallet::~CWallet() { + delete zwallet; delete pwalletdbEncryption; delete pStakerStatus; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 274397ddc481..f35e6a400f48 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -35,6 +35,7 @@ #include "zpiv/zpivtracker.h" #include +#include #include #include #include @@ -70,6 +71,23 @@ static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; static const int DEFAULT_CUSTOMBACKUPTHRESHOLD = 1; //! -minstakesplit default static const CAmount DEFAULT_MIN_STAKE_SPLIT_THRESHOLD = 100 * COIN; +//! Default for -spendzeroconfchange +static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true; +//! Default for -sendfreetransactions +static const bool DEFAULT_SEND_FREE_TRANSACTIONS = false; +//! Default for -staking +static const bool DEFAULT_STAKING = true; +//! Default for -coldstaking +static const bool DEFAULT_COLDSTAKING = true; +//! Defaults for -gen and -genproclimit +static const bool DEFAULT_GENERATE = false; +static const unsigned int DEFAULT_GENERATE_PROCLIMIT = 1; +//! Default for -createwalletbackups +static const unsigned int DEFAULT_CREATEWALLETBACKUPS = 10; +//! Default for -disablewallet +static const bool DEFAULT_DISABLE_WALLET = false; + +extern const char * DEFAULT_WALLET_DAT; class CAccountingEntry; class CCoinControl; @@ -227,6 +245,8 @@ struct CRecipient class CWallet : public CCryptoKeyStore, public CValidationInterface { private: + static std::atomic fFlushThreadRunning; + //! keeps track of whether Unlock has run a thorough check before bool fDecryptionThoroughlyChecked{false}; @@ -260,6 +280,9 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool IsKeyUsed(const CPubKey& vchPubKey); + // Zerocoin wallet + CzPIVWallet* zwallet{nullptr}; + public: static const CAmount DEFAULT_STAKE_SPLIT_THRESHOLD = 500 * COIN; @@ -626,9 +649,28 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface //! Get wallet transactions that conflict with given transaction (spend same outputs) std::set GetConflicts(const uint256& txid) const; + //! Verify the wallet database and perform salvage if required + static bool Verify(); + /* Mark a transaction (and it in-wallet descendants) as abandoned so its inputs may be respent. */ bool AbandonTransaction(const uint256& hashTx); + /* Returns the wallets help message */ + static std::string GetWalletHelpString(bool showDebug); + + /* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */ + static CWallet* CreateWalletFromFile(const std::string walletFile); + static bool InitLoadWallet(); + + /* Wallets parameter interaction */ + static bool ParameterInteraction(); + + /** + * Wallet post-init setup + * Gives the wallet a chance to register repetitive tasks and complete post-init tasks + */ + void postInitProcess(boost::thread_group& threadGroup); + /** * Address book entry changed. * @note called with lock cs_wallet held. @@ -690,7 +732,6 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface std::map GetMyZerocoinDistribution() const; // zPIV wallet - CzPIVWallet* zwalletMain{nullptr}; std::unique_ptr zpivTracker{nullptr}; void setZWallet(CzPIVWallet* zwallet); CzPIVWallet* getZWallet(); @@ -702,9 +743,6 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool UpdateMint(const CBigNum& bnValue, const int& nHeight, const uint256& txid, const libzerocoin::CoinDenomination& denom); // Zerocoin entry changed. (called with lock cs_wallet held) boost::signals2::signal NotifyZerocoinChanged; - - /* Wallets parameter interaction */ - static bool ParameterInteraction(); }; /** A key allocated from the key pool. */ diff --git a/src/wallet/wallet_zerocoin.cpp b/src/wallet/wallet_zerocoin.cpp index 3c0ac0bd0e96..e292cd5eb0b2 100644 --- a/src/wallet/wallet_zerocoin.cpp +++ b/src/wallet/wallet_zerocoin.cpp @@ -230,7 +230,7 @@ bool CWallet::CreateZPIVOutPut(libzerocoin::CoinDenomination denomination, CTxOu { // mint a new coin (create Pedersen Commitment) and extract PublicCoin that is shareable from it libzerocoin::PrivateCoin coin(Params().GetConsensus().Zerocoin_Params(false), denomination, false); - zwalletMain->GenerateDeterministicZPIV(denomination, coin, dMint); + zwallet->GenerateDeterministicZPIV(denomination, coin, dMint); libzerocoin::PublicCoin pubCoin = coin.getPublicCoin(); @@ -238,7 +238,7 @@ bool CWallet::CreateZPIVOutPut(libzerocoin::CoinDenomination denomination, CTxOu if(!pubCoin.validate()) return error("%s: newly created pubcoin is not valid", __func__); - zwalletMain->UpdateCount(); + zwallet->UpdateCount(); CScript scriptSerializedCoin = CScript() << OP_ZEROCOINMINT << pubCoin.getValue().getvch().size() << pubCoin.getValue().getvch(); outMint = CTxOut(libzerocoin::ZerocoinDenominationToAmount(denomination), scriptSerializedCoin); @@ -427,7 +427,7 @@ bool CWallet::SpendZerocoin(CAmount nAmount, CWalletTx& wtxNew, CZerocoinSpendRe } } - receipt.SetStatus("Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.", nStatus); + receipt.SetStatus("Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of this wallet file, and coins were spent in the copy but not marked as spent here.", nStatus); return false; } @@ -561,7 +561,7 @@ bool CWallet::CreateZCPublicSpendTransaction( // All of the zPIV used in the public coin spend are mature by default (everything is public now.. no need to wait for any accumulation) setMints = zpivTracker->ListMints(true, false, true, true); // need to find mints to spend if(setMints.empty()) { - receipt.SetStatus(_("Failed to find Zerocoins in wallet.dat"), nStatus); + receipt.SetStatus(_("Failed to find Zerocoins in wallet database"), nStatus); return false; } @@ -812,13 +812,13 @@ std::map CWallet::GetMyZerocoinDistribut void CWallet::setZWallet(CzPIVWallet* zwallet) { - zwalletMain = zwallet; + this->zwallet = zwallet; zpivTracker = std::unique_ptr(new CzPIVTracker(this)); } CzPIVWallet* CWallet::getZWallet() { - return zwalletMain; + return zwallet; } bool CWallet::IsMyZerocoinSpend(const CBigNum& bnSerial) const @@ -831,7 +831,7 @@ bool CWallet::IsMyMint(const CBigNum& bnValue) const if (zpivTracker->HasPubcoin(bnValue)) return true; - return zwalletMain->IsInMintPool(bnValue); + return zwallet->IsInMintPool(bnValue); } bool IsMintInChain(const uint256& hashPubcoin, uint256& txid, int& nHeight) @@ -910,7 +910,7 @@ bool CWallet::GetMint(const uint256& hashSerial, CZerocoinMint& mint) CDeterministicMint dMint; if (!walletdb.ReadDeterministicMint(meta.hashPubcoin, dMint)) return error("%s: failed to read deterministic mint", __func__); - if (!zwalletMain->RegenerateMint(dMint, mint)) + if (!zwallet->RegenerateMint(dMint, mint)) return error("%s: failed to generate mint", __func__); return true; @@ -944,8 +944,8 @@ bool CWallet::UpdateMint(const CBigNum& bnValue, const int& nHeight, const uint2 return zpivTracker->UpdateState(meta); } else { //Check if this mint is one that is in our mintpool (a potential future mint from our deterministic generation) - if (zwalletMain->IsInMintPool(bnValue)) { - if (zwalletMain->SetMintSeen(bnValue, nHeight, txid, denom)) + if (zwallet->IsInMintPool(bnValue)) { + if (zwallet->SetMintSeen(bnValue, nHeight, txid, denom)) return true; } } diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index eae496a19b7d..be2a23d29d1f 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -980,7 +980,7 @@ DBErrors CWalletDB::ZapWalletTx(CWallet* pwallet, std::vector& vWtx) return DB_LOAD_OK; } -void ThreadFlushWalletDB(const std::string& strFile) +void ThreadFlushWalletDB() { // Make this thread recognisable as the wallet flushing thread util::ThreadRename("pivx-wallet"); @@ -989,7 +989,7 @@ void ThreadFlushWalletDB(const std::string& strFile) if (fOneThread) return; fOneThread = true; - if (!GetBoolArg("-flushwallet", true)) + if (!GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) return; unsigned int nLastSeen = CWalletDB::GetUpdateCounter(); @@ -1016,18 +1016,19 @@ void ThreadFlushWalletDB(const std::string& strFile) if (nRefCount == 0) { boost::this_thread::interruption_point(); + const std::string& strFile = pwalletMain->strWalletFile; std::map::iterator mi = bitdb.mapFileUseCount.find(strFile); if (mi != bitdb.mapFileUseCount.end()) { - LogPrint(BCLog::DB, "Flushing wallet.dat\n"); + LogPrint(BCLog::DB, "Flushing %s\n", strFile); nLastFlushed = CWalletDB::GetUpdateCounter(); int64_t nStart = GetTimeMillis(); - // Flush wallet.dat so it's self contained + // Flush wallet file so it's self contained bitdb.CloseDb(strFile); bitdb.CheckpointLSN(strFile); bitdb.mapFileUseCount.erase(mi++); - LogPrint(BCLog::DB, "Flushed wallet.dat %dms\n", GetTimeMillis() - nStart); + LogPrint(BCLog::DB, "Flushed %s %dms\n", strFile, GetTimeMillis() - nStart); } } } @@ -1074,7 +1075,7 @@ bool BackupWallet(const CWallet& wallet, const fs::path& strDest, bool fEnableCu bitdb.CheckpointLSN(wallet.strWalletFile); bitdb.mapFileUseCount.erase(wallet.strWalletFile); - // Copy wallet.dat + // Copy wallet file fs::path pathDest(strDest); fs::path pathSrc = GetDataDir() / wallet.strWalletFile; if (is_directory(pathDest)) { @@ -1164,7 +1165,7 @@ bool AttemptBackupWallet(const CWallet& wallet, const fs::path& pathSrc, const f src.close(); dst.close(); #endif - strMessage = strprintf("copied wallet.dat to %s\n", pathDest.string()); + strMessage = strprintf("copied %s to %s\n", wallet.strWalletFile, pathDest.string()); LogPrintf("%s : %s\n", __func__, strMessage); retStatus = true; } catch (const fs::filesystem_error& e) { @@ -1177,15 +1178,15 @@ bool AttemptBackupWallet(const CWallet& wallet, const fs::path& pathSrc, const f } // -// Try to (very carefully!) recover wallet.dat if there is a problem. +// Try to (very carefully!) recover wallet file if there is a problem. // bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) { // Recovery procedure: - // move wallet.dat to wallet.timestamp.bak + // move wallet file to wallet.timestamp.bak // Call Salvage with fAggressive=true to // get as much data as possible. - // Rewrite salvaged data to wallet.dat + // Rewrite salvaged data to fresh wallet file. // Set -rescan so any missing transactions will be // found. int64_t now = GetTime(); diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index ef5da229ead6..ef67a14acbbf 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -24,6 +24,8 @@ #include #include +static const bool DEFAULT_FLUSHWALLET = true; + class CAccount; class CAccountingEntry; struct CBlockLocator; @@ -99,7 +101,7 @@ class CKeyMetadata } }; -/** Access to the wallet database (wallet.dat) */ +/** Access to the wallet database */ class CWalletDB : public CDB { public: @@ -232,6 +234,7 @@ class CWalletDB : public CDB void NotifyBacked(const CWallet& wallet, bool fSuccess, std::string strMessage); bool BackupWallet(const CWallet& wallet, const fs::path& strDest, bool fEnableCustom = true); bool AttemptBackupWallet(const CWallet& wallet, const fs::path& pathSrc, const fs::path& pathDest); -void ThreadFlushWalletDB(const std::string& strFile); + +void ThreadFlushWalletDB(); #endif // BITCOIN_WALLETDB_H diff --git a/src/zpiv/zpivtracker.cpp b/src/zpiv/zpivtracker.cpp index 91566cdf95a4..2c788408295d 100644 --- a/src/zpiv/zpivtracker.cpp +++ b/src/zpiv/zpivtracker.cpp @@ -449,7 +449,7 @@ std::set CzPIVTracker::ListMints(bool fUnusedOnly, bool fMatureOnly, for (auto& dMint : listDeterministicDB) { if (fExcludeV1 && dMint.GetVersion() < 2) continue; - Add(dMint, false, false, wallet->zwalletMain); + Add(dMint, false, false, wallet->getZWallet()); } LogPrint(BCLog::LEGACYZC, "%s: added %d dzpiv from DB\n", __func__, listDeterministicDB.size()); }