LCOV - code coverage report
Current view: top level - src/wallet - wallettool.cpp (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 0.0 % 106 0
Test Date: 2026-02-07 04:52:48 Functions: 0.0 % 5 0
Branches: 0.0 % 202 0

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2016-present 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 <wallet/wallettool.h>
       6                 :             : 
       7                 :             : #include <common/args.h>
       8                 :             : #include <util/check.h>
       9                 :             : #include <util/fs.h>
      10                 :             : #include <util/translation.h>
      11                 :             : #include <wallet/dump.h>
      12                 :             : #include <wallet/wallet.h>
      13                 :             : #include <wallet/walletutil.h>
      14                 :             : 
      15                 :             : namespace wallet {
      16                 :             : namespace WalletTool {
      17                 :             : 
      18                 :             : // The standard wallet deleter function blocks on the validation interface
      19                 :             : // queue, which doesn't exist for the bitcoin-wallet. Define our own
      20                 :             : // deleter here.
      21                 :           0 : static void WalletToolReleaseWallet(CWallet* wallet)
      22                 :             : {
      23                 :           0 :     wallet->WalletLogPrintf("Releasing wallet\n");
      24                 :           0 :     wallet->Close();
      25         [ #  # ]:           0 :     delete wallet;
      26                 :           0 : }
      27                 :             : 
      28                 :           0 : static void WalletCreate(CWallet* wallet_instance, uint64_t wallet_creation_flags)
      29                 :             : {
      30                 :           0 :     LOCK(wallet_instance->cs_wallet);
      31                 :             : 
      32         [ #  # ]:           0 :     wallet_instance->InitWalletFlags(wallet_creation_flags);
      33                 :             : 
      34   [ #  #  #  # ]:           0 :     Assert(wallet_instance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
      35         [ #  # ]:           0 :     wallet_instance->SetupDescriptorScriptPubKeyMans();
      36                 :             : 
      37         [ #  # ]:           0 :     tfm::format(std::cout, "Topping up keypool...\n");
      38         [ #  # ]:           0 :     wallet_instance->TopUpKeyPool();
      39                 :           0 : }
      40                 :             : 
      41                 :           0 : static std::shared_ptr<CWallet> MakeWallet(const std::string& name, const fs::path& path, DatabaseOptions options)
      42                 :             : {
      43                 :           0 :     DatabaseStatus status;
      44         [ #  # ]:           0 :     bilingual_str error;
      45                 :           0 :     std::vector<bilingual_str> warnings;
      46         [ #  # ]:           0 :     std::unique_ptr<WalletDatabase> database = MakeDatabase(path, options, status, error);
      47         [ #  # ]:           0 :     if (!database) {
      48         [ #  # ]:           0 :         tfm::format(std::cerr, "%s\n", error.original);
      49                 :           0 :         return nullptr;
      50                 :             :     }
      51                 :             : 
      52                 :             :     // dummy chain interface
      53   [ #  #  #  #  :           0 :     std::shared_ptr<CWallet> wallet_instance{new CWallet(/*chain=*/nullptr, name, std::move(database)), WalletToolReleaseWallet};
             #  #  #  # ]
      54                 :           0 :     DBErrors load_wallet_ret;
      55                 :           0 :     try {
      56         [ #  # ]:           0 :         load_wallet_ret = wallet_instance->PopulateWalletFromDB(error, warnings);
      57         [ -  - ]:           0 :     } catch (const std::runtime_error&) {
      58         [ -  - ]:           0 :         tfm::format(std::cerr, "Error loading %s. Is wallet being used by another process?\n", name);
      59                 :           0 :         return nullptr;
      60                 :           0 :     }
      61                 :             : 
      62         [ #  # ]:           0 :     if (!error.empty()) {
      63         [ #  # ]:           0 :         tfm::format(std::cerr, "%s", error.original);
      64                 :             :     }
      65                 :             : 
      66         [ #  # ]:           0 :     for (const auto &warning : warnings) {
      67         [ #  # ]:           0 :         tfm::format(std::cerr, "%s", warning.original);
      68                 :             :     }
      69                 :             : 
      70   [ #  #  #  # ]:           0 :     if (load_wallet_ret != DBErrors::LOAD_OK && load_wallet_ret != DBErrors::NONCRITICAL_ERROR && load_wallet_ret != DBErrors::NEED_RESCAN) {
      71                 :           0 :         return nullptr;
      72                 :             :     }
      73                 :             : 
      74   [ #  #  #  # ]:           0 :     if (options.require_create) WalletCreate(wallet_instance.get(), options.create_flags);
      75                 :             : 
      76                 :           0 :     return wallet_instance;
      77                 :           0 : }
      78                 :             : 
      79                 :           0 : static void WalletShowInfo(CWallet* wallet_instance)
      80                 :             : {
      81                 :           0 :     LOCK(wallet_instance->cs_wallet);
      82                 :             : 
      83         [ #  # ]:           0 :     tfm::format(std::cout, "Wallet info\n===========\n");
      84         [ #  # ]:           0 :     tfm::format(std::cout, "Name: %s\n", wallet_instance->GetName());
      85   [ #  #  #  # ]:           0 :     tfm::format(std::cout, "Format: %s\n", wallet_instance->GetDatabase().Format());
      86   [ #  #  #  #  :           0 :     tfm::format(std::cout, "Descriptors: %s\n", wallet_instance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS) ? "yes" : "no");
                   #  # ]
      87   [ #  #  #  #  :           0 :     tfm::format(std::cout, "Encrypted: %s\n", wallet_instance->HasEncryptionKeys() ? "yes" : "no");
                   #  # ]
      88   [ #  #  #  #  :           0 :     tfm::format(std::cout, "HD (hd seed available): %s\n", wallet_instance->IsHDEnabled() ? "yes" : "no");
                   #  # ]
      89   [ #  #  #  # ]:           0 :     tfm::format(std::cout, "Keypool Size: %u\n", wallet_instance->GetKeyPoolSize());
      90         [ #  # ]:           0 :     tfm::format(std::cout, "Transactions: %zu\n", wallet_instance->mapWallet.size());
      91         [ #  # ]:           0 :     tfm::format(std::cout, "Address Book: %zu\n", wallet_instance->m_address_book.size());
      92                 :           0 : }
      93                 :             : 
      94                 :           0 : bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command)
      95                 :             : {
      96   [ #  #  #  #  :           0 :     if (args.IsArgSet("-dumpfile") && command != "dump" && command != "createfromdump") {
          #  #  #  #  #  
                      # ]
      97                 :           0 :         tfm::format(std::cerr, "The -dumpfile option can only be used with the \"dump\" and \"createfromdump\" commands.\n");
      98                 :           0 :         return false;
      99                 :             :     }
     100   [ #  #  #  #  :           0 :     if ((command == "create" || command == "createfromdump") && !args.IsArgSet("-wallet")) {
          #  #  #  #  #  
                      # ]
     101                 :           0 :         tfm::format(std::cerr, "Wallet name must be provided when creating a new wallet.\n");
     102                 :           0 :         return false;
     103                 :             :     }
     104   [ #  #  #  # ]:           0 :     const std::string name = args.GetArg("-wallet", "");
     105   [ #  #  #  #  :           0 :     const fs::path path = fsbridge::AbsPathJoin(GetWalletDir(), fs::PathFromString(name));
                   #  # ]
     106                 :             : 
     107         [ #  # ]:           0 :     if (command == "create") {
     108         [ #  # ]:           0 :         if (name.empty()) {
     109         [ #  # ]:           0 :             tfm::format(std::cerr, "Wallet name cannot be empty\n");
     110                 :             :             return false;
     111                 :             :         }
     112         [ #  # ]:           0 :         DatabaseOptions options;
     113         [ #  # ]:           0 :         ReadDatabaseArgs(args, options);
     114                 :           0 :         options.require_create = true;
     115                 :           0 :         options.create_flags |= WALLET_FLAG_DESCRIPTORS;
     116                 :           0 :         options.require_format = DatabaseFormat::SQLITE;
     117                 :             : 
     118   [ #  #  #  # ]:           0 :         const std::shared_ptr<CWallet> wallet_instance = MakeWallet(name, path, options);
     119         [ #  # ]:           0 :         if (wallet_instance) {
     120         [ #  # ]:           0 :             WalletShowInfo(wallet_instance.get());
     121         [ #  # ]:           0 :             wallet_instance->Close();
     122                 :             :         }
     123         [ #  # ]:           0 :     } else if (command == "info") {
     124         [ #  # ]:           0 :         DatabaseOptions options;
     125         [ #  # ]:           0 :         ReadDatabaseArgs(args, options);
     126                 :           0 :         options.require_existing = true;
     127   [ #  #  #  # ]:           0 :         const std::shared_ptr<CWallet> wallet_instance = MakeWallet(name, path, options);
     128   [ #  #  #  # ]:           0 :         if (!wallet_instance) return false;
     129         [ #  # ]:           0 :         WalletShowInfo(wallet_instance.get());
     130         [ #  # ]:           0 :         wallet_instance->Close();
     131         [ #  # ]:           0 :     } else if (command == "dump") {
     132         [ #  # ]:           0 :         DatabaseOptions options;
     133         [ #  # ]:           0 :         ReadDatabaseArgs(args, options);
     134                 :           0 :         options.require_existing = true;
     135                 :           0 :         DatabaseStatus status;
     136                 :             : 
     137   [ #  #  #  #  :           0 :         if (IsBDBFile(BDBDataFile(path))) {
                   #  # ]
     138                 :           0 :             options.require_format = DatabaseFormat::BERKELEY_RO;
     139                 :             :         }
     140                 :             : 
     141         [ #  # ]:           0 :         bilingual_str error;
     142         [ #  # ]:           0 :         std::unique_ptr<WalletDatabase> database = MakeDatabase(path, options, status, error);
     143         [ #  # ]:           0 :         if (!database) {
     144         [ #  # ]:           0 :             tfm::format(std::cerr, "%s\n", error.original);
     145                 :             :             return false;
     146                 :             :         }
     147                 :             : 
     148         [ #  # ]:           0 :         bool ret = DumpWallet(args, *database, error);
     149   [ #  #  #  # ]:           0 :         if (!ret && !error.empty()) {
     150         [ #  # ]:           0 :             tfm::format(std::cerr, "%s\n", error.original);
     151                 :             :             return ret;
     152                 :             :         }
     153         [ #  # ]:           0 :         tfm::format(std::cout, "The dumpfile may contain private keys. To ensure the safety of your Bitcoin, do not share the dumpfile.\n");
     154                 :             :         return ret;
     155         [ #  # ]:           0 :     } else if (command == "createfromdump") {
     156         [ #  # ]:           0 :         bilingual_str error;
     157                 :           0 :         std::vector<bilingual_str> warnings;
     158         [ #  # ]:           0 :         bool ret = CreateFromDump(args, name, path, error, warnings);
     159         [ #  # ]:           0 :         for (const auto& warning : warnings) {
     160         [ #  # ]:           0 :             tfm::format(std::cout, "%s\n", warning.original);
     161                 :             :         }
     162   [ #  #  #  # ]:           0 :         if (!ret && !error.empty()) {
     163         [ #  # ]:           0 :             tfm::format(std::cerr, "%s\n", error.original);
     164                 :             :         }
     165                 :           0 :         return ret;
     166                 :           0 :     } else {
     167         [ #  # ]:           0 :         tfm::format(std::cerr, "Invalid command: %s\n", command);
     168                 :             :         return false;
     169                 :             :     }
     170                 :             : 
     171                 :             :     return true;
     172                 :           0 : }
     173                 :             : } // namespace WalletTool
     174                 :             : } // namespace wallet
        

Generated by: LCOV version 2.0-1