/root/bitcoin/src/test/fuzz/script_flags.cpp
Line | Count | Source (jump to first uncovered line) |
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> |
6 | | #include <primitives/transaction.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 | 0 | { |
20 | 0 | if (buffer.size() > 100'000) return; |
21 | 0 | DataStream ds{buffer}; |
22 | 0 | try { |
23 | 0 | const CTransaction tx(deserialize, TX_WITH_WITNESS, ds); |
24 | |
|
25 | 0 | unsigned int verify_flags; |
26 | 0 | ds >> verify_flags; |
27 | |
|
28 | 0 | if (!IsValidFlagCombination(verify_flags)) return; |
29 | | |
30 | 0 | unsigned int fuzzed_flags; |
31 | 0 | ds >> fuzzed_flags; |
32 | |
|
33 | 0 | std::vector<CTxOut> spent_outputs; |
34 | 0 | for (unsigned i = 0; i < tx.vin.size(); ++i) { |
35 | 0 | CTxOut prevout; |
36 | 0 | ds >> prevout; |
37 | 0 | if (!MoneyRange(prevout.nValue)) { |
38 | | // prevouts should be consensus-valid |
39 | 0 | prevout.nValue = 1; |
40 | 0 | } |
41 | 0 | spent_outputs.push_back(prevout); |
42 | 0 | } |
43 | 0 | PrecomputedTransactionData txdata; |
44 | 0 | txdata.Init(tx, std::move(spent_outputs)); |
45 | |
|
46 | 0 | for (unsigned i = 0; i < tx.vin.size(); ++i) { |
47 | 0 | const CTxOut& prevout = txdata.m_spent_outputs.at(i); |
48 | 0 | const TransactionSignatureChecker checker{&tx, i, prevout.nValue, txdata, MissingDataBehavior::ASSERT_FAIL}; |
49 | |
|
50 | 0 | ScriptError serror; |
51 | 0 | const bool ret = VerifyScript(tx.vin.at(i).scriptSig, prevout.scriptPubKey, &tx.vin.at(i).scriptWitness, verify_flags, checker, &serror); |
52 | 0 | 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 | 0 | if (ret) { |
56 | 0 | verify_flags &= ~fuzzed_flags; |
57 | 0 | } else { |
58 | 0 | verify_flags |= fuzzed_flags; |
59 | 0 | } |
60 | 0 | if (!IsValidFlagCombination(verify_flags)) return; |
61 | | |
62 | 0 | ScriptError serror_fuzzed; |
63 | 0 | const bool ret_fuzzed = VerifyScript(tx.vin.at(i).scriptSig, prevout.scriptPubKey, &tx.vin.at(i).scriptWitness, verify_flags, checker, &serror_fuzzed); |
64 | 0 | assert(ret_fuzzed == (serror_fuzzed == SCRIPT_ERR_OK)); |
65 | | |
66 | 0 | assert(ret_fuzzed == ret); |
67 | 0 | } |
68 | 0 | } catch (const std::ios_base::failure&) { |
69 | 0 | return; |
70 | 0 | } |
71 | 0 | } |