LCOV - code coverage report
Current view: top level - src/wallet - load.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 78 80 97.5 %
Date: 2020-09-26 01:30:44 Functions: 6 6 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2020 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             : 
       6             : #include <wallet/load.h>
       7             : 
       8             : #include <fs.h>
       9             : #include <interfaces/chain.h>
      10             : #include <scheduler.h>
      11             : #include <util/string.h>
      12             : #include <util/system.h>
      13             : #include <util/translation.h>
      14             : #include <wallet/wallet.h>
      15             : #include <wallet/walletdb.h>
      16             : 
      17             : #include <univalue.h>
      18             : 
      19         528 : bool VerifyWallets(interfaces::Chain& chain, const std::vector<std::string>& wallet_files)
      20             : {
      21         530 :     if (gArgs.IsArgSet("-walletdir")) {
      22          24 :         fs::path wallet_dir = gArgs.GetArg("-walletdir", "");
      23          24 :         boost::system::error_code error;
      24             :         // The canonical path cleans the path, preventing >1 Berkeley environment instances for the same directory
      25          24 :         fs::path canonical_wallet_dir = fs::canonical(wallet_dir, error);
      26          24 :         if (error || !fs::exists(wallet_dir)) {
      27           5 :             chain.initError(strprintf(_("Specified -walletdir \"%s\" does not exist"), wallet_dir.string()));
      28           5 :             return false;
      29          19 :         } else if (!fs::is_directory(wallet_dir)) {
      30           5 :             chain.initError(strprintf(_("Specified -walletdir \"%s\" is not a directory"), wallet_dir.string()));
      31           5 :             return false;
      32             :         // The canonical path transforms relative paths into absolute ones, so we check the non-canonical version
      33          14 :         } else if (!wallet_dir.is_absolute()) {
      34           3 :             chain.initError(strprintf(_("Specified -walletdir \"%s\" is a relative path"), wallet_dir.string()));
      35           3 :             return false;
      36             :         }
      37          11 :         gArgs.ForceSetArg("-walletdir", canonical_wallet_dir.string());
      38          24 :     }
      39             : 
      40         515 :     LogPrintf("Using wallet directory %s\n", GetWalletDir().string());
      41             : 
      42         515 :     chain.initMessage(_("Verifying wallet(s)...").translated);
      43             : 
      44             :     // Keep track of each wallet absolute path to detect duplicates.
      45         515 :     std::set<fs::path> wallet_paths;
      46             : 
      47         788 :     for (const auto& wallet_file : wallet_files) {
      48         273 :         const fs::path path = fs::absolute(wallet_file, GetWalletDir());
      49             : 
      50         273 :         if (!wallet_paths.insert(path).second) {
      51           2 :             chain.initError(strprintf(_("Error loading wallet %s. Duplicate -wallet filename specified."), wallet_file));
      52           2 :             return false;
      53             :         }
      54             : 
      55         271 :         DatabaseOptions options;
      56         271 :         DatabaseStatus status;
      57         271 :         options.verify = true;
      58         271 :         bilingual_str error_string;
      59         271 :         if (!MakeWalletDatabase(wallet_file, options, status, error_string)) {
      60           5 :             chain.initError(error_string);
      61           5 :             return false;
      62             :         }
      63         273 :     }
      64             : 
      65         506 :     return true;
      66         530 : }
      67             : 
      68         492 : bool LoadWallets(interfaces::Chain& chain, const std::vector<std::string>& wallet_files)
      69             : {
      70             :     try {
      71         744 :         for (const std::string& name : wallet_files) {
      72         252 :             DatabaseOptions options;
      73         252 :             DatabaseStatus status;
      74         252 :             options.verify = false; // No need to verify, assuming verified earlier in VerifyWallets()
      75         252 :             bilingual_str error;
      76         252 :             std::vector<bilingual_str> warnings;
      77         252 :             std::unique_ptr<WalletDatabase> database = MakeWalletDatabase(name, options, status, error);
      78         252 :             std::shared_ptr<CWallet> pwallet = database ? CWallet::Create(chain, name, std::move(database), options.create_flags, error, warnings) : nullptr;
      79         250 :             if (!warnings.empty()) chain.initWarning(Join(warnings, Untranslated("\n")));
      80         250 :             if (!pwallet) {
      81           0 :                 chain.initError(error);
      82           0 :                 return false;
      83             :             }
      84         250 :             AddWallet(pwallet);
      85         252 :         }
      86         490 :         return true;
      87           2 :     } catch (const std::runtime_error& e) {
      88           2 :         chain.initError(Untranslated(e.what()));
      89             :         return false;
      90           2 :     }
      91         494 : }
      92             : 
      93         487 : void StartWallets(CScheduler& scheduler, const ArgsManager& args)
      94             : {
      95         732 :     for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
      96         245 :         pwallet->postInitProcess();
      97             :     }
      98             : 
      99             :     // Schedule periodic wallet flushes and tx rebroadcasts
     100         487 :     if (args.GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) {
     101         487 :         scheduler.scheduleEvery(MaybeCompactWalletDB, std::chrono::milliseconds{500});
     102         487 :     }
     103         487 :     scheduler.scheduleEvery(MaybeResendWalletTxs, std::chrono::milliseconds{1000});
     104         487 : }
     105             : 
     106         524 : void FlushWallets()
     107             : {
     108        1128 :     for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
     109         604 :         pwallet->Flush();
     110             :     }
     111         524 : }
     112             : 
     113         524 : void StopWallets()
     114             : {
     115        1128 :     for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
     116         604 :         pwallet->Close();
     117             :     }
     118         524 : }
     119             : 
     120        1000 : void UnloadWallets()
     121             : {
     122        1000 :     auto wallets = GetWallets();
     123        1604 :     while (!wallets.empty()) {
     124         604 :         auto wallet = wallets.back();
     125         604 :         wallets.pop_back();
     126         604 :         std::vector<bilingual_str> warnings;
     127         604 :         RemoveWallet(wallet, nullopt, warnings);
     128         604 :         UnloadWallet(std::move(wallet));
     129         604 :     }
     130        1000 : }

Generated by: LCOV version 1.15