transaction.cpp raw

   1  // Copyright (c) 2019-2022 The Limenka 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 <chainparams.h>
   6  #include <coins.h>
   7  #include <consensus/tx_check.h>
   8  #include <consensus/tx_verify.h>
   9  #include <consensus/validation.h>
  10  #include <core_io.h>
  11  #include <core_memusage.h>
  12  #include <kernel/mempool_options.h>
  13  #include <policy/policy.h>
  14  #include <policy/settings.h>
  15  #include <primitives/transaction.h>
  16  #include <streams.h>
  17  #include <test/fuzz/fuzz.h>
  18  #include <test/util/random.h>
  19  #include <test/util/transaction_utils.h>
  20  #include <univalue.h>
  21  #include <util/chaintype.h>
  22  #include <util/rbf.h>
  23  #include <validation.h>
  24  
  25  #include <cassert>
  26  
  27  void initialize_transaction()
  28  {
  29      SelectParams(ChainType::REGTEST);
  30  }
  31  
  32  FUZZ_TARGET(transaction, .init = initialize_transaction)
  33  {
  34      SeedRandomStateForTest(SeedRand::ZEROS);
  35      DataStream ds{buffer};
  36      bool valid_tx = true;
  37      const CTransaction tx = [&] {
  38          try {
  39              return CTransaction(deserialize, TX_WITH_WITNESS, ds);
  40          } catch (const std::ios_base::failure&) {
  41              valid_tx = false;
  42              return CTransaction{CMutableTransaction{}};
  43          }
  44      }();
  45      bool valid_mutable_tx = true;
  46      DataStream ds_mtx{buffer};
  47      CMutableTransaction mutable_tx;
  48      try {
  49          ds_mtx >> TX_WITH_WITNESS(mutable_tx);
  50      } catch (const std::ios_base::failure&) {
  51          valid_mutable_tx = false;
  52      }
  53      assert(valid_tx == valid_mutable_tx);
  54      if (!valid_tx) {
  55          return;
  56      }
  57  
  58      {
  59          TxValidationState state_with_dupe_check;
  60          const bool res{CheckTransaction(tx, state_with_dupe_check)};
  61          Assert(res == state_with_dupe_check.IsValid());
  62      }
  63  
  64      std::string reason;
  65      const bool is_standard_with_permit_bare_multisig = IsStandardTx(tx, kernel::MemPoolOptions{.permit_bare_pubkey = true, .permit_bare_multisig = true}, reason);
  66      const bool is_standard_without_permit_bare_multisig = IsStandardTx(tx, kernel::MemPoolOptions{.permit_bare_pubkey = true, .permit_bare_multisig = false}, reason);
  67      if (is_standard_without_permit_bare_multisig) {
  68          assert(is_standard_with_permit_bare_multisig);
  69      }
  70  
  71      (void)tx.GetHash();
  72      (void)tx.GetTotalSize();
  73      try {
  74          (void)tx.GetValueOut();
  75      } catch (const std::runtime_error&) {
  76      }
  77      (void)tx.GetWitnessHash();
  78      (void)tx.HasWitness();
  79      (void)tx.IsCoinBase();
  80      (void)tx.IsNull();
  81      (void)tx.ToString();
  82  
  83      (void)EncodeHexTx(tx);
  84      (void)GetLegacySigOpCount(tx);
  85      (void)GetTransactionWeight(tx);
  86      (void)GetVirtualTransactionSize(tx);
  87      (void)IsFinalTx(tx, /* nBlockHeight= */ 1024, /* nBlockTime= */ 1024);
  88      (void)RecursiveDynamicUsage(tx);
  89      (void)SignalsOptInRBF(tx);
  90  
  91      CCoinsView coins_view;
  92      const CCoinsViewCache coins_view_cache(&coins_view);
  93      (void)AreInputsStandard(tx, coins_view_cache);
  94      std::string reject_reason;
  95      (void)IsWitnessStandard(tx, coins_view_cache, "fuzz", reject_reason);
  96  
  97      if (tx.GetTotalSize() < 250'000) { // Avoid high memory usage (with msan) due to json encoding
  98          {
  99              UniValue u{UniValue::VOBJ};
 100              TxToUniv(tx, /*block_hash=*/uint256::ZERO, /*entry=*/u);
 101          }
 102          {
 103              UniValue u{UniValue::VOBJ};
 104              TxToUniv(tx, /*block_hash=*/uint256::ONE, /*entry=*/u);
 105          }
 106      }
 107  }
 108