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