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