transaction.cpp
1 // Copyright (c) 2019-present 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 SpanReader 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 CMutableTransaction mutable_tx; 45 try { 46 SpanReader{buffer} >> TX_WITH_WITNESS(mutable_tx); 47 } catch (const std::ios_base::failure&) { 48 valid_mutable_tx = false; 49 } 50 assert(valid_tx == valid_mutable_tx); 51 if (!valid_tx) { 52 return; 53 } 54 55 { 56 TxValidationState state_with_dupe_check; 57 const bool res{CheckTransaction(tx, state_with_dupe_check)}; 58 Assert(res == state_with_dupe_check.IsValid()); 59 } 60 61 const CFeeRate dust_relay_fee{DUST_RELAY_TX_FEE}; 62 std::string reason; 63 const bool is_standard_with_permit_bare_multisig = IsStandardTx(tx, std::nullopt, /* permit_bare_multisig= */ true, dust_relay_fee, reason); 64 const bool is_standard_without_permit_bare_multisig = IsStandardTx(tx, std::nullopt, /* permit_bare_multisig= */ false, dust_relay_fee, reason); 65 if (is_standard_without_permit_bare_multisig) { 66 assert(is_standard_with_permit_bare_multisig); 67 } 68 69 (void)tx.GetHash(); 70 (void)tx.ComputeTotalSize(); 71 try { 72 (void)tx.GetValueOut(); 73 } catch (const std::runtime_error&) { 74 } 75 (void)tx.GetWitnessHash(); 76 (void)tx.HasWitness(); 77 (void)tx.IsCoinBase(); 78 (void)tx.IsNull(); 79 (void)tx.ToString(); 80 81 (void)EncodeHexTx(tx); 82 (void)GetLegacySigOpCount(tx); 83 (void)GetTransactionWeight(tx); 84 (void)GetVirtualTransactionSize(tx); 85 (void)IsFinalTx(tx, /* nBlockHeight= */ 1024, /* nBlockTime= */ 1024); 86 (void)RecursiveDynamicUsage(tx); 87 (void)SignalsOptInRBF(tx); 88 89 CCoinsView coins_view; 90 const CCoinsViewCache coins_view_cache(&coins_view); 91 (void)AreInputsStandard(tx, coins_view_cache); 92 (void)IsWitnessStandard(tx, coins_view_cache); 93 94 if (tx.ComputeTotalSize() < 250'000) { // Avoid high memory usage (with msan) due to json encoding 95 { 96 UniValue u{UniValue::VOBJ}; 97 TxToUniv(tx, /*block_hash=*/uint256::ZERO, /*entry=*/u); 98 } 99 { 100 UniValue u{UniValue::VOBJ}; 101 TxToUniv(tx, /*block_hash=*/uint256::ONE, /*entry=*/u); 102 } 103 } 104 }