Bitcoin Core  31.0.0
P2P Digital Currency
ismine_tests.cpp
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 #include <key.h>
6 #include <key_io.h>
7 #include <node/context.h>
8 #include <script/script.h>
9 #include <script/solver.h>
10 #include <script/signingprovider.h>
11 #include <test/util/setup_common.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 
18 using namespace util::hex_literals;
19 
20 namespace wallet {
22 
23 BOOST_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  bool 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 GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
Definition: solver.cpp:218
std::unique_ptr< interfaces::Chain > chain
Definition: context.h:76
BOOST_AUTO_TEST_CASE(ismine_standard)
node::NodeContext m_node
Definition: bitcoin-gui.cpp:43
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:183
Basic testing setup.
Definition: setup_common.h:64
CKey GenerateRandomKey(bool compressed) noexcept
Definition: key.cpp:475
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
wallet::DescriptorScriptPubKeyMan * CreateDescriptor(CWallet &keystore, const std::string &desc_str, const bool success)
Definition: util.cpp:221
BOOST_AUTO_TEST_SUITE_END()
TaprootBuilder & Finalize(const XOnlyPubKey &internal_key)
Finalize the construction.
An encapsulated public key.
Definition: pubkey.h:33
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition: key.cpp:162
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:309
""_hex is a compile-time user-defined literal returning a std::array<std::byte>, equivalent to ParseH...
Definition: strencodings.h:400
is a home for public enum and struct type definitions that are used by internally by wallet code...
bool IsFullyValid() const
Determine if this pubkey is fully valid.
Definition: pubkey.cpp:230
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Utility class to construct Taproot outputs from internal key and script tree.
std::unique_ptr< WalletDatabase > CreateMockableWalletDatabase(MockableData records)
Definition: util.cpp:211
auto result
Definition: common-types.h:74
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:17
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:404
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
Definition: solver.cpp:213
An encapsulated private key.
Definition: key.h:35
std::string EncodeSecret(const CKey &key)
Definition: key_io.cpp:231
#define Assert(val)
Identity function.
Definition: check.h:113
#define BOOST_CHECK(expr)
Definition: object.cpp:16