Branch data Line data Source code
1 : : // Copyright (c) 2011-2022 The Bitcoin Core developers
2 : : // Distributed under the MIT software license, see the accompanying
3 : 0 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 : :
5 : : #include <test/data/script_tests.json.h>
6 : : #include <test/data/bip341_wallet_vectors.json.h>
7 : :
8 : : #include <common/system.h>
9 : : #include <core_io.h>
10 : : #include <key.h>
11 : : #include <rpc/util.h>
12 : : #include <script/script.h>
13 : : #include <script/script_error.h>
14 : : #include <script/sigcache.h>
15 : : #include <script/sign.h>
16 : : #include <script/signingprovider.h>
17 : 0 : #include <script/solver.h>
18 : 0 : #include <streams.h>
19 : : #include <test/util/json.h>
20 : : #include <test/util/random.h>
21 : : #include <test/util/setup_common.h>
22 : : #include <test/util/transaction_utils.h>
23 : : #include <util/fs.h>
24 : : #include <util/strencodings.h>
25 : :
26 : : #if defined(HAVE_CONSENSUS_LIB)
27 : 0 : #include <script/bitcoinconsensus.h>
28 : : #endif
29 : :
30 : : #include <cstdint>
31 : : #include <fstream>
32 : : #include <string>
33 : : #include <vector>
34 : :
35 : : #include <boost/test/unit_test.hpp>
36 : :
37 : : #include <univalue.h>
38 : :
39 : : // Uncomment if you want to output updated JSON tests.
40 : : // #define UPDATE_JSON_TESTS
41 : :
42 : : static const unsigned int gFlags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
43 : :
44 : : unsigned int ParseScriptFlags(std::string strFlags);
45 : : std::string FormatScriptFlags(unsigned int flags);
46 : :
47 : : struct ScriptErrorDesc
48 : : {
49 : : ScriptError_t err;
50 : : const char *name;
51 : : };
52 : :
53 : : static ScriptErrorDesc script_errors[]={
54 : : {SCRIPT_ERR_OK, "OK"},
55 : : {SCRIPT_ERR_UNKNOWN_ERROR, "UNKNOWN_ERROR"},
56 : : {SCRIPT_ERR_EVAL_FALSE, "EVAL_FALSE"},
57 : : {SCRIPT_ERR_OP_RETURN, "OP_RETURN"},
58 : : {SCRIPT_ERR_SCRIPT_SIZE, "SCRIPT_SIZE"},
59 : : {SCRIPT_ERR_PUSH_SIZE, "PUSH_SIZE"},
60 : : {SCRIPT_ERR_OP_COUNT, "OP_COUNT"},
61 : : {SCRIPT_ERR_STACK_SIZE, "STACK_SIZE"},
62 : : {SCRIPT_ERR_SIG_COUNT, "SIG_COUNT"},
63 : : {SCRIPT_ERR_PUBKEY_COUNT, "PUBKEY_COUNT"},
64 : : {SCRIPT_ERR_VERIFY, "VERIFY"},
65 : : {SCRIPT_ERR_EQUALVERIFY, "EQUALVERIFY"},
66 : : {SCRIPT_ERR_CHECKMULTISIGVERIFY, "CHECKMULTISIGVERIFY"},
67 : : {SCRIPT_ERR_CHECKSIGVERIFY, "CHECKSIGVERIFY"},
68 : : {SCRIPT_ERR_NUMEQUALVERIFY, "NUMEQUALVERIFY"},
69 : : {SCRIPT_ERR_BAD_OPCODE, "BAD_OPCODE"},
70 : : {SCRIPT_ERR_DISABLED_OPCODE, "DISABLED_OPCODE"},
71 : : {SCRIPT_ERR_INVALID_STACK_OPERATION, "INVALID_STACK_OPERATION"},
72 : : {SCRIPT_ERR_INVALID_ALTSTACK_OPERATION, "INVALID_ALTSTACK_OPERATION"},
73 : : {SCRIPT_ERR_UNBALANCED_CONDITIONAL, "UNBALANCED_CONDITIONAL"},
74 : 0 : {SCRIPT_ERR_NEGATIVE_LOCKTIME, "NEGATIVE_LOCKTIME"},
75 : : {SCRIPT_ERR_UNSATISFIED_LOCKTIME, "UNSATISFIED_LOCKTIME"},
76 : : {SCRIPT_ERR_SIG_HASHTYPE, "SIG_HASHTYPE"},
77 : : {SCRIPT_ERR_SIG_DER, "SIG_DER"},
78 : : {SCRIPT_ERR_MINIMALDATA, "MINIMALDATA"},
79 : : {SCRIPT_ERR_SIG_PUSHONLY, "SIG_PUSHONLY"},
80 : : {SCRIPT_ERR_SIG_HIGH_S, "SIG_HIGH_S"},
81 : : {SCRIPT_ERR_SIG_NULLDUMMY, "SIG_NULLDUMMY"},
82 : : {SCRIPT_ERR_PUBKEYTYPE, "PUBKEYTYPE"},
83 : : {SCRIPT_ERR_CLEANSTACK, "CLEANSTACK"},
84 : : {SCRIPT_ERR_MINIMALIF, "MINIMALIF"},
85 : : {SCRIPT_ERR_SIG_NULLFAIL, "NULLFAIL"},
86 : : {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, "DISCOURAGE_UPGRADABLE_NOPS"},
87 : : {SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM, "DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"},
88 : : {SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH, "WITNESS_PROGRAM_WRONG_LENGTH"},
89 : : {SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY, "WITNESS_PROGRAM_WITNESS_EMPTY"},
90 : : {SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH, "WITNESS_PROGRAM_MISMATCH"},
91 : : {SCRIPT_ERR_WITNESS_MALLEATED, "WITNESS_MALLEATED"},
92 : : {SCRIPT_ERR_WITNESS_MALLEATED_P2SH, "WITNESS_MALLEATED_P2SH"},
93 : : {SCRIPT_ERR_WITNESS_UNEXPECTED, "WITNESS_UNEXPECTED"},
94 : : {SCRIPT_ERR_WITNESS_PUBKEYTYPE, "WITNESS_PUBKEYTYPE"},
95 : : {SCRIPT_ERR_OP_CODESEPARATOR, "OP_CODESEPARATOR"},
96 : : {SCRIPT_ERR_SIG_FINDANDDELETE, "SIG_FINDANDDELETE"},
97 : : };
98 : :
99 : 0 : static std::string FormatScriptError(ScriptError_t err)
100 : : {
101 : 0 : for (const auto& se : script_errors)
102 : 0 : if (se.err == err)
103 : 0 : return se.name;
104 : 0 : BOOST_ERROR("Unknown scripterror enumeration value, update script_errors in script_tests.cpp.");
105 : 0 : return "";
106 : 0 : }
107 : :
108 : 0 : static ScriptError_t ParseScriptError(const std::string& name)
109 : : {
110 : 0 : for (const auto& se : script_errors)
111 : 0 : if (se.name == name)
112 : 0 : return se.err;
113 : 0 : BOOST_ERROR("Unknown scripterror \"" << name << "\" in test description");
114 : 0 : return SCRIPT_ERR_UNKNOWN_ERROR;
115 : 0 : }
116 : :
117 : 0 : BOOST_FIXTURE_TEST_SUITE(script_tests, BasicTestingSetup)
118 : :
119 : 0 : void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScriptWitness& scriptWitness, uint32_t flags, const std::string& message, int scriptError, CAmount nValue = 0)
120 : : {
121 : 0 : bool expect = (scriptError == SCRIPT_ERR_OK);
122 : 0 : if (flags & SCRIPT_VERIFY_CLEANSTACK) {
123 : 0 : flags |= SCRIPT_VERIFY_P2SH;
124 : 0 : flags |= SCRIPT_VERIFY_WITNESS;
125 : 0 : }
126 : : ScriptError err;
127 : 0 : const CTransaction txCredit{BuildCreditingTransaction(scriptPubKey, nValue)};
128 : 0 : CMutableTransaction tx = BuildSpendingTransaction(scriptSig, scriptWitness, txCredit);
129 : 0 : CMutableTransaction tx2 = tx;
130 : 0 : BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err) == expect, message);
131 : 0 : BOOST_CHECK_MESSAGE(err == scriptError, FormatScriptError(err) + " where " + FormatScriptError((ScriptError_t)scriptError) + " expected: " + message);
132 : :
133 : : // Verify that removing flags from a passing test or adding flags to a failing test does not change the result.
134 : 0 : for (int i = 0; i < 16; ++i) {
135 : 0 : uint32_t extra_flags(InsecureRandBits(16));
136 : 0 : uint32_t combined_flags{expect ? (flags & ~extra_flags) : (flags | extra_flags)};
137 : : // Weed out some invalid flag combinations.
138 : 0 : if (combined_flags & SCRIPT_VERIFY_CLEANSTACK && ~combined_flags & (SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS)) continue;
139 : 0 : if (combined_flags & SCRIPT_VERIFY_WITNESS && ~combined_flags & SCRIPT_VERIFY_P2SH) continue;
140 : 0 : BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, &scriptWitness, combined_flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err) == expect, message + strprintf(" (with flags %x)", combined_flags));
141 : 0 : }
142 : :
143 : : #if defined(HAVE_CONSENSUS_LIB)
144 : 0 : CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
145 : 0 : stream << tx2;
146 : 0 : uint32_t libconsensus_flags{flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL};
147 : 0 : if (libconsensus_flags == flags) {
148 : 0 : int expectedSuccessCode = expect ? 1 : 0;
149 : 0 : if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) {
150 : 0 : BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), txCredit.vout[0].nValue, UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
151 : 0 : } else {
152 : 0 : BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script_with_amount(scriptPubKey.data(), scriptPubKey.size(), 0, UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
153 : 0 : BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), 0, libconsensus_flags, nullptr) == expectedSuccessCode, message);
154 : : }
155 : 0 : }
156 : : #endif
157 : 0 : }
158 : :
159 : 0 : void static NegateSignatureS(std::vector<unsigned char>& vchSig) {
160 : : // Parse the signature.
161 : 0 : std::vector<unsigned char> r, s;
162 : 0 : r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
163 : 0 : s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
164 : :
165 : : // Really ugly to implement mod-n negation here, but it would be feature creep to expose such functionality from libsecp256k1.
166 : : static const unsigned char order[33] = {
167 : : 0x00,
168 : : 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
169 : : 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
170 : : 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
171 : : 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41
172 : : };
173 : 0 : while (s.size() < 33) {
174 : 0 : s.insert(s.begin(), 0x00);
175 : : }
176 : 0 : int carry = 0;
177 : 0 : for (int p = 32; p >= 1; p--) {
178 : 0 : int n = (int)order[p] - s[p] - carry;
179 : 0 : s[p] = (n + 256) & 0xFF;
180 : 0 : carry = (n < 0);
181 : 0 : }
182 : 0 : assert(carry == 0);
183 : 0 : if (s.size() > 1 && s[0] == 0 && s[1] < 0x80) {
184 : 0 : s.erase(s.begin());
185 : 0 : }
186 : :
187 : : // Reconstruct the signature.
188 : 0 : vchSig.clear();
189 : 0 : vchSig.push_back(0x30);
190 : 0 : vchSig.push_back(4 + r.size() + s.size());
191 : 0 : vchSig.push_back(0x02);
192 : 0 : vchSig.push_back(r.size());
193 : 0 : vchSig.insert(vchSig.end(), r.begin(), r.end());
194 : 0 : vchSig.push_back(0x02);
195 : 0 : vchSig.push_back(s.size());
196 : 0 : vchSig.insert(vchSig.end(), s.begin(), s.end());
197 : 0 : }
198 : :
199 : : namespace
200 : : {
201 : : const unsigned char vchKey0[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
202 : : const unsigned char vchKey1[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0};
203 : : const unsigned char vchKey2[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0};
204 : :
205 : : struct KeyData
206 : : {
207 : : CKey key0, key0C, key1, key1C, key2, key2C;
208 : : CPubKey pubkey0, pubkey0C, pubkey0H;
209 : : CPubKey pubkey1, pubkey1C;
210 : : CPubKey pubkey2, pubkey2C;
211 : :
212 : 0 : KeyData()
213 : : {
214 : 0 : key0.Set(vchKey0, vchKey0 + 32, false);
215 : 0 : key0C.Set(vchKey0, vchKey0 + 32, true);
216 : 0 : pubkey0 = key0.GetPubKey();
217 : 0 : pubkey0H = key0.GetPubKey();
218 : 0 : pubkey0C = key0C.GetPubKey();
219 : 0 : *const_cast<unsigned char*>(pubkey0H.data()) = 0x06 | (pubkey0H[64] & 1);
220 : :
221 : 0 : key1.Set(vchKey1, vchKey1 + 32, false);
222 : 0 : key1C.Set(vchKey1, vchKey1 + 32, true);
223 : 0 : pubkey1 = key1.GetPubKey();
224 : 0 : pubkey1C = key1C.GetPubKey();
225 : :
226 : 0 : key2.Set(vchKey2, vchKey2 + 32, false);
227 : 0 : key2C.Set(vchKey2, vchKey2 + 32, true);
228 : 0 : pubkey2 = key2.GetPubKey();
229 : 0 : pubkey2C = key2C.GetPubKey();
230 : 0 : }
231 : : };
232 : :
233 : : enum class WitnessMode {
234 : : NONE,
235 : : PKH,
236 : : SH
237 : : };
238 : :
239 : 0 : class TestBuilder
240 : : {
241 : : private:
242 : : //! Actually executed script
243 : : CScript script;
244 : : //! The P2SH redeemscript
245 : : CScript redeemscript;
246 : : //! The Witness embedded script
247 : : CScript witscript;
248 : : CScriptWitness scriptWitness;
249 : : CTransactionRef creditTx;
250 : : CMutableTransaction spendTx;
251 : 0 : bool havePush{false};
252 : : std::vector<unsigned char> push;
253 : : std::string comment;
254 : : uint32_t flags;
255 : 0 : int scriptError{SCRIPT_ERR_OK};
256 : : CAmount nValue;
257 : :
258 : 0 : void DoPush()
259 : : {
260 : 0 : if (havePush) {
261 : 0 : spendTx.vin[0].scriptSig << push;
262 : 0 : havePush = false;
263 : 0 : }
264 : 0 : }
265 : :
266 : 0 : void DoPush(const std::vector<unsigned char>& data)
267 : : {
268 : 0 : DoPush();
269 : 0 : push = data;
270 : 0 : havePush = true;
271 : 0 : }
272 : :
273 : : public:
274 : 0 : TestBuilder(const CScript& script_, const std::string& comment_, uint32_t flags_, bool P2SH = false, WitnessMode wm = WitnessMode::NONE, int witnessversion = 0, CAmount nValue_ = 0) : script(script_), comment(comment_), flags(flags_), nValue(nValue_)
275 : : {
276 : 0 : CScript scriptPubKey = script;
277 : 0 : if (wm == WitnessMode::PKH) {
278 : 0 : uint160 hash;
279 : 0 : CHash160().Write(Span{script}.subspan(1)).Finalize(hash);
280 : 0 : script = CScript() << OP_DUP << OP_HASH160 << ToByteVector(hash) << OP_EQUALVERIFY << OP_CHECKSIG;
281 : 0 : scriptPubKey = CScript() << witnessversion << ToByteVector(hash);
282 : 0 : } else if (wm == WitnessMode::SH) {
283 : 0 : witscript = scriptPubKey;
284 : 0 : uint256 hash;
285 : 0 : CSHA256().Write(witscript.data(), witscript.size()).Finalize(hash.begin());
286 : 0 : scriptPubKey = CScript() << witnessversion << ToByteVector(hash);
287 : 0 : }
288 : 0 : if (P2SH) {
289 : 0 : redeemscript = scriptPubKey;
290 : 0 : scriptPubKey = CScript() << OP_HASH160 << ToByteVector(CScriptID(redeemscript)) << OP_EQUAL;
291 : 0 : }
292 : 0 : creditTx = MakeTransactionRef(BuildCreditingTransaction(scriptPubKey, nValue));
293 : 0 : spendTx = BuildSpendingTransaction(CScript(), CScriptWitness(), *creditTx);
294 : 0 : }
295 : :
296 : 0 : TestBuilder& ScriptError(ScriptError_t err)
297 : : {
298 : 0 : scriptError = err;
299 : 0 : return *this;
300 : : }
301 : :
302 : 0 : TestBuilder& Opcode(const opcodetype& _op)
303 : : {
304 : 0 : DoPush();
305 : 0 : spendTx.vin[0].scriptSig << _op;
306 : 0 : return *this;
307 : : }
308 : :
309 : 0 : TestBuilder& Num(int num)
310 : : {
311 : 0 : DoPush();
312 : 0 : spendTx.vin[0].scriptSig << num;
313 : 0 : return *this;
314 : : }
315 : :
316 : 0 : TestBuilder& Push(const std::string& hex)
317 : : {
318 : 0 : DoPush(ParseHex(hex));
319 : 0 : return *this;
320 : 0 : }
321 : :
322 : 0 : TestBuilder& Push(const CScript& _script)
323 : : {
324 : 0 : DoPush(std::vector<unsigned char>(_script.begin(), _script.end()));
325 : 0 : return *this;
326 : 0 : }
327 : :
328 : 0 : TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SigVersion::BASE, CAmount amount = 0)
329 : : {
330 : 0 : uint256 hash = SignatureHash(script, spendTx, 0, nHashType, amount, sigversion);
331 : 0 : std::vector<unsigned char> vchSig, r, s;
332 : 0 : uint32_t iter = 0;
333 : 0 : do {
334 : 0 : key.Sign(hash, vchSig, false, iter++);
335 : 0 : if ((lenS == 33) != (vchSig[5 + vchSig[3]] == 33)) {
336 : 0 : NegateSignatureS(vchSig);
337 : 0 : }
338 : 0 : r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
339 : 0 : s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
340 : 0 : } while (lenR != r.size() || lenS != s.size());
341 : 0 : vchSig.push_back(static_cast<unsigned char>(nHashType));
342 : 0 : DoPush(vchSig);
343 : : return *this;
344 : 0 : }
345 : :
346 : 0 : TestBuilder& PushWitSig(const CKey& key, CAmount amount = -1, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32, SigVersion sigversion = SigVersion::WITNESS_V0)
347 : : {
348 : 0 : if (amount == -1)
349 : 0 : amount = nValue;
350 : 0 : return PushSig(key, nHashType, lenR, lenS, sigversion, amount).AsWit();
351 : : }
352 : :
353 : 0 : TestBuilder& Push(const CPubKey& pubkey)
354 : : {
355 : 0 : DoPush(std::vector<unsigned char>(pubkey.begin(), pubkey.end()));
356 : 0 : return *this;
357 : 0 : }
358 : :
359 : 0 : TestBuilder& PushRedeem()
360 : : {
361 : 0 : DoPush(std::vector<unsigned char>(redeemscript.begin(), redeemscript.end()));
362 : 0 : return *this;
363 : 0 : }
364 : :
365 : 0 : TestBuilder& PushWitRedeem()
366 : : {
367 : 0 : DoPush(std::vector<unsigned char>(witscript.begin(), witscript.end()));
368 : 0 : return AsWit();
369 : 0 : }
370 : :
371 : 0 : TestBuilder& EditPush(unsigned int pos, const std::string& hexin, const std::string& hexout)
372 : : {
373 : 0 : assert(havePush);
374 : 0 : std::vector<unsigned char> datain = ParseHex(hexin);
375 : 0 : std::vector<unsigned char> dataout = ParseHex(hexout);
376 : 0 : assert(pos + datain.size() <= push.size());
377 : 0 : BOOST_CHECK_MESSAGE(std::vector<unsigned char>(push.begin() + pos, push.begin() + pos + datain.size()) == datain, comment);
378 : 0 : push.erase(push.begin() + pos, push.begin() + pos + datain.size());
379 : 0 : push.insert(push.begin() + pos, dataout.begin(), dataout.end());
380 : : return *this;
381 : 0 : }
382 : :
383 : 0 : TestBuilder& DamagePush(unsigned int pos)
384 : : {
385 : 0 : assert(havePush);
386 : 0 : assert(pos < push.size());
387 : 0 : push[pos] ^= 1;
388 : 0 : return *this;
389 : : }
390 : :
391 : 0 : TestBuilder& Test()
392 : : {
393 : 0 : TestBuilder copy = *this; // Make a copy so we can rollback the push.
394 : 0 : DoPush();
395 : 0 : DoTest(creditTx->vout[0].scriptPubKey, spendTx.vin[0].scriptSig, scriptWitness, flags, comment, scriptError, nValue);
396 : 0 : *this = copy;
397 : : return *this;
398 : 0 : }
399 : :
400 : 0 : TestBuilder& AsWit()
401 : : {
402 : 0 : assert(havePush);
403 : 0 : scriptWitness.stack.push_back(push);
404 : 0 : havePush = false;
405 : 0 : return *this;
406 : : }
407 : :
408 : 0 : UniValue GetJSON()
409 : : {
410 : 0 : DoPush();
411 : 0 : UniValue array(UniValue::VARR);
412 : 0 : if (!scriptWitness.stack.empty()) {
413 : 0 : UniValue wit(UniValue::VARR);
414 : 0 : for (unsigned i = 0; i < scriptWitness.stack.size(); i++) {
415 : 0 : wit.push_back(HexStr(scriptWitness.stack[i]));
416 : 0 : }
417 : 0 : wit.push_back(ValueFromAmount(nValue));
418 : 0 : array.push_back(wit);
419 : 0 : }
420 : 0 : array.push_back(FormatScript(spendTx.vin[0].scriptSig));
421 : 0 : array.push_back(FormatScript(creditTx->vout[0].scriptPubKey));
422 : 0 : array.push_back(FormatScriptFlags(flags));
423 : 0 : array.push_back(FormatScriptError((ScriptError_t)scriptError));
424 : 0 : array.push_back(comment);
425 : 0 : return array;
426 : 0 : }
427 : :
428 : 0 : std::string GetComment() const
429 : : {
430 : 0 : return comment;
431 : : }
432 : : };
433 : :
434 : 0 : std::string JSONPrettyPrint(const UniValue& univalue)
435 : : {
436 : 0 : std::string ret = univalue.write(4);
437 : : // Workaround for libunivalue pretty printer, which puts a space between commas and newlines
438 : 0 : size_t pos = 0;
439 : 0 : while ((pos = ret.find(" \n", pos)) != std::string::npos) {
440 : 0 : ret.replace(pos, 2, "\n");
441 : 0 : pos++;
442 : : }
443 : 0 : return ret;
444 : 0 : }
445 : : } // namespace
446 : :
447 : 0 : BOOST_AUTO_TEST_CASE(script_build)
448 : : {
449 : 0 : const KeyData keys;
450 : :
451 : 0 : std::vector<TestBuilder> tests;
452 : :
453 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
454 : 0 : "P2PK", 0
455 : 0 : ).PushSig(keys.key0));
456 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
457 : 0 : "P2PK, bad sig", 0
458 : 0 : ).PushSig(keys.key0).DamagePush(10).ScriptError(SCRIPT_ERR_EVAL_FALSE));
459 : :
460 : 0 : tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1C.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
461 : 0 : "P2PKH", 0
462 : 0 : ).PushSig(keys.key1).Push(keys.pubkey1C));
463 : 0 : tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey2C.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
464 : 0 : "P2PKH, bad pubkey", 0
465 : 0 : ).PushSig(keys.key2).Push(keys.pubkey2C).DamagePush(5).ScriptError(SCRIPT_ERR_EQUALVERIFY));
466 : :
467 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
468 : 0 : "P2PK anyonecanpay", 0
469 : 0 : ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY));
470 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
471 : 0 : "P2PK anyonecanpay marked with normal hashtype", 0
472 : 0 : ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY).EditPush(70, "81", "01").ScriptError(SCRIPT_ERR_EVAL_FALSE));
473 : :
474 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
475 : 0 : "P2SH(P2PK)", SCRIPT_VERIFY_P2SH, true
476 : 0 : ).PushSig(keys.key0).PushRedeem());
477 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
478 : 0 : "P2SH(P2PK), bad redeemscript", SCRIPT_VERIFY_P2SH, true
479 : 0 : ).PushSig(keys.key0).PushRedeem().DamagePush(10).ScriptError(SCRIPT_ERR_EVAL_FALSE));
480 : :
481 : 0 : tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey0.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
482 : 0 : "P2SH(P2PKH)", SCRIPT_VERIFY_P2SH, true
483 : 0 : ).PushSig(keys.key0).Push(keys.pubkey0).PushRedeem());
484 : 0 : tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
485 : 0 : "P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0, true
486 : 0 : ).PushSig(keys.key0).DamagePush(10).PushRedeem());
487 : 0 : tests.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
488 : 0 : "P2SH(P2PKH), bad sig", SCRIPT_VERIFY_P2SH, true
489 : 0 : ).PushSig(keys.key0).DamagePush(10).PushRedeem().ScriptError(SCRIPT_ERR_EQUALVERIFY));
490 : :
491 : 0 : tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
492 : 0 : "3-of-3", 0
493 : 0 : ).Num(0).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
494 : 0 : tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
495 : 0 : "3-of-3, 2 sigs", 0
496 : 0 : ).Num(0).PushSig(keys.key0).PushSig(keys.key1).Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE));
497 : :
498 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
499 : 0 : "P2SH(2-of-3)", SCRIPT_VERIFY_P2SH, true
500 : 0 : ).Num(0).PushSig(keys.key1).PushSig(keys.key2).PushRedeem());
501 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
502 : 0 : "P2SH(2-of-3), 1 sig", SCRIPT_VERIFY_P2SH, true
503 : 0 : ).Num(0).PushSig(keys.key1).Num(0).PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
504 : :
505 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
506 : 0 : "P2PK with too much R padding but no DERSIG", 0
507 : 0 : ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000"));
508 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
509 : 0 : "P2PK with too much R padding", SCRIPT_VERIFY_DERSIG
510 : 0 : ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").ScriptError(SCRIPT_ERR_SIG_DER));
511 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
512 : 0 : "P2PK with too much S padding but no DERSIG", 0
513 : 0 : ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100"));
514 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
515 : 0 : "P2PK with too much S padding", SCRIPT_VERIFY_DERSIG
516 : 0 : ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100").ScriptError(SCRIPT_ERR_SIG_DER));
517 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
518 : 0 : "P2PK with too little R padding but no DERSIG", 0
519 : 0 : ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
520 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
521 : 0 : "P2PK with too little R padding", SCRIPT_VERIFY_DERSIG
522 : 0 : ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER));
523 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT,
524 : 0 : "P2PK NOT with bad sig with too much R padding but no DERSIG", 0
525 : 0 : ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10));
526 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT,
527 : 0 : "P2PK NOT with bad sig with too much R padding", SCRIPT_VERIFY_DERSIG
528 : 0 : ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10).ScriptError(SCRIPT_ERR_SIG_DER));
529 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT,
530 : 0 : "P2PK NOT with too much R padding but no DERSIG", 0
531 : 0 : ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").ScriptError(SCRIPT_ERR_EVAL_FALSE));
532 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT,
533 : 0 : "P2PK NOT with too much R padding", SCRIPT_VERIFY_DERSIG
534 : 0 : ).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").ScriptError(SCRIPT_ERR_SIG_DER));
535 : :
536 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
537 : 0 : "BIP66 example 1, without DERSIG", 0
538 : 0 : ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
539 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
540 : 0 : "BIP66 example 1, with DERSIG", SCRIPT_VERIFY_DERSIG
541 : 0 : ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER));
542 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
543 : 0 : "BIP66 example 2, without DERSIG", 0
544 : 0 : ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_EVAL_FALSE));
545 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
546 : 0 : "BIP66 example 2, with DERSIG", SCRIPT_VERIFY_DERSIG
547 : 0 : ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER));
548 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
549 : 0 : "BIP66 example 3, without DERSIG", 0
550 : 0 : ).Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE));
551 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
552 : 0 : "BIP66 example 3, with DERSIG", SCRIPT_VERIFY_DERSIG
553 : 0 : ).Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE));
554 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
555 : 0 : "BIP66 example 4, without DERSIG", 0
556 : 0 : ).Num(0));
557 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
558 : 0 : "BIP66 example 4, with DERSIG", SCRIPT_VERIFY_DERSIG
559 : 0 : ).Num(0));
560 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
561 : 0 : "BIP66 example 5, without DERSIG", 0
562 : 0 : ).Num(1).ScriptError(SCRIPT_ERR_EVAL_FALSE));
563 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
564 : 0 : "BIP66 example 5, with DERSIG", SCRIPT_VERIFY_DERSIG
565 : 0 : ).Num(1).ScriptError(SCRIPT_ERR_SIG_DER));
566 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
567 : 0 : "BIP66 example 6, without DERSIG", 0
568 : 0 : ).Num(1));
569 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
570 : 0 : "BIP66 example 6, with DERSIG", SCRIPT_VERIFY_DERSIG
571 : 0 : ).Num(1).ScriptError(SCRIPT_ERR_SIG_DER));
572 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
573 : 0 : "BIP66 example 7, without DERSIG", 0
574 : 0 : ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
575 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
576 : 0 : "BIP66 example 7, with DERSIG", SCRIPT_VERIFY_DERSIG
577 : 0 : ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2).ScriptError(SCRIPT_ERR_SIG_DER));
578 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
579 : 0 : "BIP66 example 8, without DERSIG", 0
580 : 0 : ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2).ScriptError(SCRIPT_ERR_EVAL_FALSE));
581 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
582 : 0 : "BIP66 example 8, with DERSIG", SCRIPT_VERIFY_DERSIG
583 : 0 : ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2).ScriptError(SCRIPT_ERR_SIG_DER));
584 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
585 : 0 : "BIP66 example 9, without DERSIG", 0
586 : 0 : ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_EVAL_FALSE));
587 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
588 : 0 : "BIP66 example 9, with DERSIG", SCRIPT_VERIFY_DERSIG
589 : 0 : ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER));
590 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
591 : 0 : "BIP66 example 10, without DERSIG", 0
592 : 0 : ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220"));
593 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
594 : 0 : "BIP66 example 10, with DERSIG", SCRIPT_VERIFY_DERSIG
595 : 0 : ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").ScriptError(SCRIPT_ERR_SIG_DER));
596 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
597 : 0 : "BIP66 example 11, without DERSIG", 0
598 : 0 : ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE));
599 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
600 : 0 : "BIP66 example 11, with DERSIG", SCRIPT_VERIFY_DERSIG
601 : 0 : ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0).ScriptError(SCRIPT_ERR_EVAL_FALSE));
602 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
603 : 0 : "BIP66 example 12, without DERSIG", 0
604 : 0 : ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
605 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
606 : 0 : "BIP66 example 12, with DERSIG", SCRIPT_VERIFY_DERSIG
607 : 0 : ).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
608 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
609 : 0 : "P2PK with multi-byte hashtype, without DERSIG", 0
610 : 0 : ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101"));
611 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
612 : 0 : "P2PK with multi-byte hashtype, with DERSIG", SCRIPT_VERIFY_DERSIG
613 : 0 : ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101").ScriptError(SCRIPT_ERR_SIG_DER));
614 : :
615 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
616 : 0 : "P2PK with high S but no LOW_S", 0
617 : 0 : ).PushSig(keys.key2, SIGHASH_ALL, 32, 33));
618 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
619 : 0 : "P2PK with high S", SCRIPT_VERIFY_LOW_S
620 : 0 : ).PushSig(keys.key2, SIGHASH_ALL, 32, 33).ScriptError(SCRIPT_ERR_SIG_HIGH_S));
621 : :
622 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG,
623 : 0 : "P2PK with hybrid pubkey but no STRICTENC", 0
624 : 0 : ).PushSig(keys.key0, SIGHASH_ALL));
625 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG,
626 : 0 : "P2PK with hybrid pubkey", SCRIPT_VERIFY_STRICTENC
627 : 0 : ).PushSig(keys.key0, SIGHASH_ALL).ScriptError(SCRIPT_ERR_PUBKEYTYPE));
628 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
629 : 0 : "P2PK NOT with hybrid pubkey but no STRICTENC", 0
630 : 0 : ).PushSig(keys.key0, SIGHASH_ALL).ScriptError(SCRIPT_ERR_EVAL_FALSE));
631 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
632 : 0 : "P2PK NOT with hybrid pubkey", SCRIPT_VERIFY_STRICTENC
633 : 0 : ).PushSig(keys.key0, SIGHASH_ALL).ScriptError(SCRIPT_ERR_PUBKEYTYPE));
634 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
635 : 0 : "P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0
636 : 0 : ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10));
637 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
638 : 0 : "P2PK NOT with invalid hybrid pubkey", SCRIPT_VERIFY_STRICTENC
639 : 0 : ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10).ScriptError(SCRIPT_ERR_PUBKEYTYPE));
640 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
641 : 0 : "1-of-2 with the second 1 hybrid pubkey and no STRICTENC", 0
642 : 0 : ).Num(0).PushSig(keys.key1, SIGHASH_ALL));
643 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
644 : 0 : "1-of-2 with the second 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC
645 : 0 : ).Num(0).PushSig(keys.key1, SIGHASH_ALL));
646 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0H) << OP_2 << OP_CHECKMULTISIG,
647 : 0 : "1-of-2 with the first 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC
648 : 0 : ).Num(0).PushSig(keys.key1, SIGHASH_ALL).ScriptError(SCRIPT_ERR_PUBKEYTYPE));
649 : :
650 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
651 : 0 : "P2PK with undefined hashtype but no STRICTENC", 0
652 : 0 : ).PushSig(keys.key1, 5));
653 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
654 : 0 : "P2PK with undefined hashtype", SCRIPT_VERIFY_STRICTENC
655 : 0 : ).PushSig(keys.key1, 5).ScriptError(SCRIPT_ERR_SIG_HASHTYPE));
656 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT,
657 : 0 : "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC", 0
658 : 0 : ).PushSig(keys.key1, 5).DamagePush(10));
659 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT,
660 : 0 : "P2PK NOT with invalid sig and undefined hashtype", SCRIPT_VERIFY_STRICTENC
661 : 0 : ).PushSig(keys.key1, 5).DamagePush(10).ScriptError(SCRIPT_ERR_SIG_HASHTYPE));
662 : :
663 : 0 : tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
664 : 0 : "3-of-3 with nonzero dummy but no NULLDUMMY", 0
665 : 0 : ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
666 : 0 : tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
667 : 0 : "3-of-3 with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY
668 : 0 : ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).ScriptError(SCRIPT_ERR_SIG_NULLDUMMY));
669 : 0 : tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG << OP_NOT,
670 : 0 : "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY", 0
671 : 0 : ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10));
672 : 0 : tests.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG << OP_NOT,
673 : 0 : "3-of-3 NOT with invalid sig with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY
674 : 0 : ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10).ScriptError(SCRIPT_ERR_SIG_NULLDUMMY));
675 : :
676 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
677 : 0 : "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY", 0
678 : 0 : ).Num(0).PushSig(keys.key1).Opcode(OP_DUP));
679 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
680 : 0 : "2-of-2 with two identical keys and sigs pushed using OP_DUP", SCRIPT_VERIFY_SIGPUSHONLY
681 : 0 : ).Num(0).PushSig(keys.key1).Opcode(OP_DUP).ScriptError(SCRIPT_ERR_SIG_PUSHONLY));
682 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
683 : 0 : "P2SH(P2PK) with non-push scriptSig but no P2SH or SIGPUSHONLY", 0, true
684 : 0 : ).PushSig(keys.key2).Opcode(OP_NOP8).PushRedeem());
685 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
686 : 0 : "P2PK with non-push scriptSig but with P2SH validation", 0
687 : 0 : ).PushSig(keys.key2).Opcode(OP_NOP8));
688 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
689 : 0 : "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY", SCRIPT_VERIFY_P2SH, true
690 : 0 : ).PushSig(keys.key2).Opcode(OP_NOP8).PushRedeem().ScriptError(SCRIPT_ERR_SIG_PUSHONLY));
691 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
692 : 0 : "P2SH(P2PK) with non-push scriptSig but not P2SH", SCRIPT_VERIFY_SIGPUSHONLY, true
693 : 0 : ).PushSig(keys.key2).Opcode(OP_NOP8).PushRedeem().ScriptError(SCRIPT_ERR_SIG_PUSHONLY));
694 : 0 : tests.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
695 : 0 : "2-of-2 with two identical keys and sigs pushed", SCRIPT_VERIFY_SIGPUSHONLY
696 : 0 : ).Num(0).PushSig(keys.key1).PushSig(keys.key1));
697 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
698 : 0 : "P2PK with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH
699 : 0 : ).Num(11).PushSig(keys.key0));
700 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
701 : 0 : "P2PK with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH
702 : 0 : ).Num(11).PushSig(keys.key0).ScriptError(SCRIPT_ERR_CLEANSTACK));
703 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
704 : 0 : "P2SH with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH, true
705 : 0 : ).Num(11).PushSig(keys.key0).PushRedeem());
706 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
707 : 0 : "P2SH with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true
708 : 0 : ).Num(11).PushSig(keys.key0).PushRedeem().ScriptError(SCRIPT_ERR_CLEANSTACK));
709 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
710 : 0 : "P2SH with CLEANSTACK", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true
711 : 0 : ).PushSig(keys.key0).PushRedeem());
712 : :
713 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
714 : 0 : "Basic P2WSH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH,
715 : 0 : 0, 1).PushWitSig(keys.key0).PushWitRedeem());
716 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
717 : 0 : "Basic P2WPKH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::PKH,
718 : 0 : 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit());
719 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
720 : 0 : "Basic P2SH(P2WSH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::SH,
721 : 0 : 0, 1).PushWitSig(keys.key0).PushWitRedeem().PushRedeem());
722 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
723 : 0 : "Basic P2SH(P2WPKH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::PKH,
724 : 0 : 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().PushRedeem());
725 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
726 : 0 : "Basic P2WSH with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH
727 : 0 : ).PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
728 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1),
729 : 0 : "Basic P2WPKH with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::PKH
730 : 0 : ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().ScriptError(SCRIPT_ERR_EVAL_FALSE));
731 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
732 : 0 : "Basic P2SH(P2WSH) with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::SH
733 : 0 : ).PushWitSig(keys.key0).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
734 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1),
735 : 0 : "Basic P2SH(P2WPKH) with the wrong key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::PKH
736 : 0 : ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
737 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
738 : 0 : "Basic P2WSH with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, false, WitnessMode::SH
739 : 0 : ).PushWitSig(keys.key0).PushWitRedeem());
740 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1),
741 : 0 : "Basic P2WPKH with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, false, WitnessMode::PKH
742 : 0 : ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit());
743 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
744 : 0 : "Basic P2SH(P2WSH) with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, true, WitnessMode::SH
745 : 0 : ).PushWitSig(keys.key0).PushWitRedeem().PushRedeem());
746 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1),
747 : 0 : "Basic P2SH(P2WPKH) with the wrong key but no WITNESS", SCRIPT_VERIFY_P2SH, true, WitnessMode::PKH
748 : 0 : ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().PushRedeem());
749 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
750 : 0 : "Basic P2WSH with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH,
751 : 0 : 0, 0).PushWitSig(keys.key0, 1).PushWitRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
752 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
753 : 0 : "Basic P2WPKH with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::PKH,
754 : 0 : 0, 0).PushWitSig(keys.key0, 1).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_EVAL_FALSE));
755 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
756 : 0 : "Basic P2SH(P2WSH) with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::SH,
757 : 0 : 0, 0).PushWitSig(keys.key0, 1).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
758 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
759 : 0 : "Basic P2SH(P2WPKH) with wrong value", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::PKH,
760 : 0 : 0, 0).PushWitSig(keys.key0, 1).Push(keys.pubkey0).AsWit().PushRedeem().ScriptError(SCRIPT_ERR_EVAL_FALSE));
761 : :
762 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
763 : 0 : "P2WPKH with future witness version", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH |
764 : : SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM, false, WitnessMode::PKH, 1
765 : 0 : ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM));
766 : : {
767 : 0 : CScript witscript = CScript() << ToByteVector(keys.pubkey0);
768 : 0 : uint256 hash;
769 : 0 : CSHA256().Write(witscript.data(), witscript.size()).Finalize(hash.begin());
770 : 0 : std::vector<unsigned char> hashBytes = ToByteVector(hash);
771 : 0 : hashBytes.pop_back();
772 : 0 : tests.push_back(TestBuilder(CScript() << OP_0 << hashBytes,
773 : 0 : "P2WPKH with wrong witness program length", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false
774 : 0 : ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH));
775 : 0 : }
776 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
777 : 0 : "P2WSH with empty witness", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH
778 : 0 : ).ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY));
779 : : {
780 : 0 : CScript witscript = CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG;
781 : 0 : tests.push_back(TestBuilder(witscript,
782 : 0 : "P2WSH with witness program mismatch", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH
783 : 0 : ).PushWitSig(keys.key0).Push(witscript).DamagePush(0).AsWit().ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH));
784 : 0 : }
785 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
786 : 0 : "P2WPKH with witness program mismatch", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::PKH
787 : 0 : ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().Push("0").AsWit().ScriptError(SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH));
788 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
789 : 0 : "P2WPKH with non-empty scriptSig", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::PKH
790 : 0 : ).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().Num(11).ScriptError(SCRIPT_ERR_WITNESS_MALLEATED));
791 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1),
792 : 0 : "P2SH(P2WPKH) with superfluous push in scriptSig", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::PKH
793 : 0 : ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().Num(11).PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_MALLEATED_P2SH));
794 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
795 : 0 : "P2PK with witness", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH
796 : 0 : ).PushSig(keys.key0).Push("0").AsWit().ScriptError(SCRIPT_ERR_WITNESS_UNEXPECTED));
797 : :
798 : : // Compressed keys should pass SCRIPT_VERIFY_WITNESS_PUBKEYTYPE
799 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
800 : 0 : "Basic P2WSH with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
801 : 0 : 0, 1).PushWitSig(keys.key0C).PushWitRedeem());
802 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C),
803 : 0 : "Basic P2WPKH with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::PKH,
804 : 0 : 0, 1).PushWitSig(keys.key0C).Push(keys.pubkey0C).AsWit());
805 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
806 : 0 : "Basic P2SH(P2WSH) with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
807 : 0 : 0, 1).PushWitSig(keys.key0C).PushWitRedeem().PushRedeem());
808 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C),
809 : 0 : "Basic P2SH(P2WPKH) with compressed key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::PKH,
810 : 0 : 0, 1).PushWitSig(keys.key0C).Push(keys.pubkey0C).AsWit().PushRedeem());
811 : :
812 : : // Testing uncompressed key in witness with SCRIPT_VERIFY_WITNESS_PUBKEYTYPE
813 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
814 : 0 : "Basic P2WSH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
815 : 0 : 0, 1).PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
816 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
817 : 0 : "Basic P2WPKH", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::PKH,
818 : 0 : 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
819 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
820 : 0 : "Basic P2SH(P2WSH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
821 : 0 : 0, 1).PushWitSig(keys.key0).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
822 : 0 : tests.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0),
823 : 0 : "Basic P2SH(P2WPKH)", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::PKH,
824 : 0 : 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
825 : :
826 : : // P2WSH 1-of-2 multisig with compressed keys
827 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
828 : 0 : "P2WSH CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
829 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem());
830 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
831 : 0 : "P2SH(P2WSH) CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
832 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem());
833 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
834 : 0 : "P2WSH CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
835 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem());
836 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
837 : 0 : "P2SH(P2WSH) CHECKMULTISIG with compressed keys", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
838 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem());
839 : :
840 : : // P2WSH 1-of-2 multisig with first key uncompressed
841 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
842 : 0 : "P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH,
843 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem());
844 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
845 : 0 : "P2SH(P2WSH) CHECKMULTISIG first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::SH,
846 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().PushRedeem());
847 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
848 : 0 : "P2WSH CHECKMULTISIG with first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
849 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
850 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
851 : 0 : "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
852 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
853 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
854 : 0 : "P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH,
855 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem());
856 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
857 : 0 : "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::SH,
858 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem());
859 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
860 : 0 : "P2WSH CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
861 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
862 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0) << OP_2 << OP_CHECKMULTISIG,
863 : 0 : "P2SH(P2WSH) CHECKMULTISIG with first key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
864 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
865 : : // P2WSH 1-of-2 multisig with second key uncompressed
866 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
867 : 0 : "P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH,
868 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem());
869 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
870 : 0 : "P2SH(P2WSH) CHECKMULTISIG second key uncompressed and signing with the first key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::SH,
871 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem());
872 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
873 : 0 : "P2WSH CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
874 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem());
875 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
876 : 0 : "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the first key should pass as the uncompressed key is not used", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
877 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem());
878 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
879 : 0 : "P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false, WitnessMode::SH,
880 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem());
881 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
882 : 0 : "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true, WitnessMode::SH,
883 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().PushRedeem());
884 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
885 : 0 : "P2WSH CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, false, WitnessMode::SH,
886 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
887 : 0 : tests.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1) << ToByteVector(keys.pubkey0C) << OP_2 << OP_CHECKMULTISIG,
888 : 0 : "P2SH(P2WSH) CHECKMULTISIG with second key uncompressed and signing with the second key", SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, true, WitnessMode::SH,
889 : 0 : 0, 1).Push(CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().PushRedeem().ScriptError(SCRIPT_ERR_WITNESS_PUBKEYTYPE));
890 : :
891 : 0 : std::set<std::string> tests_set;
892 : :
893 : : {
894 : 0 : UniValue json_tests = read_json(json_tests::script_tests);
895 : :
896 : 0 : for (unsigned int idx = 0; idx < json_tests.size(); idx++) {
897 : 0 : const UniValue& tv = json_tests[idx];
898 : 0 : tests_set.insert(JSONPrettyPrint(tv.get_array()));
899 : 0 : }
900 : 0 : }
901 : :
902 : : #ifdef UPDATE_JSON_TESTS
903 : : std::string strGen;
904 : : #endif
905 : 0 : for (TestBuilder& test : tests) {
906 : 0 : test.Test();
907 : 0 : std::string str = JSONPrettyPrint(test.GetJSON());
908 : : #ifdef UPDATE_JSON_TESTS
909 : : strGen += str + ",\n";
910 : : #else
911 : 0 : if (tests_set.count(str) == 0) {
912 : 0 : BOOST_CHECK_MESSAGE(false, "Missing auto script_valid test: " + test.GetComment());
913 : 0 : }
914 : : #endif
915 : 0 : }
916 : :
917 : : #ifdef UPDATE_JSON_TESTS
918 : : FILE* file = fsbridge::fopen("script_tests.json.gen", "w");
919 : : fputs(strGen.c_str(), file);
920 : : fclose(file);
921 : : #endif
922 : 0 : }
923 : :
924 : 0 : BOOST_AUTO_TEST_CASE(script_json_test)
925 : : {
926 : : // Read tests from test/data/script_tests.json
927 : : // Format is an array of arrays
928 : : // Inner arrays are [ ["wit"..., nValue]?, "scriptSig", "scriptPubKey", "flags", "expected_scripterror" ]
929 : : // ... where scriptSig and scriptPubKey are stringified
930 : : // scripts.
931 : : // If a witness is given, then the last value in the array should be the
932 : : // amount (nValue) to use in the crediting tx
933 : 0 : UniValue tests = read_json(json_tests::script_tests);
934 : :
935 : 0 : for (unsigned int idx = 0; idx < tests.size(); idx++) {
936 : 0 : const UniValue& test = tests[idx];
937 : 0 : std::string strTest = test.write();
938 : 0 : CScriptWitness witness;
939 : 0 : CAmount nValue = 0;
940 : 0 : unsigned int pos = 0;
941 : 0 : if (test.size() > 0 && test[pos].isArray()) {
942 : 0 : unsigned int i=0;
943 : 0 : for (i = 0; i < test[pos].size()-1; i++) {
944 : 0 : witness.stack.push_back(ParseHex(test[pos][i].get_str()));
945 : 0 : }
946 : 0 : nValue = AmountFromValue(test[pos][i]);
947 : 0 : pos++;
948 : 0 : }
949 : 0 : if (test.size() < 4 + pos) // Allow size > 3; extra stuff ignored (useful for comments)
950 : : {
951 : 0 : if (test.size() != 1) {
952 : 0 : BOOST_ERROR("Bad test: " << strTest);
953 : 0 : }
954 : 0 : continue;
955 : : }
956 : 0 : std::string scriptSigString = test[pos++].get_str();
957 : 0 : CScript scriptSig = ParseScript(scriptSigString);
958 : 0 : std::string scriptPubKeyString = test[pos++].get_str();
959 : 0 : CScript scriptPubKey = ParseScript(scriptPubKeyString);
960 : 0 : unsigned int scriptflags = ParseScriptFlags(test[pos++].get_str());
961 : 0 : int scriptError = ParseScriptError(test[pos++].get_str());
962 : :
963 : 0 : DoTest(scriptPubKey, scriptSig, witness, scriptflags, strTest, scriptError, nValue);
964 : 0 : }
965 : 0 : }
966 : :
967 : 0 : BOOST_AUTO_TEST_CASE(script_PushData)
968 : : {
969 : : // Check that PUSHDATA1, PUSHDATA2, and PUSHDATA4 create the same value on
970 : : // the stack as the 1-75 opcodes do.
971 : : static const unsigned char direct[] = { 1, 0x5a };
972 : : static const unsigned char pushdata1[] = { OP_PUSHDATA1, 1, 0x5a };
973 : : static const unsigned char pushdata2[] = { OP_PUSHDATA2, 1, 0, 0x5a };
974 : : static const unsigned char pushdata4[] = { OP_PUSHDATA4, 1, 0, 0, 0, 0x5a };
975 : :
976 : : ScriptError err;
977 : 0 : std::vector<std::vector<unsigned char> > directStack;
978 : 0 : BOOST_CHECK(EvalScript(directStack, CScript(direct, direct + sizeof(direct)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
979 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
980 : :
981 : 0 : std::vector<std::vector<unsigned char> > pushdata1Stack;
982 : 0 : BOOST_CHECK(EvalScript(pushdata1Stack, CScript(pushdata1, pushdata1 + sizeof(pushdata1)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
983 : 0 : BOOST_CHECK(pushdata1Stack == directStack);
984 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
985 : :
986 : 0 : std::vector<std::vector<unsigned char> > pushdata2Stack;
987 : 0 : BOOST_CHECK(EvalScript(pushdata2Stack, CScript(pushdata2, pushdata2 + sizeof(pushdata2)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
988 : 0 : BOOST_CHECK(pushdata2Stack == directStack);
989 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
990 : :
991 : 0 : std::vector<std::vector<unsigned char> > pushdata4Stack;
992 : 0 : BOOST_CHECK(EvalScript(pushdata4Stack, CScript(pushdata4, pushdata4 + sizeof(pushdata4)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
993 : 0 : BOOST_CHECK(pushdata4Stack == directStack);
994 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
995 : :
996 : 0 : const std::vector<unsigned char> pushdata1_trunc{OP_PUSHDATA1, 1};
997 : 0 : const std::vector<unsigned char> pushdata2_trunc{OP_PUSHDATA2, 1, 0};
998 : 0 : const std::vector<unsigned char> pushdata4_trunc{OP_PUSHDATA4, 1, 0, 0, 0};
999 : :
1000 : 0 : std::vector<std::vector<unsigned char>> stack_ignore;
1001 : 0 : BOOST_CHECK(!EvalScript(stack_ignore, CScript(pushdata1_trunc.begin(), pushdata1_trunc.end()), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
1002 : 0 : BOOST_CHECK_EQUAL(err, SCRIPT_ERR_BAD_OPCODE);
1003 : 0 : BOOST_CHECK(!EvalScript(stack_ignore, CScript(pushdata2_trunc.begin(), pushdata2_trunc.end()), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
1004 : 0 : BOOST_CHECK_EQUAL(err, SCRIPT_ERR_BAD_OPCODE);
1005 : 0 : BOOST_CHECK(!EvalScript(stack_ignore, CScript(pushdata4_trunc.begin(), pushdata4_trunc.end()), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
1006 : 0 : BOOST_CHECK_EQUAL(err, SCRIPT_ERR_BAD_OPCODE);
1007 : 0 : }
1008 : :
1009 : 0 : BOOST_AUTO_TEST_CASE(script_cltv_truncated)
1010 : : {
1011 : 0 : const auto script_cltv_trunc = CScript() << OP_CHECKLOCKTIMEVERIFY;
1012 : :
1013 : 0 : std::vector<std::vector<unsigned char>> stack_ignore;
1014 : : ScriptError err;
1015 : 0 : BOOST_CHECK(!EvalScript(stack_ignore, script_cltv_trunc, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, BaseSignatureChecker(), SigVersion::BASE, &err));
1016 : 0 : BOOST_CHECK_EQUAL(err, SCRIPT_ERR_INVALID_STACK_OPERATION);
1017 : 0 : }
1018 : :
1019 : : static CScript
1020 : 0 : sign_multisig(const CScript& scriptPubKey, const std::vector<CKey>& keys, const CTransaction& transaction)
1021 : : {
1022 : 0 : uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL, 0, SigVersion::BASE);
1023 : :
1024 : 0 : CScript result;
1025 : : //
1026 : : // NOTE: CHECKMULTISIG has an unfortunate bug; it requires
1027 : : // one extra item on the stack, before the signatures.
1028 : : // Putting OP_0 on the stack is the workaround;
1029 : : // fixing the bug would mean splitting the block chain (old
1030 : : // clients would not accept new CHECKMULTISIG transactions,
1031 : : // and vice-versa)
1032 : : //
1033 : 0 : result << OP_0;
1034 : 0 : for (const CKey &key : keys)
1035 : : {
1036 : 0 : std::vector<unsigned char> vchSig;
1037 : 0 : BOOST_CHECK(key.Sign(hash, vchSig));
1038 : 0 : vchSig.push_back((unsigned char)SIGHASH_ALL);
1039 : 0 : result << vchSig;
1040 : 0 : }
1041 : 0 : return result;
1042 : 0 : }
1043 : : static CScript
1044 : 0 : sign_multisig(const CScript& scriptPubKey, const CKey& key, const CTransaction& transaction)
1045 : : {
1046 : 0 : std::vector<CKey> keys;
1047 : 0 : keys.push_back(key);
1048 : 0 : return sign_multisig(scriptPubKey, keys, transaction);
1049 : 0 : }
1050 : :
1051 : 0 : BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12)
1052 : : {
1053 : : ScriptError err;
1054 : 0 : CKey key1, key2, key3;
1055 : 0 : key1.MakeNewKey(true);
1056 : 0 : key2.MakeNewKey(false);
1057 : 0 : key3.MakeNewKey(true);
1058 : :
1059 : 0 : CScript scriptPubKey12;
1060 : 0 : scriptPubKey12 << OP_1 << ToByteVector(key1.GetPubKey()) << ToByteVector(key2.GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
1061 : :
1062 : 0 : const CTransaction txFrom12{BuildCreditingTransaction(scriptPubKey12)};
1063 : 0 : CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom12);
1064 : :
1065 : 0 : CScript goodsig1 = sign_multisig(scriptPubKey12, key1, CTransaction(txTo12));
1066 : 0 : BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
1067 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
1068 : 0 : txTo12.vout[0].nValue = 2;
1069 : 0 : BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
1070 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
1071 : :
1072 : 0 : CScript goodsig2 = sign_multisig(scriptPubKey12, key2, CTransaction(txTo12));
1073 : 0 : BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
1074 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
1075 : :
1076 : 0 : CScript badsig1 = sign_multisig(scriptPubKey12, key3, CTransaction(txTo12));
1077 : 0 : BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
1078 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
1079 : 0 : }
1080 : :
1081 : 0 : BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
1082 : : {
1083 : : ScriptError err;
1084 : 0 : CKey key1, key2, key3, key4;
1085 : 0 : key1.MakeNewKey(true);
1086 : 0 : key2.MakeNewKey(false);
1087 : 0 : key3.MakeNewKey(true);
1088 : 0 : key4.MakeNewKey(false);
1089 : :
1090 : 0 : CScript scriptPubKey23;
1091 : 0 : scriptPubKey23 << OP_2 << ToByteVector(key1.GetPubKey()) << ToByteVector(key2.GetPubKey()) << ToByteVector(key3.GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
1092 : :
1093 : 0 : const CTransaction txFrom23{BuildCreditingTransaction(scriptPubKey23)};
1094 : 0 : CMutableTransaction txTo23 = BuildSpendingTransaction(CScript(), CScriptWitness(), txFrom23);
1095 : :
1096 : 0 : std::vector<CKey> keys;
1097 : 0 : keys.push_back(key1); keys.push_back(key2);
1098 : 0 : CScript goodsig1 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
1099 : 0 : BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
1100 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
1101 : :
1102 : 0 : keys.clear();
1103 : 0 : keys.push_back(key1); keys.push_back(key3);
1104 : 0 : CScript goodsig2 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
1105 : 0 : BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
1106 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
1107 : :
1108 : 0 : keys.clear();
1109 : 0 : keys.push_back(key2); keys.push_back(key3);
1110 : 0 : CScript goodsig3 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
1111 : 0 : BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
1112 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
1113 : :
1114 : 0 : keys.clear();
1115 : 0 : keys.push_back(key2); keys.push_back(key2); // Can't re-use sig
1116 : 0 : CScript badsig1 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
1117 : 0 : BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
1118 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
1119 : :
1120 : 0 : keys.clear();
1121 : 0 : keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order
1122 : 0 : CScript badsig2 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
1123 : 0 : BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
1124 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
1125 : :
1126 : 0 : keys.clear();
1127 : 0 : keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order
1128 : 0 : CScript badsig3 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
1129 : 0 : BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
1130 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
1131 : :
1132 : 0 : keys.clear();
1133 : 0 : keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys
1134 : 0 : CScript badsig4 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
1135 : 0 : BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
1136 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
1137 : :
1138 : 0 : keys.clear();
1139 : 0 : keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys
1140 : 0 : CScript badsig5 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
1141 : 0 : BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
1142 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
1143 : :
1144 : 0 : keys.clear(); // Must have signatures
1145 : 0 : CScript badsig6 = sign_multisig(scriptPubKey23, keys, CTransaction(txTo23));
1146 : 0 : BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, nullptr, gFlags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err));
1147 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
1148 : 0 : }
1149 : :
1150 : : /* Wrapper around ProduceSignature to combine two scriptsigs */
1151 : 0 : SignatureData CombineSignatures(const CTxOut& txout, const CMutableTransaction& tx, const SignatureData& scriptSig1, const SignatureData& scriptSig2)
1152 : : {
1153 : 0 : SignatureData data;
1154 : 0 : data.MergeSignatureData(scriptSig1);
1155 : 0 : data.MergeSignatureData(scriptSig2);
1156 : 0 : ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(tx, 0, txout.nValue, SIGHASH_DEFAULT), txout.scriptPubKey, data);
1157 : 0 : return data;
1158 : 0 : }
1159 : :
1160 : 0 : BOOST_AUTO_TEST_CASE(script_combineSigs)
1161 : : {
1162 : : // Test the ProduceSignature's ability to combine signatures function
1163 : 0 : FillableSigningProvider keystore;
1164 : 0 : std::vector<CKey> keys;
1165 : 0 : std::vector<CPubKey> pubkeys;
1166 : 0 : for (int i = 0; i < 3; i++)
1167 : : {
1168 : 0 : CKey key;
1169 : 0 : key.MakeNewKey(i%2 == 1);
1170 : 0 : keys.push_back(key);
1171 : 0 : pubkeys.push_back(key.GetPubKey());
1172 : 0 : BOOST_CHECK(keystore.AddKey(key));
1173 : 0 : }
1174 : :
1175 : 0 : CMutableTransaction txFrom = BuildCreditingTransaction(GetScriptForDestination(PKHash(keys[0].GetPubKey())));
1176 : 0 : CMutableTransaction txTo = BuildSpendingTransaction(CScript(), CScriptWitness(), CTransaction(txFrom));
1177 : 0 : CScript& scriptPubKey = txFrom.vout[0].scriptPubKey;
1178 : 0 : SignatureData scriptSig;
1179 : :
1180 : 0 : SignatureData empty;
1181 : 0 : SignatureData combined = CombineSignatures(txFrom.vout[0], txTo, empty, empty);
1182 : 0 : BOOST_CHECK(combined.scriptSig.empty());
1183 : :
1184 : : // Single signature case:
1185 : 0 : SignatureData dummy;
1186 : 0 : BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL, dummy)); // changes scriptSig
1187 : 0 : scriptSig = DataFromTransaction(txTo, 0, txFrom.vout[0]);
1188 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, scriptSig, empty);
1189 : 0 : BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
1190 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, empty, scriptSig);
1191 : 0 : BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
1192 : 0 : SignatureData scriptSigCopy = scriptSig;
1193 : : // Signing again will give a different, valid signature:
1194 : 0 : SignatureData dummy_b;
1195 : 0 : BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL, dummy_b));
1196 : 0 : scriptSig = DataFromTransaction(txTo, 0, txFrom.vout[0]);
1197 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, scriptSigCopy, scriptSig);
1198 : 0 : BOOST_CHECK(combined.scriptSig == scriptSigCopy.scriptSig || combined.scriptSig == scriptSig.scriptSig);
1199 : :
1200 : : // P2SH, single-signature case:
1201 : 0 : CScript pkSingle; pkSingle << ToByteVector(keys[0].GetPubKey()) << OP_CHECKSIG;
1202 : 0 : BOOST_CHECK(keystore.AddCScript(pkSingle));
1203 : 0 : scriptPubKey = GetScriptForDestination(ScriptHash(pkSingle));
1204 : 0 : SignatureData dummy_c;
1205 : 0 : BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL, dummy_c));
1206 : 0 : scriptSig = DataFromTransaction(txTo, 0, txFrom.vout[0]);
1207 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, scriptSig, empty);
1208 : 0 : BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
1209 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, empty, scriptSig);
1210 : 0 : BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
1211 : 0 : scriptSigCopy = scriptSig;
1212 : 0 : SignatureData dummy_d;
1213 : 0 : BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL, dummy_d));
1214 : 0 : scriptSig = DataFromTransaction(txTo, 0, txFrom.vout[0]);
1215 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, scriptSigCopy, scriptSig);
1216 : 0 : BOOST_CHECK(combined.scriptSig == scriptSigCopy.scriptSig || combined.scriptSig == scriptSig.scriptSig);
1217 : :
1218 : : // Hardest case: Multisig 2-of-3
1219 : 0 : scriptPubKey = GetScriptForMultisig(2, pubkeys);
1220 : 0 : BOOST_CHECK(keystore.AddCScript(scriptPubKey));
1221 : 0 : SignatureData dummy_e;
1222 : 0 : BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL, dummy_e));
1223 : 0 : scriptSig = DataFromTransaction(txTo, 0, txFrom.vout[0]);
1224 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, scriptSig, empty);
1225 : 0 : BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
1226 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, empty, scriptSig);
1227 : 0 : BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
1228 : :
1229 : : // A couple of partially-signed versions:
1230 : 0 : std::vector<unsigned char> sig1;
1231 : 0 : uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL, 0, SigVersion::BASE);
1232 : 0 : BOOST_CHECK(keys[0].Sign(hash1, sig1));
1233 : 0 : sig1.push_back(SIGHASH_ALL);
1234 : 0 : std::vector<unsigned char> sig2;
1235 : 0 : uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE, 0, SigVersion::BASE);
1236 : 0 : BOOST_CHECK(keys[1].Sign(hash2, sig2));
1237 : 0 : sig2.push_back(SIGHASH_NONE);
1238 : 0 : std::vector<unsigned char> sig3;
1239 : 0 : uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE, 0, SigVersion::BASE);
1240 : 0 : BOOST_CHECK(keys[2].Sign(hash3, sig3));
1241 : 0 : sig3.push_back(SIGHASH_SINGLE);
1242 : :
1243 : : // Not fussy about order (or even existence) of placeholders or signatures:
1244 : 0 : CScript partial1a = CScript() << OP_0 << sig1 << OP_0;
1245 : 0 : CScript partial1b = CScript() << OP_0 << OP_0 << sig1;
1246 : 0 : CScript partial2a = CScript() << OP_0 << sig2;
1247 : 0 : CScript partial2b = CScript() << sig2 << OP_0;
1248 : 0 : CScript partial3a = CScript() << sig3;
1249 : 0 : CScript partial3b = CScript() << OP_0 << OP_0 << sig3;
1250 : 0 : CScript partial3c = CScript() << OP_0 << sig3 << OP_0;
1251 : 0 : CScript complete12 = CScript() << OP_0 << sig1 << sig2;
1252 : 0 : CScript complete13 = CScript() << OP_0 << sig1 << sig3;
1253 : 0 : CScript complete23 = CScript() << OP_0 << sig2 << sig3;
1254 : 0 : SignatureData partial1_sigs;
1255 : 0 : partial1_sigs.signatures.emplace(keys[0].GetPubKey().GetID(), SigPair(keys[0].GetPubKey(), sig1));
1256 : 0 : SignatureData partial2_sigs;
1257 : 0 : partial2_sigs.signatures.emplace(keys[1].GetPubKey().GetID(), SigPair(keys[1].GetPubKey(), sig2));
1258 : 0 : SignatureData partial3_sigs;
1259 : 0 : partial3_sigs.signatures.emplace(keys[2].GetPubKey().GetID(), SigPair(keys[2].GetPubKey(), sig3));
1260 : :
1261 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, partial1_sigs, partial1_sigs);
1262 : 0 : BOOST_CHECK(combined.scriptSig == partial1a);
1263 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, partial1_sigs, partial2_sigs);
1264 : 0 : BOOST_CHECK(combined.scriptSig == complete12);
1265 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, partial2_sigs, partial1_sigs);
1266 : 0 : BOOST_CHECK(combined.scriptSig == complete12);
1267 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, partial1_sigs, partial2_sigs);
1268 : 0 : BOOST_CHECK(combined.scriptSig == complete12);
1269 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, partial3_sigs, partial1_sigs);
1270 : 0 : BOOST_CHECK(combined.scriptSig == complete13);
1271 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, partial2_sigs, partial3_sigs);
1272 : 0 : BOOST_CHECK(combined.scriptSig == complete23);
1273 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, partial3_sigs, partial2_sigs);
1274 : 0 : BOOST_CHECK(combined.scriptSig == complete23);
1275 : 0 : combined = CombineSignatures(txFrom.vout[0], txTo, partial3_sigs, partial3_sigs);
1276 : 0 : BOOST_CHECK(combined.scriptSig == partial3c);
1277 : 0 : }
1278 : :
1279 : 0 : BOOST_AUTO_TEST_CASE(script_standard_push)
1280 : : {
1281 : : ScriptError err;
1282 : 0 : for (int i=0; i<67000; i++) {
1283 : 0 : CScript script;
1284 : 0 : script << i;
1285 : 0 : BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Number " << i << " is not pure push.");
1286 : 0 : BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, nullptr, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Number " << i << " push is not minimal data.");
1287 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
1288 : 0 : }
1289 : :
1290 : 0 : for (unsigned int i=0; i<=MAX_SCRIPT_ELEMENT_SIZE; i++) {
1291 : 0 : std::vector<unsigned char> data(i, '\111');
1292 : 0 : CScript script;
1293 : 0 : script << data;
1294 : 0 : BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Length " << i << " is not pure push.");
1295 : 0 : BOOST_CHECK_MESSAGE(VerifyScript(script, CScript() << OP_1, nullptr, SCRIPT_VERIFY_MINIMALDATA, BaseSignatureChecker(), &err), "Length " << i << " push is not minimal data.");
1296 : 0 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
1297 : 0 : }
1298 : 0 : }
1299 : :
1300 : 0 : BOOST_AUTO_TEST_CASE(script_IsPushOnly_on_invalid_scripts)
1301 : : {
1302 : : // IsPushOnly returns false when given a script containing only pushes that
1303 : : // are invalid due to truncation. IsPushOnly() is consensus critical
1304 : : // because P2SH evaluation uses it, although this specific behavior should
1305 : : // not be consensus critical as the P2SH evaluation would fail first due to
1306 : : // the invalid push. Still, it doesn't hurt to test it explicitly.
1307 : : static const unsigned char direct[] = { 1 };
1308 : 0 : BOOST_CHECK(!CScript(direct, direct+sizeof(direct)).IsPushOnly());
1309 : 0 : }
1310 : :
1311 : 0 : BOOST_AUTO_TEST_CASE(script_GetScriptAsm)
1312 : : {
1313 : 0 : BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_NOP2, true));
1314 : 0 : BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY, true));
1315 : 0 : BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_NOP2));
1316 : 0 : BOOST_CHECK_EQUAL("OP_CHECKLOCKTIMEVERIFY", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY));
1317 : :
1318 : 0 : std::string derSig("304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090");
1319 : 0 : std::string pubKey("03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2");
1320 : 0 : std::vector<unsigned char> vchPubKey = ToByteVector(ParseHex(pubKey));
1321 : :
1322 : 0 : BOOST_CHECK_EQUAL(derSig + "00 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "00")) << vchPubKey, true));
1323 : 0 : BOOST_CHECK_EQUAL(derSig + "80 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "80")) << vchPubKey, true));
1324 : 0 : BOOST_CHECK_EQUAL(derSig + "[ALL] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "01")) << vchPubKey, true));
1325 : 0 : BOOST_CHECK_EQUAL(derSig + "[NONE] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "02")) << vchPubKey, true));
1326 : 0 : BOOST_CHECK_EQUAL(derSig + "[SINGLE] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "03")) << vchPubKey, true));
1327 : 0 : BOOST_CHECK_EQUAL(derSig + "[ALL|ANYONECANPAY] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "81")) << vchPubKey, true));
1328 : 0 : BOOST_CHECK_EQUAL(derSig + "[NONE|ANYONECANPAY] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "82")) << vchPubKey, true));
1329 : 0 : BOOST_CHECK_EQUAL(derSig + "[SINGLE|ANYONECANPAY] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "83")) << vchPubKey, true));
1330 : :
1331 : 0 : BOOST_CHECK_EQUAL(derSig + "00 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "00")) << vchPubKey));
1332 : 0 : BOOST_CHECK_EQUAL(derSig + "80 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "80")) << vchPubKey));
1333 : 0 : BOOST_CHECK_EQUAL(derSig + "01 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "01")) << vchPubKey));
1334 : 0 : BOOST_CHECK_EQUAL(derSig + "02 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "02")) << vchPubKey));
1335 : 0 : BOOST_CHECK_EQUAL(derSig + "03 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "03")) << vchPubKey));
1336 : 0 : BOOST_CHECK_EQUAL(derSig + "81 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "81")) << vchPubKey));
1337 : 0 : BOOST_CHECK_EQUAL(derSig + "82 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "82")) << vchPubKey));
1338 : 0 : BOOST_CHECK_EQUAL(derSig + "83 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "83")) << vchPubKey));
1339 : 0 : }
1340 : :
1341 : 0 : static CScript ScriptFromHex(const std::string& str)
1342 : : {
1343 : 0 : std::vector<unsigned char> data = ParseHex(str);
1344 : 0 : return CScript(data.begin(), data.end());
1345 : 0 : }
1346 : :
1347 : 0 : BOOST_AUTO_TEST_CASE(script_FindAndDelete)
1348 : : {
1349 : : // Exercise the FindAndDelete functionality
1350 : 0 : CScript s;
1351 : 0 : CScript d;
1352 : 0 : CScript expect;
1353 : :
1354 : 0 : s = CScript() << OP_1 << OP_2;
1355 : 0 : d = CScript(); // delete nothing should be a no-op
1356 : 0 : expect = s;
1357 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0);
1358 : 0 : BOOST_CHECK(s == expect);
1359 : :
1360 : 0 : s = CScript() << OP_1 << OP_2 << OP_3;
1361 : 0 : d = CScript() << OP_2;
1362 : 0 : expect = CScript() << OP_1 << OP_3;
1363 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);
1364 : 0 : BOOST_CHECK(s == expect);
1365 : :
1366 : 0 : s = CScript() << OP_3 << OP_1 << OP_3 << OP_3 << OP_4 << OP_3;
1367 : 0 : d = CScript() << OP_3;
1368 : 0 : expect = CScript() << OP_1 << OP_4;
1369 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 4);
1370 : 0 : BOOST_CHECK(s == expect);
1371 : :
1372 : 0 : s = ScriptFromHex("0302ff03"); // PUSH 0x02ff03 onto stack
1373 : 0 : d = ScriptFromHex("0302ff03");
1374 : 0 : expect = CScript();
1375 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);
1376 : 0 : BOOST_CHECK(s == expect);
1377 : :
1378 : 0 : s = ScriptFromHex("0302ff030302ff03"); // PUSH 0x2ff03 PUSH 0x2ff03
1379 : 0 : d = ScriptFromHex("0302ff03");
1380 : 0 : expect = CScript();
1381 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 2);
1382 : 0 : BOOST_CHECK(s == expect);
1383 : :
1384 : 0 : s = ScriptFromHex("0302ff030302ff03");
1385 : 0 : d = ScriptFromHex("02");
1386 : 0 : expect = s; // FindAndDelete matches entire opcodes
1387 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0);
1388 : 0 : BOOST_CHECK(s == expect);
1389 : :
1390 : 0 : s = ScriptFromHex("0302ff030302ff03");
1391 : 0 : d = ScriptFromHex("ff");
1392 : 0 : expect = s;
1393 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0);
1394 : 0 : BOOST_CHECK(s == expect);
1395 : :
1396 : : // This is an odd edge case: strip of the push-three-bytes
1397 : : // prefix, leaving 02ff03 which is push-two-bytes:
1398 : 0 : s = ScriptFromHex("0302ff030302ff03");
1399 : 0 : d = ScriptFromHex("03");
1400 : 0 : expect = CScript() << ParseHex("ff03") << ParseHex("ff03");
1401 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 2);
1402 : 0 : BOOST_CHECK(s == expect);
1403 : :
1404 : : // Byte sequence that spans multiple opcodes:
1405 : 0 : s = ScriptFromHex("02feed5169"); // PUSH(0xfeed) OP_1 OP_VERIFY
1406 : 0 : d = ScriptFromHex("feed51");
1407 : 0 : expect = s;
1408 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0); // doesn't match 'inside' opcodes
1409 : 0 : BOOST_CHECK(s == expect);
1410 : :
1411 : 0 : s = ScriptFromHex("02feed5169"); // PUSH(0xfeed) OP_1 OP_VERIFY
1412 : 0 : d = ScriptFromHex("02feed51");
1413 : 0 : expect = ScriptFromHex("69");
1414 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);
1415 : 0 : BOOST_CHECK(s == expect);
1416 : :
1417 : 0 : s = ScriptFromHex("516902feed5169");
1418 : 0 : d = ScriptFromHex("feed51");
1419 : 0 : expect = s;
1420 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0);
1421 : 0 : BOOST_CHECK(s == expect);
1422 : :
1423 : 0 : s = ScriptFromHex("516902feed5169");
1424 : 0 : d = ScriptFromHex("02feed51");
1425 : 0 : expect = ScriptFromHex("516969");
1426 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);
1427 : 0 : BOOST_CHECK(s == expect);
1428 : :
1429 : 0 : s = CScript() << OP_0 << OP_0 << OP_1 << OP_1;
1430 : 0 : d = CScript() << OP_0 << OP_1;
1431 : 0 : expect = CScript() << OP_0 << OP_1; // FindAndDelete is single-pass
1432 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);
1433 : 0 : BOOST_CHECK(s == expect);
1434 : :
1435 : 0 : s = CScript() << OP_0 << OP_0 << OP_1 << OP_0 << OP_1 << OP_1;
1436 : 0 : d = CScript() << OP_0 << OP_1;
1437 : 0 : expect = CScript() << OP_0 << OP_1; // FindAndDelete is single-pass
1438 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 2);
1439 : 0 : BOOST_CHECK(s == expect);
1440 : :
1441 : : // Another weird edge case:
1442 : : // End with invalid push (not enough data)...
1443 : 0 : s = ScriptFromHex("0003feed");
1444 : 0 : d = ScriptFromHex("03feed"); // ... can remove the invalid push
1445 : 0 : expect = ScriptFromHex("00");
1446 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);
1447 : 0 : BOOST_CHECK(s == expect);
1448 : :
1449 : 0 : s = ScriptFromHex("0003feed");
1450 : 0 : d = ScriptFromHex("00");
1451 : 0 : expect = ScriptFromHex("03feed");
1452 : 0 : BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);
1453 : 0 : BOOST_CHECK(s == expect);
1454 : 0 : }
1455 : :
1456 : 0 : BOOST_AUTO_TEST_CASE(script_HasValidOps)
1457 : : {
1458 : : // Exercise the HasValidOps functionality
1459 : 0 : CScript script;
1460 : 0 : script = ScriptFromHex("76a9141234567890abcdefa1a2a3a4a5a6a7a8a9a0aaab88ac"); // Normal script
1461 : 0 : BOOST_CHECK(script.HasValidOps());
1462 : 0 : script = ScriptFromHex("76a914ff34567890abcdefa1a2a3a4a5a6a7a8a9a0aaab88ac");
1463 : 0 : BOOST_CHECK(script.HasValidOps());
1464 : 0 : script = ScriptFromHex("ff88ac"); // Script with OP_INVALIDOPCODE explicit
1465 : 0 : BOOST_CHECK(!script.HasValidOps());
1466 : 0 : script = ScriptFromHex("88acc0"); // Script with undefined opcode
1467 : 0 : BOOST_CHECK(!script.HasValidOps());
1468 : 0 : }
1469 : :
1470 : 0 : static CMutableTransaction TxFromHex(const std::string& str)
1471 : : {
1472 : 0 : CMutableTransaction tx;
1473 : 0 : SpanReader{SERIALIZE_TRANSACTION_NO_WITNESS, ParseHex(str)} >> tx;
1474 : 0 : return tx;
1475 : 0 : }
1476 : :
1477 : 0 : static std::vector<CTxOut> TxOutsFromJSON(const UniValue& univalue)
1478 : : {
1479 : 0 : assert(univalue.isArray());
1480 : 0 : std::vector<CTxOut> prevouts;
1481 : 0 : for (size_t i = 0; i < univalue.size(); ++i) {
1482 : 0 : CTxOut txout;
1483 : 0 : SpanReader{0, ParseHex(univalue[i].get_str())} >> txout;
1484 : 0 : prevouts.push_back(std::move(txout));
1485 : 0 : }
1486 : 0 : return prevouts;
1487 : 0 : }
1488 : :
1489 : 0 : static CScriptWitness ScriptWitnessFromJSON(const UniValue& univalue)
1490 : : {
1491 : 0 : assert(univalue.isArray());
1492 : 0 : CScriptWitness scriptwitness;
1493 : 0 : for (size_t i = 0; i < univalue.size(); ++i) {
1494 : 0 : auto bytes = ParseHex(univalue[i].get_str());
1495 : 0 : scriptwitness.stack.push_back(std::move(bytes));
1496 : 0 : }
1497 : 0 : return scriptwitness;
1498 : 0 : }
1499 : :
1500 : : #if defined(HAVE_CONSENSUS_LIB)
1501 : :
1502 : : /* Test simple (successful) usage of bitcoinconsensus_verify_script */
1503 : 0 : BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_returns_true)
1504 : : {
1505 : 0 : unsigned int libconsensus_flags = 0;
1506 : 0 : int nIn = 0;
1507 : :
1508 : 0 : CScript scriptPubKey;
1509 : 0 : CScript scriptSig;
1510 : 0 : CScriptWitness wit;
1511 : :
1512 : 0 : scriptPubKey << OP_1;
1513 : 0 : CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)};
1514 : 0 : CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)};
1515 : :
1516 : 0 : CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
1517 : 0 : stream << spendTx;
1518 : :
1519 : : bitcoinconsensus_error err;
1520 : 0 : int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
1521 : 0 : BOOST_CHECK_EQUAL(result, 1);
1522 : 0 : BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_OK);
1523 : 0 : }
1524 : :
1525 : : /* Test bitcoinconsensus_verify_script returns invalid tx index err*/
1526 : 0 : BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_index_err)
1527 : : {
1528 : 0 : unsigned int libconsensus_flags = 0;
1529 : 0 : int nIn = 3;
1530 : :
1531 : 0 : CScript scriptPubKey;
1532 : 0 : CScript scriptSig;
1533 : 0 : CScriptWitness wit;
1534 : :
1535 : 0 : scriptPubKey << OP_EQUAL;
1536 : 0 : CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)};
1537 : 0 : CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)};
1538 : :
1539 : 0 : CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
1540 : 0 : stream << spendTx;
1541 : :
1542 : : bitcoinconsensus_error err;
1543 : 0 : int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
1544 : 0 : BOOST_CHECK_EQUAL(result, 0);
1545 : 0 : BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_INDEX);
1546 : 0 : }
1547 : :
1548 : : /* Test bitcoinconsensus_verify_script returns tx size mismatch err*/
1549 : 0 : BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_size)
1550 : : {
1551 : 0 : unsigned int libconsensus_flags = 0;
1552 : 0 : int nIn = 0;
1553 : :
1554 : 0 : CScript scriptPubKey;
1555 : 0 : CScript scriptSig;
1556 : 0 : CScriptWitness wit;
1557 : :
1558 : 0 : scriptPubKey << OP_EQUAL;
1559 : 0 : CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)};
1560 : 0 : CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)};
1561 : :
1562 : 0 : CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
1563 : 0 : stream << spendTx;
1564 : :
1565 : : bitcoinconsensus_error err;
1566 : 0 : int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size() * 2, nIn, libconsensus_flags, &err);
1567 : 0 : BOOST_CHECK_EQUAL(result, 0);
1568 : 0 : BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH);
1569 : 0 : }
1570 : :
1571 : : /* Test bitcoinconsensus_verify_script returns invalid tx serialization error */
1572 : 0 : BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_tx_serialization)
1573 : : {
1574 : 0 : unsigned int libconsensus_flags = 0;
1575 : 0 : int nIn = 0;
1576 : :
1577 : 0 : CScript scriptPubKey;
1578 : 0 : CScript scriptSig;
1579 : 0 : CScriptWitness wit;
1580 : :
1581 : 0 : scriptPubKey << OP_EQUAL;
1582 : 0 : CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)};
1583 : 0 : CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)};
1584 : :
1585 : 0 : CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
1586 : 0 : stream << 0xffffffff;
1587 : :
1588 : : bitcoinconsensus_error err;
1589 : 0 : int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
1590 : 0 : BOOST_CHECK_EQUAL(result, 0);
1591 : 0 : BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_TX_DESERIALIZE);
1592 : 0 : }
1593 : :
1594 : : /* Test bitcoinconsensus_verify_script returns amount required error */
1595 : 0 : BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_amount_required_err)
1596 : : {
1597 : 0 : unsigned int libconsensus_flags = bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS;
1598 : 0 : int nIn = 0;
1599 : :
1600 : 0 : CScript scriptPubKey;
1601 : 0 : CScript scriptSig;
1602 : 0 : CScriptWitness wit;
1603 : :
1604 : 0 : scriptPubKey << OP_EQUAL;
1605 : 0 : CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)};
1606 : 0 : CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)};
1607 : :
1608 : 0 : CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
1609 : 0 : stream << spendTx;
1610 : :
1611 : : bitcoinconsensus_error err;
1612 : 0 : int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
1613 : 0 : BOOST_CHECK_EQUAL(result, 0);
1614 : 0 : BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_AMOUNT_REQUIRED);
1615 : 0 : }
1616 : :
1617 : : /* Test bitcoinconsensus_verify_script returns invalid flags err */
1618 : 0 : BOOST_AUTO_TEST_CASE(bitcoinconsensus_verify_script_invalid_flags)
1619 : : {
1620 : 0 : unsigned int libconsensus_flags = 1 << 3;
1621 : 0 : int nIn = 0;
1622 : :
1623 : 0 : CScript scriptPubKey;
1624 : 0 : CScript scriptSig;
1625 : 0 : CScriptWitness wit;
1626 : :
1627 : 0 : scriptPubKey << OP_EQUAL;
1628 : 0 : CTransaction creditTx{BuildCreditingTransaction(scriptPubKey, 1)};
1629 : 0 : CTransaction spendTx{BuildSpendingTransaction(scriptSig, wit, creditTx)};
1630 : :
1631 : 0 : CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
1632 : 0 : stream << spendTx;
1633 : :
1634 : : bitcoinconsensus_error err;
1635 : 0 : int result = bitcoinconsensus_verify_script(scriptPubKey.data(), scriptPubKey.size(), UCharCast(stream.data()), stream.size(), nIn, libconsensus_flags, &err);
1636 : 0 : BOOST_CHECK_EQUAL(result, 0);
1637 : 0 : BOOST_CHECK_EQUAL(err, bitcoinconsensus_ERR_INVALID_FLAGS);
1638 : 0 : }
1639 : :
1640 : : #endif // defined(HAVE_CONSENSUS_LIB)
1641 : :
1642 : 0 : static std::vector<unsigned int> AllConsensusFlags()
1643 : : {
1644 : 0 : std::vector<unsigned int> ret;
1645 : :
1646 : 0 : for (unsigned int i = 0; i < 128; ++i) {
1647 : 0 : unsigned int flag = 0;
1648 : 0 : if (i & 1) flag |= SCRIPT_VERIFY_P2SH;
1649 : 0 : if (i & 2) flag |= SCRIPT_VERIFY_DERSIG;
1650 : 0 : if (i & 4) flag |= SCRIPT_VERIFY_NULLDUMMY;
1651 : 0 : if (i & 8) flag |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
1652 : 0 : if (i & 16) flag |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
1653 : 0 : if (i & 32) flag |= SCRIPT_VERIFY_WITNESS;
1654 : 0 : if (i & 64) flag |= SCRIPT_VERIFY_TAPROOT;
1655 : :
1656 : : // SCRIPT_VERIFY_WITNESS requires SCRIPT_VERIFY_P2SH
1657 : 0 : if (flag & SCRIPT_VERIFY_WITNESS && !(flag & SCRIPT_VERIFY_P2SH)) continue;
1658 : : // SCRIPT_VERIFY_TAPROOT requires SCRIPT_VERIFY_WITNESS
1659 : 0 : if (flag & SCRIPT_VERIFY_TAPROOT && !(flag & SCRIPT_VERIFY_WITNESS)) continue;
1660 : :
1661 : 0 : ret.push_back(flag);
1662 : 0 : }
1663 : :
1664 : 0 : return ret;
1665 : 0 : }
1666 : :
1667 : : /** Precomputed list of all valid combinations of consensus-relevant script validation flags. */
1668 : 0 : static const std::vector<unsigned int> ALL_CONSENSUS_FLAGS = AllConsensusFlags();
1669 : :
1670 : 0 : static void AssetTest(const UniValue& test)
1671 : : {
1672 : 0 : BOOST_CHECK(test.isObject());
1673 : :
1674 : 0 : CMutableTransaction mtx = TxFromHex(test["tx"].get_str());
1675 : 0 : const std::vector<CTxOut> prevouts = TxOutsFromJSON(test["prevouts"]);
1676 : 0 : BOOST_CHECK(prevouts.size() == mtx.vin.size());
1677 : 0 : size_t idx = test["index"].getInt<int64_t>();
1678 : 0 : uint32_t test_flags{ParseScriptFlags(test["flags"].get_str())};
1679 : 0 : bool fin = test.exists("final") && test["final"].get_bool();
1680 : :
1681 : 0 : if (test.exists("success")) {
1682 : 0 : mtx.vin[idx].scriptSig = ScriptFromHex(test["success"]["scriptSig"].get_str());
1683 : 0 : mtx.vin[idx].scriptWitness = ScriptWitnessFromJSON(test["success"]["witness"]);
1684 : 0 : CTransaction tx(mtx);
1685 : 0 : PrecomputedTransactionData txdata;
1686 : 0 : txdata.Init(tx, std::vector<CTxOut>(prevouts));
1687 : 0 : CachingTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, true, txdata);
1688 : 0 : for (const auto flags : ALL_CONSENSUS_FLAGS) {
1689 : : // "final": true tests are valid for all flags. Others are only valid with flags that are
1690 : : // a subset of test_flags.
1691 : 0 : if (fin || ((flags & test_flags) == flags)) {
1692 : 0 : bool ret = VerifyScript(tx.vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.vin[idx].scriptWitness, flags, txcheck, nullptr);
1693 : 0 : BOOST_CHECK(ret);
1694 : 0 : }
1695 : : }
1696 : 0 : }
1697 : :
1698 : 0 : if (test.exists("failure")) {
1699 : 0 : mtx.vin[idx].scriptSig = ScriptFromHex(test["failure"]["scriptSig"].get_str());
1700 : 0 : mtx.vin[idx].scriptWitness = ScriptWitnessFromJSON(test["failure"]["witness"]);
1701 : 0 : CTransaction tx(mtx);
1702 : 0 : PrecomputedTransactionData txdata;
1703 : 0 : txdata.Init(tx, std::vector<CTxOut>(prevouts));
1704 : 0 : CachingTransactionSignatureChecker txcheck(&tx, idx, prevouts[idx].nValue, true, txdata);
1705 : 0 : for (const auto flags : ALL_CONSENSUS_FLAGS) {
1706 : : // If a test is supposed to fail with test_flags, it should also fail with any superset thereof.
1707 : 0 : if ((flags & test_flags) == test_flags) {
1708 : 0 : bool ret = VerifyScript(tx.vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.vin[idx].scriptWitness, flags, txcheck, nullptr);
1709 : 0 : BOOST_CHECK(!ret);
1710 : 0 : }
1711 : : }
1712 : 0 : }
1713 : 0 : }
1714 : :
1715 : 0 : BOOST_AUTO_TEST_CASE(script_assets_test)
1716 : : {
1717 : : // See src/test/fuzz/script_assets_test_minimizer.cpp for information on how to generate
1718 : : // the script_assets_test.json file used by this test.
1719 : :
1720 : 0 : const char* dir = std::getenv("DIR_UNIT_TEST_DATA");
1721 : 0 : BOOST_WARN_MESSAGE(dir != nullptr, "Variable DIR_UNIT_TEST_DATA unset, skipping script_assets_test");
1722 : 0 : if (dir == nullptr) return;
1723 : 0 : auto path = fs::path(dir) / "script_assets_test.json";
1724 : 0 : bool exists = fs::exists(path);
1725 : 0 : BOOST_WARN_MESSAGE(exists, "File $DIR_UNIT_TEST_DATA/script_assets_test.json not found, skipping script_assets_test");
1726 : 0 : if (!exists) return;
1727 : 0 : std::ifstream file{path};
1728 : 0 : BOOST_CHECK(file.is_open());
1729 : 0 : file.seekg(0, std::ios::end);
1730 : 0 : size_t length = file.tellg();
1731 : 0 : file.seekg(0, std::ios::beg);
1732 : 0 : std::string data(length, '\0');
1733 : 0 : file.read(data.data(), data.size());
1734 : 0 : UniValue tests = read_json(data);
1735 : 0 : BOOST_CHECK(tests.isArray());
1736 : 0 : BOOST_CHECK(tests.size() > 0);
1737 : :
1738 : 0 : for (size_t i = 0; i < tests.size(); i++) {
1739 : 0 : AssetTest(tests[i]);
1740 : 0 : }
1741 : 0 : file.close();
1742 : 0 : }
1743 : :
1744 : 0 : BOOST_AUTO_TEST_CASE(bip341_keypath_test_vectors)
1745 : : {
1746 : 0 : UniValue tests;
1747 : 0 : tests.read(json_tests::bip341_wallet_vectors);
1748 : :
1749 : 0 : const auto& vectors = tests["keyPathSpending"];
1750 : :
1751 : 0 : for (const auto& vec : vectors.getValues()) {
1752 : 0 : auto txhex = ParseHex(vec["given"]["rawUnsignedTx"].get_str());
1753 : 0 : CMutableTransaction tx;
1754 : 0 : SpanReader{PROTOCOL_VERSION, txhex} >> tx;
1755 : 0 : std::vector<CTxOut> utxos;
1756 : 0 : for (const auto& utxo_spent : vec["given"]["utxosSpent"].getValues()) {
1757 : 0 : auto script_bytes = ParseHex(utxo_spent["scriptPubKey"].get_str());
1758 : 0 : CScript script{script_bytes.begin(), script_bytes.end()};
1759 : 0 : CAmount amount{utxo_spent["amountSats"].getInt<int>()};
1760 : 0 : utxos.emplace_back(amount, script);
1761 : 0 : }
1762 : :
1763 : 0 : PrecomputedTransactionData txdata;
1764 : 0 : txdata.Init(tx, std::vector<CTxOut>{utxos}, true);
1765 : :
1766 : 0 : BOOST_CHECK(txdata.m_bip341_taproot_ready);
1767 : 0 : BOOST_CHECK_EQUAL(HexStr(txdata.m_spent_amounts_single_hash), vec["intermediary"]["hashAmounts"].get_str());
1768 : 0 : BOOST_CHECK_EQUAL(HexStr(txdata.m_outputs_single_hash), vec["intermediary"]["hashOutputs"].get_str());
1769 : 0 : BOOST_CHECK_EQUAL(HexStr(txdata.m_prevouts_single_hash), vec["intermediary"]["hashPrevouts"].get_str());
1770 : 0 : BOOST_CHECK_EQUAL(HexStr(txdata.m_spent_scripts_single_hash), vec["intermediary"]["hashScriptPubkeys"].get_str());
1771 : 0 : BOOST_CHECK_EQUAL(HexStr(txdata.m_sequences_single_hash), vec["intermediary"]["hashSequences"].get_str());
1772 : :
1773 : 0 : for (const auto& input : vec["inputSpending"].getValues()) {
1774 : 0 : int txinpos = input["given"]["txinIndex"].getInt<int>();
1775 : 0 : int hashtype = input["given"]["hashType"].getInt<int>();
1776 : :
1777 : : // Load key.
1778 : 0 : auto privkey = ParseHex(input["given"]["internalPrivkey"].get_str());
1779 : 0 : CKey key;
1780 : 0 : key.Set(privkey.begin(), privkey.end(), true);
1781 : :
1782 : : // Load Merkle root.
1783 : 0 : uint256 merkle_root;
1784 : 0 : if (!input["given"]["merkleRoot"].isNull()) {
1785 : 0 : merkle_root = uint256{ParseHex(input["given"]["merkleRoot"].get_str())};
1786 : 0 : }
1787 : :
1788 : : // Compute and verify (internal) public key.
1789 : 0 : XOnlyPubKey pubkey{key.GetPubKey()};
1790 : 0 : BOOST_CHECK_EQUAL(HexStr(pubkey), input["intermediary"]["internalPubkey"].get_str());
1791 : :
1792 : : // Sign and verify signature.
1793 : 0 : FlatSigningProvider provider;
1794 : 0 : provider.keys[key.GetPubKey().GetID()] = key;
1795 : 0 : MutableTransactionSignatureCreator creator(tx, txinpos, utxos[txinpos].nValue, &txdata, hashtype);
1796 : 0 : std::vector<unsigned char> signature;
1797 : 0 : BOOST_CHECK(creator.CreateSchnorrSig(provider, signature, pubkey, nullptr, &merkle_root, SigVersion::TAPROOT));
1798 : 0 : BOOST_CHECK_EQUAL(HexStr(signature), input["expected"]["witness"][0].get_str());
1799 : :
1800 : : // We can't observe the tweak used inside the signing logic, so verify by recomputing it.
1801 : 0 : BOOST_CHECK_EQUAL(HexStr(pubkey.ComputeTapTweakHash(merkle_root.IsNull() ? nullptr : &merkle_root)), input["intermediary"]["tweak"].get_str());
1802 : :
1803 : : // We can't observe the sighash used inside the signing logic, so verify by recomputing it.
1804 : 0 : ScriptExecutionData sed;
1805 : 0 : sed.m_annex_init = true;
1806 : 0 : sed.m_annex_present = false;
1807 : 0 : uint256 sighash;
1808 : 0 : BOOST_CHECK(SignatureHashSchnorr(sighash, sed, tx, txinpos, hashtype, SigVersion::TAPROOT, txdata, MissingDataBehavior::FAIL));
1809 : 0 : BOOST_CHECK_EQUAL(HexStr(sighash), input["intermediary"]["sigHash"].get_str());
1810 : :
1811 : : // To verify the sigmsg, hash the expected sigmsg, and compare it with the (expected) sighash.
1812 : 0 : BOOST_CHECK_EQUAL(HexStr((HashWriter{HASHER_TAPSIGHASH} << Span{ParseHex(input["intermediary"]["sigMsg"].get_str())}).GetSHA256()), input["intermediary"]["sigHash"].get_str());
1813 : 0 : }
1814 : :
1815 : 0 : }
1816 : 0 : }
1817 : :
1818 : 0 : BOOST_AUTO_TEST_CASE(compute_tapbranch)
1819 : : {
1820 : 0 : uint256 hash1 = uint256S("8ad69ec7cf41c2a4001fd1f738bf1e505ce2277acdcaa63fe4765192497f47a7");
1821 : 0 : uint256 hash2 = uint256S("f224a923cd0021ab202ab139cc56802ddb92dcfc172b9212261a539df79a112a");
1822 : 0 : uint256 result = uint256S("a64c5b7b943315f9b805d7a7296bedfcfd08919270a1f7a1466e98f8693d8cd9");
1823 : 0 : BOOST_CHECK_EQUAL(ComputeTapbranchHash(hash1, hash2), result);
1824 : 0 : }
1825 : :
1826 : 0 : BOOST_AUTO_TEST_CASE(compute_tapleaf)
1827 : : {
1828 : 0 : const uint8_t script[6] = {'f','o','o','b','a','r'};
1829 : 0 : uint256 tlc0 = uint256S("edbc10c272a1215dcdcc11d605b9027b5ad6ed97cd45521203f136767b5b9c06");
1830 : 0 : uint256 tlc2 = uint256S("8b5c4f90ae6bf76e259dbef5d8a59df06359c391b59263741b25eca76451b27a");
1831 : :
1832 : 0 : BOOST_CHECK_EQUAL(ComputeTapleafHash(0xc0, Span(script)), tlc0);
1833 : 0 : BOOST_CHECK_EQUAL(ComputeTapleafHash(0xc2, Span(script)), tlc2);
1834 : 0 : }
1835 : :
1836 : 0 : BOOST_AUTO_TEST_SUITE_END()
|