LCOV - code coverage report
Current view: top level - src/wallet/test - util.cpp (source / functions) Coverage Total Hit
Test: total_coverage.info Lines: 80.7 % 109 88
Test Date: 2026-04-27 06:58:15 Functions: 75.0 % 12 9
Branches: 43.9 % 164 72

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2021-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/test/util.h>
       6                 :             : 
       7                 :             : #include <chain.h>
       8                 :             : #include <key.h>
       9                 :             : #include <key_io.h>
      10                 :             : #include <streams.h>
      11                 :             : #include <test/util/setup_common.h>
      12                 :             : #include <validationinterface.h>
      13                 :             : #include <wallet/context.h>
      14                 :             : #include <wallet/wallet.h>
      15                 :             : #include <wallet/walletdb.h>
      16                 :             : 
      17                 :             : #include <sqlite3.h>
      18                 :             : 
      19                 :             : #include <memory>
      20                 :             : 
      21                 :             : namespace wallet {
      22                 :           4 : std::unique_ptr<CWallet> CreateSyncedWallet(interfaces::Chain& chain, CChain& cchain, const CKey& key)
      23                 :             : {
      24         [ +  - ]:           4 :     auto wallet = std::make_unique<CWallet>(&chain, "", CreateMockableWalletDatabase());
      25                 :           4 :     {
      26   [ +  -  +  - ]:           4 :         LOCK2(wallet->cs_wallet, ::cs_main);
      27   [ -  +  +  - ]:           8 :         wallet->SetLastBlockProcessed(cchain.Height(), cchain.Tip()->GetBlockHash());
      28         [ +  - ]:           4 :     }
      29                 :           4 :     {
      30         [ +  - ]:           4 :         LOCK(wallet->cs_wallet);
      31         [ +  - ]:           4 :         wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
      32         [ +  - ]:           4 :         wallet->SetupDescriptorScriptPubKeyMans();
      33                 :             : 
      34                 :           4 :         FlatSigningProvider provider;
      35         [ +  - ]:           4 :         std::string error;
      36   [ +  -  +  -  :          12 :         auto descs = Parse("combo(" + EncodeSecret(key) + ")", provider, error, /* require_checksum=*/ false);
             -  +  +  - ]
      37   [ -  +  -  + ]:           4 :         assert(descs.size() == 1);
      38         [ +  - ]:           4 :         auto& desc = descs.at(0);
      39   [ +  -  +  - ]:           4 :         WalletDescriptor w_desc(std::move(desc), 0, 0, 1, 1);
      40   [ +  -  +  - ]:           8 :         Assert(wallet->AddWalletDescriptor(w_desc, provider, "", false));
      41         [ +  - ]:           4 :     }
      42                 :           4 :     WalletRescanReserver reserver(*wallet);
      43                 :           4 :     reserver.reserve();
      44   [ -  +  +  - ]:           8 :     CWallet::ScanResult result = wallet->ScanForWalletTransactions(cchain.Genesis()->GetBlockHash(), /*start_height=*/0, /*max_height=*/{}, reserver, /*fUpdate=*/false, /*save_progress=*/false);
      45         [ -  + ]:           4 :     assert(result.status == CWallet::ScanResult::SUCCESS);
      46   [ -  +  -  + ]:           8 :     assert(result.last_scanned_block == cchain.Tip()->GetBlockHash());
      47   [ -  +  -  + ]:           4 :     assert(*result.last_scanned_height == cchain.Height());
      48         [ -  + ]:           4 :     assert(result.last_failed_block.IsNull());
      49                 :           4 :     return wallet;
      50                 :           4 : }
      51                 :             : 
      52                 :           3 : std::shared_ptr<CWallet> TestCreateWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, uint64_t create_flags)
      53                 :             : {
      54         [ +  - ]:           3 :     bilingual_str _error;
      55                 :           3 :     std::vector<bilingual_str> _warnings;
      56   [ +  -  +  - ]:           6 :     auto wallet = CWallet::CreateNew(context, "", std::move(database), create_flags, _error, _warnings);
      57         [ +  - ]:           3 :     NotifyWalletLoaded(context, wallet);
      58         [ +  + ]:           3 :     if (context.chain) {
      59         [ +  - ]:           2 :         wallet->postInitProcess();
      60                 :             :     }
      61                 :           6 :     return wallet;
      62                 :           6 : }
      63                 :             : 
      64                 :           3 : std::shared_ptr<CWallet> TestCreateWallet(WalletContext& context)
      65                 :             : {
      66         [ +  - ]:           3 :     DatabaseOptions options;
      67                 :           3 :     options.require_create = true;
      68                 :           3 :     options.create_flags = WALLET_FLAG_DESCRIPTORS;
      69                 :           3 :     DatabaseStatus status;
      70         [ +  - ]:           3 :     bilingual_str error;
      71                 :           3 :     std::vector<bilingual_str> warnings;
      72   [ +  -  +  - ]:           3 :     auto database = MakeWalletDatabase("", options, status, error);
      73         [ +  - ]:           3 :     return TestCreateWallet(std::move(database), context, options.create_flags);
      74                 :           6 : }
      75                 :             : 
      76                 :             : 
      77                 :           2 : std::shared_ptr<CWallet> TestLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context)
      78                 :             : {
      79         [ +  - ]:           2 :     bilingual_str error;
      80                 :           2 :     std::vector<bilingual_str> warnings;
      81   [ +  -  +  - ]:           4 :     auto wallet = CWallet::LoadExisting(context, "", std::move(database), error, warnings);
      82         [ +  - ]:           2 :     NotifyWalletLoaded(context, wallet);
      83         [ +  - ]:           2 :     if (context.chain) {
      84         [ +  - ]:           2 :         wallet->postInitProcess();
      85                 :             :     }
      86                 :           4 :     return wallet;
      87                 :           4 : }
      88                 :             : 
      89                 :           2 : std::shared_ptr<CWallet> TestLoadWallet(WalletContext& context)
      90                 :             : {
      91         [ +  - ]:           2 :     DatabaseOptions options;
      92                 :           2 :     options.require_existing = true;
      93                 :           2 :     DatabaseStatus status;
      94         [ +  - ]:           2 :     bilingual_str error;
      95                 :           2 :     std::vector<bilingual_str> warnings;
      96   [ +  -  +  - ]:           2 :     auto database = MakeWalletDatabase("", options, status, error);
      97         [ +  - ]:           2 :     return TestLoadWallet(std::move(database), context);
      98                 :           4 : }
      99                 :             : 
     100                 :           4 : void TestUnloadWallet(std::shared_ptr<CWallet>&& wallet)
     101                 :             : {
     102                 :             :     // Calls SyncWithValidationInterfaceQueue
     103                 :           4 :     wallet->chain().waitForNotificationsIfTipChanged({});
     104         [ +  - ]:           4 :     wallet->m_chain_notifications_handler.reset();
     105                 :           4 :     WaitForDeleteWallet(std::move(wallet));
     106                 :           4 : }
     107                 :             : 
     108                 :           0 : std::unique_ptr<WalletDatabase> DuplicateMockDatabase(WalletDatabase& database)
     109                 :             : {
     110                 :           0 :     std::unique_ptr<DatabaseBatch> batch_orig = database.MakeBatch();
     111         [ #  # ]:           0 :     std::unique_ptr<DatabaseCursor> cursor_orig = batch_orig->GetNewCursor();
     112                 :             : 
     113         [ #  # ]:           0 :     std::unique_ptr<WalletDatabase> new_db = CreateMockableWalletDatabase();
     114         [ #  # ]:           0 :     std::unique_ptr<DatabaseBatch> new_db_batch = new_db->MakeBatch();
     115         [ #  # ]:           0 :     MockableSQLiteBatch* batch_new = dynamic_cast<MockableSQLiteBatch*>(new_db_batch.get());
     116         [ #  # ]:           0 :     Assert(batch_new);
     117                 :             : 
     118                 :           0 :     while (true) {
     119                 :           0 :         DataStream key, value;
     120         [ #  # ]:           0 :         DatabaseCursor::Status status = cursor_orig->Next(key, value);
     121         [ #  # ]:           0 :         Assert(status != DatabaseCursor::Status::FAIL);
     122         [ #  # ]:           0 :         if (status != DatabaseCursor::Status::MORE) break;
     123         [ #  # ]:           0 :         batch_new->WriteKey(std::move(key), std::move(value));
     124                 :           0 :     }
     125                 :             : 
     126                 :           0 :     return new_db;
     127                 :           0 : }
     128                 :             : 
     129                 :           0 : std::string getnewaddress(CWallet& w)
     130                 :             : {
     131                 :           0 :     constexpr auto output_type = OutputType::BECH32;
     132         [ #  # ]:           0 :     return EncodeDestination(getNewDestination(w, output_type));
     133                 :             : }
     134                 :             : 
     135                 :           0 : CTxDestination getNewDestination(CWallet& w, OutputType output_type)
     136                 :             : {
     137   [ #  #  #  # ]:           0 :     return *Assert(w.GetNewDestination(output_type, ""));
     138                 :             : }
     139                 :             : 
     140                 :          75 : MockableSQLiteDatabase::MockableSQLiteDatabase()
     141   [ +  -  +  -  :         225 :     : SQLiteDatabase(fs::PathFromString("mock/"), fs::PathFromString("mock/wallet.dat"), DatabaseOptions(), SQLITE_OPEN_MEMORY)
          +  -  +  -  +  
                      - ]
     142                 :          75 : {}
     143                 :             : 
     144                 :          75 : std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase()
     145                 :             : {
     146                 :          75 :     return std::make_unique<MockableSQLiteDatabase>();
     147                 :             : }
     148                 :             : 
     149                 :          20 : wallet::DescriptorScriptPubKeyMan* CreateDescriptor(CWallet& keystore, const std::string& desc_str, const bool success)
     150                 :             : {
     151                 :          20 :     keystore.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
     152                 :             : 
     153                 :          20 :     FlatSigningProvider keys;
     154         [ -  + ]:          20 :     std::string error;
     155   [ -  +  +  - ]:          20 :     auto parsed_descs = Parse(desc_str, keys, error, false);
     156         [ -  + ]:          20 :     Assert(success == (!parsed_descs.empty()));
     157         [ +  + ]:          20 :     if (!success) return nullptr;
     158         [ +  - ]:          14 :     auto& desc = parsed_descs.at(0);
     159                 :             : 
     160                 :          14 :     const int64_t range_start = 0, range_end = 1, next_index = 0, timestamp = 1;
     161                 :             : 
     162   [ +  -  +  - ]:          14 :     WalletDescriptor w_desc(std::move(desc), timestamp, range_start, range_end, next_index);
     163                 :             : 
     164         [ +  - ]:          14 :     LOCK(keystore.cs_wallet);
     165   [ +  -  +  - ]:          28 :     auto spkm = Assert(keystore.AddWalletDescriptor(w_desc, keys,/*label=*/"", /*internal=*/false));
     166                 :          14 :     return &spkm.value().get();
     167         [ +  - ]:          34 : };
     168                 :             : } // namespace wallet
        

Generated by: LCOV version 2.0-1