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