Repository navigation
Expand file tree
/
Copy pathwalletutil.h
More file actions
175 lines (141 loc) · 6.91 KB
/
Copy pathwalletutil.h
File metadata and controls
175 lines (141 loc) · 6.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// Copyright (c) 2017-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_WALLET_WALLETUTIL_H
#define BITCOIN_WALLET_WALLETUTIL_H
#include <script/descriptor.h>
#include <util/fs.h>
#include <vector>
namespace wallet {
enum WalletFlags : uint64_t {
// wallet flags in the upper section (> 1 << 31) will lead to not opening the wallet if flag is unknown
// unknown wallet flags in the lower section <= (1 << 31) will be tolerated
// will categorize coins as clean (not reused) and dirty (reused), and handle
// them with privacy considerations in mind
WALLET_FLAG_AVOID_REUSE = (1ULL << 0),
// Indicates that the metadata has already been upgraded to contain key origins
WALLET_FLAG_KEY_ORIGIN_METADATA = (1ULL << 1),
// Indicates that the descriptor cache has been upgraded to cache last hardened xpubs
WALLET_FLAG_LAST_HARDENED_XPUB_CACHED = (1ULL << 2),
// will enforce the rule that the wallet can't contain any private keys (only watch-only/pubkeys)
WALLET_FLAG_DISABLE_PRIVATE_KEYS = (1ULL << 32),
//! Flag set when a wallet contains no HD seed and no private keys, scripts,
//! addresses, and other watch only things, and is therefore "blank."
//!
//! The main function this flag serves is to distinguish a blank wallet from
//! a newly created wallet when the wallet database is loaded, to avoid
//! initialization that should only happen on first run.
//!
//! A secondary function of this flag, which applies to descriptor wallets
//! only, is to serve as an ongoing indication that descriptors in the
//! wallet should be created manually, and that the wallet should not
//! generate automatically generate new descriptors if it is later
//! encrypted. To support this behavior, descriptor wallets unlike legacy
//! wallets do not automatically unset the BLANK flag when things are
//! imported.
//!
//! This flag is also a mandatory flag to prevent previous versions of
//! bitcoin from opening the wallet, thinking it was newly created, and
//! then improperly reinitializing it.
WALLET_FLAG_BLANK_WALLET = (1ULL << 33),
//! Indicate that this wallet supports DescriptorScriptPubKeyMan
WALLET_FLAG_DESCRIPTORS = (1ULL << 34),
//! Indicates that the wallet needs an external signer
WALLET_FLAG_EXTERNAL_SIGNER = (1ULL << 35),
};
// Version numbers for the wallet client that opens a wallet
// These numbers will be written as the last client version in the "version" record and can be used to detect
// when an upgrade-downgrade-upgrade was performed. However, we should prefer to use LastClientFeatures rather
// than new version numbers.
// New version numbers must be greater than 329900 which is guaranteed by setting bit 19
enum WalletClientVersion : int32_t {
MIN_VERSION = (1L << 19),
// The wallet client supports the records for LastClientFeatures
VERSION_LAST_CLIENT_FEATURES = MIN_VERSION + 1,
VERSION_LATEST = VERSION_LAST_CLIENT_FEATURES
};
enum LastClientFeatures : uint64_t {
// Flags indicating the automatic upgrade features supported by the wallet client that last opened a wallet file
// New automatic upgrades must define a flag here so that upgrade-downgrade-upgrade can be detected to determine whether
// an automatic upgrade should be performed.
WALLET_CLIENT_FEATURES = 0
};
//! Get the path of the wallet directory.
fs::path GetWalletDir();
/** Descriptor with some wallet metadata */
class WalletDescriptor
{
private:
int32_t range_start = 0; // First item in range; start of range, inclusive, i.e. [range_start, range_end). This never changes.
int32_t next_index = 0; // Position of the next item to generate
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()
mutable std::optional<uint256> m_canonical_hash; // Hash of the canonical string, used as a shortcut for comparing canonical strings
uint256 GetCanonicalHash() const;
public:
const std::shared_ptr<const Descriptor> descriptor;
uint64_t creation_time = 0;
DescriptorCache cache;
int32_t GetStart() const { return range_start; }
int32_t GetNext() const { return next_index; }
int32_t GetEnd() const { return range_end; }
//! Increments the next_index of the descriptor.
void IncNext()
{
next_index++;
}
//! Increments the next_index of the descriptor.
void DecNext()
{
next_index--;
}
//! Sets the range_end of the descriptor.
void SetEnd(int32_t end)
{
if (!descriptor->IsRange()) {
CHECK_NONFATAL(end == 1);
}
range_end = end;
}
template <typename Stream>
void Serialize(Stream& s) const
{
std::string descriptor_str = descriptor->ToString();
s << descriptor_str << creation_time << next_index << range_start << range_end;
}
template <typename Stream>
static WalletDescriptor FromStream(deserialize_type, Stream& s)
{
std::string descriptor_str;
uint64_t creation_time;
int32_t next_index, range_start, range_end;
s >> descriptor_str >> creation_time >> next_index >> range_start >> range_end;
std::string error;
FlatSigningProvider keys;
auto descs = Parse(descriptor_str, keys, error, true);
if (descs.empty()) {
throw std::ios_base::failure("Invalid descriptor: " + error);
}
if (descs.size() > 1) {
throw std::ios_base::failure("Can't load a multipath descriptor from databases");
}
return WalletDescriptor(std::move(descs.at(0)), creation_time, range_start, range_end, next_index);
}
WalletDescriptor() = delete;
WalletDescriptor(std::shared_ptr<Descriptor> descriptor, uint64_t creation_time, int32_t range_start, int32_t range_end, int32_t next_index)
: range_start(descriptor->IsRange() ? range_start : 0),
next_index(next_index),
range_end(descriptor->IsRange() ? range_end : 1),
descriptor(descriptor),
creation_time(creation_time)
{}
/** Replaces all metadata (range, start, end, creation time), and cache from another WalletDescriptor if it has the same canonical descriptor string.
* The descriptor itself is not replaced to preserve existing serialization to maintain compatibility with previous software versions that expect
* specific serialization.
*/
void UpdateFrom(const WalletDescriptor& other);
// Compare by using the canonical string to make the hardened indicators consistent for comparison
bool IsCanonicallyEquivalent(const WalletDescriptor& other) const;
};
WalletDescriptor GenerateWalletDescriptor(const CExtPubKey& master_key, const OutputType& output_type, bool internal);
} // namespace wallet
#endif // BITCOIN_WALLET_WALLETUTIL_H