script/verify_flags: make script_verify_flags type safe
`using script_verify_flags = uint32_t` allows implicit conversion to and from int, so replace it with a class to have the compiler ensure we use the correct type. Provide from_int and as_int to allow for explicit conversions when desired. Introduces the type `script_verify_flag_name` for the individual flag name enumeration.
This commit is contained in:
1 parent
a5ead122fe
commit
bddcadee82
12 files changed
+100
-25
No files matched your search
@@ -2164,7 +2164,7 @@ size_t CountWitnessSigOps(const CScript& scriptSig, const CScript& scriptPubKey,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define FLAG_NAME(flag) {std::string(#flag), SCRIPT_VERIFY_##flag}
|
#define FLAG_NAME(flag) {std::string(#flag), SCRIPT_VERIFY_##flag}
|
||||||
const std::map<std::string, uint32_t> g_verify_flag_names{
|
const std::map<std::string, script_verify_flag_name> g_verify_flag_names{
|
||||||
FLAG_NAME(P2SH),
|
FLAG_NAME(P2SH),
|
||||||
FLAG_NAME(STRICTENC),
|
FLAG_NAME(STRICTENC),
|
||||||
FLAG_NAME(DERSIG),
|
FLAG_NAME(DERSIG),
|
||||||
@@ -2203,7 +2203,7 @@ std::vector<std::string> GetScriptFlagNames(script_verify_flags flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (leftover != 0) {
|
if (leftover != 0) {
|
||||||
res.push_back(strprintf("0x%08x", leftover));
|
res.push_back(strprintf("0x%08x", leftover.as_int()));
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <span.h>
|
#include <span.h>
|
||||||
#include <uint256.h>
|
#include <uint256.h>
|
||||||
|
|
||||||
|
#include <bit>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
@@ -43,9 +44,10 @@ enum
|
|||||||
* All flags are intended to be soft forks: the set of acceptable scripts under
|
* All flags are intended to be soft forks: the set of acceptable scripts under
|
||||||
* flags (A | B) is a subset of the acceptable scripts under flag (A).
|
* flags (A | B) is a subset of the acceptable scripts under flag (A).
|
||||||
*/
|
*/
|
||||||
enum : uint32_t {
|
|
||||||
SCRIPT_VERIFY_NONE = 0,
|
|
||||||
|
|
||||||
|
static constexpr script_verify_flags SCRIPT_VERIFY_NONE{0};
|
||||||
|
|
||||||
|
enum class script_verify_flag_name : uint32_t {
|
||||||
// Evaluate P2SH subscripts (BIP16).
|
// Evaluate P2SH subscripts (BIP16).
|
||||||
SCRIPT_VERIFY_P2SH = (1U << 0),
|
SCRIPT_VERIFY_P2SH = (1U << 0),
|
||||||
|
|
||||||
@@ -148,6 +150,13 @@ enum : uint32_t {
|
|||||||
//
|
//
|
||||||
SCRIPT_VERIFY_END_MARKER
|
SCRIPT_VERIFY_END_MARKER
|
||||||
};
|
};
|
||||||
|
using enum script_verify_flag_name;
|
||||||
|
|
||||||
|
// assert there is still a spare bit
|
||||||
|
static_assert(static_cast<script_verify_flags::value_type>(SCRIPT_VERIFY_END_MARKER) < (1u << 31));
|
||||||
|
|
||||||
|
static constexpr script_verify_flags::value_type MAX_SCRIPT_VERIFY_FLAGS = ((static_cast<script_verify_flags::value_type>(SCRIPT_VERIFY_END_MARKER) - 1) << 1) - 1;
|
||||||
|
static constexpr int MAX_SCRIPT_VERIFY_FLAGS_BITS = std::bit_width(MAX_SCRIPT_VERIFY_FLAGS);
|
||||||
|
|
||||||
bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, script_verify_flags flags, ScriptError* serror);
|
bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, script_verify_flags flags, ScriptError* serror);
|
||||||
|
|
||||||
@@ -372,7 +381,7 @@ size_t CountWitnessSigOps(const CScript& scriptSig, const CScript& scriptPubKey,
|
|||||||
|
|
||||||
int FindAndDelete(CScript& script, const CScript& b);
|
int FindAndDelete(CScript& script, const CScript& b);
|
||||||
|
|
||||||
extern const std::map<std::string, uint32_t> g_verify_flag_names;
|
extern const std::map<std::string, script_verify_flag_name> g_verify_flag_names;
|
||||||
|
|
||||||
std::vector<std::string> GetScriptFlagNames(script_verify_flags flags);
|
std::vector<std::string> GetScriptFlagNames(script_verify_flags flags);
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,66 @@
|
|||||||
#ifndef BITCOIN_SCRIPT_VERIFY_FLAGS_H
|
#ifndef BITCOIN_SCRIPT_VERIFY_FLAGS_H
|
||||||
#define BITCOIN_SCRIPT_VERIFY_FLAGS_H
|
#define BITCOIN_SCRIPT_VERIFY_FLAGS_H
|
||||||
|
|
||||||
|
#include <compare>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
using script_verify_flags = uint32_t;
|
enum class script_verify_flag_name : uint32_t;
|
||||||
|
|
||||||
|
class script_verify_flags
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using value_type = uint32_t;
|
||||||
|
|
||||||
|
consteval script_verify_flags() = default;
|
||||||
|
|
||||||
|
// also allow construction with hard-coded 0 (but not other integers)
|
||||||
|
consteval explicit(false) script_verify_flags(value_type f) : m_value{f} { if (f != 0) throw 0; }
|
||||||
|
|
||||||
|
// implicit construction from a hard-coded SCRIPT_VERIFY_* constant is also okay
|
||||||
|
constexpr explicit(false) script_verify_flags(script_verify_flag_name f) : m_value{static_cast<value_type>(f)} { }
|
||||||
|
|
||||||
|
// rule of 5
|
||||||
|
constexpr script_verify_flags(const script_verify_flags&) = default;
|
||||||
|
constexpr script_verify_flags(script_verify_flags&&) = default;
|
||||||
|
constexpr script_verify_flags& operator=(const script_verify_flags&) = default;
|
||||||
|
constexpr script_verify_flags& operator=(script_verify_flags&&) = default;
|
||||||
|
constexpr ~script_verify_flags() = default;
|
||||||
|
|
||||||
|
// integer conversion needs to be very explicit
|
||||||
|
static constexpr script_verify_flags from_int(value_type f) { script_verify_flags r; r.m_value = f; return r; }
|
||||||
|
constexpr value_type as_int() const { return m_value; }
|
||||||
|
|
||||||
|
// bitwise operations
|
||||||
|
constexpr script_verify_flags operator~() const { return from_int(~m_value); }
|
||||||
|
friend constexpr script_verify_flags operator|(script_verify_flags a, script_verify_flags b) { return from_int(a.m_value | b.m_value); }
|
||||||
|
friend constexpr script_verify_flags operator&(script_verify_flags a, script_verify_flags b) { return from_int(a.m_value & b.m_value); }
|
||||||
|
|
||||||
|
// in-place bitwise operations
|
||||||
|
constexpr script_verify_flags& operator|=(script_verify_flags vf) { m_value |= vf.m_value; return *this; }
|
||||||
|
constexpr script_verify_flags& operator&=(script_verify_flags vf) { m_value &= vf.m_value; return *this; }
|
||||||
|
|
||||||
|
// tests
|
||||||
|
constexpr explicit operator bool() const { return m_value != 0; }
|
||||||
|
constexpr bool operator==(script_verify_flags other) const { return m_value == other.m_value; }
|
||||||
|
|
||||||
|
/** Compare two script_verify_flags. <, >, <=, and >= are auto-generated from this. */
|
||||||
|
friend constexpr std::strong_ordering operator<=>(const script_verify_flags& a, const script_verify_flags& b) noexcept
|
||||||
|
{
|
||||||
|
return a.m_value <=> b.m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
value_type m_value{0}; // default value is SCRIPT_VERIFY_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr script_verify_flags operator~(script_verify_flag_name f)
|
||||||
|
{
|
||||||
|
return ~script_verify_flags{f};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr script_verify_flags operator|(script_verify_flag_name f1, script_verify_flag_name f2)
|
||||||
|
{
|
||||||
|
return script_verify_flags{f1} | f2;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // BITCOIN_SCRIPT_VERIFY_FLAGS_H
|
#endif // BITCOIN_SCRIPT_VERIFY_FLAGS_H
|
||||||
@@ -288,7 +288,7 @@ void TestCoinsView(FuzzedDataProvider& fuzzed_data_provider, CCoinsView& backend
|
|||||||
// consensus/tx_verify.cpp:130: unsigned int GetP2SHSigOpCount(const CTransaction &, const CCoinsViewCache &): Assertion `!coin.IsSpent()' failed.
|
// consensus/tx_verify.cpp:130: unsigned int GetP2SHSigOpCount(const CTransaction &, const CCoinsViewCache &): Assertion `!coin.IsSpent()' failed.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto flags{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
|
const auto flags = script_verify_flags::from_int(fuzzed_data_provider.ConsumeIntegral<script_verify_flags::value_type>());
|
||||||
if (!transaction.vin.empty() && (flags & SCRIPT_VERIFY_WITNESS) != 0 && (flags & SCRIPT_VERIFY_P2SH) == 0) {
|
if (!transaction.vin.empty() && (flags & SCRIPT_VERIFY_WITNESS) != 0 && (flags & SCRIPT_VERIFY_P2SH) == 0) {
|
||||||
// Avoid:
|
// Avoid:
|
||||||
// script/interpreter.cpp:1705: size_t CountWitnessSigOps(const CScript &, const CScript &, const CScriptWitness *, unsigned int): Assertion `(flags & SCRIPT_VERIFY_P2SH) != 0' failed.
|
// script/interpreter.cpp:1705: size_t CountWitnessSigOps(const CScript &, const CScript &, const CScriptWitness *, unsigned int): Assertion `(flags & SCRIPT_VERIFY_P2SH) != 0' failed.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
FUZZ_TARGET(eval_script)
|
FUZZ_TARGET(eval_script)
|
||||||
{
|
{
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
const script_verify_flags flags = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
|
const auto flags = script_verify_flags::from_int(fuzzed_data_provider.ConsumeIntegral<script_verify_flags::value_type>());
|
||||||
const std::vector<uint8_t> script_bytes = [&] {
|
const std::vector<uint8_t> script_bytes = [&] {
|
||||||
if (fuzzed_data_provider.remaining_bytes() != 0) {
|
if (fuzzed_data_provider.remaining_bytes() != 0) {
|
||||||
return fuzzed_data_provider.ConsumeRemainingBytes<uint8_t>();
|
return fuzzed_data_provider.ConsumeRemainingBytes<uint8_t>();
|
||||||
|
|||||||
@@ -118,8 +118,8 @@ FUZZ_TARGET(script, .init = initialize_script)
|
|||||||
(void)FindAndDelete(script_mut, *other_script);
|
(void)FindAndDelete(script_mut, *other_script);
|
||||||
}
|
}
|
||||||
const std::vector<std::string> random_string_vector = ConsumeRandomLengthStringVector(fuzzed_data_provider);
|
const std::vector<std::string> random_string_vector = ConsumeRandomLengthStringVector(fuzzed_data_provider);
|
||||||
const uint32_t u32{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
|
const auto flags_rand{fuzzed_data_provider.ConsumeIntegral<script_verify_flags::value_type>()};
|
||||||
const script_verify_flags flags{u32 | SCRIPT_VERIFY_P2SH};
|
const auto flags = script_verify_flags::from_int(flags_rand) | SCRIPT_VERIFY_P2SH;
|
||||||
{
|
{
|
||||||
CScriptWitness wit;
|
CScriptWitness wit;
|
||||||
for (const auto& s : random_string_vector) {
|
for (const auto& s : random_string_vector) {
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ CScriptWitness ScriptWitnessFromJSON(const UniValue& univalue)
|
|||||||
return scriptwitness;
|
return scriptwitness;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<std::string, uint32_t> FLAG_NAMES = {
|
const std::map<std::string, script_verify_flag_name> FLAG_NAMES = {
|
||||||
{std::string("P2SH"), SCRIPT_VERIFY_P2SH},
|
{std::string("P2SH"), SCRIPT_VERIFY_P2SH},
|
||||||
{std::string("DERSIG"), SCRIPT_VERIFY_DERSIG},
|
{std::string("DERSIG"), SCRIPT_VERIFY_DERSIG},
|
||||||
{std::string("NULLDUMMY"), SCRIPT_VERIFY_NULLDUMMY},
|
{std::string("NULLDUMMY"), SCRIPT_VERIFY_NULLDUMMY},
|
||||||
|
|||||||
@@ -15,6 +15,14 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
static DataStream& operator>>(DataStream& ds, script_verify_flags& f)
|
||||||
|
{
|
||||||
|
script_verify_flags::value_type n{0};
|
||||||
|
ds >> n;
|
||||||
|
f = script_verify_flags::from_int(n);
|
||||||
|
return ds;
|
||||||
|
}
|
||||||
|
|
||||||
FUZZ_TARGET(script_flags)
|
FUZZ_TARGET(script_flags)
|
||||||
{
|
{
|
||||||
if (buffer.size() > 100'000) return;
|
if (buffer.size() > 100'000) return;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public:
|
|||||||
FUZZ_TARGET(signature_checker)
|
FUZZ_TARGET(signature_checker)
|
||||||
{
|
{
|
||||||
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
|
||||||
const script_verify_flags flags = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
|
const auto flags = script_verify_flags::from_int(fuzzed_data_provider.ConsumeIntegral<script_verify_flags::value_type>());
|
||||||
const SigVersion sig_version = fuzzed_data_provider.PickValueInArray({SigVersion::BASE, SigVersion::WITNESS_V0});
|
const SigVersion sig_version = fuzzed_data_provider.PickValueInArray({SigVersion::BASE, SigVersion::WITNESS_V0});
|
||||||
const auto script_1{ConsumeScript(fuzzed_data_provider)};
|
const auto script_1{ConsumeScript(fuzzed_data_provider)};
|
||||||
const auto script_2{ConsumeScript(fuzzed_data_provider)};
|
const auto script_2{ConsumeScript(fuzzed_data_provider)};
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ static ScriptErrorDesc script_errors[]={
|
|||||||
{SCRIPT_ERR_SIG_FINDANDDELETE, "SIG_FINDANDDELETE"},
|
{SCRIPT_ERR_SIG_FINDANDDELETE, "SIG_FINDANDDELETE"},
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string FormatScriptFlags(uint32_t flags)
|
static std::string FormatScriptFlags(script_verify_flags flags)
|
||||||
{
|
{
|
||||||
return util::Join(GetScriptFlagNames(flags), ",");
|
return util::Join(GetScriptFlagNames(flags), ",");
|
||||||
}
|
}
|
||||||
@@ -134,13 +134,13 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript
|
|||||||
BOOST_CHECK_MESSAGE(err == scriptError, FormatScriptError(err) + " where " + FormatScriptError((ScriptError_t)scriptError) + " expected: " + message);
|
BOOST_CHECK_MESSAGE(err == scriptError, FormatScriptError(err) + " where " + FormatScriptError((ScriptError_t)scriptError) + " expected: " + message);
|
||||||
|
|
||||||
// Verify that removing flags from a passing test or adding flags to a failing test does not change the result.
|
// Verify that removing flags from a passing test or adding flags to a failing test does not change the result.
|
||||||
for (int i = 0; i < 16; ++i) {
|
for (int i = 0; i < 256; ++i) {
|
||||||
uint32_t extra_flags(m_rng.randbits(16));
|
script_verify_flags extra_flags = script_verify_flags::from_int(m_rng.randbits(MAX_SCRIPT_VERIFY_FLAGS_BITS));
|
||||||
uint32_t combined_flags{expect ? (flags & ~extra_flags) : (flags | extra_flags)};
|
script_verify_flags combined_flags{expect ? (flags & ~extra_flags) : (flags | extra_flags)};
|
||||||
// Weed out some invalid flag combinations.
|
// Weed out some invalid flag combinations.
|
||||||
if (combined_flags & SCRIPT_VERIFY_CLEANSTACK && ~combined_flags & (SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS)) continue;
|
if (combined_flags & SCRIPT_VERIFY_CLEANSTACK && ~combined_flags & (SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS)) continue;
|
||||||
if (combined_flags & SCRIPT_VERIFY_WITNESS && ~combined_flags & SCRIPT_VERIFY_P2SH) continue;
|
if (combined_flags & SCRIPT_VERIFY_WITNESS && ~combined_flags & SCRIPT_VERIFY_P2SH) continue;
|
||||||
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));
|
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.as_int()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}; // struct ScriptTest
|
}; // struct ScriptTest
|
||||||
@@ -1716,9 +1716,9 @@ BOOST_AUTO_TEST_CASE(formatscriptflags)
|
|||||||
{
|
{
|
||||||
// quick check that FormatScriptFlags reports any unknown/unexpected bits
|
// quick check that FormatScriptFlags reports any unknown/unexpected bits
|
||||||
BOOST_CHECK_EQUAL(FormatScriptFlags(SCRIPT_VERIFY_P2SH), "P2SH");
|
BOOST_CHECK_EQUAL(FormatScriptFlags(SCRIPT_VERIFY_P2SH), "P2SH");
|
||||||
BOOST_CHECK_EQUAL(FormatScriptFlags(SCRIPT_VERIFY_P2SH | (1u<<31)), "P2SH,0x80000000");
|
BOOST_CHECK_EQUAL(FormatScriptFlags(SCRIPT_VERIFY_P2SH | script_verify_flags::from_int(1u<<31)), "P2SH,0x80000000");
|
||||||
BOOST_CHECK_EQUAL(FormatScriptFlags(SCRIPT_VERIFY_TAPROOT | (1u<<27)), "TAPROOT,0x08000000");
|
BOOST_CHECK_EQUAL(FormatScriptFlags(SCRIPT_VERIFY_TAPROOT | script_verify_flags::from_int(1u<<27)), "TAPROOT,0x08000000");
|
||||||
BOOST_CHECK_EQUAL(FormatScriptFlags(1u<<26), "0x04000000");
|
BOOST_CHECK_EQUAL(FormatScriptFlags(script_verify_flags::from_int(1u<<26)), "0x04000000");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
@@ -50,7 +50,7 @@ typedef std::vector<unsigned char> valtype;
|
|||||||
static CFeeRate g_dust{DUST_RELAY_TX_FEE};
|
static CFeeRate g_dust{DUST_RELAY_TX_FEE};
|
||||||
static bool g_bare_multi{DEFAULT_PERMIT_BAREMULTISIG};
|
static bool g_bare_multi{DEFAULT_PERMIT_BAREMULTISIG};
|
||||||
|
|
||||||
static const std::map<std::string, unsigned int>& mapFlagNames = g_verify_flag_names;
|
static const std::map<std::string, script_verify_flag_name>& mapFlagNames = g_verify_flag_names;
|
||||||
|
|
||||||
script_verify_flags ParseScriptFlags(std::string strFlags)
|
script_verify_flags ParseScriptFlags(std::string strFlags)
|
||||||
{
|
{
|
||||||
@@ -230,9 +230,9 @@ BOOST_AUTO_TEST_CASE(tx_valid)
|
|||||||
BOOST_ERROR("Tx unexpectedly failed with flag " << name << " unset: " << strTest);
|
BOOST_ERROR("Tx unexpectedly failed with flag " << name << " unset: " << strTest);
|
||||||
}
|
}
|
||||||
// Removing random combinations of flags
|
// Removing random combinations of flags
|
||||||
flags = TrimFlags(~(verify_flags | (unsigned int)m_rng.randbits(mapFlagNames.size())));
|
flags = TrimFlags(~(verify_flags | script_verify_flags::from_int(m_rng.randbits(MAX_SCRIPT_VERIFY_FLAGS_BITS))));
|
||||||
if (!CheckTxScripts(tx, mapprevOutScriptPubKeys, mapprevOutValues, flags, txdata, strTest, /*expect_valid=*/true)) {
|
if (!CheckTxScripts(tx, mapprevOutScriptPubKeys, mapprevOutValues, flags, txdata, strTest, /*expect_valid=*/true)) {
|
||||||
BOOST_ERROR("Tx unexpectedly failed with random flags " << ToString(flags) << ": " << strTest);
|
BOOST_ERROR("Tx unexpectedly failed with random flags " << ToString(flags.as_int()) << ": " << strTest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,7 +321,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
|
|||||||
BOOST_ERROR("Tx unexpectedly passed with flag " << name << " set: " << strTest);
|
BOOST_ERROR("Tx unexpectedly passed with flag " << name << " set: " << strTest);
|
||||||
}
|
}
|
||||||
// Adding random combinations of flags
|
// Adding random combinations of flags
|
||||||
flags = FillFlags(verify_flags | (unsigned int)m_rng.randbits(mapFlagNames.size()));
|
flags = FillFlags(verify_flags | script_verify_flags::from_int(m_rng.randbits(MAX_SCRIPT_VERIFY_FLAGS_BITS)));
|
||||||
if (!CheckTxScripts(tx, mapprevOutScriptPubKeys, mapprevOutValues, flags, txdata, strTest, /*expect_valid=*/false)) {
|
if (!CheckTxScripts(tx, mapprevOutScriptPubKeys, mapprevOutValues, flags, txdata, strTest, /*expect_valid=*/false)) {
|
||||||
BOOST_ERROR("Tx unexpectedly passed with random flags " << name << ": " << strTest);
|
BOOST_ERROR("Tx unexpectedly passed with random flags " << name << ": " << strTest);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, script_verify
|
|||||||
TxValidationState state;
|
TxValidationState state;
|
||||||
|
|
||||||
// Randomly selects flag combinations
|
// Randomly selects flag combinations
|
||||||
script_verify_flags test_flags = (uint32_t) insecure_rand.randrange((SCRIPT_VERIFY_END_MARKER - 1) << 1);
|
script_verify_flags test_flags = script_verify_flags::from_int(insecure_rand.randrange(MAX_SCRIPT_VERIFY_FLAGS));
|
||||||
|
|
||||||
// Filter out incompatible flag choices
|
// Filter out incompatible flag choices
|
||||||
if ((test_flags & SCRIPT_VERIFY_CLEANSTACK)) {
|
if ((test_flags & SCRIPT_VERIFY_CLEANSTACK)) {
|
||||||
|
|||||||
Reference in new issue
Block a user