LCOV - code coverage report
Current view: top level - src/wallet - wallettool.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 66 87 75.9 %
Date: 2020-09-26 01:30:44 Functions: 5 5 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2016-2020 The Bitcoin Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #include <fs.h>
       6             : #include <util/system.h>
       7             : #include <util/translation.h>
       8             : #include <wallet/salvage.h>
       9             : #include <wallet/wallet.h>
      10             : #include <wallet/walletutil.h>
      11             : 
      12             : namespace WalletTool {
      13             : 
      14             : // The standard wallet deleter function blocks on the validation interface
      15             : // queue, which doesn't exist for the bitcoin-wallet. Define our own
      16             : // deleter here.
      17           3 : static void WalletToolReleaseWallet(CWallet* wallet)
      18             : {
      19           3 :     wallet->WalletLogPrintf("Releasing wallet\n");
      20           3 :     wallet->Close();
      21           3 :     delete wallet;
      22           3 : }
      23             : 
      24           1 : static void WalletCreate(CWallet* wallet_instance)
      25             : {
      26           1 :     LOCK(wallet_instance->cs_wallet);
      27             : 
      28           1 :     wallet_instance->SetMinVersion(FEATURE_HD_SPLIT);
      29             : 
      30             :     // generate a new HD seed
      31           1 :     auto spk_man = wallet_instance->GetOrCreateLegacyScriptPubKeyMan();
      32           1 :     CPubKey seed = spk_man->GenerateNewSeed();
      33           1 :     spk_man->SetHDSeed(seed);
      34             : 
      35           1 :     tfm::format(std::cout, "Topping up keypool...\n");
      36           1 :     wallet_instance->TopUpKeyPool();
      37           1 : }
      38             : 
      39           5 : static std::shared_ptr<CWallet> MakeWallet(const std::string& name, const fs::path& path, bool create)
      40             : {
      41           5 :     DatabaseOptions options;
      42           5 :     DatabaseStatus status;
      43           5 :     if (create) {
      44           1 :         options.require_create = true;
      45           1 :     } else {
      46           4 :         options.require_existing = true;
      47             :     }
      48           5 :     bilingual_str error;
      49           5 :     std::unique_ptr<WalletDatabase> database = MakeDatabase(path, options, status, error);
      50           5 :     if (!database) {
      51           2 :         tfm::format(std::cerr, "%s\n", error.original);
      52           2 :         return nullptr;
      53             :     }
      54             : 
      55             :     // dummy chain interface
      56           3 :     std::shared_ptr<CWallet> wallet_instance{new CWallet(nullptr /* chain */, name, std::move(database)), WalletToolReleaseWallet};
      57             :     DBErrors load_wallet_ret;
      58             :     try {
      59           3 :         bool first_run;
      60           3 :         load_wallet_ret = wallet_instance->LoadWallet(first_run);
      61           3 :     } catch (const std::runtime_error&) {
      62           0 :         tfm::format(std::cerr, "Error loading %s. Is wallet being used by another process?\n", name);
      63           0 :         return nullptr;
      64           0 :     }
      65             : 
      66           3 :     if (load_wallet_ret != DBErrors::LOAD_OK) {
      67           0 :         wallet_instance = nullptr;
      68           0 :         if (load_wallet_ret == DBErrors::CORRUPT) {
      69           0 :             tfm::format(std::cerr, "Error loading %s: Wallet corrupted", name);
      70           0 :             return nullptr;
      71           0 :         } else if (load_wallet_ret == DBErrors::NONCRITICAL_ERROR) {
      72           0 :             tfm::format(std::cerr, "Error reading %s! All keys read correctly, but transaction data"
      73             :                             " or address book entries might be missing or incorrect.",
      74             :                 name);
      75           0 :         } else if (load_wallet_ret == DBErrors::TOO_NEW) {
      76           0 :             tfm::format(std::cerr, "Error loading %s: Wallet requires newer version of %s",
      77             :                 name, PACKAGE_NAME);
      78           0 :             return nullptr;
      79           0 :         } else if (load_wallet_ret == DBErrors::NEED_REWRITE) {
      80           0 :             tfm::format(std::cerr, "Wallet needed to be rewritten: restart %s to complete", PACKAGE_NAME);
      81           0 :             return nullptr;
      82             :         } else {
      83           0 :             tfm::format(std::cerr, "Error loading %s", name);
      84           0 :             return nullptr;
      85             :         }
      86             :     }
      87             : 
      88           3 :     if (create) WalletCreate(wallet_instance.get());
      89             : 
      90           3 :     return wallet_instance;
      91           5 : }
      92             : 
      93           3 : static void WalletShowInfo(CWallet* wallet_instance)
      94             : {
      95           3 :     LOCK(wallet_instance->cs_wallet);
      96             : 
      97           3 :     tfm::format(std::cout, "Wallet info\n===========\n");
      98           3 :     tfm::format(std::cout, "Encrypted: %s\n", wallet_instance->IsCrypted() ? "yes" : "no");
      99           3 :     tfm::format(std::cout, "HD (hd seed available): %s\n", wallet_instance->IsHDEnabled() ? "yes" : "no");
     100           3 :     tfm::format(std::cout, "Keypool Size: %u\n", wallet_instance->GetKeyPoolSize());
     101           3 :     tfm::format(std::cout, "Transactions: %zu\n", wallet_instance->mapWallet.size());
     102           3 :     tfm::format(std::cout, "Address Book: %zu\n", wallet_instance->m_address_book.size());
     103           3 : }
     104             : 
     105           8 : bool ExecuteWalletToolFunc(const std::string& command, const std::string& name)
     106             : {
     107           8 :     fs::path path = fs::absolute(name, GetWalletDir());
     108             : 
     109           8 :     if (command == "create") {
     110           1 :         std::shared_ptr<CWallet> wallet_instance = MakeWallet(name, path, /* create= */ true);
     111           1 :         if (wallet_instance) {
     112           1 :             WalletShowInfo(wallet_instance.get());
     113           1 :             wallet_instance->Close();
     114             :         }
     115           8 :     } else if (command == "info" || command == "salvage") {
     116           5 :         if (command == "info") {
     117           4 :             std::shared_ptr<CWallet> wallet_instance = MakeWallet(name, path, /* create= */ false);
     118           4 :             if (!wallet_instance) return false;
     119           2 :             WalletShowInfo(wallet_instance.get());
     120           2 :             wallet_instance->Close();
     121           5 :         } else if (command == "salvage") {
     122           1 :             bilingual_str error;
     123           1 :             std::vector<bilingual_str> warnings;
     124           1 :             bool ret = RecoverDatabaseFile(path, error, warnings);
     125           1 :             if (!ret) {
     126           0 :                 for (const auto& warning : warnings) {
     127           0 :                     tfm::format(std::cerr, "%s\n", warning.original);
     128             :                 }
     129           0 :                 if (!error.empty()) {
     130           0 :                     tfm::format(std::cerr, "%s\n", error.original);
     131             :                 }
     132             :             }
     133             :             return ret;
     134           1 :         }
     135             :     } else {
     136           2 :         tfm::format(std::cerr, "Invalid command: %s\n", command);
     137           2 :         return false;
     138             :     }
     139             : 
     140           3 :     return true;
     141           8 : }
     142             : } // namespace WalletTool

Generated by: LCOV version 1.15