Line data Source code
1 : // Copyright (c) 2011-2020 The Bitcoin Core developers
2 : // Distributed under the MIT software license, see the accompanying
3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 :
5 : #include <test/data/tx_invalid.json.h>
6 : #include <test/data/tx_valid.json.h>
7 : #include <test/util/setup_common.h>
8 :
9 : #include <checkqueue.h>
10 : #include <clientversion.h>
11 : #include <consensus/tx_check.h>
12 : #include <consensus/validation.h>
13 : #include <core_io.h>
14 : #include <key.h>
15 : #include <policy/policy.h>
16 : #include <policy/settings.h>
17 : #include <script/script.h>
18 : #include <script/script_error.h>
19 : #include <script/sign.h>
20 : #include <script/signingprovider.h>
21 : #include <script/standard.h>
22 : #include <streams.h>
23 : #include <test/util/transaction_utils.h>
24 : #include <util/strencodings.h>
25 : #include <validation.h>
26 :
27 : #include <map>
28 : #include <string>
29 :
30 : #include <boost/algorithm/string/classification.hpp>
31 : #include <boost/algorithm/string/split.hpp>
32 : #include <boost/test/unit_test.hpp>
33 :
34 : #include <univalue.h>
35 :
36 : typedef std::vector<unsigned char> valtype;
37 :
38 : // In script_tests.cpp
39 : extern UniValue read_json(const std::string& jsondata);
40 :
41 1602 : static std::map<std::string, unsigned int> mapFlagNames = {
42 89 : {std::string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE},
43 89 : {std::string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH},
44 89 : {std::string("STRICTENC"), (unsigned int)SCRIPT_VERIFY_STRICTENC},
45 89 : {std::string("DERSIG"), (unsigned int)SCRIPT_VERIFY_DERSIG},
46 89 : {std::string("LOW_S"), (unsigned int)SCRIPT_VERIFY_LOW_S},
47 89 : {std::string("SIGPUSHONLY"), (unsigned int)SCRIPT_VERIFY_SIGPUSHONLY},
48 89 : {std::string("MINIMALDATA"), (unsigned int)SCRIPT_VERIFY_MINIMALDATA},
49 89 : {std::string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY},
50 89 : {std::string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS},
51 89 : {std::string("CLEANSTACK"), (unsigned int)SCRIPT_VERIFY_CLEANSTACK},
52 89 : {std::string("MINIMALIF"), (unsigned int)SCRIPT_VERIFY_MINIMALIF},
53 89 : {std::string("NULLFAIL"), (unsigned int)SCRIPT_VERIFY_NULLFAIL},
54 89 : {std::string("CHECKLOCKTIMEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY},
55 89 : {std::string("CHECKSEQUENCEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKSEQUENCEVERIFY},
56 89 : {std::string("WITNESS"), (unsigned int)SCRIPT_VERIFY_WITNESS},
57 89 : {std::string("DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM},
58 89 : {std::string("WITNESS_PUBKEYTYPE"), (unsigned int)SCRIPT_VERIFY_WITNESS_PUBKEYTYPE},
59 89 : {std::string("CONST_SCRIPTCODE"), (unsigned int)SCRIPT_VERIFY_CONST_SCRIPTCODE},
60 : };
61 :
62 1465 : unsigned int ParseScriptFlags(std::string strFlags)
63 : {
64 1465 : if (strFlags.empty()) {
65 120 : return 0;
66 : }
67 : unsigned int flags = 0;
68 1345 : std::vector<std::string> words;
69 1345 : boost::algorithm::split(words, strFlags, boost::algorithm::is_any_of(","));
70 :
71 3867 : for (const std::string& word : words)
72 : {
73 2522 : if (!mapFlagNames.count(word))
74 0 : BOOST_ERROR("Bad test: unknown verification flag '" << word << "'");
75 2522 : flags |= mapFlagNames[word];
76 : }
77 :
78 : return flags;
79 1465 : }
80 :
81 134 : std::string FormatScriptFlags(unsigned int flags)
82 : {
83 134 : if (flags == 0) {
84 39 : return "";
85 : }
86 95 : std::string ret;
87 95 : std::map<std::string, unsigned int>::const_iterator it = mapFlagNames.begin();
88 1805 : while (it != mapFlagNames.end()) {
89 1710 : if (flags & it->second) {
90 167 : ret += it->first + ",";
91 167 : }
92 1710 : it++;
93 : }
94 95 : return ret.substr(0, ret.size() - 1);
95 134 : }
96 :
97 89 : BOOST_FIXTURE_TEST_SUITE(transaction_tests, BasicTestingSetup)
98 :
99 95 : BOOST_AUTO_TEST_CASE(tx_valid)
100 : {
101 : // Read tests from test/data/tx_valid.json
102 : // Format is an array of arrays
103 : // Inner arrays are either [ "comment" ]
104 : // or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], serializedTransaction, verifyFlags
105 : // ... where all scripts are stringified scripts.
106 : //
107 : // verifyFlags is a comma separated list of script verification flags to apply, or "NONE"
108 1 : UniValue tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid)));
109 :
110 1 : ScriptError err;
111 248 : for (unsigned int idx = 0; idx < tests.size(); idx++) {
112 247 : UniValue test = tests[idx];
113 247 : std::string strTest = test.write();
114 247 : if (test[0].isArray())
115 : {
116 120 : if (test.size() != 3 || !test[1].isStr() || !test[2].isStr())
117 : {
118 0 : BOOST_ERROR("Bad test: " << strTest);
119 0 : continue;
120 : }
121 :
122 120 : std::map<COutPoint, CScript> mapprevOutScriptPubKeys;
123 120 : std::map<COutPoint, int64_t> mapprevOutValues;
124 120 : UniValue inputs = test[0].get_array();
125 : bool fValid = true;
126 295 : for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) {
127 175 : const UniValue& input = inputs[inpIdx];
128 175 : if (!input.isArray()) {
129 : fValid = false;
130 0 : break;
131 : }
132 175 : UniValue vinput = input.get_array();
133 175 : if (vinput.size() < 3 || vinput.size() > 4)
134 : {
135 : fValid = false;
136 0 : break;
137 : }
138 175 : COutPoint outpoint(uint256S(vinput[0].get_str()), vinput[1].get_int());
139 175 : mapprevOutScriptPubKeys[outpoint] = ParseScript(vinput[2].get_str());
140 175 : if (vinput.size() >= 4)
141 : {
142 81 : mapprevOutValues[outpoint] = vinput[3].get_int64();
143 81 : }
144 175 : }
145 120 : if (!fValid)
146 : {
147 0 : BOOST_ERROR("Bad test: " << strTest);
148 0 : continue;
149 : }
150 :
151 120 : std::string transaction = test[1].get_str();
152 120 : CDataStream stream(ParseHex(transaction), SER_NETWORK, PROTOCOL_VERSION);
153 120 : CTransaction tx(deserialize, stream);
154 :
155 120 : TxValidationState state;
156 120 : BOOST_CHECK_MESSAGE(CheckTransaction(tx, state), strTest);
157 120 : BOOST_CHECK(state.IsValid());
158 :
159 120 : PrecomputedTransactionData txdata(tx);
160 295 : for (unsigned int i = 0; i < tx.vin.size(); i++)
161 : {
162 175 : if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout))
163 : {
164 0 : BOOST_ERROR("Bad test: " << strTest);
165 0 : break;
166 : }
167 :
168 175 : CAmount amount = 0;
169 175 : if (mapprevOutValues.count(tx.vin[i].prevout)) {
170 81 : amount = mapprevOutValues[tx.vin[i].prevout];
171 81 : }
172 175 : unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
173 175 : const CScriptWitness *witness = &tx.vin[i].scriptWitness;
174 175 : BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
175 : witness, verify_flags, TransactionSignatureChecker(&tx, i, amount, txdata), &err),
176 : strTest);
177 175 : BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
178 175 : }
179 120 : }
180 247 : }
181 1 : }
182 :
183 95 : BOOST_AUTO_TEST_CASE(tx_invalid)
184 : {
185 : // Read tests from test/data/tx_invalid.json
186 : // Format is an array of arrays
187 : // Inner arrays are either [ "comment" ]
188 : // or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], serializedTransaction, verifyFlags
189 : // ... where all scripts are stringified scripts.
190 : //
191 : // verifyFlags is a comma separated list of script verification flags to apply, or "NONE"
192 1 : UniValue tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid)));
193 :
194 : // Initialize to SCRIPT_ERR_OK. The tests expect err to be changed to a
195 : // value other than SCRIPT_ERR_OK.
196 1 : ScriptError err = SCRIPT_ERR_OK;
197 199 : for (unsigned int idx = 0; idx < tests.size(); idx++) {
198 198 : UniValue test = tests[idx];
199 198 : std::string strTest = test.write();
200 198 : if (test[0].isArray())
201 : {
202 92 : if (test.size() != 3 || !test[1].isStr() || !test[2].isStr())
203 : {
204 0 : BOOST_ERROR("Bad test: " << strTest);
205 0 : continue;
206 : }
207 :
208 92 : std::map<COutPoint, CScript> mapprevOutScriptPubKeys;
209 92 : std::map<COutPoint, int64_t> mapprevOutValues;
210 92 : UniValue inputs = test[0].get_array();
211 : bool fValid = true;
212 201 : for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) {
213 109 : const UniValue& input = inputs[inpIdx];
214 109 : if (!input.isArray()) {
215 : fValid = false;
216 0 : break;
217 : }
218 109 : UniValue vinput = input.get_array();
219 109 : if (vinput.size() < 3 || vinput.size() > 4)
220 : {
221 : fValid = false;
222 0 : break;
223 : }
224 109 : COutPoint outpoint(uint256S(vinput[0].get_str()), vinput[1].get_int());
225 109 : mapprevOutScriptPubKeys[outpoint] = ParseScript(vinput[2].get_str());
226 109 : if (vinput.size() >= 4)
227 : {
228 28 : mapprevOutValues[outpoint] = vinput[3].get_int64();
229 28 : }
230 109 : }
231 92 : if (!fValid)
232 : {
233 0 : BOOST_ERROR("Bad test: " << strTest);
234 0 : continue;
235 : }
236 :
237 92 : std::string transaction = test[1].get_str();
238 92 : CDataStream stream(ParseHex(transaction), SER_NETWORK, PROTOCOL_VERSION );
239 92 : CTransaction tx(deserialize, stream);
240 :
241 92 : TxValidationState state;
242 92 : fValid = CheckTransaction(tx, state) && state.IsValid();
243 :
244 92 : PrecomputedTransactionData txdata(tx);
245 179 : for (unsigned int i = 0; i < tx.vin.size() && fValid; i++)
246 : {
247 87 : if (!mapprevOutScriptPubKeys.count(tx.vin[i].prevout))
248 : {
249 0 : BOOST_ERROR("Bad test: " << strTest);
250 0 : break;
251 : }
252 :
253 87 : unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
254 87 : CAmount amount = 0;
255 87 : if (mapprevOutValues.count(tx.vin[i].prevout)) {
256 19 : amount = mapprevOutValues[tx.vin[i].prevout];
257 19 : }
258 87 : const CScriptWitness *witness = &tx.vin[i].scriptWitness;
259 174 : fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
260 87 : witness, verify_flags, TransactionSignatureChecker(&tx, i, amount, txdata), &err);
261 87 : }
262 92 : BOOST_CHECK_MESSAGE(!fValid, strTest);
263 92 : BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err));
264 92 : }
265 198 : }
266 1 : }
267 :
268 95 : BOOST_AUTO_TEST_CASE(basic_transaction_tests)
269 : {
270 : // Random real transaction (e2769b09e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436)
271 1 : unsigned char ch[] = {0x01, 0x00, 0x00, 0x00, 0x01, 0x6b, 0xff, 0x7f, 0xcd, 0x4f, 0x85, 0x65, 0xef, 0x40, 0x6d, 0xd5, 0xd6, 0x3d, 0x4f, 0xf9, 0x4f, 0x31, 0x8f, 0xe8, 0x20, 0x27, 0xfd, 0x4d, 0xc4, 0x51, 0xb0, 0x44, 0x74, 0x01, 0x9f, 0x74, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xda, 0x0d, 0xc6, 0xae, 0xce, 0xfe, 0x1e, 0x06, 0xef, 0xdf, 0x05, 0x77, 0x37, 0x57, 0xde, 0xb1, 0x68, 0x82, 0x09, 0x30, 0xe3, 0xb0, 0xd0, 0x3f, 0x46, 0xf5, 0xfc, 0xf1, 0x50, 0xbf, 0x99, 0x0c, 0x02, 0x21, 0x00, 0xd2, 0x5b, 0x5c, 0x87, 0x04, 0x00, 0x76, 0xe4, 0xf2, 0x53, 0xf8, 0x26, 0x2e, 0x76, 0x3e, 0x2d, 0xd5, 0x1e, 0x7f, 0xf0, 0xbe, 0x15, 0x77, 0x27, 0xc4, 0xbc, 0x42, 0x80, 0x7f, 0x17, 0xbd, 0x39, 0x01, 0x41, 0x04, 0xe6, 0xc2, 0x6e, 0xf6, 0x7d, 0xc6, 0x10, 0xd2, 0xcd, 0x19, 0x24, 0x84, 0x78, 0x9a, 0x6c, 0xf9, 0xae, 0xa9, 0x93, 0x0b, 0x94, 0x4b, 0x7e, 0x2d, 0xb5, 0x34, 0x2b, 0x9d, 0x9e, 0x5b, 0x9f, 0xf7, 0x9a, 0xff, 0x9a, 0x2e, 0xe1, 0x97, 0x8d, 0xd7, 0xfd, 0x01, 0xdf, 0xc5, 0x22, 0xee, 0x02, 0x28, 0x3d, 0x3b, 0x06, 0xa9, 0xd0, 0x3a, 0xcf, 0x80, 0x96, 0x96, 0x8d, 0x7d, 0xbb, 0x0f, 0x91, 0x78, 0xff, 0xff, 0xff, 0xff, 0x02, 0x8b, 0xa7, 0x94, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xba, 0xde, 0xec, 0xfd, 0xef, 0x05, 0x07, 0x24, 0x7f, 0xc8, 0xf7, 0x42, 0x41, 0xd7, 0x3b, 0xc0, 0x39, 0x97, 0x2d, 0x7b, 0x88, 0xac, 0x40, 0x94, 0xa8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xc1, 0x09, 0x32, 0x48, 0x3f, 0xec, 0x93, 0xed, 0x51, 0xf5, 0xfe, 0x95, 0xe7, 0x25, 0x59, 0xf2, 0xcc, 0x70, 0x43, 0xf9, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00};
272 1 : std::vector<unsigned char> vch(ch, ch + sizeof(ch) -1);
273 1 : CDataStream stream(vch, SER_DISK, CLIENT_VERSION);
274 1 : CMutableTransaction tx;
275 1 : stream >> tx;
276 1 : TxValidationState state;
277 1 : BOOST_CHECK_MESSAGE(CheckTransaction(CTransaction(tx), state) && state.IsValid(), "Simple deserialized transaction should be valid.");
278 :
279 : // Check that duplicate txins fail
280 1 : tx.vin.push_back(tx.vin[0]);
281 1 : BOOST_CHECK_MESSAGE(!CheckTransaction(CTransaction(tx), state) || !state.IsValid(), "Transaction with duplicate txins should be invalid.");
282 1 : }
283 :
284 95 : BOOST_AUTO_TEST_CASE(test_Get)
285 : {
286 1 : FillableSigningProvider keystore;
287 1 : CCoinsView coinsDummy;
288 1 : CCoinsViewCache coins(&coinsDummy);
289 1 : std::vector<CMutableTransaction> dummyTransactions =
290 1 : SetupDummyInputs(keystore, coins, {11*CENT, 50*CENT, 21*CENT, 22*CENT});
291 :
292 1 : CMutableTransaction t1;
293 1 : t1.vin.resize(3);
294 1 : t1.vin[0].prevout.hash = dummyTransactions[0].GetHash();
295 1 : t1.vin[0].prevout.n = 1;
296 1 : t1.vin[0].scriptSig << std::vector<unsigned char>(65, 0);
297 1 : t1.vin[1].prevout.hash = dummyTransactions[1].GetHash();
298 1 : t1.vin[1].prevout.n = 0;
299 1 : t1.vin[1].scriptSig << std::vector<unsigned char>(65, 0) << std::vector<unsigned char>(33, 4);
300 1 : t1.vin[2].prevout.hash = dummyTransactions[1].GetHash();
301 1 : t1.vin[2].prevout.n = 1;
302 1 : t1.vin[2].scriptSig << std::vector<unsigned char>(65, 0) << std::vector<unsigned char>(33, 4);
303 1 : t1.vout.resize(2);
304 1 : t1.vout[0].nValue = 90*CENT;
305 1 : t1.vout[0].scriptPubKey << OP_1;
306 :
307 1 : BOOST_CHECK(AreInputsStandard(CTransaction(t1), coins));
308 1 : }
309 :
310 24 : static void CreateCreditAndSpend(const FillableSigningProvider& keystore, const CScript& outscript, CTransactionRef& output, CMutableTransaction& input, bool success = true)
311 : {
312 24 : CMutableTransaction outputm;
313 24 : outputm.nVersion = 1;
314 24 : outputm.vin.resize(1);
315 24 : outputm.vin[0].prevout.SetNull();
316 24 : outputm.vin[0].scriptSig = CScript();
317 24 : outputm.vout.resize(1);
318 24 : outputm.vout[0].nValue = 1;
319 24 : outputm.vout[0].scriptPubKey = outscript;
320 24 : CDataStream ssout(SER_NETWORK, PROTOCOL_VERSION);
321 24 : ssout << outputm;
322 24 : ssout >> output;
323 24 : assert(output->vin.size() == 1);
324 24 : assert(output->vin[0] == outputm.vin[0]);
325 24 : assert(output->vout.size() == 1);
326 24 : assert(output->vout[0] == outputm.vout[0]);
327 :
328 24 : CMutableTransaction inputm;
329 24 : inputm.nVersion = 1;
330 24 : inputm.vin.resize(1);
331 24 : inputm.vin[0].prevout.hash = output->GetHash();
332 24 : inputm.vin[0].prevout.n = 0;
333 24 : inputm.vout.resize(1);
334 24 : inputm.vout[0].nValue = 1;
335 24 : inputm.vout[0].scriptPubKey = CScript();
336 24 : bool ret = SignSignature(keystore, *output, inputm, 0, SIGHASH_ALL);
337 24 : assert(ret == success);
338 24 : CDataStream ssin(SER_NETWORK, PROTOCOL_VERSION);
339 24 : ssin << inputm;
340 24 : ssin >> input;
341 24 : assert(input.vin.size() == 1);
342 24 : assert(input.vin[0] == inputm.vin[0]);
343 24 : assert(input.vout.size() == 1);
344 24 : assert(input.vout[0] == inputm.vout[0]);
345 24 : assert(input.vin[0].scriptWitness.stack == inputm.vin[0].scriptWitness.stack);
346 24 : }
347 :
348 69 : static void CheckWithFlag(const CTransactionRef& output, const CMutableTransaction& input, int flags, bool success)
349 : {
350 69 : ScriptError error;
351 69 : CTransaction inputi(input);
352 69 : bool ret = VerifyScript(inputi.vin[0].scriptSig, output->vout[0].scriptPubKey, &inputi.vin[0].scriptWitness, flags, TransactionSignatureChecker(&inputi, 0, output->vout[0].nValue), &error);
353 69 : assert(ret == success);
354 69 : }
355 :
356 3 : static CScript PushAll(const std::vector<valtype>& values)
357 : {
358 3 : CScript result;
359 8 : for (const valtype& v : values) {
360 5 : if (v.size() == 0) {
361 0 : result << OP_0;
362 5 : } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) {
363 0 : result << CScript::EncodeOP_N(v[0]);
364 5 : } else if (v.size() == 1 && v[0] == 0x81) {
365 0 : result << OP_1NEGATE;
366 : } else {
367 5 : result << v;
368 : }
369 : }
370 : return result;
371 3 : }
372 :
373 3 : static void ReplaceRedeemScript(CScript& script, const CScript& redeemScript)
374 : {
375 3 : std::vector<valtype> stack;
376 3 : EvalScript(stack, script, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker(), SigVersion::BASE);
377 3 : assert(stack.size() > 0);
378 3 : stack.back() = std::vector<unsigned char>(redeemScript.begin(), redeemScript.end());
379 3 : script = PushAll(stack);
380 3 : }
381 :
382 95 : BOOST_AUTO_TEST_CASE(test_big_witness_transaction)
383 : {
384 1 : CMutableTransaction mtx;
385 1 : mtx.nVersion = 1;
386 :
387 1 : CKey key;
388 1 : key.MakeNewKey(true); // Need to use compressed keys in segwit or the signing will fail
389 1 : FillableSigningProvider keystore;
390 1 : BOOST_CHECK(keystore.AddKeyPubKey(key, key.GetPubKey()));
391 1 : CKeyID hash = key.GetPubKey().GetID();
392 1 : CScript scriptPubKey = CScript() << OP_0 << std::vector<unsigned char>(hash.begin(), hash.end());
393 :
394 1 : std::vector<int> sigHashes;
395 1 : sigHashes.push_back(SIGHASH_NONE | SIGHASH_ANYONECANPAY);
396 1 : sigHashes.push_back(SIGHASH_SINGLE | SIGHASH_ANYONECANPAY);
397 1 : sigHashes.push_back(SIGHASH_ALL | SIGHASH_ANYONECANPAY);
398 1 : sigHashes.push_back(SIGHASH_NONE);
399 1 : sigHashes.push_back(SIGHASH_SINGLE);
400 1 : sigHashes.push_back(SIGHASH_ALL);
401 :
402 : // create a big transaction of 4500 inputs signed by the same key
403 4501 : for(uint32_t ij = 0; ij < 4500; ij++) {
404 4500 : uint32_t i = mtx.vin.size();
405 4500 : uint256 prevId;
406 4500 : prevId.SetHex("0000000000000000000000000000000000000000000000000000000000000100");
407 4500 : COutPoint outpoint(prevId, i);
408 :
409 4500 : mtx.vin.resize(mtx.vin.size() + 1);
410 4500 : mtx.vin[i].prevout = outpoint;
411 4500 : mtx.vin[i].scriptSig = CScript();
412 :
413 4500 : mtx.vout.resize(mtx.vout.size() + 1);
414 4500 : mtx.vout[i].nValue = 1000;
415 4500 : mtx.vout[i].scriptPubKey = CScript() << OP_1;
416 4500 : }
417 :
418 : // sign all inputs
419 4501 : for(uint32_t i = 0; i < mtx.vin.size(); i++) {
420 4500 : bool hashSigned = SignSignature(keystore, scriptPubKey, mtx, i, 1000, sigHashes.at(i % sigHashes.size()));
421 4500 : assert(hashSigned);
422 : }
423 :
424 1 : CDataStream ssout(SER_NETWORK, PROTOCOL_VERSION);
425 1 : ssout << mtx;
426 1 : CTransaction tx(deserialize, ssout);
427 :
428 : // check all inputs concurrently, with the cache
429 1 : PrecomputedTransactionData txdata(tx);
430 1 : boost::thread_group threadGroup;
431 1 : CCheckQueue<CScriptCheck> scriptcheckqueue(128);
432 1 : CCheckQueueControl<CScriptCheck> control(&scriptcheckqueue);
433 :
434 21 : for (int i=0; i<20; i++)
435 20 : threadGroup.create_thread(std::bind(&CCheckQueue<CScriptCheck>::Thread, std::ref(scriptcheckqueue)));
436 :
437 1 : std::vector<Coin> coins;
438 4501 : for(uint32_t i = 0; i < mtx.vin.size(); i++) {
439 4500 : Coin coin;
440 4500 : coin.nHeight = 1;
441 4500 : coin.fCoinBase = false;
442 4500 : coin.out.nValue = 1000;
443 4500 : coin.out.scriptPubKey = scriptPubKey;
444 4500 : coins.emplace_back(std::move(coin));
445 4500 : }
446 :
447 4501 : for(uint32_t i = 0; i < mtx.vin.size(); i++) {
448 4500 : std::vector<CScriptCheck> vChecks;
449 4500 : CScriptCheck check(coins[tx.vin[i].prevout.n].out, tx, i, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false, &txdata);
450 4500 : vChecks.push_back(CScriptCheck());
451 4500 : check.swap(vChecks.back());
452 4500 : control.Add(vChecks);
453 4500 : }
454 :
455 1 : bool controlCheck = control.Wait();
456 1 : assert(controlCheck);
457 :
458 1 : threadGroup.interrupt_all();
459 1 : threadGroup.join_all();
460 1 : }
461 :
462 4 : SignatureData CombineSignatures(const CMutableTransaction& input1, const CMutableTransaction& input2, const CTransactionRef tx)
463 : {
464 4 : SignatureData sigdata;
465 4 : sigdata = DataFromTransaction(input1, 0, tx->vout[0]);
466 4 : sigdata.MergeSignatureData(DataFromTransaction(input2, 0, tx->vout[0]));
467 4 : ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(&input1, 0, tx->vout[0].nValue), tx->vout[0].scriptPubKey, sigdata);
468 : return sigdata;
469 4 : }
470 :
471 95 : BOOST_AUTO_TEST_CASE(test_witness)
472 : {
473 1 : FillableSigningProvider keystore, keystore2;
474 1 : CKey key1, key2, key3, key1L, key2L;
475 1 : CPubKey pubkey1, pubkey2, pubkey3, pubkey1L, pubkey2L;
476 1 : key1.MakeNewKey(true);
477 1 : key2.MakeNewKey(true);
478 1 : key3.MakeNewKey(true);
479 1 : key1L.MakeNewKey(false);
480 1 : key2L.MakeNewKey(false);
481 1 : pubkey1 = key1.GetPubKey();
482 1 : pubkey2 = key2.GetPubKey();
483 1 : pubkey3 = key3.GetPubKey();
484 1 : pubkey1L = key1L.GetPubKey();
485 1 : pubkey2L = key2L.GetPubKey();
486 1 : BOOST_CHECK(keystore.AddKeyPubKey(key1, pubkey1));
487 1 : BOOST_CHECK(keystore.AddKeyPubKey(key2, pubkey2));
488 1 : BOOST_CHECK(keystore.AddKeyPubKey(key1L, pubkey1L));
489 1 : BOOST_CHECK(keystore.AddKeyPubKey(key2L, pubkey2L));
490 1 : CScript scriptPubkey1, scriptPubkey2, scriptPubkey1L, scriptPubkey2L, scriptMulti;
491 1 : scriptPubkey1 << ToByteVector(pubkey1) << OP_CHECKSIG;
492 1 : scriptPubkey2 << ToByteVector(pubkey2) << OP_CHECKSIG;
493 1 : scriptPubkey1L << ToByteVector(pubkey1L) << OP_CHECKSIG;
494 1 : scriptPubkey2L << ToByteVector(pubkey2L) << OP_CHECKSIG;
495 1 : std::vector<CPubKey> oneandthree;
496 1 : oneandthree.push_back(pubkey1);
497 1 : oneandthree.push_back(pubkey3);
498 1 : scriptMulti = GetScriptForMultisig(2, oneandthree);
499 1 : BOOST_CHECK(keystore.AddCScript(scriptPubkey1));
500 1 : BOOST_CHECK(keystore.AddCScript(scriptPubkey2));
501 1 : BOOST_CHECK(keystore.AddCScript(scriptPubkey1L));
502 1 : BOOST_CHECK(keystore.AddCScript(scriptPubkey2L));
503 1 : BOOST_CHECK(keystore.AddCScript(scriptMulti));
504 1 : CScript destination_script_1, destination_script_2, destination_script_1L, destination_script_2L, destination_script_multi;
505 1 : destination_script_1 = GetScriptForDestination(WitnessV0KeyHash(pubkey1));
506 1 : destination_script_2 = GetScriptForDestination(WitnessV0KeyHash(pubkey2));
507 1 : destination_script_1L = GetScriptForDestination(WitnessV0KeyHash(pubkey1L));
508 1 : destination_script_2L = GetScriptForDestination(WitnessV0KeyHash(pubkey2L));
509 1 : destination_script_multi = GetScriptForDestination(WitnessV0ScriptHash(scriptMulti));
510 1 : BOOST_CHECK(keystore.AddCScript(destination_script_1));
511 1 : BOOST_CHECK(keystore.AddCScript(destination_script_2));
512 1 : BOOST_CHECK(keystore.AddCScript(destination_script_1L));
513 1 : BOOST_CHECK(keystore.AddCScript(destination_script_2L));
514 1 : BOOST_CHECK(keystore.AddCScript(destination_script_multi));
515 1 : BOOST_CHECK(keystore2.AddCScript(scriptMulti));
516 1 : BOOST_CHECK(keystore2.AddCScript(destination_script_multi));
517 1 : BOOST_CHECK(keystore2.AddKeyPubKey(key3, pubkey3));
518 :
519 1 : CTransactionRef output1, output2;
520 1 : CMutableTransaction input1, input2;
521 :
522 : // Normal pay-to-compressed-pubkey.
523 1 : CreateCreditAndSpend(keystore, scriptPubkey1, output1, input1);
524 1 : CreateCreditAndSpend(keystore, scriptPubkey2, output2, input2);
525 1 : CheckWithFlag(output1, input1, 0, true);
526 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
527 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
528 1 : CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
529 1 : CheckWithFlag(output1, input2, 0, false);
530 1 : CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);
531 1 : CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);
532 1 : CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
533 :
534 : // P2SH pay-to-compressed-pubkey.
535 1 : CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(scriptPubkey1)), output1, input1);
536 1 : CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(scriptPubkey2)), output2, input2);
537 1 : ReplaceRedeemScript(input2.vin[0].scriptSig, scriptPubkey1);
538 1 : CheckWithFlag(output1, input1, 0, true);
539 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
540 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
541 1 : CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
542 1 : CheckWithFlag(output1, input2, 0, true);
543 1 : CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);
544 1 : CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);
545 1 : CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
546 :
547 : // Witness pay-to-compressed-pubkey (v0).
548 1 : CreateCreditAndSpend(keystore, destination_script_1, output1, input1);
549 1 : CreateCreditAndSpend(keystore, destination_script_2, output2, input2);
550 1 : CheckWithFlag(output1, input1, 0, true);
551 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
552 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
553 1 : CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
554 1 : CheckWithFlag(output1, input2, 0, true);
555 1 : CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true);
556 1 : CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);
557 1 : CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
558 :
559 : // P2SH witness pay-to-compressed-pubkey (v0).
560 1 : CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_1)), output1, input1);
561 1 : CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_2)), output2, input2);
562 1 : ReplaceRedeemScript(input2.vin[0].scriptSig, destination_script_1);
563 1 : CheckWithFlag(output1, input1, 0, true);
564 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
565 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
566 1 : CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
567 1 : CheckWithFlag(output1, input2, 0, true);
568 1 : CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true);
569 1 : CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);
570 1 : CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
571 :
572 : // Normal pay-to-uncompressed-pubkey.
573 1 : CreateCreditAndSpend(keystore, scriptPubkey1L, output1, input1);
574 1 : CreateCreditAndSpend(keystore, scriptPubkey2L, output2, input2);
575 1 : CheckWithFlag(output1, input1, 0, true);
576 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
577 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
578 1 : CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
579 1 : CheckWithFlag(output1, input2, 0, false);
580 1 : CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);
581 1 : CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);
582 1 : CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
583 :
584 : // P2SH pay-to-uncompressed-pubkey.
585 1 : CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(scriptPubkey1L)), output1, input1);
586 1 : CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(scriptPubkey2L)), output2, input2);
587 1 : ReplaceRedeemScript(input2.vin[0].scriptSig, scriptPubkey1L);
588 1 : CheckWithFlag(output1, input1, 0, true);
589 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
590 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);
591 1 : CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
592 1 : CheckWithFlag(output1, input2, 0, true);
593 1 : CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);
594 1 : CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);
595 1 : CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);
596 :
597 : // Signing disabled for witness pay-to-uncompressed-pubkey (v1).
598 1 : CreateCreditAndSpend(keystore, destination_script_1L, output1, input1, false);
599 1 : CreateCreditAndSpend(keystore, destination_script_2L, output2, input2, false);
600 :
601 : // Signing disabled for P2SH witness pay-to-uncompressed-pubkey (v1).
602 1 : CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_1L)), output1, input1, false);
603 1 : CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_2L)), output2, input2, false);
604 :
605 : // Normal 2-of-2 multisig
606 1 : CreateCreditAndSpend(keystore, scriptMulti, output1, input1, false);
607 1 : CheckWithFlag(output1, input1, 0, false);
608 1 : CreateCreditAndSpend(keystore2, scriptMulti, output2, input2, false);
609 1 : CheckWithFlag(output2, input2, 0, false);
610 1 : BOOST_CHECK(*output1 == *output2);
611 1 : UpdateInput(input1.vin[0], CombineSignatures(input1, input2, output1));
612 1 : CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
613 :
614 : // P2SH 2-of-2 multisig
615 1 : CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(scriptMulti)), output1, input1, false);
616 1 : CheckWithFlag(output1, input1, 0, true);
617 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, false);
618 1 : CreateCreditAndSpend(keystore2, GetScriptForDestination(ScriptHash(scriptMulti)), output2, input2, false);
619 1 : CheckWithFlag(output2, input2, 0, true);
620 1 : CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH, false);
621 1 : BOOST_CHECK(*output1 == *output2);
622 1 : UpdateInput(input1.vin[0], CombineSignatures(input1, input2, output1));
623 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
624 1 : CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
625 :
626 : // Witness 2-of-2 multisig
627 1 : CreateCreditAndSpend(keystore, destination_script_multi, output1, input1, false);
628 1 : CheckWithFlag(output1, input1, 0, true);
629 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);
630 1 : CreateCreditAndSpend(keystore2, destination_script_multi, output2, input2, false);
631 1 : CheckWithFlag(output2, input2, 0, true);
632 1 : CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);
633 1 : BOOST_CHECK(*output1 == *output2);
634 1 : UpdateInput(input1.vin[0], CombineSignatures(input1, input2, output1));
635 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true);
636 1 : CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
637 :
638 : // P2SH witness 2-of-2 multisig
639 1 : CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_multi)), output1, input1, false);
640 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);
641 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);
642 1 : CreateCreditAndSpend(keystore2, GetScriptForDestination(ScriptHash(destination_script_multi)), output2, input2, false);
643 1 : CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH, true);
644 1 : CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);
645 1 : BOOST_CHECK(*output1 == *output2);
646 1 : UpdateInput(input1.vin[0], CombineSignatures(input1, input2, output1));
647 1 : CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true);
648 1 : CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);
649 1 : }
650 :
651 95 : BOOST_AUTO_TEST_CASE(test_IsStandard)
652 : {
653 1 : LOCK(cs_main);
654 1 : FillableSigningProvider keystore;
655 1 : CCoinsView coinsDummy;
656 1 : CCoinsViewCache coins(&coinsDummy);
657 1 : std::vector<CMutableTransaction> dummyTransactions =
658 1 : SetupDummyInputs(keystore, coins, {11*CENT, 50*CENT, 21*CENT, 22*CENT});
659 :
660 1 : CMutableTransaction t;
661 1 : t.vin.resize(1);
662 1 : t.vin[0].prevout.hash = dummyTransactions[0].GetHash();
663 1 : t.vin[0].prevout.n = 1;
664 1 : t.vin[0].scriptSig << std::vector<unsigned char>(65, 0);
665 1 : t.vout.resize(1);
666 1 : t.vout[0].nValue = 90*CENT;
667 1 : CKey key;
668 1 : key.MakeNewKey(true);
669 1 : t.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
670 :
671 1 : std::string reason;
672 1 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
673 :
674 : // Check dust with default relay fee:
675 1 : CAmount nDustThreshold = 182 * dustRelayFee.GetFeePerK()/1000;
676 1 : BOOST_CHECK_EQUAL(nDustThreshold, 546);
677 : // dust:
678 1 : t.vout[0].nValue = nDustThreshold - 1;
679 1 : reason.clear();
680 1 : BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
681 1 : BOOST_CHECK_EQUAL(reason, "dust");
682 : // not dust:
683 1 : t.vout[0].nValue = nDustThreshold;
684 1 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
685 :
686 : // Disallowed nVersion
687 1 : t.nVersion = -1;
688 1 : reason.clear();
689 1 : BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
690 1 : BOOST_CHECK_EQUAL(reason, "version");
691 :
692 1 : t.nVersion = 0;
693 1 : reason.clear();
694 1 : BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
695 1 : BOOST_CHECK_EQUAL(reason, "version");
696 :
697 1 : t.nVersion = 3;
698 1 : reason.clear();
699 1 : BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
700 1 : BOOST_CHECK_EQUAL(reason, "version");
701 :
702 : // Allowed nVersion
703 1 : t.nVersion = 1;
704 1 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
705 :
706 1 : t.nVersion = 2;
707 1 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
708 :
709 : // Check dust with odd relay fee to verify rounding:
710 : // nDustThreshold = 182 * 3702 / 1000
711 1 : dustRelayFee = CFeeRate(3702);
712 : // dust:
713 1 : t.vout[0].nValue = 673 - 1;
714 1 : reason.clear();
715 1 : BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
716 1 : BOOST_CHECK_EQUAL(reason, "dust");
717 : // not dust:
718 1 : t.vout[0].nValue = 673;
719 1 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
720 1 : dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE);
721 :
722 1 : t.vout[0].scriptPubKey = CScript() << OP_1;
723 1 : reason.clear();
724 1 : BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
725 1 : BOOST_CHECK_EQUAL(reason, "scriptpubkey");
726 :
727 : // MAX_OP_RETURN_RELAY-byte TxoutType::NULL_DATA (standard)
728 1 : t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
729 1 : BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY, t.vout[0].scriptPubKey.size());
730 1 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
731 :
732 : // MAX_OP_RETURN_RELAY+1-byte TxoutType::NULL_DATA (non-standard)
733 1 : t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800");
734 1 : BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY + 1, t.vout[0].scriptPubKey.size());
735 1 : reason.clear();
736 1 : BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
737 1 : BOOST_CHECK_EQUAL(reason, "scriptpubkey");
738 :
739 : // Data payload can be encoded in any way...
740 1 : t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("");
741 1 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
742 1 : t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("00") << ParseHex("01");
743 1 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
744 : // OP_RESERVED *is* considered to be a PUSHDATA type opcode by IsPushOnly()!
745 1 : t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_RESERVED << -1 << 0 << ParseHex("01") << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11 << 12 << 13 << 14 << 15 << 16;
746 1 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
747 1 : t.vout[0].scriptPubKey = CScript() << OP_RETURN << 0 << ParseHex("01") << 2 << ParseHex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
748 1 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
749 :
750 : // ...so long as it only contains PUSHDATA's
751 1 : t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_RETURN;
752 1 : reason.clear();
753 1 : BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
754 1 : BOOST_CHECK_EQUAL(reason, "scriptpubkey");
755 :
756 : // TxoutType::NULL_DATA w/o PUSHDATA
757 1 : t.vout.resize(1);
758 1 : t.vout[0].scriptPubKey = CScript() << OP_RETURN;
759 1 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
760 :
761 : // Only one TxoutType::NULL_DATA permitted in all cases
762 1 : t.vout.resize(2);
763 1 : t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
764 1 : t.vout[1].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
765 1 : reason.clear();
766 1 : BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
767 1 : BOOST_CHECK_EQUAL(reason, "multi-op-return");
768 :
769 1 : t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
770 1 : t.vout[1].scriptPubKey = CScript() << OP_RETURN;
771 1 : reason.clear();
772 1 : BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
773 1 : BOOST_CHECK_EQUAL(reason, "multi-op-return");
774 :
775 1 : t.vout[0].scriptPubKey = CScript() << OP_RETURN;
776 1 : t.vout[1].scriptPubKey = CScript() << OP_RETURN;
777 1 : reason.clear();
778 1 : BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
779 1 : BOOST_CHECK_EQUAL(reason, "multi-op-return");
780 :
781 : // Check large scriptSig (non-standard if size is >1650 bytes)
782 1 : t.vout.resize(1);
783 1 : t.vout[0].nValue = MAX_MONEY;
784 1 : t.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
785 : // OP_PUSHDATA2 with len (3 bytes) + data (1647 bytes) = 1650 bytes
786 1 : t.vin[0].scriptSig = CScript() << std::vector<unsigned char>(1647, 0); // 1650
787 1 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
788 :
789 1 : t.vin[0].scriptSig = CScript() << std::vector<unsigned char>(1648, 0); // 1651
790 1 : reason.clear();
791 1 : BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
792 1 : BOOST_CHECK_EQUAL(reason, "scriptsig-size");
793 :
794 : // Check scriptSig format (non-standard if there are any other ops than just PUSHs)
795 2 : t.vin[0].scriptSig = CScript()
796 1 : << OP_TRUE << OP_0 << OP_1NEGATE << OP_16 // OP_n (single byte pushes: n = 1, 0, -1, 16)
797 1 : << std::vector<unsigned char>(75, 0) // OP_PUSHx [...x bytes...]
798 1 : << std::vector<unsigned char>(235, 0) // OP_PUSHDATA1 x [...x bytes...]
799 1 : << std::vector<unsigned char>(1234, 0) // OP_PUSHDATA2 x [...x bytes...]
800 1 : << OP_9;
801 1 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
802 :
803 1 : const std::vector<unsigned char> non_push_ops = { // arbitrary set of non-push operations
804 : OP_NOP, OP_VERIFY, OP_IF, OP_ROT, OP_3DUP, OP_SIZE, OP_EQUAL, OP_ADD, OP_SUB,
805 : OP_HASH256, OP_CODESEPARATOR, OP_CHECKSIG, OP_CHECKLOCKTIMEVERIFY };
806 :
807 1 : CScript::const_iterator pc = t.vin[0].scriptSig.begin();
808 9 : while (pc < t.vin[0].scriptSig.end()) {
809 8 : opcodetype opcode;
810 8 : CScript::const_iterator prev_pc = pc;
811 8 : t.vin[0].scriptSig.GetOp(pc, opcode); // advance to next op
812 : // for the sake of simplicity, we only replace single-byte push operations
813 8 : if (opcode >= 1 && opcode <= OP_PUSHDATA4)
814 3 : continue;
815 :
816 5 : int index = prev_pc - t.vin[0].scriptSig.begin();
817 5 : unsigned char orig_op = *prev_pc; // save op
818 : // replace current push-op with each non-push-op
819 70 : for (auto op : non_push_ops) {
820 65 : t.vin[0].scriptSig[index] = op;
821 65 : BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
822 65 : BOOST_CHECK_EQUAL(reason, "scriptsig-not-pushonly");
823 : }
824 5 : t.vin[0].scriptSig[index] = orig_op; // restore op
825 5 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
826 8 : }
827 :
828 : // Check tx-size (non-standard if transaction weight is > MAX_STANDARD_TX_WEIGHT)
829 1 : t.vin.clear();
830 1 : t.vin.resize(2438); // size per input (empty scriptSig): 41 bytes
831 1 : t.vout[0].scriptPubKey = CScript() << OP_RETURN << std::vector<unsigned char>(19, 0); // output size: 30 bytes
832 : // tx header: 12 bytes => 48 vbytes
833 : // 2438 inputs: 2438*41 = 99958 bytes => 399832 vbytes
834 : // 1 output: 30 bytes => 120 vbytes
835 : // ===============================
836 : // total: 400000 vbytes
837 1 : BOOST_CHECK_EQUAL(GetTransactionWeight(CTransaction(t)), 400000);
838 1 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
839 :
840 : // increase output size by one byte, so we end up with 400004 vbytes
841 1 : t.vout[0].scriptPubKey = CScript() << OP_RETURN << std::vector<unsigned char>(20, 0); // output size: 31 bytes
842 1 : BOOST_CHECK_EQUAL(GetTransactionWeight(CTransaction(t)), 400004);
843 1 : reason.clear();
844 1 : BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
845 1 : BOOST_CHECK_EQUAL(reason, "tx-size");
846 :
847 : // Check bare multisig (standard if policy flag fIsBareMultisigStd is set)
848 1 : fIsBareMultisigStd = true;
849 1 : t.vout[0].scriptPubKey = GetScriptForMultisig(1, {key.GetPubKey()}); // simple 1-of-1
850 1 : t.vin.resize(1);
851 1 : t.vin[0].scriptSig = CScript() << std::vector<unsigned char>(65, 0);
852 1 : BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
853 :
854 1 : fIsBareMultisigStd = false;
855 1 : reason.clear();
856 1 : BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
857 1 : BOOST_CHECK_EQUAL(reason, "bare-multisig");
858 1 : fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG;
859 1 : }
860 :
861 89 : BOOST_AUTO_TEST_SUITE_END()
|