Bitcoin Core  27.99.0
P2P Digital Currency
script_flags.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2021 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 <consensus/amount.h>
7 #include <script/interpreter.h>
8 #include <serialize.h>
9 #include <streams.h>
10 #include <test/fuzz/fuzz.h>
11 #include <test/util/script.h>
12 
13 #include <cassert>
14 #include <ios>
15 #include <utility>
16 #include <vector>
17 
18 FUZZ_TARGET(script_flags)
19 {
20  if (buffer.size() > 100'000) return;
21  DataStream ds{buffer};
22  try {
24 
25  unsigned int verify_flags;
26  ds >> verify_flags;
27 
29 
30  unsigned int fuzzed_flags;
31  ds >> fuzzed_flags;
32 
33  std::vector<CTxOut> spent_outputs;
34  for (unsigned i = 0; i < tx.vin.size(); ++i) {
35  CTxOut prevout;
36  ds >> prevout;
37  if (!MoneyRange(prevout.nValue)) {
38  // prevouts should be consensus-valid
39  prevout.nValue = 1;
40  }
41  spent_outputs.push_back(prevout);
42  }
44  txdata.Init(tx, std::move(spent_outputs));
45 
46  for (unsigned i = 0; i < tx.vin.size(); ++i) {
47  const CTxOut& prevout = txdata.m_spent_outputs.at(i);
48  const TransactionSignatureChecker checker{&tx, i, prevout.nValue, txdata, MissingDataBehavior::ASSERT_FAIL};
49 
50  ScriptError serror;
51  const bool ret = VerifyScript(tx.vin.at(i).scriptSig, prevout.scriptPubKey, &tx.vin.at(i).scriptWitness, verify_flags, checker, &serror);
52  assert(ret == (serror == SCRIPT_ERR_OK));
53 
54  // Verify that removing flags from a passing test or adding flags to a failing test does not change the result
55  if (ret) {
56  verify_flags &= ~fuzzed_flags;
57  } else {
58  verify_flags |= fuzzed_flags;
59  }
61 
62  ScriptError serror_fuzzed;
63  const bool ret_fuzzed = VerifyScript(tx.vin.at(i).scriptSig, prevout.scriptPubKey, &tx.vin.at(i).scriptWitness, verify_flags, checker, &serror_fuzzed);
64  assert(ret_fuzzed == (serror_fuzzed == SCRIPT_ERR_OK));
65 
66  assert(ret_fuzzed == ret);
67  }
68  } catch (const std::ios_base::failure&) {
69  return;
70  }
71 }
bool MoneyRange(const CAmount &nValue)
Definition: amount.h:27
int ret
static bool verify_flags(unsigned int flags)
Check that all specified flags are part of the libconsensus interface.
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:296
const std::vector< CTxIn > vin
Definition: transaction.h:306
An output of a transaction.
Definition: transaction.h:150
CScript scriptPubKey
Definition: transaction.h:153
CAmount nValue
Definition: transaction.h:152
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:147
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
@ ASSERT_FAIL
Abort execution through assertion failure (for consensus code)
static constexpr TransactionSerParams TX_WITH_WITNESS
Definition: transaction.h:195
enum ScriptError_t ScriptError
@ SCRIPT_ERR_OK
Definition: script_error.h:13
FUZZ_TARGET(script_flags)
constexpr deserialize_type deserialize
Definition: serialize.h:49
void Init(const T &tx, std::vector< CTxOut > &&spent_outputs, bool force=false)
Initialize this PrecomputedTransactionData with transaction data.
std::vector< CTxOut > m_spent_outputs
Definition: interpreter.h:170
bool IsValidFlagCombination(unsigned flags)
Flags that are not forbidden by an assert in script validation.
Definition: script.cpp:8
assert(!tx.IsCoinBase())