You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

init.cpp 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2017 The Bitcoin Core developers
  3. // Distributed under the MIT software license, see the accompanying
  4. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. #include <wallet/init.h>
  6. #include <net.h>
  7. #include <util.h>
  8. #include <utilmoneystr.h>
  9. #include <validation.h>
  10. #include <wallet/rpcwallet.h>
  11. #include <wallet/wallet.h>
  12. #include <wallet/walletutil.h>
  13. std::string GetWalletHelpString(bool showDebug)
  14. {
  15. std::string strUsage = HelpMessageGroup(_("Wallet options:"));
  16. strUsage += HelpMessageOpt("-addresstype", strprintf("What type of addresses to use (\"legacy\", \"p2sh-segwit\", or \"bech32\", default: \"%s\")", FormatOutputType(OUTPUT_TYPE_DEFAULT)));
  17. strUsage += HelpMessageOpt("-changetype", "What type of change to use (\"legacy\", \"p2sh-segwit\", or \"bech32\"). Default is same as -addresstype, except when -addresstype=p2sh-segwit a native segwit output is used when sending to a native segwit address)");
  18. strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
  19. strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), DEFAULT_KEYPOOL_SIZE));
  20. strUsage += HelpMessageOpt("-fallbackfee=<amt>", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"),
  21. CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE)));
  22. 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). "
  23. "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"),
  24. CURRENCY_UNIT, FormatMoney(DEFAULT_DISCARD_FEE)));
  25. strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"),
  26. CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE)));
  27. strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"),
  28. CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK())));
  29. strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup"));
  30. strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet on startup"));
  31. strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE));
  32. 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));
  33. strUsage += HelpMessageOpt("-walletrbf", strprintf(_("Send transactions with full-RBF opt-in enabled (RPC only, default: %u)"), DEFAULT_WALLET_RBF));
  34. strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup"));
  35. strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT));
  36. strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST));
  37. strUsage += HelpMessageOpt("-walletdir=<dir>", _("Specify directory to hold wallets (default: <datadir>/wallets if it exists, otherwise <datadir>)"));
  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. if (showDebug)
  42. {
  43. strUsage += HelpMessageGroup(_("Wallet debugging/testing options:"));
  44. strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush wallet database activity from memory to disk log every <n> megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE));
  45. strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET));
  46. strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB));
  47. strUsage += HelpMessageOpt("-walletrejectlongchains", strprintf(_("Wallet will not create transactions that violate mempool chain limits (default: %u)"), DEFAULT_WALLET_REJECT_LONG_CHAINS));
  48. }
  49. return strUsage;
  50. }
  51. bool WalletParameterInteraction()
  52. {
  53. if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
  54. for (const std::string& wallet : gArgs.GetArgs("-wallet")) {
  55. LogPrintf("%s: parameter interaction: -disablewallet -> ignoring -wallet=%s\n", __func__, wallet);
  56. }
  57. return true;
  58. }
  59. gArgs.SoftSetArg("-wallet", DEFAULT_WALLET_DAT);
  60. const bool is_multiwallet = gArgs.GetArgs("-wallet").size() > 1;
  61. if (gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && gArgs.SoftSetBoolArg("-walletbroadcast", false)) {
  62. LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__);
  63. }
  64. if (gArgs.GetBoolArg("-salvagewallet", false)) {
  65. if (is_multiwallet) {
  66. return InitError(strprintf("%s is only allowed with a single wallet file", "-salvagewallet"));
  67. }
  68. // Rewrite just private keys: rescan to find transactions
  69. if (gArgs.SoftSetBoolArg("-rescan", true)) {
  70. LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__);
  71. }
  72. }
  73. bool zapwallettxes = gArgs.GetBoolArg("-zapwallettxes", false);
  74. // -zapwallettxes implies dropping the mempool on startup
  75. if (zapwallettxes && gArgs.SoftSetBoolArg("-persistmempool", false)) {
  76. LogPrintf("%s: parameter interaction: -zapwallettxes enabled -> setting -persistmempool=0\n", __func__);
  77. }
  78. // -zapwallettxes implies a rescan
  79. if (zapwallettxes) {
  80. if (is_multiwallet) {
  81. return InitError(strprintf("%s is only allowed with a single wallet file", "-zapwallettxes"));
  82. }
  83. if (gArgs.SoftSetBoolArg("-rescan", true)) {
  84. LogPrintf("%s: parameter interaction: -zapwallettxes enabled -> setting -rescan=1\n", __func__);
  85. }
  86. }
  87. if (is_multiwallet) {
  88. if (gArgs.GetBoolArg("-upgradewallet", false)) {
  89. return InitError(strprintf("%s is only allowed with a single wallet file", "-upgradewallet"));
  90. }
  91. }
  92. if (gArgs.GetBoolArg("-sysperms", false))
  93. return InitError("-sysperms is not allowed in combination with enabled wallet functionality");
  94. if (gArgs.GetArg("-prune", 0) && gArgs.GetBoolArg("-rescan", false))
  95. return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again."));
  96. if (::minRelayTxFee.GetFeePerK() > HIGH_TX_FEE_PER_KB)
  97. InitWarning(AmountHighWarn("-minrelaytxfee") + " " +
  98. _("The wallet will avoid paying less than the minimum relay fee."));
  99. if (gArgs.IsArgSet("-mintxfee"))
  100. {
  101. CAmount n = 0;
  102. if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n)
  103. return InitError(AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")));
  104. if (n > HIGH_TX_FEE_PER_KB)
  105. InitWarning(AmountHighWarn("-mintxfee") + " " +
  106. _("This is the minimum transaction fee you pay on every transaction."));
  107. CWallet::minTxFee = CFeeRate(n);
  108. }
  109. if (gArgs.IsArgSet("-fallbackfee"))
  110. {
  111. CAmount nFeePerK = 0;
  112. if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK))
  113. return InitError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), gArgs.GetArg("-fallbackfee", "")));
  114. if (nFeePerK > HIGH_TX_FEE_PER_KB)
  115. InitWarning(AmountHighWarn("-fallbackfee") + " " +
  116. _("This is the transaction fee you may pay when fee estimates are not available."));
  117. CWallet::fallbackFee = CFeeRate(nFeePerK);
  118. }
  119. if (gArgs.IsArgSet("-discardfee"))
  120. {
  121. CAmount nFeePerK = 0;
  122. if (!ParseMoney(gArgs.GetArg("-discardfee", ""), nFeePerK))
  123. return InitError(strprintf(_("Invalid amount for -discardfee=<amount>: '%s'"), gArgs.GetArg("-discardfee", "")));
  124. if (nFeePerK > HIGH_TX_FEE_PER_KB)
  125. InitWarning(AmountHighWarn("-discardfee") + " " +
  126. _("This is the transaction fee you may discard if change is smaller than dust at this level"));
  127. CWallet::m_discard_rate = CFeeRate(nFeePerK);
  128. }
  129. if (gArgs.IsArgSet("-paytxfee"))
  130. {
  131. CAmount nFeePerK = 0;
  132. if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK))
  133. return InitError(AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", "")));
  134. if (nFeePerK > HIGH_TX_FEE_PER_KB)
  135. InitWarning(AmountHighWarn("-paytxfee") + " " +
  136. _("This is the transaction fee you will pay if you send a transaction."));
  137. payTxFee = CFeeRate(nFeePerK, 1000);
  138. if (payTxFee < ::minRelayTxFee)
  139. {
  140. return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
  141. gArgs.GetArg("-paytxfee", ""), ::minRelayTxFee.ToString()));
  142. }
  143. }
  144. if (gArgs.IsArgSet("-maxtxfee"))
  145. {
  146. CAmount nMaxFee = 0;
  147. if (!ParseMoney(gArgs.GetArg("-maxtxfee", ""), nMaxFee))
  148. return InitError(AmountErrMsg("maxtxfee", gArgs.GetArg("-maxtxfee", "")));
  149. if (nMaxFee > HIGH_MAX_TX_FEE)
  150. InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction."));
  151. maxTxFee = nMaxFee;
  152. if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee)
  153. {
  154. return InitError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
  155. gArgs.GetArg("-maxtxfee", ""), ::minRelayTxFee.ToString()));
  156. }
  157. }
  158. nTxConfirmTarget = gArgs.GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET);
  159. bSpendZeroConfChange = gArgs.GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE);
  160. fWalletRbf = gArgs.GetBoolArg("-walletrbf", DEFAULT_WALLET_RBF);
  161. g_address_type = ParseOutputType(gArgs.GetArg("-addresstype", ""));
  162. if (g_address_type == OUTPUT_TYPE_NONE) {
  163. return InitError(strprintf("Unknown address type '%s'", gArgs.GetArg("-addresstype", "")));
  164. }
  165. // If changetype is set in config file or parameter, check that it's valid.
  166. // Default to OUTPUT_TYPE_NONE if not set.
  167. g_change_type = ParseOutputType(gArgs.GetArg("-changetype", ""), OUTPUT_TYPE_NONE);
  168. if (g_change_type == OUTPUT_TYPE_NONE && !gArgs.GetArg("-changetype", "").empty()) {
  169. return InitError(strprintf("Unknown change type '%s'", gArgs.GetArg("-changetype", "")));
  170. }
  171. return true;
  172. }
  173. void RegisterWalletRPC(CRPCTable &t)
  174. {
  175. if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
  176. return;
  177. }
  178. RegisterWalletRPCCommands(t);
  179. }
  180. bool VerifyWallets()
  181. {
  182. if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
  183. return true;
  184. }
  185. if (gArgs.IsArgSet("-walletdir")) {
  186. fs::path wallet_dir = gArgs.GetArg("-walletdir", "");
  187. if (!fs::exists(wallet_dir)) {
  188. return InitError(strprintf(_("Specified -walletdir \"%s\" does not exist"), wallet_dir.string()));
  189. } else if (!fs::is_directory(wallet_dir)) {
  190. return InitError(strprintf(_("Specified -walletdir \"%s\" is not a directory"), wallet_dir.string()));
  191. } else if (!wallet_dir.is_absolute()) {
  192. return InitError(strprintf(_("Specified -walletdir \"%s\" is a relative path"), wallet_dir.string()));
  193. }
  194. }
  195. LogPrintf("Using wallet directory %s\n", GetWalletDir().string());
  196. uiInterface.InitMessage(_("Verifying wallet(s)..."));
  197. // Keep track of each wallet absolute path to detect duplicates.
  198. std::set<fs::path> wallet_paths;
  199. for (const std::string& walletFile : gArgs.GetArgs("-wallet")) {
  200. if (boost::filesystem::path(walletFile).filename() != walletFile) {
  201. return InitError(strprintf(_("Error loading wallet %s. -wallet parameter must only specify a filename (not a path)."), walletFile));
  202. }
  203. if (SanitizeString(walletFile, SAFE_CHARS_FILENAME) != walletFile) {
  204. return InitError(strprintf(_("Error loading wallet %s. Invalid characters in -wallet filename."), walletFile));
  205. }
  206. fs::path wallet_path = fs::absolute(walletFile, GetWalletDir());
  207. if (fs::exists(wallet_path) && (!fs::is_regular_file(wallet_path) || fs::is_symlink(wallet_path))) {
  208. return InitError(strprintf(_("Error loading wallet %s. -wallet filename must be a regular file."), walletFile));
  209. }
  210. if (!wallet_paths.insert(wallet_path).second) {
  211. return InitError(strprintf(_("Error loading wallet %s. Duplicate -wallet filename specified."), walletFile));
  212. }
  213. std::string strError;
  214. if (!CWalletDB::VerifyEnvironment(walletFile, GetWalletDir().string(), strError)) {
  215. return InitError(strError);
  216. }
  217. if (gArgs.GetBoolArg("-salvagewallet", false)) {
  218. // Recover readable keypairs:
  219. CWallet dummyWallet;
  220. std::string backup_filename;
  221. if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter, backup_filename)) {
  222. return false;
  223. }
  224. }
  225. std::string strWarning;
  226. bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetWalletDir().string(), strWarning, strError);
  227. if (!strWarning.empty()) {
  228. InitWarning(strWarning);
  229. }
  230. if (!dbV) {
  231. InitError(strError);
  232. return false;
  233. }
  234. }
  235. return true;
  236. }
  237. bool OpenWallets()
  238. {
  239. if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
  240. LogPrintf("Wallet disabled!\n");
  241. return true;
  242. }
  243. for (const std::string& walletFile : gArgs.GetArgs("-wallet")) {
  244. CWallet * const pwallet = CWallet::CreateWalletFromFile(walletFile);
  245. if (!pwallet) {
  246. return false;
  247. }
  248. vpwallets.push_back(pwallet);
  249. }
  250. return true;
  251. }
  252. void StartWallets(CScheduler& scheduler) {
  253. for (CWalletRef pwallet : vpwallets) {
  254. pwallet->postInitProcess(scheduler);
  255. }
  256. }
  257. void FlushWallets() {
  258. for (CWalletRef pwallet : vpwallets) {
  259. pwallet->Flush(false);
  260. }
  261. }
  262. void StopWallets() {
  263. for (CWalletRef pwallet : vpwallets) {
  264. pwallet->Flush(true);
  265. }
  266. }
  267. void CloseWallets() {
  268. for (CWalletRef pwallet : vpwallets) {
  269. delete pwallet;
  270. }
  271. vpwallets.clear();
  272. }