Coverage Report

Created: 2026-04-29 19:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/tmp/bitcoin/src/wallet/db.h
Line
Count
Source
1
// Copyright (c) 2009-2010 Satoshi Nakamoto
2
// Copyright (c) 2009-present 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
#ifndef BITCOIN_WALLET_DB_H
7
#define BITCOIN_WALLET_DB_H
8
9
#include <clientversion.h>
10
#include <streams.h>
11
#include <support/allocators/secure.h>
12
#include <util/fs.h>
13
14
#include <atomic>
15
#include <memory>
16
#include <optional>
17
#include <string>
18
19
class ArgsManager;
20
struct bilingual_str;
21
22
namespace wallet {
23
// BytePrefix compares equality with other byte spans that begin with the same prefix.
24
struct BytePrefix {
25
    std::span<const std::byte> prefix;
26
};
27
bool operator<(BytePrefix a, std::span<const std::byte> b);
28
bool operator<(std::span<const std::byte> a, BytePrefix b);
29
30
class DatabaseCursor
31
{
32
public:
33
17.3k
    explicit DatabaseCursor() = default;
34
17.3k
    virtual ~DatabaseCursor() = default;
35
36
    DatabaseCursor(const DatabaseCursor&) = delete;
37
    DatabaseCursor& operator=(const DatabaseCursor&) = delete;
38
39
    enum class Status
40
    {
41
        FAIL,
42
        MORE,
43
        DONE,
44
    };
45
46
0
    virtual Status Next(DataStream& key, DataStream& value) { return Status::FAIL; }
47
};
48
49
/** RAII class that provides access to a WalletDatabase */
50
class DatabaseBatch
51
{
52
private:
53
    virtual bool ReadKey(DataStream&& key, DataStream& value) = 0;
54
    virtual bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite = true) = 0;
55
    virtual bool EraseKey(DataStream&& key) = 0;
56
    virtual bool HasKey(DataStream&& key) = 0;
57
58
public:
59
167k
    explicit DatabaseBatch() = default;
60
167k
    virtual ~DatabaseBatch() = default;
61
62
    DatabaseBatch(const DatabaseBatch&) = delete;
63
    DatabaseBatch& operator=(const DatabaseBatch&) = delete;
64
65
    virtual void Close() = 0;
66
67
    template <typename K, typename T>
68
    bool Read(const K& key, T& value)
69
4.33k
    {
70
4.33k
        DataStream ssKey{};
71
4.33k
        ssKey.reserve(1000);
72
4.33k
        ssKey << key;
73
74
4.33k
        DataStream ssValue{};
75
4.33k
        if (!ReadKey(std::move(ssKey), ssValue)) return false;
76
4.31k
        try {
77
4.31k
            ssValue >> value;
78
4.31k
            return true;
79
4.31k
        } catch (const std::exception&) {
80
0
            return false;
81
0
        }
82
4.31k
    }
bool wallet::DatabaseBatch::Read<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&)
Line
Count
Source
69
4
    {
70
4
        DataStream ssKey{};
71
4
        ssKey.reserve(1000);
72
4
        ssKey << key;
73
74
4
        DataStream ssValue{};
75
4
        if (!ReadKey(std::move(ssKey), ssValue)) return false;
76
4
        try {
77
4
            ssValue >> value;
78
4
            return true;
79
4
        } catch (const std::exception&) {
80
0
            return false;
81
0
        }
82
4
    }
bool wallet::DatabaseBatch::Read<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned long>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, unsigned long&)
Line
Count
Source
69
360
    {
70
360
        DataStream ssKey{};
71
360
        ssKey.reserve(1000);
72
360
        ssKey << key;
73
74
360
        DataStream ssValue{};
75
360
        if (!ReadKey(std::move(ssKey), ssValue)) return false;
76
354
        try {
77
354
            ssValue >> value;
78
354
            return true;
79
354
        } catch (const std::exception&) {
80
0
            return false;
81
0
        }
82
354
    }
Unexecuted instantiation: bool wallet::DatabaseBatch::Read<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CPubKey>, std::vector<unsigned char, std::allocator<unsigned char>>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CPubKey> const&, std::vector<unsigned char, std::allocator<unsigned char>>&)
bool wallet::DatabaseBatch::Read<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CBlockLocator>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, CBlockLocator&)
Line
Count
Source
69
3.61k
    {
70
3.61k
        DataStream ssKey{};
71
3.61k
        ssKey.reserve(1000);
72
3.61k
        ssKey << key;
73
74
3.61k
        DataStream ssValue{};
75
3.61k
        if (!ReadKey(std::move(ssKey), ssValue)) return false;
76
3.60k
        try {
77
3.60k
            ssValue >> value;
78
3.60k
            return true;
79
3.60k
        } catch (const std::exception&) {
80
0
            return false;
81
0
        }
82
3.60k
    }
bool wallet::DatabaseBatch::Read<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, int&)
Line
Count
Source
69
360
    {
70
360
        DataStream ssKey{};
71
360
        ssKey.reserve(1000);
72
360
        ssKey << key;
73
74
360
        DataStream ssValue{};
75
360
        if (!ReadKey(std::move(ssKey), ssValue)) return false;
76
353
        try {
77
353
            ssValue >> value;
78
353
            return true;
79
353
        } catch (const std::exception&) {
80
0
            return false;
81
0
        }
82
353
    }
83
84
    template <typename K, typename T>
85
    bool Write(const K& key, const T& value, bool fOverwrite = true)
86
260k
    {
87
260k
        DataStream ssKey{};
88
260k
        ssKey.reserve(1000);
89
260k
        ssKey << key;
90
91
260k
        DataStream ssValue{};
92
260k
        ssValue.reserve(10000);
93
260k
        ssValue << value;
94
95
260k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
260k
    }
bool wallet::DatabaseBatch::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, int const&, bool)
Line
Count
Source
86
695
    {
87
695
        DataStream ssKey{};
88
695
        ssKey.reserve(1000);
89
695
        ssKey << key;
90
91
695
        DataStream ssValue{};
92
695
        ssValue.reserve(10000);
93
695
        ssValue << value;
94
95
695
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
695
    }
bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned int>, unsigned int>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned int> const&, unsigned int const&, bool)
Line
Count
Source
86
120
    {
87
120
        DataStream ssKey{};
88
120
        ssKey.reserve(1000);
89
120
        ssKey << key;
90
91
120
        DataStream ssValue{};
92
120
        ssValue.reserve(10000);
93
120
        ssValue << value;
94
95
120
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
120
    }
bool wallet::DatabaseBatch::Write<std::span<std::byte const, 18446744073709551615ul>, std::span<std::byte const, 18446744073709551615ul>>(std::span<std::byte const, 18446744073709551615ul> const&, std::span<std::byte const, 18446744073709551615ul> const&, bool)
Line
Count
Source
86
1.19k
    {
87
1.19k
        DataStream ssKey{};
88
1.19k
        ssKey.reserve(1000);
89
1.19k
        ssKey << key;
90
91
1.19k
        DataStream ssValue{};
92
1.19k
        ssValue.reserve(10000);
93
1.19k
        ssValue << value;
94
95
1.19k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
1.19k
    }
bool wallet::DatabaseBatch::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool)
Line
Count
Source
86
10
    {
87
10
        DataStream ssKey{};
88
10
        ssKey.reserve(1000);
89
10
        ssKey << key;
90
91
10
        DataStream ssValue{};
92
10
        ssValue.reserve(10000);
93
10
        ssValue << value;
94
95
10
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
10
    }
bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool)
Line
Count
Source
86
56.1k
    {
87
56.1k
        DataStream ssKey{};
88
56.1k
        ssKey.reserve(1000);
89
56.1k
        ssKey << key;
90
91
56.1k
        DataStream ssValue{};
92
56.1k
        ssValue.reserve(10000);
93
56.1k
        ssValue << value;
94
95
56.1k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
56.1k
    }
bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, transaction_identifier<false>>, wallet::CWalletTx>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, transaction_identifier<false>> const&, wallet::CWalletTx const&, bool)
Line
Count
Source
86
23.2k
    {
87
23.2k
        DataStream ssKey{};
88
23.2k
        ssKey.reserve(1000);
89
23.2k
        ssKey << key;
90
91
23.2k
        DataStream ssValue{};
92
23.2k
        ssValue.reserve(10000);
93
23.2k
        ssValue << value;
94
95
23.2k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
23.2k
    }
Unexecuted instantiation: bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CPubKey>, wallet::CKeyMetadata>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CPubKey> const&, wallet::CKeyMetadata const&, bool)
Unexecuted instantiation: bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CPubKey>, std::pair<std::vector<unsigned char, secure_allocator<unsigned char>>, uint256>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CPubKey> const&, std::pair<std::vector<unsigned char, secure_allocator<unsigned char>>, uint256> const&, bool)
Unexecuted instantiation: bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CPubKey>, std::pair<std::vector<unsigned char, std::allocator<unsigned char>>, uint256>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CPubKey> const&, std::pair<std::vector<unsigned char, std::allocator<unsigned char>>, uint256> const&, bool)
bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned int>, wallet::CMasterKey>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned int> const&, wallet::CMasterKey const&, bool)
Line
Count
Source
86
26
    {
87
26
        DataStream ssKey{};
88
26
        ssKey.reserve(1000);
89
26
        ssKey << key;
90
91
26
        DataStream ssValue{};
92
26
        ssValue.reserve(10000);
93
26
        ssValue << value;
94
95
26
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
26
    }
Unexecuted instantiation: bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CScript>, wallet::CKeyMetadata>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CScript> const&, wallet::CKeyMetadata const&, bool)
Unexecuted instantiation: bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CScript>, unsigned char>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CScript> const&, unsigned char const&, bool)
bool wallet::DatabaseBatch::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CBlockLocator>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, CBlockLocator const&, bool)
Line
Count
Source
86
27.1k
    {
87
27.1k
        DataStream ssKey{};
88
27.1k
        ssKey.reserve(1000);
89
27.1k
        ssKey << key;
90
91
27.1k
        DataStream ssValue{};
92
27.1k
        ssValue.reserve(10000);
93
27.1k
        ssValue << value;
94
95
27.1k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
27.1k
    }
bool wallet::DatabaseBatch::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, long>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, long const&, bool)
Line
Count
Source
86
17.6k
    {
87
17.6k
        DataStream ssKey{};
88
17.6k
        ssKey.reserve(1000);
89
17.6k
        ssKey << key;
90
91
17.6k
        DataStream ssValue{};
92
17.6k
        ssValue.reserve(10000);
93
17.6k
        ssValue << value;
94
95
17.6k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
17.6k
    }
bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned char>, uint256>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned char> const&, uint256 const&, bool)
Line
Count
Source
86
4.03k
    {
87
4.03k
        DataStream ssKey{};
88
4.03k
        ssKey.reserve(1000);
89
4.03k
        ssKey << key;
90
91
4.03k
        DataStream ssValue{};
92
4.03k
        ssValue.reserve(10000);
93
4.03k
        ssValue << value;
94
95
4.03k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
4.03k
    }
bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<uint256, CPubKey>>, std::pair<std::vector<unsigned char, secure_allocator<unsigned char>>, uint256>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<uint256, CPubKey>> const&, std::pair<std::vector<unsigned char, secure_allocator<unsigned char>>, uint256> const&, bool)
Line
Count
Source
86
4.24k
    {
87
4.24k
        DataStream ssKey{};
88
4.24k
        ssKey.reserve(1000);
89
4.24k
        ssKey << key;
90
91
4.24k
        DataStream ssValue{};
92
4.24k
        ssValue.reserve(10000);
93
4.24k
        ssValue << value;
94
95
4.24k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
4.24k
    }
bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<uint256, CPubKey>>, std::vector<unsigned char, std::allocator<unsigned char>>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<uint256, CPubKey>> const&, std::vector<unsigned char, std::allocator<unsigned char>> const&, bool)
Line
Count
Source
86
265
    {
87
265
        DataStream ssKey{};
88
265
        ssKey.reserve(1000);
89
265
        ssKey << key;
90
91
265
        DataStream ssValue{};
92
265
        ssValue.reserve(10000);
93
265
        ssValue << value;
94
95
265
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
265
    }
bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, uint256>, wallet::WalletDescriptor>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, uint256> const&, wallet::WalletDescriptor const&, bool)
Line
Count
Source
86
102k
    {
87
102k
        DataStream ssKey{};
88
102k
        ssKey.reserve(1000);
89
102k
        ssKey << key;
90
91
102k
        DataStream ssValue{};
92
102k
        ssValue.reserve(10000);
93
102k
        ssValue << value;
94
95
102k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
102k
    }
bool wallet::DatabaseBatch::Write<std::pair<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, uint256>, std::pair<unsigned int, unsigned int>>, std::vector<unsigned char, std::allocator<unsigned char>>>(std::pair<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, uint256>, std::pair<unsigned int, unsigned int>> const&, std::vector<unsigned char, std::allocator<unsigned char>> const&, bool)
Line
Count
Source
86
10.0k
    {
87
10.0k
        DataStream ssKey{};
88
10.0k
        ssKey.reserve(1000);
89
10.0k
        ssKey << key;
90
91
10.0k
        DataStream ssValue{};
92
10.0k
        ssValue.reserve(10000);
93
10.0k
        ssValue << value;
94
95
10.0k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
10.0k
    }
bool wallet::DatabaseBatch::Write<std::pair<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, uint256>, unsigned int>, std::vector<unsigned char, std::allocator<unsigned char>>>(std::pair<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, uint256>, unsigned int> const&, std::vector<unsigned char, std::allocator<unsigned char>> const&, bool)
Line
Count
Source
86
8.88k
    {
87
8.88k
        DataStream ssKey{};
88
8.88k
        ssKey.reserve(1000);
89
8.88k
        ssKey << key;
90
91
8.88k
        DataStream ssValue{};
92
8.88k
        ssValue.reserve(10000);
93
8.88k
        ssValue << value;
94
95
8.88k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
8.88k
    }
bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<transaction_identifier<false>, unsigned int>>, unsigned char>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<transaction_identifier<false>, unsigned int>> const&, unsigned char const&, bool)
Line
Count
Source
86
1
    {
87
1
        DataStream ssKey{};
88
1
        ssKey.reserve(1000);
89
1
        ssKey << key;
90
91
1
        DataStream ssValue{};
92
1
        ssValue.reserve(10000);
93
1
        ssValue << value;
94
95
1
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
1
    }
bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool)
Line
Count
Source
86
27
    {
87
27
        DataStream ssKey{};
88
27
        ssKey.reserve(1000);
89
27
        ssKey << key;
90
91
27
        DataStream ssValue{};
92
27
        ssValue.reserve(10000);
93
27
        ssValue << value;
94
95
27
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
27
    }
bool wallet::DatabaseBatch::Write<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned long>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, unsigned long const&, bool)
Line
Count
Source
86
4.36k
    {
87
4.36k
        DataStream ssKey{};
88
4.36k
        ssKey.reserve(1000);
89
4.36k
        ssKey << key;
90
91
4.36k
        DataStream ssValue{};
92
4.36k
        ssValue.reserve(10000);
93
4.36k
        ssValue << value;
94
95
4.36k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
96
4.36k
    }
97
98
    template <typename K>
99
    bool Erase(const K& key)
100
341
    {
101
341
        DataStream ssKey{};
102
341
        ssKey.reserve(1000);
103
341
        ssKey << key;
104
105
341
        return EraseKey(std::move(ssKey));
106
341
    }
bool wallet::DatabaseBatch::Erase<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>> const&)
Line
Count
Source
100
54
    {
101
54
        DataStream ssKey{};
102
54
        ssKey.reserve(1000);
103
54
        ssKey << key;
104
105
54
        return EraseKey(std::move(ssKey));
106
54
    }
bool wallet::DatabaseBatch::Erase<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, uint256>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, uint256> const&)
Line
Count
Source
100
17
    {
101
17
        DataStream ssKey{};
102
17
        ssKey.reserve(1000);
103
17
        ssKey << key;
104
105
17
        return EraseKey(std::move(ssKey));
106
17
    }
Unexecuted instantiation: bool wallet::DatabaseBatch::Erase<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CPubKey>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CPubKey> const&)
bool wallet::DatabaseBatch::Erase<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned int>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned int> const&)
Line
Count
Source
100
1
    {
101
1
        DataStream ssKey{};
102
1
        ssKey.reserve(1000);
103
1
        ssKey << key;
104
105
1
        return EraseKey(std::move(ssKey));
106
1
    }
Unexecuted instantiation: bool wallet::DatabaseBatch::Erase<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CScript>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, CScript> const&)
bool wallet::DatabaseBatch::Erase<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned char>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned char> const&)
Line
Count
Source
100
1
    {
101
1
        DataStream ssKey{};
102
1
        ssKey.reserve(1000);
103
1
        ssKey << key;
104
105
1
        return EraseKey(std::move(ssKey));
106
1
    }
bool wallet::DatabaseBatch::Erase<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<uint256, CPubKey>>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<uint256, CPubKey>> const&)
Line
Count
Source
100
265
    {
101
265
        DataStream ssKey{};
102
265
        ssKey.reserve(1000);
103
265
        ssKey << key;
104
105
265
        return EraseKey(std::move(ssKey));
106
265
    }
bool wallet::DatabaseBatch::Erase<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<transaction_identifier<false>, unsigned int>>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<transaction_identifier<false>, unsigned int>> const&)
Line
Count
Source
100
1
    {
101
1
        DataStream ssKey{};
102
1
        ssKey.reserve(1000);
103
1
        ssKey << key;
104
105
1
        return EraseKey(std::move(ssKey));
106
1
    }
bool wallet::DatabaseBatch::Erase<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>> const&)
Line
Count
Source
100
2
    {
101
2
        DataStream ssKey{};
102
2
        ssKey.reserve(1000);
103
2
        ssKey << key;
104
105
2
        return EraseKey(std::move(ssKey));
106
2
    }
107
108
    template <typename K>
109
    bool Exists(const K& key)
110
11
    {
111
11
        DataStream ssKey{};
112
11
        ssKey.reserve(1000);
113
11
        ssKey << key;
114
115
11
        return HasKey(std::move(ssKey));
116
11
    }
bool wallet::DatabaseBatch::Exists<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>> const&)
Line
Count
Source
110
8
    {
111
8
        DataStream ssKey{};
112
8
        ssKey.reserve(1000);
113
8
        ssKey << key;
114
115
8
        return HasKey(std::move(ssKey));
116
8
    }
bool wallet::DatabaseBatch::Exists<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
Line
Count
Source
110
3
    {
111
3
        DataStream ssKey{};
112
3
        ssKey.reserve(1000);
113
3
        ssKey << key;
114
115
3
        return HasKey(std::move(ssKey));
116
3
    }
117
    virtual bool ErasePrefix(std::span<const std::byte> prefix) = 0;
118
119
    virtual std::unique_ptr<DatabaseCursor> GetNewCursor() = 0;
120
    virtual std::unique_ptr<DatabaseCursor> GetNewPrefixCursor(std::span<const std::byte> prefix) = 0;
121
    virtual bool TxnBegin() = 0;
122
    virtual bool TxnCommit() = 0;
123
    virtual bool TxnAbort() = 0;
124
    virtual bool HasActiveTxn() = 0;
125
};
126
127
/** An instance of this class represents one database.
128
 **/
129
class WalletDatabase
130
{
131
public:
132
    /** Create dummy DB handle */
133
1.19k
    WalletDatabase() = default;
134
1.19k
    virtual ~WalletDatabase() = default;
135
136
    /** Open the database if it is not already opened. */
137
    virtual void Open() = 0;
138
139
    //! Counts the number of active database users to be sure that the database is not closed while someone is using it
140
    std::atomic<int> m_refcount{0};
141
142
    /** Rewrite the entire database on disk
143
     */
144
    virtual bool Rewrite() = 0;
145
146
    /** Back up the entire database to a file.
147
     */
148
    virtual bool Backup(const std::string& strDest) const = 0;
149
150
    /** Flush to the database file and close the database.
151
     *  Also close the environment if no other databases are open in it.
152
     */
153
    virtual void Close() = 0;
154
155
    /** Return path to main database file for logs and error messages. */
156
    virtual std::string Filename() = 0;
157
158
    /** Return paths to all database created files */
159
    virtual std::vector<fs::path> Files() = 0;
160
161
    virtual std::string Format() = 0;
162
163
    /** Make a DatabaseBatch connected to this database */
164
    virtual std::unique_ptr<DatabaseBatch> MakeBatch() = 0;
165
};
166
167
enum class DatabaseFormat {
168
    SQLITE,
169
    BERKELEY_RO,
170
};
171
172
struct DatabaseOptions {
173
    bool require_existing = false;
174
    bool require_create = false;
175
    std::optional<DatabaseFormat> require_format;
176
    uint64_t create_flags = 0;
177
    SecureString create_passphrase;
178
179
    // Specialized options. Not every option is supported by every backend.
180
    bool verify = true;             //!< Check data integrity on load.
181
    bool use_unsafe_sync = false;   //!< Disable file sync for faster performance.
182
    bool use_shared_memory = false; //!< Let other processes access the database.
183
    int64_t max_log_mb = 100;       //!< Max log size to allow before consolidating.
184
};
185
186
enum class DatabaseStatus {
187
    SUCCESS,
188
    FAILED_BAD_PATH,
189
    FAILED_BAD_FORMAT,
190
    FAILED_LEGACY_DISABLED,
191
    FAILED_ALREADY_LOADED,
192
    FAILED_ALREADY_EXISTS,
193
    FAILED_NOT_FOUND,
194
    FAILED_CREATE,
195
    FAILED_LOAD,
196
    FAILED_VERIFY,
197
    FAILED_ENCRYPT,
198
    FAILED_INVALID_BACKUP_FILE,
199
    FAILED_NEW_UNNAMED,
200
};
201
202
/** Recursively list database paths in directory. */
203
std::vector<std::pair<fs::path, std::string>> ListDatabases(const fs::path& path);
204
205
void ReadDatabaseArgs(const ArgsManager& args, DatabaseOptions& options);
206
std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
207
208
fs::path BDBDataFile(const fs::path& path);
209
fs::path SQLiteDataFile(const fs::path& path);
210
bool IsBDBFile(const fs::path& path);
211
bool IsSQLiteFile(const fs::path& path);
212
} // namespace wallet
213
214
#endif // BITCOIN_WALLET_DB_H