Raven Core  3.0.0
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) 2017-2019 The Raven 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 "net.h"
10 #include "util.h"
11 #include "utilmoneystr.h"
12 #include "validation.h"
13 #include "wallet/wallet.h"
14 #include "wallet/rpcwallet.h"
15 
16 std::string GetWalletHelpString(bool showDebug)
17 {
18  std::string strUsage = HelpMessageGroup(_("Wallet options:"));
19  strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
20  strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), DEFAULT_KEYPOOL_SIZE));
21  strUsage += HelpMessageOpt("-fallbackfee=<amt>", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"),
22  CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE)));
23  strUsage += HelpMessageOpt("-discardfee=<amt>", strprintf(_("The fee rate (in %s/kB) that indicates your tolerance for discarding change by adding it to the fee (default: %s). "
24  "Note: An output is discarded if it is dust at this rate, but we will always discard up to the dust relay fee and a discard fee above that is limited by the fee estimate for the longest target"),
25  CURRENCY_UNIT, FormatMoney(DEFAULT_DISCARD_FEE)));
26  strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"),
27  CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE)));
28  strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"),
30  strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup"));
31  strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet on startup"));
32  strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE));
33  strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET));
34  strUsage += HelpMessageOpt("-walletrbf", strprintf(_("Send transactions with full-RBF opt-in enabled (default: %u)"), DEFAULT_WALLET_RBF));
35  strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup"));
36  strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT));
37  strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST));
38  strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)"));
39  strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") +
40  " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)"));
41 
42  if (showDebug)
43  {
44  strUsage += HelpMessageGroup(_("Wallet debugging/testing options:"));
45 
46  strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush wallet database activity from memory to disk log every <n> megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE));
47  strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET));
48  strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB));
49  strUsage += HelpMessageOpt("-walletrejectlongchains", strprintf(_("Wallet will not create transactions that violate mempool chain limits (default: %u)"), DEFAULT_WALLET_REJECT_LONG_CHAINS));
50  }
51 
52  return strUsage;
53 }
54 
56 {
58  const bool is_multiwallet = gArgs.GetArgs("-wallet").size() > 1;
59 
60  if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET))
61  return true;
62 
63  if (gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && gArgs.SoftSetBoolArg("-walletbroadcast", false)) {
64  LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__);
65  }
66 
67  if (gArgs.GetBoolArg("-salvagewallet", false)) {
68  if (is_multiwallet) {
69  return InitError(strprintf("%s is only allowed with a single wallet file", "-salvagewallet"));
70  }
71  // Rewrite just private keys: rescan to find transactions
72  if (gArgs.SoftSetBoolArg("-rescan", true)) {
73  LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__);
74  }
75  }
76 
77  int zapwallettxes = gArgs.GetArg("-zapwallettxes", 0);
78  // -zapwallettxes implies dropping the mempool on startup
79  if (zapwallettxes != 0 && gArgs.SoftSetBoolArg("-persistmempool", false)) {
80  LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -persistmempool=0\n", __func__, zapwallettxes);
81  }
82 
83  // -zapwallettxes implies a rescan
84  if (zapwallettxes != 0) {
85  if (is_multiwallet) {
86  return InitError(strprintf("%s is only allowed with a single wallet file", "-zapwallettxes"));
87  }
88  if (gArgs.SoftSetBoolArg("-rescan", true)) {
89  LogPrintf("%s: parameter interaction: -zapwallettxes=%s -> setting -rescan=1\n", __func__, zapwallettxes);
90  }
91  }
92 
93  if (is_multiwallet) {
94  if (gArgs.GetBoolArg("-upgradewallet", false)) {
95  return InitError(strprintf("%s is only allowed with a single wallet file", "-upgradewallet"));
96  }
97  }
98 
99  if (gArgs.GetBoolArg("-sysperms", false))
100  return InitError("-sysperms is not allowed in combination with enabled wallet functionality");
101  if (gArgs.GetArg("-prune", 0) && gArgs.GetBoolArg("-rescan", false))
102  return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again."));
103 
104  if (::minRelayTxFee.GetFeePerK() > HIGH_TX_FEE_PER_KB)
105  InitWarning(AmountHighWarn("-minrelaytxfee") + " " +
106  _("The wallet will avoid paying less than the minimum relay fee."));
107 
108  if (gArgs.IsArgSet("-mintxfee"))
109  {
110  CAmount n = 0;
111  if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n)
112  return InitError(AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")));
113  if (n > HIGH_TX_FEE_PER_KB)
114  InitWarning(AmountHighWarn("-mintxfee") + " " +
115  _("This is the minimum transaction fee you pay on every transaction."));
117  }
118  if (gArgs.IsArgSet("-fallbackfee"))
119  {
120  CAmount nFeePerK = 0;
121  if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK))
122  return InitError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), gArgs.GetArg("-fallbackfee", "")));
123  if (nFeePerK > HIGH_TX_FEE_PER_KB)
124  InitWarning(AmountHighWarn("-fallbackfee") + " " +
125  _("This is the transaction fee you may pay when fee estimates are not available."));
126  CWallet::fallbackFee = CFeeRate(nFeePerK);
127  }
128  if (gArgs.IsArgSet("-discardfee"))
129  {
130  CAmount nFeePerK = 0;
131  if (!ParseMoney(gArgs.GetArg("-discardfee", ""), nFeePerK))
132  return InitError(strprintf(_("Invalid amount for -discardfee=<amount>: '%s'"), gArgs.GetArg("-discardfee", "")));
133  if (nFeePerK > HIGH_TX_FEE_PER_KB)
134  InitWarning(AmountHighWarn("-discardfee") + " " +
135  _("This is the transaction fee you may discard if change is smaller than dust at this level"));
136  CWallet::m_discard_rate = CFeeRate(nFeePerK);
137  }
138  if (gArgs.IsArgSet("-paytxfee"))
139  {
140  CAmount nFeePerK = 0;
141  if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK))
142  return InitError(AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", "")));
143  if (nFeePerK > HIGH_TX_FEE_PER_KB)
144  InitWarning(AmountHighWarn("-paytxfee") + " " +
145  _("This is the transaction fee you will pay if you send a transaction."));
146 
147  payTxFee = CFeeRate(nFeePerK, 1000);
148  if (payTxFee < ::minRelayTxFee)
149  {
150  return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
151  gArgs.GetArg("-paytxfee", ""), ::minRelayTxFee.ToString()));
152  }
153  }
154  if (gArgs.IsArgSet("-maxtxfee"))
155  {
156  CAmount nMaxFee = 0;
157  if (!ParseMoney(gArgs.GetArg("-maxtxfee", ""), nMaxFee))
158  return InitError(AmountErrMsg("maxtxfee", gArgs.GetArg("-maxtxfee", "")));
159  if (nMaxFee > HIGH_MAX_TX_FEE)
160  InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction."));
161  maxTxFee = nMaxFee;
162  if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee)
163  {
164  return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
165  gArgs.GetArg("-maxtxfee", ""), ::minRelayTxFee.ToString()));
166  }
167  }
168  nTxConfirmTarget = gArgs.GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET);
169  bSpendZeroConfChange = gArgs.GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE);
170  fWalletRbf = gArgs.GetBoolArg("-walletrbf", DEFAULT_WALLET_RBF);
171 
172  return true;
173 }
174 
176 {
177  if (gArgs.GetBoolArg("-disablewallet", false)) return;
178 
180 }
181 
183 {
184  if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET))
185  return true;
186 
187  uiInterface.InitMessage(_("Verifying wallet(s)..."));
188 
189  // Keep track of each wallet absolute path to detect duplicates.
190  std::set<fs::path> wallet_paths;
191 
192  for (const std::string& walletFile : gArgs.GetArgs("-wallet")) {
193  if (boost::filesystem::path(walletFile).filename() != walletFile) {
194  return InitError(strprintf(_("Error loading wallet %s. -wallet parameter must only specify a filename (not a path)."), walletFile));
195  }
196 
197  if (SanitizeString(walletFile, SAFE_CHARS_FILENAME) != walletFile) {
198  return InitError(strprintf(_("Error loading wallet %s. Invalid characters in -wallet filename."), walletFile));
199  }
200 
201  fs::path wallet_path = fs::absolute(walletFile, GetDataDir());
202 
203  if (fs::exists(wallet_path) && (!fs::is_regular_file(wallet_path) || fs::is_symlink(wallet_path))) {
204  return InitError(strprintf(_("Error loading wallet %s. -wallet filename must be a regular file."), walletFile));
205  }
206 
207  if (!wallet_paths.insert(wallet_path).second) {
208  return InitError(strprintf(_("Error loading wallet %s. Duplicate -wallet filename specified."), walletFile));
209  }
210 
211  std::string strError;
212  if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(), strError)) {
213  return InitError(strError);
214  }
215 
216  if (gArgs.GetBoolArg("-salvagewallet", false)) {
217  // Recover readable keypairs:
218  CWallet dummyWallet;
219  std::string backup_filename;
220  if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter, backup_filename)) {
221  return false;
222  }
223  }
224 
225  std::string strWarning;
226  bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetDataDir().string(), strWarning, strError);
227  if (!strWarning.empty()) {
228  InitWarning(strWarning);
229  }
230  if (!dbV) {
231  InitError(strError);
232  return false;
233  }
234  }
235 
236  return true;
237 }
238 
240 {
241  if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
242  LogPrintf("Wallet disabled!\n");
243  return true;
244  }
245 
246  for (const std::string& walletFile : gArgs.GetArgs("-wallet")) {
247  CWallet * const pwallet = CWallet::CreateWalletFromFile(walletFile);
248  if (!pwallet) {
249  return false;
250  }
251  vpwallets.push_back(pwallet);
252  }
253 
254  return true;
255 }
256 
257 void StartWallets(CScheduler& scheduler) {
258  for (CWalletRef pwallet : vpwallets) {
259  pwallet->postInitProcess(scheduler);
260  }
261 }
262 
263 void FlushWallets() {
264  for (CWalletRef pwallet : vpwallets) {
265  pwallet->Flush(false);
266  }
267 }
268 
269 void StopWallets() {
270  for (CWalletRef pwallet : vpwallets) {
271  pwallet->Flush(true);
272  }
273 }
274 
275 void CloseWallets() {
276  for (CWalletRef pwallet : vpwallets) {
277  delete pwallet;
278  }
279  vpwallets.clear();
280 }
std::string HelpMessageOpt(const std::string &option, const std::string &message)
Format a string to be used as option description in help messages.
Definition: util.cpp:511
const char * DEFAULT_WALLET_DAT
Definition: wallet.cpp:51
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: util.cpp:448
Raven RPC command dispatcher.
Definition: server.h:143
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn&#39;t already have a value.
Definition: util.cpp:486
#define strprintf
Definition: tinyformat.h:1054
CAmount maxTxFee
Absolute maximum transaction fee (in satoshis) used by wallet and mempool (rejects high fee in sendra...
Definition: validation.cpp:105
bool bSpendZeroConfChange
Definition: wallet.cpp:48
bool OpenWallets()
Load wallet databases.
Definition: init.cpp:239
void CloseWallets()
Close all wallets.
Definition: init.cpp:275
std::vector< CWalletRef > vpwallets
Definition: wallet.cpp:44
const std::string CURRENCY_UNIT
Definition: feerate.cpp:11
std::string GetWalletHelpString(bool showDebug)
Return the wallets help message.
Definition: init.cpp:16
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: util.cpp:470
void StopWallets()
Stop all wallets. Wallets will be flushed first.
Definition: init.cpp:269
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn&#39;t already have a value.
Definition: util.cpp:478
static bool RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue)
Definition: walletdb.cpp:802
int64_t CAmount
Amount in corbies (Can be negative)
Definition: amount.h:13
unsigned int nTxConfirmTarget
Definition: wallet.cpp:47
#define LogPrintf(...)
Definition: util.h:149
static CFeeRate m_discard_rate
Definition: wallet.h:1037
static bool VerifyEnvironment(const std::string &walletFile, const fs::path &dataDir, std::string &errorStr)
Definition: walletdb.cpp:825
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
Definition: validation.cpp:104
void RegisterWalletRPC(CRPCTable &t)
Register wallet RPCs.
Definition: init.cpp:175
bool fWalletRbf
Definition: wallet.cpp:49
static bool VerifyDatabaseFile(const std::string &walletFile, const fs::path &dataDir, std::string &warningStr, std::string &errorStr)
Definition: walletdb.cpp:830
Chars allowed in filenames.
bool ParseMoney(const std::string &str, CAmount &nRet)
static bool Recover(const std::string &filename, void *callbackDataIn, bool(*recoverKVcallback)(void *callbackData, CDataStream ssKey, CDataStream ssValue), std::string &out_backup_filename)
Definition: walletdb.cpp:790
bool WalletParameterInteraction()
Wallets parameter interaction.
Definition: init.cpp:55
std::string AmountHighWarn(const std::string &optname)
static CWallet * CreateWalletFromFile(const std::string walletFile)
Definition: wallet.cpp:4529
std::string FormatMoney(const CAmount &n)
Money parsing/formatting utilities.
void RegisterWalletRPCCommands(CRPCTable &t)
Definition: rpcwallet.cpp:3398
ArgsManager gArgs
Definition: util.cpp:94
bool InitError(const std::string &str)
Show error message.
static CFeeRate fallbackFee
If fee estimation does not have enough data to provide estimates, use this fee instead.
Definition: wallet.h:1036
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: util.cpp:454
static CFeeRate minTxFee
Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) Override with ...
Definition: wallet.h:1035
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:673
Fee rate in satoshis per kilobyte: CAmount / kB.
Definition: feerate.h:20
void FlushWallets()
Flush all wallets in preparation for shutdown.
Definition: init.cpp:263
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE)
Transaction fee set by the user.
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:572
void StartWallets(CScheduler &scheduler)
Complete startup of wallets.
Definition: init.cpp:257
std::string ToString() const
Definition: feerate.cpp:41
void InitWarning(const std::string &str)
Show warning message.
CClientUIInterface uiInterface
Definition: ui_interface.cpp:9
bool VerifyWallets()
Responsible for reading and validating the -wallet arguments and verifying the wallet database...
Definition: init.cpp:182
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: util.cpp:440
std::string AmountErrMsg(const char *const optname, const std::string &strValue)
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Definition: util.cpp:506
CAmount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
Definition: feerate.h:42
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
Definition: util.h:66
boost::signals2::signal< void(const std::string &message)> InitMessage
Progress message during initialization.
Definition: ui_interface.h:82