Bitcoin Core 32.99.0
P2P Digital Currency
walletutil.h
Go to the documentation of this file.
1// Copyright (c) 2017-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#ifndef BITCOIN_WALLET_WALLETUTIL_H
6#define BITCOIN_WALLET_WALLETUTIL_H
7
8#include <script/descriptor.h>
9#include <util/fs.h>
10
11#include <vector>
12
13namespace wallet {
14
15enum WalletFlags : uint64_t {
16 // wallet flags in the upper section (> 1 << 31) will lead to not opening the wallet if flag is unknown
17 // unknown wallet flags in the lower section <= (1 << 31) will be tolerated
18
19 // will categorize coins as clean (not reused) and dirty (reused), and handle
20 // them with privacy considerations in mind
22
23 // Indicates that the metadata has already been upgraded to contain key origins
25
26 // Indicates that the descriptor cache has been upgraded to cache last hardened xpubs
28
29 // will enforce the rule that the wallet can't contain any private keys (only watch-only/pubkeys)
31
51
54
57};
58
59// Version numbers for the wallet client that opens a wallet
60// These numbers will be written as the last client version in the "version" record and can be used to detect
61// when an upgrade-downgrade-upgrade was performed. However, we should prefer to use LastClientFeatures rather
62// than new version numbers.
63// New version numbers must be greater than 329900 which is guaranteed by setting bit 19
64enum WalletClientVersion : int32_t {
65 MIN_VERSION = (1L << 19),
66
67 // The wallet client supports the records for LastClientFeatures
69
71};
72
73enum LastClientFeatures : uint64_t {
74 // Flags indicating the automatic upgrade features supported by the wallet client that last opened a wallet file
75 // New automatic upgrades must define a flag here so that upgrade-downgrade-upgrade can be detected to determine whether
76 // an automatic upgrade should be performed.
77
79};
80
82fs::path GetWalletDir();
83
86{
87private:
88 int32_t range_start = 0; // First item in range; start of range, inclusive, i.e. [range_start, range_end). This never changes.
89 int32_t next_index = 0; // Position of the next item to generate
90 int32_t range_end = 0; // Item after the last; end of range, exclusive, i.e. [range_start, range_end). This will increment with each TopUp()
91
92 mutable std::optional<uint256> m_canonical_hash; // Hash of the canonical string, used as a shortcut for comparing canonical strings
93
95
96public:
97 const std::shared_ptr<const Descriptor> descriptor;
98 uint64_t creation_time = 0;
100
101 int32_t GetStart() const { return range_start; }
102 int32_t GetNext() const { return next_index; }
103 int32_t GetEnd() const { return range_end; }
104
106 void IncNext()
107 {
108 next_index++;
109 }
110
112 void DecNext()
113 {
114 next_index--;
115 }
116
118 void SetEnd(int32_t end)
119 {
120 if (!descriptor->IsRange()) {
121 CHECK_NONFATAL(end == 1);
122 }
123 range_end = end;
124 }
125
126 template <typename Stream>
127 void Serialize(Stream& s) const
128 {
129 std::string descriptor_str = descriptor->ToString();
130 s << descriptor_str << creation_time << next_index << range_start << range_end;
131 }
132
133 template <typename Stream>
135 {
136 std::string descriptor_str;
137 uint64_t creation_time;
139 s >> descriptor_str >> creation_time >> next_index >> range_start >> range_end;
140
141 std::string error;
143 auto descs = Parse(descriptor_str, keys, error, true);
144 if (descs.empty()) {
145 throw std::ios_base::failure("Invalid descriptor: " + error);
146 }
147 if (descs.size() > 1) {
148 throw std::ios_base::failure("Can't load a multipath descriptor from databases");
149 }
150 return WalletDescriptor(std::move(descs.at(0)), creation_time, range_start, range_end, next_index);
151 }
152
154 WalletDescriptor(std::shared_ptr<Descriptor> descriptor, uint64_t creation_time, int32_t range_start, int32_t range_end, int32_t next_index)
155 : range_start(descriptor->IsRange() ? range_start : 0),
157 range_end(descriptor->IsRange() ? range_end : 1),
160 {}
161
166 void UpdateFrom(const WalletDescriptor& other);
167
168 // Compare by using the canonical string to make the hardened indicators consistent for comparison
169 bool IsCanonicallyEquivalent(const WalletDescriptor& other) const;
170};
171
172WalletDescriptor GenerateWalletDescriptor(const CExtPubKey& master_key, const OutputType& output_type, bool internal);
173} // namespace wallet
174
175#endif // BITCOIN_WALLET_WALLETUTIL_H
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:112
Cache for single descriptor's derived extended pubkeys.
Definition: descriptor.h:30
256-bit opaque blob.
Definition: uint256.h:196
Descriptor with some wallet metadata.
Definition: walletutil.h:86
WalletDescriptor(std::shared_ptr< Descriptor > descriptor, uint64_t creation_time, int32_t range_start, int32_t range_end, int32_t next_index)
Definition: walletutil.h:154
int32_t GetStart() const
Definition: walletutil.h:101
uint256 GetCanonicalHash() const
Definition: walletutil.cpp:100
std::optional< uint256 > m_canonical_hash
Definition: walletutil.h:92
static WalletDescriptor FromStream(deserialize_type, Stream &s)
Definition: walletutil.h:134
void Serialize(Stream &s) const
Definition: walletutil.h:127
bool IsCanonicallyEquivalent(const WalletDescriptor &other) const
Definition: walletutil.cpp:110
int32_t GetNext() const
Definition: walletutil.h:102
void IncNext()
Increments the next_index of the descriptor.
Definition: walletutil.h:106
void SetEnd(int32_t end)
Sets the range_end of the descriptor.
Definition: walletutil.h:118
int32_t GetEnd() const
Definition: walletutil.h:103
void DecNext()
Increments the next_index of the descriptor.
Definition: walletutil.h:112
const std::shared_ptr< const Descriptor > descriptor
Definition: walletutil.h:97
void UpdateFrom(const WalletDescriptor &other)
Replaces all metadata (range, start, end, creation time), and cache from another WalletDescriptor if ...
Definition: walletutil.cpp:88
DescriptorCache cache
Definition: walletutil.h:99
static UniValue Parse(std::string_view raw, ParamFormat format=ParamFormat::JSON)
Parse string to UniValue or throw runtime_error if string contains invalid JSON.
Definition: client.cpp:411
SocketId Stream
Definition: util.h:30
fs::path GetWalletDir()
Get the path of the wallet directory.
Definition: walletutil.cpp:13
WalletFlags
Definition: walletutil.h:15
@ WALLET_FLAG_EXTERNAL_SIGNER
Indicates that the wallet needs an external signer.
Definition: walletutil.h:56
@ WALLET_FLAG_LAST_HARDENED_XPUB_CACHED
Definition: walletutil.h:27
@ WALLET_FLAG_KEY_ORIGIN_METADATA
Definition: walletutil.h:24
@ WALLET_FLAG_AVOID_REUSE
Definition: walletutil.h:21
@ WALLET_FLAG_DESCRIPTORS
Indicate that this wallet supports DescriptorScriptPubKeyMan.
Definition: walletutil.h:53
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
Definition: walletutil.h:30
@ WALLET_FLAG_BLANK_WALLET
Flag set when a wallet contains no HD seed and no private keys, scripts, addresses,...
Definition: walletutil.h:50
WalletClientVersion
Definition: walletutil.h:64
@ VERSION_LAST_CLIENT_FEATURES
Definition: walletutil.h:68
@ MIN_VERSION
Definition: walletutil.h:65
@ VERSION_LATEST
Definition: walletutil.h:70
LastClientFeatures
Definition: walletutil.h:73
@ WALLET_CLIENT_FEATURES
Definition: walletutil.h:78
WalletDescriptor GenerateWalletDescriptor(const CExtPubKey &master_key, const OutputType &addr_type, bool internal)
Definition: walletutil.cpp:35
OutputType
Definition: outputtype.h:18
Dummy data type to identify deserializing constructors.
Definition: serialize.h:51
std::vector< uint16_t > keys
Definition: dbwrapper.cpp:376