LCOV - code coverage report
Current view: top level - src/wallet - load.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 111 117 94.9 %
Date: 2021-06-29 14:35:33 Functions: 7 7 100.0 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 37 46 80.4 %

           Branch data     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                 :            : bool VerifyWallets(interfaces::Chain& chain)
#      20                 :        659 : {
#      21         [ +  + ]:        659 :     if (gArgs.IsArgSet("-walletdir")) {
#      22                 :         33 :         fs::path wallet_dir = gArgs.GetArg("-walletdir", "");
#      23                 :         33 :         boost::system::error_code error;
#      24                 :            :         // The canonical path cleans the path, preventing >1 Berkeley environment instances for the same directory
#      25                 :         33 :         fs::path canonical_wallet_dir = fs::canonical(wallet_dir, error);
#      26 [ +  + ][ -  + ]:         33 :         if (error || !fs::exists(wallet_dir)) {
#      27                 :          7 :             chain.initError(strprintf(_("Specified -walletdir \"%s\" does not exist"), wallet_dir.string()));
#      28                 :          7 :             return false;
#      29         [ +  + ]:         26 :         } else if (!fs::is_directory(wallet_dir)) {
#      30                 :          7 :             chain.initError(strprintf(_("Specified -walletdir \"%s\" is not a directory"), wallet_dir.string()));
#      31                 :          7 :             return false;
#      32                 :            :         // The canonical path transforms relative paths into absolute ones, so we check the non-canonical version
#      33         [ +  + ]:         19 :         } else if (!wallet_dir.is_absolute()) {
#      34                 :          4 :             chain.initError(strprintf(_("Specified -walletdir \"%s\" is a relative path"), wallet_dir.string()));
#      35                 :          4 :             return false;
#      36                 :          4 :         }
#      37                 :         15 :         gArgs.ForceSetArg("-walletdir", canonical_wallet_dir.string());
#      38                 :         15 :     }
#      39                 :            : 
#      40                 :        659 :     LogPrintf("Using wallet directory %s\n", GetWalletDir().string());
#      41                 :            : 
#      42                 :        641 :     chain.initMessage(_("Verifying wallet(s)…").translated);
#      43                 :            : 
#      44                 :            :     // For backwards compatibility if an unnamed top level wallet exists in the
#      45                 :            :     // wallets directory, include it in the default list of wallets to load.
#      46         [ +  + ]:        641 :     if (!gArgs.IsArgSet("wallet")) {
#      47                 :        472 :         DatabaseOptions options;
#      48                 :        472 :         DatabaseStatus status;
#      49                 :        472 :         bilingual_str error_string;
#      50                 :        472 :         options.require_existing = true;
#      51                 :        472 :         options.verify = false;
#      52         [ +  + ]:        472 :         if (MakeWalletDatabase("", options, status, error_string)) {
#      53                 :          1 :             gArgs.LockSettings([&](util::Settings& settings) {
#      54                 :          1 :                 util::SettingsValue wallets(util::SettingsValue::VARR);
#      55                 :          1 :                 wallets.push_back(""); // Default wallet name is ""
#      56                 :          1 :                 settings.rw_settings["wallet"] = wallets;
#      57                 :          1 :             });
#      58                 :          1 :         }
#      59                 :        472 :     }
#      60                 :            : 
#      61                 :            :     // Keep track of each wallet absolute path to detect duplicates.
#      62                 :        641 :     std::set<fs::path> wallet_paths;
#      63                 :            : 
#      64         [ +  + ]:        641 :     for (const auto& wallet_file : gArgs.GetArgs("-wallet")) {
#      65                 :        151 :         const fs::path path = fsbridge::AbsPathJoin(GetWalletDir(), wallet_file);
#      66                 :            : 
#      67         [ +  + ]:        151 :         if (!wallet_paths.insert(path).second) {
#      68                 :          3 :             chain.initWarning(strprintf(_("Ignoring duplicate -wallet %s."), wallet_file));
#      69                 :          3 :             continue;
#      70                 :          3 :         }
#      71                 :            : 
#      72                 :        148 :         DatabaseOptions options;
#      73                 :        148 :         DatabaseStatus status;
#      74                 :        148 :         options.require_existing = true;
#      75                 :        148 :         options.verify = true;
#      76                 :        148 :         bilingual_str error_string;
#      77         [ +  + ]:        148 :         if (!MakeWalletDatabase(wallet_file, options, status, error_string)) {
#      78         [ -  + ]:          8 :             if (status == DatabaseStatus::FAILED_NOT_FOUND) {
#      79                 :          0 :                 chain.initWarning(Untranslated(strprintf("Skipping -wallet path that doesn't exist. %s", error_string.original)));
#      80                 :          8 :             } else {
#      81                 :          8 :                 chain.initError(error_string);
#      82                 :          8 :                 return false;
#      83                 :          8 :             }
#      84                 :          8 :         }
#      85                 :        148 :     }
#      86                 :            : 
#      87                 :        641 :     return true;
#      88                 :        641 : }
#      89                 :            : 
#      90                 :            : bool LoadWallets(interfaces::Chain& chain)
#      91                 :        617 : {
#      92                 :        617 :     try {
#      93                 :        617 :         std::set<fs::path> wallet_paths;
#      94         [ +  + ]:        617 :         for (const std::string& name : gArgs.GetArgs("-wallet")) {
#      95         [ +  + ]:        140 :             if (!wallet_paths.insert(name).second) {
#      96                 :          3 :                 continue;
#      97                 :          3 :             }
#      98                 :        137 :             DatabaseOptions options;
#      99                 :        137 :             DatabaseStatus status;
#     100                 :        137 :             options.require_existing = true;
#     101                 :        137 :             options.verify = false; // No need to verify, assuming verified earlier in VerifyWallets()
#     102                 :        137 :             bilingual_str error;
#     103                 :        137 :             std::vector<bilingual_str> warnings;
#     104                 :        137 :             std::unique_ptr<WalletDatabase> database = MakeWalletDatabase(name, options, status, error);
#     105 [ -  + ][ #  # ]:        137 :             if (!database && status == DatabaseStatus::FAILED_NOT_FOUND) {
#     106                 :          0 :                 continue;
#     107                 :          0 :             }
#     108                 :        137 :             chain.initMessage(_("Loading wallet…").translated);
#     109         [ +  - ]:        137 :             std::shared_ptr<CWallet> pwallet = database ? CWallet::Create(&chain, name, std::move(database), options.create_flags, error, warnings) : nullptr;
#     110         [ -  + ]:        137 :             if (!warnings.empty()) chain.initWarning(Join(warnings, Untranslated("\n")));
#     111         [ -  + ]:        137 :             if (!pwallet) {
#     112                 :          0 :                 chain.initError(error);
#     113                 :          0 :                 return false;
#     114                 :          0 :             }
#     115                 :        137 :             AddWallet(pwallet);
#     116                 :        137 :         }
#     117                 :        617 :         return true;
#     118                 :          2 :     } catch (const std::runtime_error& e) {
#     119                 :          2 :         chain.initError(Untranslated(e.what()));
#     120                 :          2 :         return false;
#     121                 :          2 :     }
#     122                 :        617 : }
#     123                 :            : 
#     124                 :            : void StartWallets(CScheduler& scheduler, const ArgsManager& args)
#     125                 :        612 : {
#     126         [ +  + ]:        612 :     for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
#     127                 :        133 :         pwallet->postInitProcess();
#     128                 :        133 :     }
#     129                 :            : 
#     130                 :            :     // Schedule periodic wallet flushes and tx rebroadcasts
#     131         [ +  - ]:        612 :     if (args.GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) {
#     132                 :        612 :         scheduler.scheduleEvery(MaybeCompactWalletDB, std::chrono::milliseconds{500});
#     133                 :        612 :     }
#     134                 :        612 :     scheduler.scheduleEvery(MaybeResendWalletTxs, std::chrono::milliseconds{1000});
#     135                 :        612 : }
#     136                 :            : 
#     137                 :            : void FlushWallets()
#     138                 :        657 : {
#     139         [ +  + ]:        657 :     for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
#     140                 :        577 :         pwallet->Flush();
#     141                 :        577 :     }
#     142                 :        657 : }
#     143                 :            : 
#     144                 :            : void StopWallets()
#     145                 :        657 : {
#     146         [ +  + ]:        657 :     for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
#     147                 :        577 :         pwallet->Close();
#     148                 :        577 :     }
#     149                 :        657 : }
#     150                 :            : 
#     151                 :            : void UnloadWallets()
#     152                 :       1520 : {
#     153                 :       1520 :     auto wallets = GetWallets();
#     154         [ +  + ]:       2097 :     while (!wallets.empty()) {
#     155                 :        577 :         auto wallet = wallets.back();
#     156                 :        577 :         wallets.pop_back();
#     157                 :        577 :         std::vector<bilingual_str> warnings;
#     158                 :        577 :         RemoveWallet(wallet, std::nullopt, warnings);
#     159                 :        577 :         UnloadWallet(std::move(wallet));
#     160                 :        577 :     }
#     161                 :       1520 : }

Generated by: LCOV version 1.14