PIVX Core  5.6.99
P2P Digital Currency
init.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2017 The Bitcoin Core developers
3 // Copyright (c) 2021 The PIVX Core developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include "wallet/init.h"
8 
9 #include "guiinterfaceutil.h"
10 #include "net.h"
11 #include "util/system.h"
12 #include "utilmoneystr.h"
13 #include "validation.h"
14 #include "wallet/wallet.h"
15 #include "wallet/walletutil.h"
16 
17 std::string GetWalletHelpString(bool showDebug)
18 {
19  std::string strUsage = HelpMessageGroup("Wallet options:");
20  strUsage += HelpMessageOpt("-createwalletbackups=<n>", strprintf("Number of automatic wallet backups (default: %d)", DEFAULT_CREATEWALLETBACKUPS));
21  strUsage += HelpMessageOpt("-disablewallet", strprintf("Do not load the wallet and disable wallet RPC calls (default: %u)", DEFAULT_DISABLE_WALLET));
22  strUsage += HelpMessageOpt("-keypool=<n>", strprintf("Set key pool size to <n> (default: %u)", DEFAULT_KEYPOOL_SIZE));
23  strUsage += HelpMessageOpt("-legacywallet", "On first run, create a legacy wallet instead of a HD wallet");
24  strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)", FormatMoney(maxTxFee)));
25  strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf("Fees (in %s/Kb) smaller than this are considered zero fee for transaction creation (default: %s)", CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK())));
26  strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf("Fee (in %s/kB) to add to transactions you send (default: %s)", CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK())));
27  strUsage += HelpMessageOpt("-rescan", "Rescan the block chain for missing wallet transactions on startup");
28  strUsage += HelpMessageOpt("-salvagewallet", "Attempt to recover private keys from a corrupt wallet file on startup");
29  strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf("Spend unconfirmed change when sending transactions (default: %u)", DEFAULT_SPEND_ZEROCONF_CHANGE));
30  strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)", 1));
31  strUsage += HelpMessageOpt("-upgradewallet", "Upgrade wallet to latest format on startup");
32  strUsage += HelpMessageOpt("-wallet=<path>", "Specify wallet database path. Can be specified multiple times to load multiple wallets. Path is interpreted relative to <walletdir> if it is not absolute, and will be created if it does not exist (as a directory containing a wallet.dat file and log files). For backwards compatibility this will also accept names of existing data files in <walletdir>.)");
33  strUsage += HelpMessageOpt("-walletdir=<dir>", "Specify directory to hold wallets (default: <datadir>/wallets if it exists, otherwise <datadir>)");
34  strUsage += HelpMessageOpt("-walletnotify=<cmd>", "Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)");
35  strUsage += HelpMessageOpt("-zapwallettxes=<mode>", "Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup"
36  "(1 = keep tx meta data e.g. payment request information, 2 = drop tx meta data)");
37  strUsage += HelpMessageGroup("Mining/Staking options:");
38  strUsage += HelpMessageOpt("-coldstaking=<n>", strprintf("Enable cold staking functionality (0-1, default: %u). Disabled if staking=0", DEFAULT_COLDSTAKING));
39  strUsage += HelpMessageOpt("-gen", strprintf("Generate coins (default: %u)", DEFAULT_GENERATE));
40  strUsage += HelpMessageOpt("-genproclimit=<n>", strprintf("Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)", DEFAULT_GENERATE_PROCLIMIT));
41  strUsage += HelpMessageOpt("-minstakesplit=<amt>", strprintf("Minimum positive amount (in PIV) allowed by GUI and RPC for the stake split threshold (default: %s)", FormatMoney(DEFAULT_MIN_STAKE_SPLIT_THRESHOLD)));
42  strUsage += HelpMessageOpt("-staking=<n>", strprintf("Enable staking functionality (0-1, default: %u)", DEFAULT_STAKING));
43  if (showDebug) {
44  strUsage += HelpMessageGroup("Wallet debugging/testing options:");
45  strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush database activity from memory pool to disk log every <n> megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE));
46  strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET));
47  strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB));
48  }
49 
50  return strUsage;
51 }
52 
54 {
55  if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
56  return true;
57  }
58 
59  if (gArgs.GetBoolArg("-sysperms", false)) {
60  return UIError(strprintf(_("%s is not allowed in combination with enabled wallet functionality"), "-sysperms"));
61  }
62 
63  gArgs.SoftSetArg("-wallet", "");
64  const bool is_multiwallet = gArgs.GetArgs("-wallet").size() > 1;
65 
66  if (gArgs.GetBoolArg("-salvagewallet", false)) {
67  if (is_multiwallet) {
68  return UIError(strprintf(_("%s is only allowed with a single wallet file"), "-salvagewallet"));
69  }
70  // Rewrite just private keys: rescan to find transactions
71  if (gArgs.SoftSetBoolArg("-rescan", true)) {
72  LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__);
73  }
74  }
75 
76  bool zapwallettxes = gArgs.GetBoolArg("-zapwallettxes", false);
77  // -zapwallettxes implies dropping the mempool on startup
78  if (zapwallettxes && gArgs.SoftSetBoolArg("-persistmempool", false)) {
79  LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -persistmempool=0\n", __func__, zapwallettxes);
80  }
81 
82  // -zapwallettxes implies a rescan
83  if (zapwallettxes) {
84  if (is_multiwallet) {
85  return UIError(strprintf(_("%s is only allowed with a single wallet file"), "-zapwallettxes"));
86  }
87  if (gArgs.SoftSetBoolArg("-rescan", true)) {
88  LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n", __func__);
89  }
90  }
91 
92  if (is_multiwallet) {
93  if (gArgs.GetBoolArg("-upgradewallet", false)) {
94  return UIError(strprintf(_("%s is only allowed with a single wallet file"), "-upgradewallet"));
95  }
96  }
97 
98  if (gArgs.IsArgSet("-mintxfee")) {
99  CAmount n = 0;
100  if (ParseMoney(gArgs.GetArg("-mintxfee", ""), n) && n > 0)
102  else
103  return UIError(AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")));
104  }
105  if (gArgs.IsArgSet("-paytxfee")) {
106  CAmount nFeePerK = 0;
107  if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK))
108  return UIError(AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", "")));
109  if (nFeePerK > nHighTransactionFeeWarning)
110  UIWarning(strprintf(_("Warning: %s is set very high! This is the transaction fee you will pay if you send a transaction."), "-paytxfee"));
111  payTxFee = CFeeRate(nFeePerK, 1000);
112  if (payTxFee < ::minRelayTxFee) {
113  return UIError(strprintf(_("Invalid amount for %s: '%s' (must be at least %s)"), "-paytxfee",
114  gArgs.GetArg("-paytxfee", ""), ::minRelayTxFee.ToString()));
115  }
116  }
117  if (gArgs.IsArgSet("-maxtxfee")) {
118  CAmount nMaxFee = 0;
119  if (!ParseMoney(gArgs.GetArg("-maxtxfee", ""), nMaxFee))
120  return UIError(AmountErrMsg("maxtxfee", gArgs.GetArg("-maxtxfee", "")));
121  if (nMaxFee > nHighTransactionMaxFeeWarning)
122  UIWarning(strprintf(_("Warning: %s is set very high! Fees this large could be paid on a single transaction."), "-maxtxfee"));
123  maxTxFee = nMaxFee;
124  if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) {
125  return UIError(strprintf(_("Invalid amount for %s: '%s' (must be at least the minimum relay fee of %s to prevent stuck transactions)"),
126  "-maxtxfee", gArgs.GetArg("-maxtxfee", ""), ::minRelayTxFee.ToString()));
127  }
128  }
129  if (gArgs.IsArgSet("-minstakesplit")) {
130  CAmount n = 0;
131  if (ParseMoney(gArgs.GetArg("-minstakesplit", ""), n) && n > 0)
133  else
134  return UIError(AmountErrMsg("minstakesplit", gArgs.GetArg("-minstakesplit", "")));
135  }
136  nTxConfirmTarget = gArgs.GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET);
137  bSpendZeroConfChange = gArgs.GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE);
138  bdisableSystemnotifications = gArgs.GetBoolArg("-disablesystemnotifications", false);
139 
140  return true;
141 }
142 
144 {
145  if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
146  return true;
147  }
148 
149  if (gArgs.IsArgSet("-walletdir")) {
150  fs::path wallet_dir = gArgs.GetArg("-walletdir", "");
151  if (!fs::exists(wallet_dir)) {
152  return UIError(strprintf(_("Specified -walletdir \"%s\" does not exist"), wallet_dir.string()));
153  } else if (!fs::is_directory(wallet_dir)) {
154  return UIError(strprintf(_("Specified -walletdir \"%s\" is not a directory"), wallet_dir.string()));
155  } else if (!wallet_dir.is_absolute()) {
156  return UIError(strprintf(_("Specified -walletdir \"%s\" is a relative path"), wallet_dir.string()));
157  }
158  }
159 
160  LogPrintf("Using wallet directory %s\n", GetWalletDir().string());
161 
162  uiInterface.InitMessage(_("Verifying wallet(s)..."));
163 
164  // Keep track of each wallet absolute path to detect duplicates.
165  std::set<fs::path> wallet_paths;
166 
167  for (const std::string& walletFile : gArgs.GetArgs("-wallet")) {
168  auto opRes = VerifyWalletPath(walletFile);
169  if (!opRes) return UIError(opRes.getError());
170 
171  fs::path wallet_path = fs::absolute(walletFile, GetWalletDir());
172  if (!wallet_paths.insert(wallet_path).second) {
173  return UIError(strprintf(_("Error loading wallet %s. Duplicate %s filename specified."), walletFile, "-wallet"));
174  }
175 
176  std::string strError;
177  if (!WalletBatch::VerifyEnvironment(wallet_path, strError)) {
178  return UIError(strError);
179  }
180 
181  if (gArgs.GetBoolArg("-salvagewallet", false)) {
182  // Recover readable keypairs:
183  CWallet dummyWallet("dummy", WalletDatabase::CreateDummy());
184  std::string backup_filename;
185  // Even if we don't use this lock in this function, we want to preserve
186  // lock order in LoadToWallet if query of chain state is needed to know
187  // tx status. If lock can't be taken, tx confirmation status may be not
188  // reliable.
189  LOCK(cs_main);
190  if (!WalletBatch::Recover(wallet_path, (void *)&dummyWallet, WalletBatch::RecoverKeysOnlyFilter, backup_filename)) {
191  return false;
192  }
193  }
194 
195  std::string strWarning;
196  bool dbV = WalletBatch::VerifyDatabaseFile(wallet_path, strWarning, strError);
197  if (!strWarning.empty()) {
198  UIWarning(strWarning);
199  }
200  if (!dbV) {
201  return UIError(strError);
202  }
203  }
204 
205  return true;
206 }
207 
209 {
210  if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
211  LogPrintf("Wallet disabled!\n");
212  return true;
213  }
214 
215  for (const std::string& walletFile : gArgs.GetArgs("-wallet")) {
216  // create/load wallet
217  CWallet * const pwallet = CWallet::CreateWalletFromFile(walletFile, fs::absolute(walletFile, GetWalletDir()));
218  if (!pwallet) {
219  return false;
220  }
221 
222  // add to wallets in use
223  vpwallets.emplace_back(pwallet);
224  }
225 
226  // automatic backup
227  // do this after loading all wallets, so unique fileids are checked properly
228  for (CWallet* pwallet: vpwallets) {
229  std::string strWarning, strError;
230  if (!AutoBackupWallet(*pwallet, strWarning, strError)) {
231  if (!strWarning.empty()) {
232  UIWarning(strprintf("%s: %s", pwallet->GetName(), strWarning));
233  }
234  if (!strError.empty()) {
235  return UIError(strprintf("%s: %s", pwallet->GetName(), strError));
236  }
237  }
238  }
239 
240  return true;
241 }
int64_t CAmount
Amount in PIV (Can be negative)
Definition: amount.h:13
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: system.cpp:406
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn't already have a value.
Definition: system.cpp:473
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:425
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:449
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
Definition: system.cpp:481
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:465
static std::unique_ptr< BerkeleyDatabase > CreateDummy()
Return object for accessing dummy database with no read/write capabilities.
Definition: db.h:132
boost::signals2::signal< void(const std::string &message)> InitMessage
Progress message during initialization.
Definition: guiinterface.h:87
Fee rate in PIV per kilobyte: CAmount / kB.
Definition: feerate.h:20
std::string ToString() const
Definition: feerate.cpp:31
CAmount GetFeePerK() const
Definition: feerate.h:29
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,...
Definition: wallet.h:577
static CWallet * CreateWalletFromFile(const std::string &name, const fs::path &path)
Definition: wallet.cpp:4251
static CAmount minStakeSplitThreshold
minimum accpeted value for stake split threshold
Definition: wallet.h:735
static CFeeRate minTxFee
Fees smaller than this (in upiv) are considered zero fee (for transaction creation) We are ~100 times...
Definition: wallet.h:1129
static bool RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue)
Definition: walletdb.cpp:926
static bool Recover(const fs::path &wallet_path, void *callbackDataIn, bool(*recoverKVcallback)(void *callbackData, CDataStream ssKey, CDataStream ssValue), std::string &out_backup_filename)
Definition: walletdb.cpp:914
static bool VerifyEnvironment(const fs::path &wallet_path, std::string &errorStr)
Definition: walletdb.cpp:949
static bool VerifyDatabaseFile(const fs::path &wallet_path, std::string &warningStr, std::string &errorStr)
Definition: walletdb.cpp:954
const std::string CURRENCY_UNIT
Definition: feerate.cpp:11
CClientUIInterface uiInterface
Definition: init.cpp:109
@ LOCK
Definition: lockunlock.h:16
RecursiveMutex cs_main
Global state.
Definition: validation.cpp:80
ArgsManager gArgs
Definition: system.cpp:89
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Definition: system.cpp:499
std::string HelpMessageOpt(const std::string &option, const std::string &message)
Format a string to be used as option description in help messages.
Definition: system.cpp:503
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a Optional result.
Definition: system.h:65
#define strprintf
Definition: tinyformat.h:1056
bool ParseMoney(const std::string &str, CAmount &nRet)
std::string FormatMoney(const CAmount &n, bool fPlus)
Money parsing/formatting utilities.
CFeeRate minRelayTxFee
Fees smaller than this (in upiv) are considered zero fee (for relaying, mining and transaction creati...
Definition: validation.cpp:108
bool WalletVerify()
Responsible for reading and validating the -wallet arguments and verifying the wallet database.
Definition: init.cpp:143
std::string GetWalletHelpString(bool showDebug)
Return the wallets help message.
Definition: init.cpp:17
bool InitLoadWallet()
Load wallet databases.
Definition: init.cpp:208
bool WalletParameterInteraction()
Wallets parameter interaction.
Definition: init.cpp:53
std::vector< CWalletRef > vpwallets
Definition: wallet.cpp:33
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE)
Settings.
bool bSpendZeroConfChange
Definition: wallet.cpp:42
CAmount maxTxFee
Definition: wallet.cpp:38
unsigned int nTxConfirmTarget
Definition: wallet.cpp:39
bool bdisableSystemnotifications
Definition: wallet.cpp:40
bool AutoBackupWallet(CWallet &wallet, std::string &strBackupWarning, std::string &strBackupError)
Called during init: Automatic backups.
Definition: walletdb.cpp:880
fs::path GetWalletDir()
Get the path of the wallet directory.
Definition: walletutil.cpp:8
OperationResult VerifyWalletPath(const std::string &walletFile)
Verify the wallet db's path.
Definition: walletutil.cpp:30