Bitcoin Core 29.99.0
P2P Digital Currency
ismine_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2017-2022 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 <key.h>
6#include <key_io.h>
7#include <node/context.h>
8#include <script/script.h>
9#include <script/solver.h>
12#include <wallet/types.h>
13#include <wallet/wallet.h>
14#include <wallet/test/util.h>
15
16#include <boost/test/unit_test.hpp>
17
18using namespace util::hex_literals;
19
20namespace wallet {
22
23BOOST_AUTO_TEST_CASE(ismine_standard)
24{
25 CKey keys[2];
26 CPubKey pubkeys[2];
27 for (int i = 0; i < 2; i++) {
28 keys[i].MakeNewKey(true);
29 pubkeys[i] = keys[i].GetPubKey();
30 }
31
32 CKey uncompressedKey = GenerateRandomKey(/*compressed=*/false);
33 CPubKey uncompressedPubkey = uncompressedKey.GetPubKey();
34 std::unique_ptr<interfaces::Chain>& chain = m_node.chain;
35
36 CScript scriptPubKey;
37 isminetype result;
38
39 // P2PK compressed - Descriptor
40 {
41 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
42 std::string desc_str = "pk(" + EncodeSecret(keys[0]) + ")";
43
44 auto spk_manager = CreateDescriptor(keystore, desc_str, true);
45
46 scriptPubKey = GetScriptForRawPubKey(pubkeys[0]);
47 result = spk_manager->IsMine(scriptPubKey);
49 }
50
51 // P2PK uncompressed - Descriptor
52 {
53 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
54 std::string desc_str = "pk(" + EncodeSecret(uncompressedKey) + ")";
55
56 auto spk_manager = CreateDescriptor(keystore, desc_str, true);
57
58 scriptPubKey = GetScriptForRawPubKey(uncompressedPubkey);
59 result = spk_manager->IsMine(scriptPubKey);
61 }
62
63 // P2PKH compressed - Descriptor
64 {
65 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
66 std::string desc_str = "pkh(" + EncodeSecret(keys[0]) + ")";
67
68 auto spk_manager = CreateDescriptor(keystore, desc_str, true);
69
70 scriptPubKey = GetScriptForDestination(PKHash(pubkeys[0]));
71 result = spk_manager->IsMine(scriptPubKey);
73 }
74
75 // P2PKH uncompressed - Descriptor
76 {
77 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
78 std::string desc_str = "pkh(" + EncodeSecret(uncompressedKey) + ")";
79
80 auto spk_manager = CreateDescriptor(keystore, desc_str, true);
81
82 scriptPubKey = GetScriptForDestination(PKHash(uncompressedPubkey));
83 result = spk_manager->IsMine(scriptPubKey);
85 }
86
87 // P2SH - Descriptor
88 {
89 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
90 std::string desc_str = "sh(pkh(" + EncodeSecret(keys[0]) + "))";
91
92 auto spk_manager = CreateDescriptor(keystore, desc_str, true);
93
94 CScript redeemScript = GetScriptForDestination(PKHash(pubkeys[0]));
95 scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript));
96 result = spk_manager->IsMine(scriptPubKey);
98 }
99
100 // (P2PKH inside) P2SH inside P2SH (invalid) - Descriptor
101 {
102 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
103 std::string desc_str = "sh(sh(" + EncodeSecret(keys[0]) + "))";
104
105 auto spk_manager = CreateDescriptor(keystore, desc_str, false);
106 BOOST_CHECK_EQUAL(spk_manager, nullptr);
107 }
108
109 // (P2PKH inside) P2SH inside P2WSH (invalid) - Descriptor
110 {
111 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
112 std::string desc_str = "wsh(sh(" + EncodeSecret(keys[0]) + "))";
113
114 auto spk_manager = CreateDescriptor(keystore, desc_str, false);
115 BOOST_CHECK_EQUAL(spk_manager, nullptr);
116 }
117
118 // P2WPKH inside P2WSH (invalid) - Descriptor
119 {
120 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
121 std::string desc_str = "wsh(wpkh(" + EncodeSecret(keys[0]) + "))";
122
123 auto spk_manager = CreateDescriptor(keystore, desc_str, false);
124 BOOST_CHECK_EQUAL(spk_manager, nullptr);
125 }
126
127 // (P2PKH inside) P2WSH inside P2WSH (invalid) - Descriptor
128 {
129 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
130 std::string desc_str = "wsh(wsh(" + EncodeSecret(keys[0]) + "))";
131
132 auto spk_manager = CreateDescriptor(keystore, desc_str, false);
133 BOOST_CHECK_EQUAL(spk_manager, nullptr);
134 }
135
136 // P2WPKH compressed - Descriptor
137 {
138 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
139 std::string desc_str = "wpkh(" + EncodeSecret(keys[0]) + ")";
140
141 auto spk_manager = CreateDescriptor(keystore, desc_str, true);
142
143 scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(pubkeys[0]));
144 result = spk_manager->IsMine(scriptPubKey);
146 }
147
148 // P2WPKH uncompressed (invalid) - Descriptor
149 {
150 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
151 std::string desc_str = "wpkh(" + EncodeSecret(uncompressedKey) + ")";
152
153 auto spk_manager = CreateDescriptor(keystore, desc_str, false);
154 BOOST_CHECK_EQUAL(spk_manager, nullptr);
155 }
156
157 // scriptPubKey multisig - Descriptor
158 {
159 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
160 std::string desc_str = "multi(2," + EncodeSecret(uncompressedKey) + "," + EncodeSecret(keys[1]) + ")";
161
162 auto spk_manager = CreateDescriptor(keystore, desc_str, true);
163
164 scriptPubKey = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]});
165 result = spk_manager->IsMine(scriptPubKey);
167 }
168
169 // P2SH multisig - Descriptor
170 {
171 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
172
173 std::string desc_str = "sh(multi(2," + EncodeSecret(uncompressedKey) + "," + EncodeSecret(keys[1]) + "))";
174
175 auto spk_manager = CreateDescriptor(keystore, desc_str, true);
176
177 CScript redeemScript = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]});
178 scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript));
179 result = spk_manager->IsMine(scriptPubKey);
181 }
182
183 // P2WSH multisig with compressed keys - Descriptor
184 {
185 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
186
187 std::string desc_str = "wsh(multi(2," + EncodeSecret(keys[0]) + "," + EncodeSecret(keys[1]) + "))";
188
189 auto spk_manager = CreateDescriptor(keystore, desc_str, true);
190
191 CScript redeemScript = GetScriptForMultisig(2, {pubkeys[0], pubkeys[1]});
192 scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(redeemScript));
193 result = spk_manager->IsMine(scriptPubKey);
195 }
196
197 // P2WSH multisig with uncompressed key (invalid) - Descriptor
198 {
199 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
200
201 std::string desc_str = "wsh(multi(2," + EncodeSecret(uncompressedKey) + "," + EncodeSecret(keys[1]) + "))";
202
203 auto spk_manager = CreateDescriptor(keystore, desc_str, false);
204 BOOST_CHECK_EQUAL(spk_manager, nullptr);
205 }
206
207 // P2WSH multisig wrapped in P2SH - Descriptor
208 {
209 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
210
211 std::string desc_str = "sh(wsh(multi(2," + EncodeSecret(keys[0]) + "," + EncodeSecret(keys[1]) + ")))";
212
213 auto spk_manager = CreateDescriptor(keystore, desc_str, true);
214
215 CScript witnessScript = GetScriptForMultisig(2, {pubkeys[0], pubkeys[1]});
216 CScript redeemScript = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
217 scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript));
218 result = spk_manager->IsMine(scriptPubKey);
220 }
221
222 // Combo - Descriptor
223 {
224 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
225
226 std::string desc_str = "combo(" + EncodeSecret(keys[0]) + ")";
227
228 auto spk_manager = CreateDescriptor(keystore, desc_str, true);
229
230 // Test P2PK
231 result = spk_manager->IsMine(GetScriptForRawPubKey(pubkeys[0]));
233
234 // Test P2PKH
235 result = spk_manager->IsMine(GetScriptForDestination(PKHash(pubkeys[0])));
237
238 // Test P2SH (combo descriptor does not describe P2SH)
239 CScript redeemScript = GetScriptForDestination(PKHash(pubkeys[0]));
240 scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript));
241 result = spk_manager->IsMine(scriptPubKey);
243
244 // Test P2WPKH
245 scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(pubkeys[0]));
246 result = spk_manager->IsMine(scriptPubKey);
248
249 // P2SH-P2WPKH output
250 redeemScript = GetScriptForDestination(WitnessV0KeyHash(pubkeys[0]));
251 scriptPubKey = GetScriptForDestination(ScriptHash(redeemScript));
252 result = spk_manager->IsMine(scriptPubKey);
254
255 // Test P2TR (combo descriptor does not describe P2TR)
256 XOnlyPubKey xpk(pubkeys[0]);
257 Assert(xpk.IsFullyValid());
258 TaprootBuilder builder;
259 builder.Finalize(xpk);
260 WitnessV1Taproot output = builder.GetOutput();
261 scriptPubKey = GetScriptForDestination(output);
262 result = spk_manager->IsMine(scriptPubKey);
264 }
265
266 // Taproot - Descriptor
267 {
268 CWallet keystore(chain.get(), "", CreateMockableWalletDatabase());
269
270 std::string desc_str = "tr(" + EncodeSecret(keys[0]) + ")";
271
272 auto spk_manager = CreateDescriptor(keystore, desc_str, true);
273
274 XOnlyPubKey xpk(pubkeys[0]);
275 Assert(xpk.IsFullyValid());
276 TaprootBuilder builder;
277 builder.Finalize(xpk);
278 WitnessV1Taproot output = builder.GetOutput();
279 scriptPubKey = GetScriptForDestination(output);
280 result = spk_manager->IsMine(scriptPubKey);
282 }
283}
284
286} // namespace wallet
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
node::NodeContext m_node
Definition: bitcoin-gui.cpp:42
#define Assert(val)
Identity function.
Definition: check.h:106
An encapsulated private key.
Definition: key.h:35
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition: key.cpp:161
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:182
An encapsulated public key.
Definition: pubkey.h:34
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:415
Utility class to construct Taproot outputs from internal key and script tree.
WitnessV1Taproot GetOutput()
Compute scriptPubKey (after Finalize()).
TaprootBuilder & Finalize(const XOnlyPubKey &internal_key)
Finalize the construction.
bool IsFullyValid() const
Determine if this pubkey is fully valid.
Definition: pubkey.cpp:224
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:300
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
CKey GenerateRandomKey(bool compressed) noexcept
Definition: key.cpp:352
std::string EncodeSecret(const CKey &key)
Definition: key_io.cpp:231
""_hex is a compile-time user-defined literal returning a std::array<std::byte>, equivalent to ParseH...
Definition: strencodings.h:427
wallet::ScriptPubKeyMan * CreateDescriptor(CWallet &keystore, const std::string &desc_str, const bool success)
Definition: util.cpp:197
std::unique_ptr< WalletDatabase > CreateMockableWalletDatabase(MockableData records)
Definition: util.cpp:187
BOOST_AUTO_TEST_CASE(bnb_test)
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
Definition: types.h:41
@ ISMINE_NO
Definition: types.h:42
@ ISMINE_SPENDABLE
Definition: types.h:44
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
Definition: solver.cpp:218
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
Definition: solver.cpp:213
Basic testing setup.
Definition: setup_common.h:64
std::unique_ptr< interfaces::Chain > chain
Definition: context.h:76
is a home for public enum and struct type definitions that are used by internally by wallet code,...