Bitcoin Core 30.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>
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
19{
21 ds >> n;
23 assert(n == f.as_int());
24 return ds;
25}
26
27FUZZ_TARGET(script_flags)
28{
29 if (buffer.size() > 100'000) return;
30 DataStream ds{buffer};
31 try {
33
34 script_verify_flags verify_flags;
35 ds >> verify_flags;
36
37 assert(verify_flags == script_verify_flags::from_int(verify_flags.as_int()));
38
39 if (!IsValidFlagCombination(verify_flags)) return;
40
41 script_verify_flags fuzzed_flags;
42 ds >> fuzzed_flags;
43
44 std::vector<CTxOut> spent_outputs;
45 for (unsigned i = 0; i < tx.vin.size(); ++i) {
46 CTxOut prevout;
47 ds >> prevout;
48 if (!MoneyRange(prevout.nValue)) {
49 // prevouts should be consensus-valid
50 prevout.nValue = 1;
51 }
52 spent_outputs.push_back(prevout);
53 }
55 txdata.Init(tx, std::move(spent_outputs));
56
57 for (unsigned i = 0; i < tx.vin.size(); ++i) {
58 const CTxOut& prevout = txdata.m_spent_outputs.at(i);
59 const TransactionSignatureChecker checker{&tx, i, prevout.nValue, txdata, MissingDataBehavior::ASSERT_FAIL};
60
61 ScriptError serror;
62 const bool ret = VerifyScript(tx.vin.at(i).scriptSig, prevout.scriptPubKey, &tx.vin.at(i).scriptWitness, verify_flags, checker, &serror);
63 assert(ret == (serror == SCRIPT_ERR_OK));
64
65 // Verify that removing flags from a passing test or adding flags to a failing test does not change the result
66 if (ret) {
67 verify_flags &= ~fuzzed_flags;
68 } else {
69 verify_flags |= fuzzed_flags;
70 }
71 if (!IsValidFlagCombination(verify_flags)) return;
72
73 ScriptError serror_fuzzed;
74 const bool ret_fuzzed = VerifyScript(tx.vin.at(i).scriptSig, prevout.scriptPubKey, &tx.vin.at(i).scriptWitness, verify_flags, checker, &serror_fuzzed);
75 assert(ret_fuzzed == (serror_fuzzed == SCRIPT_ERR_OK));
76
77 assert(ret_fuzzed == ret);
78 }
79 } catch (const std::ios_base::failure&) {
80 return;
81 }
82}
bool MoneyRange(const CAmount &nValue)
Definition: amount.h:27
int ret
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:130
constexpr value_type as_int() const
Definition: verify_flags.h:36
static constexpr script_verify_flags from_int(value_type f)
Definition: verify_flags.h:35
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, script_verify_flags 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
static DataStream & operator>>(DataStream &ds, script_verify_flags &f)
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:180
bool IsValidFlagCombination(script_verify_flags flags)
Flags that are not forbidden by an assert in script validation.
Definition: script.cpp:8
assert(!tx.IsCoinBase())