1 // Copyright (c) 2017-2018 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 <keystore.h>
7 #include <script/ismine.h>
8 #include <script/script.h>
9 #include <script/script_error.h>
10 #include <script/standard.h>
11 #include <test/test_bitcoin.h>
12
13 #include <boost/test/unit_test.hpp>
14
15
BOOST_FIXTURE_TEST_SUITE(script_standard_tests,BasicTestingSetup)16 BOOST_FIXTURE_TEST_SUITE(script_standard_tests, BasicTestingSetup)
17
18 BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
19 {
20 CKey keys[3];
21 CPubKey pubkeys[3];
22 for (int i = 0; i < 3; i++) {
23 keys[i].MakeNewKey(true);
24 pubkeys[i] = keys[i].GetPubKey();
25 }
26
27 CScript s;
28 std::vector<std::vector<unsigned char> > solutions;
29
30 // TX_PUBKEY
31 s.clear();
32 s << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
33 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_PUBKEY);
34 BOOST_CHECK_EQUAL(solutions.size(), 1U);
35 BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0]));
36
37 // TX_PUBKEYHASH
38 s.clear();
39 s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
40 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_PUBKEYHASH);
41 BOOST_CHECK_EQUAL(solutions.size(), 1U);
42 BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));
43
44 // TX_SCRIPTHASH
45 CScript redeemScript(s); // initialize with leftover P2PKH script
46 s.clear();
47 s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
48 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_SCRIPTHASH);
49 BOOST_CHECK_EQUAL(solutions.size(), 1U);
50 BOOST_CHECK(solutions[0] == ToByteVector(CScriptID(redeemScript)));
51
52 // TX_MULTISIG
53 s.clear();
54 s << OP_1 <<
55 ToByteVector(pubkeys[0]) <<
56 ToByteVector(pubkeys[1]) <<
57 OP_2 << OP_CHECKMULTISIG;
58 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_MULTISIG);
59 BOOST_CHECK_EQUAL(solutions.size(), 4U);
60 BOOST_CHECK(solutions[0] == std::vector<unsigned char>({1}));
61 BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
62 BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1]));
63 BOOST_CHECK(solutions[3] == std::vector<unsigned char>({2}));
64
65 s.clear();
66 s << OP_2 <<
67 ToByteVector(pubkeys[0]) <<
68 ToByteVector(pubkeys[1]) <<
69 ToByteVector(pubkeys[2]) <<
70 OP_3 << OP_CHECKMULTISIG;
71 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_MULTISIG);
72 BOOST_CHECK_EQUAL(solutions.size(), 5U);
73 BOOST_CHECK(solutions[0] == std::vector<unsigned char>({2}));
74 BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
75 BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1]));
76 BOOST_CHECK(solutions[3] == ToByteVector(pubkeys[2]));
77 BOOST_CHECK(solutions[4] == std::vector<unsigned char>({3}));
78
79 // TX_NULL_DATA
80 s.clear();
81 s << OP_RETURN <<
82 std::vector<unsigned char>({0}) <<
83 std::vector<unsigned char>({75}) <<
84 std::vector<unsigned char>({255});
85 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NULL_DATA);
86 BOOST_CHECK_EQUAL(solutions.size(), 0U);
87
88 // TX_WITNESS_V0_KEYHASH
89 s.clear();
90 s << OP_0 << ToByteVector(pubkeys[0].GetID());
91 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_WITNESS_V0_KEYHASH);
92 BOOST_CHECK_EQUAL(solutions.size(), 1U);
93 BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));
94
95 // TX_WITNESS_V0_SCRIPTHASH
96 uint256 scriptHash;
97 CSHA256().Write(&redeemScript[0], redeemScript.size())
98 .Finalize(scriptHash.begin());
99
100 s.clear();
101 s << OP_0 << ToByteVector(scriptHash);
102 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_WITNESS_V0_SCRIPTHASH);
103 BOOST_CHECK_EQUAL(solutions.size(), 1U);
104 BOOST_CHECK(solutions[0] == ToByteVector(scriptHash));
105
106 // TX_NONSTANDARD
107 s.clear();
108 s << OP_9 << OP_ADD << OP_11 << OP_EQUAL;
109 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
110 }
111
BOOST_AUTO_TEST_CASE(script_standard_Solver_failure)112 BOOST_AUTO_TEST_CASE(script_standard_Solver_failure)
113 {
114 CKey key;
115 CPubKey pubkey;
116 key.MakeNewKey(true);
117 pubkey = key.GetPubKey();
118
119 CScript s;
120 std::vector<std::vector<unsigned char> > solutions;
121
122 // TX_PUBKEY with incorrectly sized pubkey
123 s.clear();
124 s << std::vector<unsigned char>(30, 0x01) << OP_CHECKSIG;
125 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
126
127 // TX_PUBKEYHASH with incorrectly sized key hash
128 s.clear();
129 s << OP_DUP << OP_HASH160 << ToByteVector(pubkey) << OP_EQUALVERIFY << OP_CHECKSIG;
130 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
131
132 // TX_SCRIPTHASH with incorrectly sized script hash
133 s.clear();
134 s << OP_HASH160 << std::vector<unsigned char>(21, 0x01) << OP_EQUAL;
135 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
136
137 // TX_MULTISIG 0/2
138 s.clear();
139 s << OP_0 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
140 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
141
142 // TX_MULTISIG 2/1
143 s.clear();
144 s << OP_2 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
145 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
146
147 // TX_MULTISIG n = 2 with 1 pubkey
148 s.clear();
149 s << OP_1 << ToByteVector(pubkey) << OP_2 << OP_CHECKMULTISIG;
150 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
151
152 // TX_MULTISIG n = 1 with 0 pubkeys
153 s.clear();
154 s << OP_1 << OP_1 << OP_CHECKMULTISIG;
155 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
156
157 // TX_NULL_DATA with other opcodes
158 s.clear();
159 s << OP_RETURN << std::vector<unsigned char>({75}) << OP_ADD;
160 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
161
162 // TX_WITNESS with incorrect program size
163 s.clear();
164 s << OP_0 << std::vector<unsigned char>(19, 0x01);
165 BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
166 }
167
BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)168 BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
169 {
170 CKey key;
171 CPubKey pubkey;
172 key.MakeNewKey(true);
173 pubkey = key.GetPubKey();
174
175 CScript s;
176 CTxDestination address;
177
178 // TX_PUBKEY
179 s.clear();
180 s << ToByteVector(pubkey) << OP_CHECKSIG;
181 BOOST_CHECK(ExtractDestination(s, address));
182 BOOST_CHECK(boost::get<CKeyID>(&address) &&
183 *boost::get<CKeyID>(&address) == pubkey.GetID());
184
185 // TX_PUBKEYHASH
186 s.clear();
187 s << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
188 BOOST_CHECK(ExtractDestination(s, address));
189 BOOST_CHECK(boost::get<CKeyID>(&address) &&
190 *boost::get<CKeyID>(&address) == pubkey.GetID());
191
192 // TX_SCRIPTHASH
193 CScript redeemScript(s); // initialize with leftover P2PKH script
194 s.clear();
195 s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
196 BOOST_CHECK(ExtractDestination(s, address));
197 BOOST_CHECK(boost::get<CScriptID>(&address) &&
198 *boost::get<CScriptID>(&address) == CScriptID(redeemScript));
199
200 // TX_MULTISIG
201 s.clear();
202 s << OP_1 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
203 BOOST_CHECK(!ExtractDestination(s, address));
204
205 // TX_NULL_DATA
206 s.clear();
207 s << OP_RETURN << std::vector<unsigned char>({75});
208 BOOST_CHECK(!ExtractDestination(s, address));
209
210 // TX_WITNESS_V0_KEYHASH
211 s.clear();
212 s << OP_0 << ToByteVector(pubkey.GetID());
213 BOOST_CHECK(ExtractDestination(s, address));
214 WitnessV0KeyHash keyhash;
215 CHash160().Write(pubkey.begin(), pubkey.size()).Finalize(keyhash.begin());
216 BOOST_CHECK(boost::get<WitnessV0KeyHash>(&address) && *boost::get<WitnessV0KeyHash>(&address) == keyhash);
217
218 // TX_WITNESS_V0_SCRIPTHASH
219 s.clear();
220 WitnessV0ScriptHash scripthash;
221 CSHA256().Write(redeemScript.data(), redeemScript.size()).Finalize(scripthash.begin());
222 s << OP_0 << ToByteVector(scripthash);
223 BOOST_CHECK(ExtractDestination(s, address));
224 BOOST_CHECK(boost::get<WitnessV0ScriptHash>(&address) && *boost::get<WitnessV0ScriptHash>(&address) == scripthash);
225
226 // TX_WITNESS with unknown version
227 s.clear();
228 s << OP_1 << ToByteVector(pubkey);
229 BOOST_CHECK(ExtractDestination(s, address));
230 WitnessUnknown unk;
231 unk.length = 33;
232 unk.version = 1;
233 std::copy(pubkey.begin(), pubkey.end(), unk.program);
234 BOOST_CHECK(boost::get<WitnessUnknown>(&address) && *boost::get<WitnessUnknown>(&address) == unk);
235 }
236
BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)237 BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
238 {
239 CKey keys[3];
240 CPubKey pubkeys[3];
241 for (int i = 0; i < 3; i++) {
242 keys[i].MakeNewKey(true);
243 pubkeys[i] = keys[i].GetPubKey();
244 }
245
246 CScript s;
247 txnouttype whichType;
248 std::vector<CTxDestination> addresses;
249 int nRequired;
250
251 // TX_PUBKEY
252 s.clear();
253 s << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
254 BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
255 BOOST_CHECK_EQUAL(whichType, TX_PUBKEY);
256 BOOST_CHECK_EQUAL(addresses.size(), 1U);
257 BOOST_CHECK_EQUAL(nRequired, 1);
258 BOOST_CHECK(boost::get<CKeyID>(&addresses[0]) &&
259 *boost::get<CKeyID>(&addresses[0]) == pubkeys[0].GetID());
260
261 // TX_PUBKEYHASH
262 s.clear();
263 s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
264 BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
265 BOOST_CHECK_EQUAL(whichType, TX_PUBKEYHASH);
266 BOOST_CHECK_EQUAL(addresses.size(), 1U);
267 BOOST_CHECK_EQUAL(nRequired, 1);
268 BOOST_CHECK(boost::get<CKeyID>(&addresses[0]) &&
269 *boost::get<CKeyID>(&addresses[0]) == pubkeys[0].GetID());
270
271 // TX_SCRIPTHASH
272 CScript redeemScript(s); // initialize with leftover P2PKH script
273 s.clear();
274 s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
275 BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
276 BOOST_CHECK_EQUAL(whichType, TX_SCRIPTHASH);
277 BOOST_CHECK_EQUAL(addresses.size(), 1U);
278 BOOST_CHECK_EQUAL(nRequired, 1);
279 BOOST_CHECK(boost::get<CScriptID>(&addresses[0]) &&
280 *boost::get<CScriptID>(&addresses[0]) == CScriptID(redeemScript));
281
282 // TX_MULTISIG
283 s.clear();
284 s << OP_2 <<
285 ToByteVector(pubkeys[0]) <<
286 ToByteVector(pubkeys[1]) <<
287 OP_2 << OP_CHECKMULTISIG;
288 BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
289 BOOST_CHECK_EQUAL(whichType, TX_MULTISIG);
290 BOOST_CHECK_EQUAL(addresses.size(), 2U);
291 BOOST_CHECK_EQUAL(nRequired, 2);
292 BOOST_CHECK(boost::get<CKeyID>(&addresses[0]) &&
293 *boost::get<CKeyID>(&addresses[0]) == pubkeys[0].GetID());
294 BOOST_CHECK(boost::get<CKeyID>(&addresses[1]) &&
295 *boost::get<CKeyID>(&addresses[1]) == pubkeys[1].GetID());
296
297 // TX_NULL_DATA
298 s.clear();
299 s << OP_RETURN << std::vector<unsigned char>({75});
300 BOOST_CHECK(!ExtractDestinations(s, whichType, addresses, nRequired));
301 }
302
BOOST_AUTO_TEST_CASE(script_standard_GetScriptFor_)303 BOOST_AUTO_TEST_CASE(script_standard_GetScriptFor_)
304 {
305 CKey keys[3];
306 CPubKey pubkeys[3];
307 for (int i = 0; i < 3; i++) {
308 keys[i].MakeNewKey(true);
309 pubkeys[i] = keys[i].GetPubKey();
310 }
311
312 CScript expected, result;
313
314 // CKeyID
315 expected.clear();
316 expected << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
317 result = GetScriptForDestination(pubkeys[0].GetID());
318 BOOST_CHECK(result == expected);
319
320 // CScriptID
321 CScript redeemScript(result);
322 expected.clear();
323 expected << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
324 result = GetScriptForDestination(CScriptID(redeemScript));
325 BOOST_CHECK(result == expected);
326
327 // CNoDestination
328 expected.clear();
329 result = GetScriptForDestination(CNoDestination());
330 BOOST_CHECK(result == expected);
331
332 // GetScriptForRawPubKey
333 expected.clear();
334 expected << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
335 result = GetScriptForRawPubKey(pubkeys[0]);
336 BOOST_CHECK(result == expected);
337
338 // GetScriptForMultisig
339 expected.clear();
340 expected << OP_2 <<
341 ToByteVector(pubkeys[0]) <<
342 ToByteVector(pubkeys[1]) <<
343 ToByteVector(pubkeys[2]) <<
344 OP_3 << OP_CHECKMULTISIG;
345 result = GetScriptForMultisig(2, std::vector<CPubKey>(pubkeys, pubkeys + 3));
346 BOOST_CHECK(result == expected);
347
348 // GetScriptForWitness
349 CScript witnessScript;
350
351 witnessScript << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
352 expected.clear();
353 expected << OP_0 << ToByteVector(pubkeys[0].GetID());
354 result = GetScriptForWitness(witnessScript);
355 BOOST_CHECK(result == expected);
356
357 witnessScript.clear();
358 witnessScript << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
359 result = GetScriptForWitness(witnessScript);
360 BOOST_CHECK(result == expected);
361
362 witnessScript.clear();
363 witnessScript << OP_1 << ToByteVector(pubkeys[0]) << OP_1 << OP_CHECKMULTISIG;
364
365 uint256 scriptHash;
366 CSHA256().Write(&witnessScript[0], witnessScript.size())
367 .Finalize(scriptHash.begin());
368
369 expected.clear();
370 expected << OP_0 << ToByteVector(scriptHash);
371 result = GetScriptForWitness(witnessScript);
372 BOOST_CHECK(result == expected);
373 }
374
BOOST_AUTO_TEST_CASE(script_standard_IsMine)375 BOOST_AUTO_TEST_CASE(script_standard_IsMine)
376 {
377 CKey keys[2];
378 CPubKey pubkeys[2];
379 for (int i = 0; i < 2; i++) {
380 keys[i].MakeNewKey(true);
381 pubkeys[i] = keys[i].GetPubKey();
382 }
383
384 CKey uncompressedKey;
385 uncompressedKey.MakeNewKey(false);
386 CPubKey uncompressedPubkey = uncompressedKey.GetPubKey();
387
388 CScript scriptPubKey;
389 isminetype result;
390
391 // P2PK compressed
392 {
393 CBasicKeyStore keystore;
394 scriptPubKey = GetScriptForRawPubKey(pubkeys[0]);
395
396 // Keystore does not have key
397 result = IsMine(keystore, scriptPubKey);
398 BOOST_CHECK_EQUAL(result, ISMINE_NO);
399
400 // Keystore has key
401 BOOST_CHECK(keystore.AddKey(keys[0]));
402 result = IsMine(keystore, scriptPubKey);
403 BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
404 }
405
406 // P2PK uncompressed
407 {
408 CBasicKeyStore keystore;
409 scriptPubKey = GetScriptForRawPubKey(uncompressedPubkey);
410
411 // Keystore does not have key
412 result = IsMine(keystore, scriptPubKey);
413 BOOST_CHECK_EQUAL(result, ISMINE_NO);
414
415 // Keystore has key
416 BOOST_CHECK(keystore.AddKey(uncompressedKey));
417 result = IsMine(keystore, scriptPubKey);
418 BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
419 }
420
421 // P2PKH compressed
422 {
423 CBasicKeyStore keystore;
424 scriptPubKey = GetScriptForDestination(pubkeys[0].GetID());
425
426 // Keystore does not have key
427 result = IsMine(keystore, scriptPubKey);
428 BOOST_CHECK_EQUAL(result, ISMINE_NO);
429
430 // Keystore has key
431 BOOST_CHECK(keystore.AddKey(keys[0]));
432 result = IsMine(keystore, scriptPubKey);
433 BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
434 }
435
436 // P2PKH uncompressed
437 {
438 CBasicKeyStore keystore;
439 scriptPubKey = GetScriptForDestination(uncompressedPubkey.GetID());
440
441 // Keystore does not have key
442 result = IsMine(keystore, scriptPubKey);
443 BOOST_CHECK_EQUAL(result, ISMINE_NO);
444
445 // Keystore has key
446 BOOST_CHECK(keystore.AddKey(uncompressedKey));
447 result = IsMine(keystore, scriptPubKey);
448 BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
449 }
450
451 // P2SH
452 {
453 CBasicKeyStore keystore;
454
455 CScript redeemScript = GetScriptForDestination(pubkeys[0].GetID());
456 scriptPubKey = GetScriptForDestination(CScriptID(redeemScript));
457
458 // Keystore does not have redeemScript or key
459 result = IsMine(keystore, scriptPubKey);
460 BOOST_CHECK_EQUAL(result, ISMINE_NO);
461
462 // Keystore has redeemScript but no key
463 BOOST_CHECK(keystore.AddCScript(redeemScript));
464 result = IsMine(keystore, scriptPubKey);
465 BOOST_CHECK_EQUAL(result, ISMINE_NO);
466
467 // Keystore has redeemScript and key
468 BOOST_CHECK(keystore.AddKey(keys[0]));
469 result = IsMine(keystore, scriptPubKey);
470 BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
471 }
472
473 // (P2PKH inside) P2SH inside P2SH (invalid)
474 {
475 CBasicKeyStore keystore;
476
477 CScript redeemscript_inner = GetScriptForDestination(pubkeys[0].GetID());
478 CScript redeemscript = GetScriptForDestination(CScriptID(redeemscript_inner));
479 scriptPubKey = GetScriptForDestination(CScriptID(redeemscript));
480
481 BOOST_CHECK(keystore.AddCScript(redeemscript));
482 BOOST_CHECK(keystore.AddCScript(redeemscript_inner));
483 BOOST_CHECK(keystore.AddCScript(scriptPubKey));
484 BOOST_CHECK(keystore.AddKey(keys[0]));
485 result = IsMine(keystore, scriptPubKey);
486 BOOST_CHECK_EQUAL(result, ISMINE_NO);
487 }
488
489 // (P2PKH inside) P2SH inside P2WSH (invalid)
490 {
491 CBasicKeyStore keystore;
492
493 CScript redeemscript = GetScriptForDestination(pubkeys[0].GetID());
494 CScript witnessscript = GetScriptForDestination(CScriptID(redeemscript));
495 scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript));
496
497 BOOST_CHECK(keystore.AddCScript(witnessscript));
498 BOOST_CHECK(keystore.AddCScript(redeemscript));
499 BOOST_CHECK(keystore.AddCScript(scriptPubKey));
500 BOOST_CHECK(keystore.AddKey(keys[0]));
501 result = IsMine(keystore, scriptPubKey);
502 BOOST_CHECK_EQUAL(result, ISMINE_NO);
503 }
504
505 // P2WPKH inside P2WSH (invalid)
506 {
507 CBasicKeyStore keystore;
508
509 CScript witnessscript = GetScriptForDestination(WitnessV0KeyHash(pubkeys[0].GetID()));
510 scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript));
511
512 BOOST_CHECK(keystore.AddCScript(witnessscript));
513 BOOST_CHECK(keystore.AddCScript(scriptPubKey));
514 BOOST_CHECK(keystore.AddKey(keys[0]));
515 result = IsMine(keystore, scriptPubKey);
516 BOOST_CHECK_EQUAL(result, ISMINE_NO);
517 }
518
519 // (P2PKH inside) P2WSH inside P2WSH (invalid)
520 {
521 CBasicKeyStore keystore;
522
523 CScript witnessscript_inner = GetScriptForDestination(pubkeys[0].GetID());
524 CScript witnessscript = GetScriptForDestination(WitnessV0ScriptHash(witnessscript_inner));
525 scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessscript));
526
527 BOOST_CHECK(keystore.AddCScript(witnessscript_inner));
528 BOOST_CHECK(keystore.AddCScript(witnessscript));
529 BOOST_CHECK(keystore.AddCScript(scriptPubKey));
530 BOOST_CHECK(keystore.AddKey(keys[0]));
531 result = IsMine(keystore, scriptPubKey);
532 BOOST_CHECK_EQUAL(result, ISMINE_NO);
533 }
534
535 // P2WPKH compressed
536 {
537 CBasicKeyStore keystore;
538 BOOST_CHECK(keystore.AddKey(keys[0]));
539
540 scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(pubkeys[0].GetID()));
541
542 // Keystore implicitly has key and P2SH redeemScript
543 BOOST_CHECK(keystore.AddCScript(scriptPubKey));
544 result = IsMine(keystore, scriptPubKey);
545 BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
546 }
547
548 // P2WPKH uncompressed
549 {
550 CBasicKeyStore keystore;
551 BOOST_CHECK(keystore.AddKey(uncompressedKey));
552
553 scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(uncompressedPubkey.GetID()));
554
555 // Keystore has key, but no P2SH redeemScript
556 result = IsMine(keystore, scriptPubKey);
557 BOOST_CHECK_EQUAL(result, ISMINE_NO);
558
559 // Keystore has key and P2SH redeemScript
560 BOOST_CHECK(keystore.AddCScript(scriptPubKey));
561 result = IsMine(keystore, scriptPubKey);
562 BOOST_CHECK_EQUAL(result, ISMINE_NO);
563 }
564
565 // scriptPubKey multisig
566 {
567 CBasicKeyStore keystore;
568
569 scriptPubKey = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]});
570
571 // Keystore does not have any keys
572 result = IsMine(keystore, scriptPubKey);
573 BOOST_CHECK_EQUAL(result, ISMINE_NO);
574
575 // Keystore has 1/2 keys
576 BOOST_CHECK(keystore.AddKey(uncompressedKey));
577
578 result = IsMine(keystore, scriptPubKey);
579 BOOST_CHECK_EQUAL(result, ISMINE_NO);
580
581 // Keystore has 2/2 keys
582 BOOST_CHECK(keystore.AddKey(keys[1]));
583
584 result = IsMine(keystore, scriptPubKey);
585 BOOST_CHECK_EQUAL(result, ISMINE_NO);
586
587 // Keystore has 2/2 keys and the script
588 BOOST_CHECK(keystore.AddCScript(scriptPubKey));
589
590 result = IsMine(keystore, scriptPubKey);
591 BOOST_CHECK_EQUAL(result, ISMINE_NO);
592 }
593
594 // P2SH multisig
595 {
596 CBasicKeyStore keystore;
597 BOOST_CHECK(keystore.AddKey(uncompressedKey));
598 BOOST_CHECK(keystore.AddKey(keys[1]));
599
600 CScript redeemScript = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]});
601 scriptPubKey = GetScriptForDestination(CScriptID(redeemScript));
602
603 // Keystore has no redeemScript
604 result = IsMine(keystore, scriptPubKey);
605 BOOST_CHECK_EQUAL(result, ISMINE_NO);
606
607 // Keystore has redeemScript
608 BOOST_CHECK(keystore.AddCScript(redeemScript));
609 result = IsMine(keystore, scriptPubKey);
610 BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
611 }
612
613 // P2WSH multisig with compressed keys
614 {
615 CBasicKeyStore keystore;
616 BOOST_CHECK(keystore.AddKey(keys[0]));
617 BOOST_CHECK(keystore.AddKey(keys[1]));
618
619 CScript witnessScript = GetScriptForMultisig(2, {pubkeys[0], pubkeys[1]});
620 scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
621
622 // Keystore has keys, but no witnessScript or P2SH redeemScript
623 result = IsMine(keystore, scriptPubKey);
624 BOOST_CHECK_EQUAL(result, ISMINE_NO);
625
626 // Keystore has keys and witnessScript, but no P2SH redeemScript
627 BOOST_CHECK(keystore.AddCScript(witnessScript));
628 result = IsMine(keystore, scriptPubKey);
629 BOOST_CHECK_EQUAL(result, ISMINE_NO);
630
631 // Keystore has keys, witnessScript, P2SH redeemScript
632 BOOST_CHECK(keystore.AddCScript(scriptPubKey));
633 result = IsMine(keystore, scriptPubKey);
634 BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
635 }
636
637 // P2WSH multisig with uncompressed key
638 {
639 CBasicKeyStore keystore;
640 BOOST_CHECK(keystore.AddKey(uncompressedKey));
641 BOOST_CHECK(keystore.AddKey(keys[1]));
642
643 CScript witnessScript = GetScriptForMultisig(2, {uncompressedPubkey, pubkeys[1]});
644 scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
645
646 // Keystore has keys, but no witnessScript or P2SH redeemScript
647 result = IsMine(keystore, scriptPubKey);
648 BOOST_CHECK_EQUAL(result, ISMINE_NO);
649
650 // Keystore has keys and witnessScript, but no P2SH redeemScript
651 BOOST_CHECK(keystore.AddCScript(witnessScript));
652 result = IsMine(keystore, scriptPubKey);
653 BOOST_CHECK_EQUAL(result, ISMINE_NO);
654
655 // Keystore has keys, witnessScript, P2SH redeemScript
656 BOOST_CHECK(keystore.AddCScript(scriptPubKey));
657 result = IsMine(keystore, scriptPubKey);
658 BOOST_CHECK_EQUAL(result, ISMINE_NO);
659 }
660
661 // P2WSH multisig wrapped in P2SH
662 {
663 CBasicKeyStore keystore;
664
665 CScript witnessScript = GetScriptForMultisig(2, {pubkeys[0], pubkeys[1]});
666 CScript redeemScript = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
667 scriptPubKey = GetScriptForDestination(CScriptID(redeemScript));
668
669 // Keystore has no witnessScript, P2SH redeemScript, or keys
670 result = IsMine(keystore, scriptPubKey);
671 BOOST_CHECK_EQUAL(result, ISMINE_NO);
672
673 // Keystore has witnessScript and P2SH redeemScript, but no keys
674 BOOST_CHECK(keystore.AddCScript(redeemScript));
675 BOOST_CHECK(keystore.AddCScript(witnessScript));
676 result = IsMine(keystore, scriptPubKey);
677 BOOST_CHECK_EQUAL(result, ISMINE_NO);
678
679 // Keystore has keys, witnessScript, P2SH redeemScript
680 BOOST_CHECK(keystore.AddKey(keys[0]));
681 BOOST_CHECK(keystore.AddKey(keys[1]));
682 result = IsMine(keystore, scriptPubKey);
683 BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE);
684 }
685
686 // OP_RETURN
687 {
688 CBasicKeyStore keystore;
689 BOOST_CHECK(keystore.AddKey(keys[0]));
690
691 scriptPubKey.clear();
692 scriptPubKey << OP_RETURN << ToByteVector(pubkeys[0]);
693
694 result = IsMine(keystore, scriptPubKey);
695 BOOST_CHECK_EQUAL(result, ISMINE_NO);
696 }
697
698 // witness unspendable
699 {
700 CBasicKeyStore keystore;
701 BOOST_CHECK(keystore.AddKey(keys[0]));
702
703 scriptPubKey.clear();
704 scriptPubKey << OP_0 << ToByteVector(ParseHex("aabb"));
705
706 result = IsMine(keystore, scriptPubKey);
707 BOOST_CHECK_EQUAL(result, ISMINE_NO);
708 }
709
710 // witness unknown
711 {
712 CBasicKeyStore keystore;
713 BOOST_CHECK(keystore.AddKey(keys[0]));
714
715 scriptPubKey.clear();
716 scriptPubKey << OP_16 << ToByteVector(ParseHex("aabb"));
717
718 result = IsMine(keystore, scriptPubKey);
719 BOOST_CHECK_EQUAL(result, ISMINE_NO);
720 }
721
722 // Nonstandard
723 {
724 CBasicKeyStore keystore;
725 BOOST_CHECK(keystore.AddKey(keys[0]));
726
727 scriptPubKey.clear();
728 scriptPubKey << OP_9 << OP_ADD << OP_11 << OP_EQUAL;
729
730 result = IsMine(keystore, scriptPubKey);
731 BOOST_CHECK_EQUAL(result, ISMINE_NO);
732 }
733 }
734
735 BOOST_AUTO_TEST_SUITE_END()
736