Coverage Report

Created: 2026-10-07 13:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/tmp/bitcoin/src/wallet/test/util.cpp
Line
Count
Source
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 <test/util/setup_common.h>
11
#include <validationinterface.h>
12
#include <wallet/context.h>
13
#include <wallet/scan.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
std::unique_ptr<CWallet> CreateSyncedWallet(interfaces::Chain& chain, CChain& cchain, const CKey& key)
23
4
{
24
4
    auto wallet = std::make_unique<CWallet>(&chain, "", CreateMockableWalletDatabase());
25
4
    {
26
4
        LOCK2(wallet->cs_wallet, ::cs_main);
27
4
        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
4
    }
34
4
    AddKey(*wallet, key);
35
4
    WalletRescanReserver reserver(*wallet);
36
4
    reserver.reserve();
37
4
    ScanResult result = wallet->Scanner().Scan(cchain.Genesis()->GetBlockHash(), /*start_height=*/0, /*max_height=*/{}, reserver, /*save_progress=*/false);
38
4
    assert(result.status == ScanResult::SUCCESS);
39
4
    assert(result.last_scanned_block == cchain.Tip()->GetBlockHash());
40
4
    assert(*result.last_scanned_height == cchain.Height());
41
4
    assert(result.last_failed_block.IsNull());
42
4
    return wallet;
43
4
}
44
45
void AddKey(CWallet& wallet, const CKey& key)
46
25
{
47
25
    LOCK(wallet.cs_wallet);
48
25
    FlatSigningProvider provider;
49
25
    std::string error;
50
25
    auto descs = Parse("combo(" + EncodeSecret(key) + ")", provider, error, /* require_checksum=*/ false);
51
25
    assert(descs.size() == 1);
52
25
    auto& desc = descs.at(0);
53
25
    WalletDescriptor w_desc(std::move(desc), /*creation_time=*/0, /*range_start=*/0, /*range_end=*/1, /*next_index=*/1);
54
25
    Assert(wallet.AddWalletDescriptor(w_desc, provider, /*label=*/"", /*internal=*/false));
55
25
}
56
57
std::shared_ptr<CWallet> TestCreateWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, uint64_t create_flags)
58
20
{
59
20
    bilingual_str _error;
60
20
    std::vector<bilingual_str> _warnings;
61
20
    auto wallet = CWallet::CreateNew(context, "", std::move(database), create_flags, /*born_encrypted=*/false, _error, _warnings);
62
20
    NotifyWalletLoaded(context, wallet);
63
20
    if (context.chain) {
64
15
        wallet->postInitProcess();
65
15
    }
66
20
    return wallet;
67
20
}
68
69
std::shared_ptr<CWallet> TestCreateWallet(WalletContext& context)
70
8
{
71
8
    DatabaseOptions options;
72
8
    options.require_create = true;
73
8
    options.create_flags = WALLET_FLAG_DESCRIPTORS;
74
8
    DatabaseStatus status;
75
8
    bilingual_str error;
76
8
    auto database = MakeWalletDatabase("", options, status, error);
77
8
    return TestCreateWallet(std::move(database), context, options.create_flags);
78
8
}
79
80
81
std::shared_ptr<CWallet> TestLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context)
82
3
{
83
3
    bilingual_str error;
84
3
    std::vector<bilingual_str> warnings;
85
3
    auto wallet = CWallet::LoadExisting(context, "", std::move(database), error, warnings);
86
3
    NotifyWalletLoaded(context, wallet);
87
3
    if (context.chain) {
88
3
        wallet->postInitProcess();
89
3
    }
90
3
    return wallet;
91
3
}
92
93
std::shared_ptr<CWallet> TestLoadWallet(WalletContext& context)
94
3
{
95
3
    DatabaseOptions options;
96
3
    options.require_existing = true;
97
3
    DatabaseStatus status;
98
3
    bilingual_str error;
99
3
    auto database = MakeWalletDatabase("", options, status, error);
100
3
    return TestLoadWallet(std::move(database), context);
101
3
}
102
103
void TestUnloadWallet(std::shared_ptr<CWallet>&& wallet)
104
18
{
105
    // Calls SyncWithValidationInterfaceQueue
106
18
    wallet->chain().waitForNotificationsIfTipChanged({});
107
18
    wallet->m_chain_notifications_handler.reset();
108
18
    WaitForDeleteWallet(std::move(wallet));
109
18
}
110
111
std::string getnewaddress(CWallet& w)
112
0
{
113
0
    constexpr auto output_type = OutputType::BECH32;
114
0
    return EncodeDestination(getNewDestination(w, output_type));
115
0
}
116
117
CTxDestination getNewDestination(CWallet& w, OutputType output_type)
118
0
{
119
0
    return *Assert(w.GetNewDestination(output_type, ""));
120
0
}
121
122
MockableSQLiteDatabase::MockableSQLiteDatabase()
123
103
    : InMemoryWalletDatabase()
124
103
{}
125
126
std::unique_ptr<WalletDatabase> CreateMockableWalletDatabase()
127
91
{
128
91
    return std::make_unique<MockableSQLiteDatabase>();
129
91
}
130
131
wallet::DescriptorScriptPubKeyMan* CreateDescriptor(CWallet& keystore, const std::string& desc_str, const bool success)
132
25
{
133
25
    keystore.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
134
135
25
    FlatSigningProvider keys;
136
25
    std::string error;
137
25
    auto parsed_descs = Parse(desc_str, keys, error, false);
138
25
    Assert(success == (!parsed_descs.empty()));
139
25
    if (!success) return nullptr;
140
19
    auto& desc = parsed_descs.at(0);
141
142
19
    const int64_t range_start = 0, range_end = 1, next_index = 0, timestamp = 1;
143
144
19
    WalletDescriptor w_desc(std::move(desc), timestamp, range_start, range_end, next_index);
145
146
19
    LOCK(keystore.cs_wallet);
147
19
    auto spkm = Assert(keystore.AddWalletDescriptor(w_desc, keys,/*label=*/"", /*internal=*/false));
148
19
    return &spkm.value().get();
149
25
};
150
} // namespace wallet