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