20
20
#include < script/signingprovider.h>
21
21
#include < script/standard.h>
22
22
#include < streams.h>
23
+ #include < test/util/script.h>
23
24
#include < test/util/transaction_utils.h>
24
25
#include < util/strencodings.h>
25
26
#include < util/string.h>
@@ -59,6 +60,9 @@ static std::map<std::string, unsigned int> mapFlagNames = {
59
60
{std::string (" WITNESS_PUBKEYTYPE" ), (unsigned int )SCRIPT_VERIFY_WITNESS_PUBKEYTYPE},
60
61
{std::string (" CONST_SCRIPTCODE" ), (unsigned int )SCRIPT_VERIFY_CONST_SCRIPTCODE},
61
62
{std::string (" TAPROOT" ), (unsigned int )SCRIPT_VERIFY_TAPROOT},
63
+ {std::string (" DISCOURAGE_UPGRADABLE_PUBKEYTYPE" ), (unsigned int )SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE},
64
+ {std::string (" DISCOURAGE_OP_SUCCESS" ), (unsigned int )SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS},
65
+ {std::string (" DISCOURAGE_UPGRADABLE_TAPROOT_VERSION" ), (unsigned int )SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION},
62
66
};
63
67
64
68
unsigned int ParseScriptFlags (std::string strFlags)
@@ -139,6 +143,7 @@ unsigned int TrimFlags(unsigned int flags)
139
143
140
144
// CLEANSTACK requires WITNESS (and transitively CLEANSTACK requires P2SH)
141
145
if (!(flags & SCRIPT_VERIFY_WITNESS)) flags &= ~(unsigned int )SCRIPT_VERIFY_CLEANSTACK;
146
+ Assert (IsValidFlagCombination (flags));
142
147
return flags;
143
148
}
144
149
@@ -149,6 +154,7 @@ unsigned int FillFlags(unsigned int flags)
149
154
150
155
// WITNESS implies P2SH (and transitively CLEANSTACK implies P2SH)
151
156
if (flags & SCRIPT_VERIFY_WITNESS) flags |= SCRIPT_VERIFY_P2SH;
157
+ Assert (IsValidFlagCombination (flags));
152
158
return flags;
153
159
}
154
160
@@ -231,16 +237,15 @@ BOOST_AUTO_TEST_CASE(tx_valid)
231
237
BOOST_ERROR (" Bad test flags: " << strTest);
232
238
}
233
239
234
- if (!CheckTxScripts (tx, mapprevOutScriptPubKeys, mapprevOutValues, ~verify_flags, txdata, strTest, /* expect_valid */ true )) {
235
- BOOST_ERROR (" Tx unexpectedly failed: " << strTest);
236
- }
240
+ BOOST_CHECK_MESSAGE (CheckTxScripts (tx, mapprevOutScriptPubKeys, mapprevOutValues, ~verify_flags, txdata, strTest, /* expect_valid */ true ),
241
+ " Tx unexpectedly failed: " << strTest);
237
242
238
243
// Backwards compatibility of script verification flags: Removing any flag(s) should not invalidate a valid transaction
239
- for (size_t i = 0 ; i < mapFlagNames. size (); ++i ) {
244
+ for (const auto & [name, flag] : mapFlagNames) {
240
245
// Removing individual flags
241
- unsigned int flags = TrimFlags (~(verify_flags | ( 1U << i) ));
246
+ unsigned int flags = TrimFlags (~(verify_flags | flag ));
242
247
if (!CheckTxScripts (tx, mapprevOutScriptPubKeys, mapprevOutValues, flags, txdata, strTest, /* expect_valid */ true )) {
243
- BOOST_ERROR (" Tx unexpectedly failed with flag " << ToString (i) << " unset: " << strTest);
248
+ BOOST_ERROR (" Tx unexpectedly failed with flag " << name << " unset: " << strTest);
244
249
}
245
250
// Removing random combinations of flags
246
251
flags = TrimFlags (~(verify_flags | (unsigned int )InsecureRandBits (mapFlagNames.size ())));
@@ -250,7 +255,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
250
255
}
251
256
252
257
// Check that flags are maximal: transaction should fail if any unset flags are set.
253
- for (auto flags_excluding_one: ExcludeIndividualFlags (verify_flags)) {
258
+ for (auto flags_excluding_one : ExcludeIndividualFlags (verify_flags)) {
254
259
if (!CheckTxScripts (tx, mapprevOutScriptPubKeys, mapprevOutValues, ~flags_excluding_one, txdata, strTest, /* expect_valid */ false )) {
255
260
BOOST_ERROR (" Too many flags unset: " << strTest);
256
261
}
@@ -317,27 +322,31 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
317
322
PrecomputedTransactionData txdata (tx);
318
323
unsigned int verify_flags = ParseScriptFlags (test[2 ].get_str ());
319
324
320
- // Not using FillFlags() in the main test, in order to detect invalid verifyFlags combination
321
- if (! CheckTxScripts (tx, mapprevOutScriptPubKeys, mapprevOutValues, verify_flags, txdata, strTest, /* expect_valid */ false )) {
322
- BOOST_ERROR (" Tx unexpectedly passed : " << strTest);
325
+ // Check that the test gives a valid combination of flags (otherwise VerifyScript will throw). Don't edit the flags.
326
+ if (verify_flags != FillFlags (verify_flags )) {
327
+ BOOST_ERROR (" Bad test flags : " << strTest);
323
328
}
324
329
330
+ // Not using FillFlags() in the main test, in order to detect invalid verifyFlags combination
331
+ BOOST_CHECK_MESSAGE (CheckTxScripts (tx, mapprevOutScriptPubKeys, mapprevOutValues, verify_flags, txdata, strTest, /* expect_valid */ false ),
332
+ " Tx unexpectedly passed: " << strTest);
333
+
325
334
// Backwards compatibility of script verification flags: Adding any flag(s) should not validate an invalid transaction
326
- for (size_t i = 0 ; i < mapFlagNames. size (); i++ ) {
327
- unsigned int flags = FillFlags (verify_flags | ( 1U << i) );
335
+ for (const auto & [name, flag] : mapFlagNames) {
336
+ unsigned int flags = FillFlags (verify_flags | flag );
328
337
// Adding individual flags
329
338
if (!CheckTxScripts (tx, mapprevOutScriptPubKeys, mapprevOutValues, flags, txdata, strTest, /* expect_valid */ false )) {
330
- BOOST_ERROR (" Tx unexpectedly passed with flag " << ToString (i) << " set: " << strTest);
339
+ BOOST_ERROR (" Tx unexpectedly passed with flag " << name << " set: " << strTest);
331
340
}
332
341
// Adding random combinations of flags
333
342
flags = FillFlags (verify_flags | (unsigned int )InsecureRandBits (mapFlagNames.size ()));
334
343
if (!CheckTxScripts (tx, mapprevOutScriptPubKeys, mapprevOutValues, flags, txdata, strTest, /* expect_valid */ false )) {
335
- BOOST_ERROR (" Tx unexpectedly passed with random flags " << ToString (flags) << " : " << strTest);
344
+ BOOST_ERROR (" Tx unexpectedly passed with random flags " << name << " : " << strTest);
336
345
}
337
346
}
338
347
339
348
// Check that flags are minimal: transaction should succeed if any set flags are unset.
340
- for (auto flags_excluding_one: ExcludeIndividualFlags (verify_flags)) {
349
+ for (auto flags_excluding_one : ExcludeIndividualFlags (verify_flags)) {
341
350
if (!CheckTxScripts (tx, mapprevOutScriptPubKeys, mapprevOutValues, flags_excluding_one, txdata, strTest, /* expect_valid */ true )) {
342
351
BOOST_ERROR (" Too many flags set: " << strTest);
343
352
}
0 commit comments