LCOV - code coverage report
Current view: top level - src/test/fuzz - script_flags.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 6 43 14.0 %
Date: 2023-09-26 12:08:55 Functions: 4 5 80.0 %

          Line data    Source code
       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 <pubkey.h>
       7             : #include <script/interpreter.h>
       8             : #include <streams.h>
       9             : #include <test/util/script.h>
      10             : #include <version.h>
      11           2 : 
      12           2 : #include <test/fuzz/fuzz.h>
      13           2 : 
      14           6 : FUZZ_TARGET(script_flags)
      15           2 : {
      16           0 :     CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
      17             :     try {
      18             :         int nVersion;
      19           0 :         ds >> nVersion;
      20           0 :         ds.SetVersion(nVersion);
      21           0 :     } catch (const std::ios_base::failure&) {
      22             :         return;
      23           0 :     }
      24             : 
      25           2 :     try {
      26           0 :         const CTransaction tx(deserialize, ds);
      27             : 
      28             :         unsigned int verify_flags;
      29           0 :         ds >> verify_flags;
      30             : 
      31           0 :         if (!IsValidFlagCombination(verify_flags)) return;
      32             : 
      33             :         unsigned int fuzzed_flags;
      34           0 :         ds >> fuzzed_flags;
      35             : 
      36           0 :         std::vector<CTxOut> spent_outputs;
      37           0 :         for (unsigned i = 0; i < tx.vin.size(); ++i) {
      38           0 :             CTxOut prevout;
      39           0 :             ds >> prevout;
      40           0 :             if (!MoneyRange(prevout.nValue)) {
      41             :                 // prevouts should be consensus-valid
      42           0 :                 prevout.nValue = 1;
      43           0 :             }
      44           0 :             spent_outputs.push_back(prevout);
      45           0 :         }
      46           0 :         PrecomputedTransactionData txdata;
      47           0 :         txdata.Init(tx, std::move(spent_outputs));
      48             : 
      49           0 :         for (unsigned i = 0; i < tx.vin.size(); ++i) {
      50           0 :             const CTxOut& prevout = txdata.m_spent_outputs.at(i);
      51           0 :             const TransactionSignatureChecker checker{&tx, i, prevout.nValue, txdata, MissingDataBehavior::ASSERT_FAIL};
      52             : 
      53             :             ScriptError serror;
      54           0 :             const bool ret = VerifyScript(tx.vin.at(i).scriptSig, prevout.scriptPubKey, &tx.vin.at(i).scriptWitness, verify_flags, checker, &serror);
      55           0 :             assert(ret == (serror == SCRIPT_ERR_OK));
      56             : 
      57             :             // Verify that removing flags from a passing test or adding flags to a failing test does not change the result
      58           0 :             if (ret) {
      59           0 :                 verify_flags &= ~fuzzed_flags;
      60           0 :             } else {
      61           0 :                 verify_flags |= fuzzed_flags;
      62             :             }
      63           0 :             if (!IsValidFlagCombination(verify_flags)) return;
      64             : 
      65             :             ScriptError serror_fuzzed;
      66           0 :             const bool ret_fuzzed = VerifyScript(tx.vin.at(i).scriptSig, prevout.scriptPubKey, &tx.vin.at(i).scriptWitness, verify_flags, checker, &serror_fuzzed);
      67           0 :             assert(ret_fuzzed == (serror_fuzzed == SCRIPT_ERR_OK));
      68             : 
      69           0 :             assert(ret_fuzzed == ret);
      70           0 :         }
      71           0 :     } catch (const std::ios_base::failure&) {
      72             :         return;
      73           0 :     }
      74           0 : }

Generated by: LCOV version 1.14