Coverage Report

Created: 2026-09-14 20:36

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 <memory>
15
#include <optional>
16
#include <string>
17
18
class ArgsManager;
19
struct bilingual_str;
20
21
namespace wallet {
22
// BytePrefix compares equality with other byte spans that begin with the same prefix.
23
struct BytePrefix {
24
    std::span<const std::byte> prefix;
25
};
26
bool operator<(BytePrefix a, std::span<const std::byte> b);
27
bool operator<(std::span<const std::byte> a, BytePrefix b);
28
29
class DatabaseCursor
30
{
31
public:
32
30.1k
    explicit DatabaseCursor() = default;
33
30.1k
    virtual ~DatabaseCursor() = default;
34
35
    DatabaseCursor(const DatabaseCursor&) = delete;
36
    DatabaseCursor& operator=(const DatabaseCursor&) = delete;
37
38
    enum class Status
39
    {
40
        FAIL,
41
        MORE,
42
        DONE,
43
    };
44
45
0
    virtual Status Next(DataStream& key, DataStream& value) { return Status::FAIL; }
46
};
47
48
/** RAII class that provides access to a WalletDatabase */
49
class DatabaseBatch
50
{
51
private:
52
    virtual bool ReadKey(DataStream&& key, DataStream& value) = 0;
53
    virtual bool WriteKey(DataStream&& key, DataStream&& value, bool overwrite = true) = 0;
54
    virtual bool EraseKey(DataStream&& key) = 0;
55
    virtual bool HasKey(DataStream&& key) = 0;
56
57
public:
58
170k
    explicit DatabaseBatch() = default;
59
170k
    virtual ~DatabaseBatch() = default;
60
61
    DatabaseBatch(const DatabaseBatch&) = delete;
62
    DatabaseBatch& operator=(const DatabaseBatch&) = delete;
63
64
    virtual void Close() = 0;
65
66
    template <typename K, typename T>
67
    bool Read(const K& key, T& value)
68
4.88k
    {
69
4.88k
        DataStream ssKey{};
70
4.88k
        ssKey.reserve(1000);
71
4.88k
        ssKey << key;
72
73
4.88k
        DataStream ssValue{};
74
4.88k
        if (!ReadKey(std::move(ssKey), ssValue)) return false;
75
4.85k
        try {
76
4.85k
            ssValue >> value;
77
4.85k
            return true;
78
4.85k
        } catch (const std::exception&) {
79
0
            return false;
80
0
        }
81
4.85k
    }
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
68
4
    {
69
4
        DataStream ssKey{};
70
4
        ssKey.reserve(1000);
71
4
        ssKey << key;
72
73
4
        DataStream ssValue{};
74
4
        if (!ReadKey(std::move(ssKey), ssValue)) return false;
75
4
        try {
76
4
            ssValue >> value;
77
4
            return true;
78
4
        } catch (const std::exception&) {
79
0
            return false;
80
0
        }
81
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
68
416
    {
69
416
        DataStream ssKey{};
70
416
        ssKey.reserve(1000);
71
416
        ssKey << key;
72
73
416
        DataStream ssValue{};
74
416
        if (!ReadKey(std::move(ssKey), ssValue)) return false;
75
406
        try {
76
406
            ssValue >> value;
77
406
            return true;
78
406
        } catch (const std::exception&) {
79
0
            return false;
80
0
        }
81
406
    }
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
68
4.04k
    {
69
4.04k
        DataStream ssKey{};
70
4.04k
        ssKey.reserve(1000);
71
4.04k
        ssKey << key;
72
73
4.04k
        DataStream ssValue{};
74
4.04k
        if (!ReadKey(std::move(ssKey), ssValue)) return false;
75
4.03k
        try {
76
4.03k
            ssValue >> value;
77
4.03k
            return true;
78
4.03k
        } catch (const std::exception&) {
79
0
            return false;
80
0
        }
81
4.03k
    }
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
68
416
    {
69
416
        DataStream ssKey{};
70
416
        ssKey.reserve(1000);
71
416
        ssKey << key;
72
73
416
        DataStream ssValue{};
74
416
        if (!ReadKey(std::move(ssKey), ssValue)) return false;
75
409
        try {
76
409
            ssValue >> value;
77
409
            return true;
78
409
        } catch (const std::exception&) {
79
0
            return false;
80
0
        }
81
409
    }
82
83
    template <typename K, typename T>
84
    bool Write(const K& key, const T& value, bool fOverwrite = true)
85
297k
    {
86
297k
        DataStream ssKey{};
87
297k
        ssKey.reserve(1000);
88
297k
        ssKey << key;
89
90
297k
        DataStream ssValue{};
91
297k
        ssValue.reserve(10000);
92
297k
        ssValue << value;
93
94
297k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
297k
    }
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
85
784
    {
86
784
        DataStream ssKey{};
87
784
        ssKey.reserve(1000);
88
784
        ssKey << key;
89
90
784
        DataStream ssValue{};
91
784
        ssValue.reserve(10000);
92
784
        ssValue << value;
93
94
784
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
784
    }
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
85
120
    {
86
120
        DataStream ssKey{};
87
120
        ssKey.reserve(1000);
88
120
        ssKey << key;
89
90
120
        DataStream ssValue{};
91
120
        ssValue.reserve(10000);
92
120
        ssValue << value;
93
94
120
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
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
85
1.95k
    {
86
1.95k
        DataStream ssKey{};
87
1.95k
        ssKey.reserve(1000);
88
1.95k
        ssKey << key;
89
90
1.95k
        DataStream ssValue{};
91
1.95k
        ssValue.reserve(10000);
92
1.95k
        ssValue << value;
93
94
1.95k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
1.95k
    }
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
85
10
    {
86
10
        DataStream ssKey{};
87
10
        ssKey.reserve(1000);
88
10
        ssKey << key;
89
90
10
        DataStream ssValue{};
91
10
        ssValue.reserve(10000);
92
10
        ssValue << value;
93
94
10
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
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
85
56.4k
    {
86
56.4k
        DataStream ssKey{};
87
56.4k
        ssKey.reserve(1000);
88
56.4k
        ssKey << key;
89
90
56.4k
        DataStream ssValue{};
91
56.4k
        ssValue.reserve(10000);
92
56.4k
        ssValue << value;
93
94
56.4k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
56.4k
    }
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
85
24.2k
    {
86
24.2k
        DataStream ssKey{};
87
24.2k
        ssKey.reserve(1000);
88
24.2k
        ssKey << key;
89
90
24.2k
        DataStream ssValue{};
91
24.2k
        ssValue.reserve(10000);
92
24.2k
        ssValue << value;
93
94
24.2k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
24.2k
    }
bool wallet::DatabaseBatch::Write<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<transaction_identifier<false>, transaction_identifier<true>>>, ParamsWrapper<TransactionSerParams, std::shared_ptr<CTransaction const> const>>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<transaction_identifier<false>, transaction_identifier<true>>> const&, ParamsWrapper<TransactionSerParams, std::shared_ptr<CTransaction const> const> const&, bool)
Line
Count
Source
85
17.9k
    {
86
17.9k
        DataStream ssKey{};
87
17.9k
        ssKey.reserve(1000);
88
17.9k
        ssKey << key;
89
90
17.9k
        DataStream ssValue{};
91
17.9k
        ssValue.reserve(10000);
92
17.9k
        ssValue << value;
93
94
17.9k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
17.9k
    }
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)
Line
Count
Source
85
60
    {
86
60
        DataStream ssKey{};
87
60
        ssKey.reserve(1000);
88
60
        ssKey << key;
89
90
60
        DataStream ssValue{};
91
60
        ssValue.reserve(10000);
92
60
        ssValue << value;
93
94
60
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
60
    }
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)
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)
Line
Count
Source
85
60
    {
86
60
        DataStream ssKey{};
87
60
        ssKey.reserve(1000);
88
60
        ssKey << key;
89
90
60
        DataStream ssValue{};
91
60
        ssValue.reserve(10000);
92
60
        ssValue << value;
93
94
60
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
60
    }
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
85
30
    {
86
30
        DataStream ssKey{};
87
30
        ssKey.reserve(1000);
88
30
        ssKey << key;
89
90
30
        DataStream ssValue{};
91
30
        ssValue.reserve(10000);
92
30
        ssValue << value;
93
94
30
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
30
    }
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
85
25.5k
    {
86
25.5k
        DataStream ssKey{};
87
25.5k
        ssKey.reserve(1000);
88
25.5k
        ssKey << key;
89
90
25.5k
        DataStream ssValue{};
91
25.5k
        ssValue.reserve(10000);
92
25.5k
        ssValue << value;
93
94
25.5k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
25.5k
    }
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
85
17.9k
    {
86
17.9k
        DataStream ssKey{};
87
17.9k
        ssKey.reserve(1000);
88
17.9k
        ssKey << key;
89
90
17.9k
        DataStream ssValue{};
91
17.9k
        ssValue.reserve(10000);
92
17.9k
        ssValue << value;
93
94
17.9k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
17.9k
    }
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
85
4.48k
    {
86
4.48k
        DataStream ssKey{};
87
4.48k
        ssKey.reserve(1000);
88
4.48k
        ssKey << key;
89
90
4.48k
        DataStream ssValue{};
91
4.48k
        ssValue.reserve(10000);
92
4.48k
        ssValue << value;
93
94
4.48k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
4.48k
    }
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
85
4.66k
    {
86
4.66k
        DataStream ssKey{};
87
4.66k
        ssKey.reserve(1000);
88
4.66k
        ssKey << key;
89
90
4.66k
        DataStream ssValue{};
91
4.66k
        ssValue.reserve(10000);
92
4.66k
        ssValue << value;
93
94
4.66k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
4.66k
    }
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
85
348
    {
86
348
        DataStream ssKey{};
87
348
        ssKey.reserve(1000);
88
348
        ssKey << key;
89
90
348
        DataStream ssValue{};
91
348
        ssValue.reserve(10000);
92
348
        ssValue << value;
93
94
348
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
348
    }
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
85
104k
    {
86
104k
        DataStream ssKey{};
87
104k
        ssKey.reserve(1000);
88
104k
        ssKey << key;
89
90
104k
        DataStream ssValue{};
91
104k
        ssValue.reserve(10000);
92
104k
        ssValue << value;
93
94
104k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
104k
    }
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
85
24.0k
    {
86
24.0k
        DataStream ssKey{};
87
24.0k
        ssKey.reserve(1000);
88
24.0k
        ssKey << key;
89
90
24.0k
        DataStream ssValue{};
91
24.0k
        ssValue.reserve(10000);
92
24.0k
        ssValue << value;
93
94
24.0k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
24.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
85
9.82k
    {
86
9.82k
        DataStream ssKey{};
87
9.82k
        ssKey.reserve(1000);
88
9.82k
        ssKey << key;
89
90
9.82k
        DataStream ssValue{};
91
9.82k
        ssValue.reserve(10000);
92
9.82k
        ssValue << value;
93
94
9.82k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
9.82k
    }
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
85
3
    {
86
3
        DataStream ssKey{};
87
3
        ssKey.reserve(1000);
88
3
        ssKey << key;
89
90
3
        DataStream ssValue{};
91
3
        ssValue.reserve(10000);
92
3
        ssValue << value;
93
94
3
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
3
    }
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
85
29
    {
86
29
        DataStream ssKey{};
87
29
        ssKey.reserve(1000);
88
29
        ssKey << key;
89
90
29
        DataStream ssValue{};
91
29
        ssValue.reserve(10000);
92
29
        ssValue << value;
93
94
29
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
29
    }
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
85
4.83k
    {
86
4.83k
        DataStream ssKey{};
87
4.83k
        ssKey.reserve(1000);
88
4.83k
        ssKey << key;
89
90
4.83k
        DataStream ssValue{};
91
4.83k
        ssValue.reserve(10000);
92
4.83k
        ssValue << value;
93
94
4.83k
        return WriteKey(std::move(ssKey), std::move(ssValue), fOverwrite);
95
4.83k
    }
96
97
    template <typename K>
98
    bool Erase(const K& key)
99
485
    {
100
485
        DataStream ssKey{};
101
485
        ssKey.reserve(1000);
102
485
        ssKey << key;
103
104
485
        return EraseKey(std::move(ssKey));
105
485
    }
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
99
56
    {
100
56
        DataStream ssKey{};
101
56
        ssKey.reserve(1000);
102
56
        ssKey << key;
103
104
56
        return EraseKey(std::move(ssKey));
105
56
    }
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
99
15
    {
100
15
        DataStream ssKey{};
101
15
        ssKey.reserve(1000);
102
15
        ssKey << key;
103
104
15
        return EraseKey(std::move(ssKey));
105
15
    }
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&)
Line
Count
Source
99
60
    {
100
60
        DataStream ssKey{};
101
60
        ssKey.reserve(1000);
102
60
        ssKey << key;
103
104
60
        return EraseKey(std::move(ssKey));
105
60
    }
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
99
1
    {
100
1
        DataStream ssKey{};
101
1
        ssKey.reserve(1000);
102
1
        ssKey << key;
103
104
1
        return EraseKey(std::move(ssKey));
105
1
    }
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
99
2
    {
100
2
        DataStream ssKey{};
101
2
        ssKey.reserve(1000);
102
2
        ssKey << key;
103
104
2
        return EraseKey(std::move(ssKey));
105
2
    }
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
99
348
    {
100
348
        DataStream ssKey{};
101
348
        ssKey.reserve(1000);
102
348
        ssKey << key;
103
104
348
        return EraseKey(std::move(ssKey));
105
348
    }
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
99
1
    {
100
1
        DataStream ssKey{};
101
1
        ssKey.reserve(1000);
102
1
        ssKey << key;
103
104
1
        return EraseKey(std::move(ssKey));
105
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
99
2
    {
100
2
        DataStream ssKey{};
101
2
        ssKey.reserve(1000);
102
2
        ssKey << key;
103
104
2
        return EraseKey(std::move(ssKey));
105
2
    }
106
107
    template <typename K>
108
    bool Exists(const K& key)
109
11
    {
110
11
        DataStream ssKey{};
111
11
        ssKey.reserve(1000);
112
11
        ssKey << key;
113
114
11
        return HasKey(std::move(ssKey));
115
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
109
8
    {
110
8
        DataStream ssKey{};
111
8
        ssKey.reserve(1000);
112
8
        ssKey << key;
113
114
8
        return HasKey(std::move(ssKey));
115
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
109
3
    {
110
3
        DataStream ssKey{};
111
3
        ssKey.reserve(1000);
112
3
        ssKey << key;
113
114
3
        return HasKey(std::move(ssKey));
115
3
    }
116
    virtual bool ErasePrefix(std::span<const std::byte> prefix) = 0;
117
118
    virtual std::unique_ptr<DatabaseCursor> GetNewCursor() = 0;
119
    virtual std::unique_ptr<DatabaseCursor> GetNewPrefixCursor(std::span<const std::byte> prefix) = 0;
120
    virtual bool TxnBegin() = 0;
121
    virtual bool TxnCommit() = 0;
122
    virtual bool TxnAbort() = 0;
123
    virtual bool HasActiveTxn() = 0;
124
};
125
126
/** An instance of this class represents one database.
127
 **/
128
class WalletDatabase
129
{
130
public:
131
    /** Create dummy DB handle */
132
1.34k
    WalletDatabase() = default;
133
1.34k
    virtual ~WalletDatabase() = default;
134
135
    /** Open the database if it is not already opened. */
136
    virtual void Open() = 0;
137
138
    /** Rewrite the entire database on disk
139
     */
140
    virtual bool Rewrite() = 0;
141
142
    /** Back up the entire database to a file.
143
     */
144
    virtual bool Backup(const std::string& strDest) const = 0;
145
146
    /** Flush to the database file and close the database.
147
     *  Also close the environment if no other databases are open in it.
148
     */
149
    virtual void Close() = 0;
150
151
    /** Return path to main database file for logs and error messages. */
152
    virtual std::string Filename() = 0;
153
154
    /** Return paths to all database created files */
155
    virtual std::vector<fs::path> Files() = 0;
156
157
    virtual std::string Format() = 0;
158
159
    /** Make a DatabaseBatch connected to this database */
160
    virtual std::unique_ptr<DatabaseBatch> MakeBatch() = 0;
161
};
162
163
enum class DatabaseFormat {
164
    SQLITE,
165
    BERKELEY_RO,
166
};
167
168
struct DatabaseOptions {
169
    bool require_existing = false;
170
    bool require_create = false;
171
    std::optional<DatabaseFormat> require_format;
172
    uint64_t create_flags = 0;
173
    SecureString create_passphrase;
174
175
    // Specialized options. Not every option is supported by every backend.
176
    bool verify = true;             //!< Check data integrity on load.
177
    bool use_unsafe_sync = false;   //!< Disable file sync for faster performance.
178
};
179
180
enum class DatabaseStatus {
181
    SUCCESS,
182
    FAILED_BAD_PATH,
183
    FAILED_BAD_FORMAT,
184
    FAILED_LEGACY_DISABLED,
185
    FAILED_ALREADY_LOADED,
186
    FAILED_ALREADY_EXISTS,
187
    FAILED_NOT_FOUND,
188
    FAILED_CREATE,
189
    FAILED_LOAD,
190
    FAILED_VERIFY,
191
    FAILED_ENCRYPT,
192
    FAILED_INVALID_BACKUP_FILE,
193
    FAILED_NEW_UNNAMED,
194
};
195
196
/** Recursively list database paths in directory. */
197
std::vector<std::pair<fs::path, std::string>> ListDatabases(const fs::path& path);
198
199
void ReadDatabaseArgs(const ArgsManager& args, DatabaseOptions& options);
200
std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
201
202
fs::path BDBDataFile(const fs::path& path);
203
fs::path SQLiteDataFile(const fs::path& path);
204
bool IsBDBFile(const fs::path& path);
205
bool IsSQLiteFile(const fs::path& path);
206
} // namespace wallet
207
208
#endif // BITCOIN_WALLET_DB_H