From 5786a818e1a96bc1dd65b0e81b05998876357a74 Mon Sep 17 00:00:00 2001 From: gzhao408 Date: Tue, 26 Jan 2021 14:08:28 -0800 Subject: [PATCH] Verify that all validation flags are backward compatible See #10699, i.e. adding a flag should always reduce the number of acceptable scripts. Co-authored-by: Johnson Lau --- src/test/transaction_tests.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index e2a99874e8..d1770f750f 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -230,6 +231,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)) { @@ -302,6 +318,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)) {