diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 87d906f637ad42..1120879113e301 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -224,6 +225,21 @@ BOOST_AUTO_TEST_CASE(tx_valid) if (!CheckTxScripts(tx, mapprevOutScriptPubKeys, mapprevOutValues, ~verify_flags, txdata, strTest, /* expect_valid */ true)) { BOOST_ERROR("Tx unexpectedly failed: " << strTest); } + + // Backwards compatibility of script verification flags: Removing any flag(s) should not invalidate a valid transaction + for (size_t i = 0; i < mapFlagNames.size(); ++i) { + // Removing individual flags + unsigned int flags = TrimFlags(~(verify_flags | (1U << i))); + if (!CheckTxScripts(tx, mapprevOutScriptPubKeys, mapprevOutValues, flags, txdata, strTest, /* expect_valid */ true)) { + BOOST_ERROR("Tx unexpectedly failed with flag " << ToString(i) << " unset: " << strTest); + } + // Removing random combinations of flags + flags = TrimFlags(~(verify_flags | (unsigned int)InsecureRandBits(mapFlagNames.size()))); + if (!CheckTxScripts(tx, mapprevOutScriptPubKeys, mapprevOutValues, flags, txdata, strTest, /* expect_valid */ true)) { + BOOST_ERROR("Tx unexpectedly failed with random flags " << ToString(flags) << ": " << strTest); + } + } + // Check that flags are maximal: transaction should fail if any unset flags are set. for (auto flags_excluding_one: ExcludeIndividualFlags(verify_flags)) { if (!CheckTxScripts(tx, mapprevOutScriptPubKeys, mapprevOutValues, ~flags_excluding_one, txdata, strTest, /* expect_valid */ false)) { @@ -296,6 +312,21 @@ BOOST_AUTO_TEST_CASE(tx_invalid) if (!CheckTxScripts(tx, mapprevOutScriptPubKeys, mapprevOutValues, verify_flags, txdata, strTest, /* expect_valid */ false)) { BOOST_ERROR("Tx unexpectedly passed: " << strTest); } + + // Backwards compatibility of script verification flags: Adding any flag(s) should not validate an invalid transaction + for (size_t i = 0; i < mapFlagNames.size(); i++) { + unsigned int flags = FillFlags(verify_flags | (1U << i)); + // Adding individual flags + if (!CheckTxScripts(tx, mapprevOutScriptPubKeys, mapprevOutValues, flags, txdata, strTest, /* expect_valid */ false)) { + BOOST_ERROR("Tx unexpectedly passed with flag " << ToString(i) << " set: " << strTest); + } + // Adding random combinations of flags + flags = FillFlags(verify_flags | (unsigned int)InsecureRandBits(mapFlagNames.size())); + if (!CheckTxScripts(tx, mapprevOutScriptPubKeys, mapprevOutValues, flags, txdata, strTest, /* expect_valid */ false)) { + BOOST_ERROR("Tx unexpectedly passed with random flags " << ToString(flags) << ": " << strTest); + } + } + // Check that flags are minimal: transaction should succeed if any set flags are unset. for (auto flags_excluding_one: ExcludeIndividualFlags(verify_flags)) { if (!CheckTxScripts(tx, mapprevOutScriptPubKeys, mapprevOutValues, flags_excluding_one, txdata, strTest, /* expect_valid */ true)) {