LCOV - code coverage report
Current view: top level - src/wallet - transaction.h (source / functions) Coverage Total Hit
Test: total_coverage.info Lines: 93.3 % 120 112
Test Date: 2025-07-10 05:20:26 Functions: 76.9 % 13 10
Branches: 55.1 % 396 218

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2021-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                 :             : #ifndef BITCOIN_WALLET_TRANSACTION_H
       6                 :             : #define BITCOIN_WALLET_TRANSACTION_H
       7                 :             : 
       8                 :             : #include <attributes.h>
       9                 :             : #include <consensus/amount.h>
      10                 :             : #include <primitives/transaction.h>
      11                 :             : #include <tinyformat.h>
      12                 :             : #include <uint256.h>
      13                 :             : #include <util/check.h>
      14                 :             : #include <util/overloaded.h>
      15                 :             : #include <util/strencodings.h>
      16                 :             : #include <util/string.h>
      17                 :             : #include <wallet/types.h>
      18                 :             : 
      19                 :             : #include <bitset>
      20                 :             : #include <cstdint>
      21                 :             : #include <map>
      22                 :             : #include <utility>
      23                 :             : #include <variant>
      24                 :             : #include <vector>
      25                 :             : 
      26                 :             : namespace interfaces {
      27                 :             : class Chain;
      28                 :             : } // namespace interfaces
      29                 :             : 
      30                 :             : namespace wallet {
      31                 :             : //! State of transaction confirmed in a block.
      32                 :             : struct TxStateConfirmed {
      33                 :             :     uint256 confirmed_block_hash;
      34                 :             :     int confirmed_block_height;
      35                 :             :     int position_in_block;
      36                 :             : 
      37   [ +  -  +  - ]:      139645 :     explicit TxStateConfirmed(const uint256& block_hash, int height, int index) : confirmed_block_hash(block_hash), confirmed_block_height(height), position_in_block(index) {}
           [ +  -  #  # ]
      38         [ +  - ]:       39838 :     std::string toString() const { return strprintf("Confirmed (block=%s, height=%i, index=%i)", confirmed_block_hash.ToString(), confirmed_block_height, position_in_block); }
      39                 :             : };
      40                 :             : 
      41                 :             : //! State of transaction added to mempool.
      42                 :             : struct TxStateInMempool {
      43                 :        3434 :     std::string toString() const { return strprintf("InMempool"); }
      44                 :             : };
      45                 :             : 
      46                 :             : //! State of rejected transaction that conflicts with a confirmed block.
      47                 :             : struct TxStateBlockConflicted {
      48                 :             :     uint256 conflicting_block_hash;
      49                 :             :     int conflicting_block_height;
      50                 :             : 
      51                 :         267 :     explicit TxStateBlockConflicted(const uint256& block_hash, int height) : conflicting_block_hash(block_hash), conflicting_block_height(height) {}
      52         [ #  # ]:           0 :     std::string toString() const { return strprintf("BlockConflicted (block=%s, height=%i)", conflicting_block_hash.ToString(), conflicting_block_height); }
      53                 :             : };
      54                 :             : 
      55                 :             : //! State of transaction not confirmed or conflicting with a known block and
      56                 :             : //! not in the mempool. May conflict with the mempool, or with an unknown block,
      57                 :             : //! or be abandoned, never broadcast, or rejected from the mempool for another
      58                 :             : //! reason.
      59                 :             : struct TxStateInactive {
      60                 :             :     bool abandoned;
      61                 :             : 
      62   [ +  -  +  -  :      131063 :     explicit TxStateInactive(bool abandoned = false) : abandoned(abandoned) {}
          -  +  +  -  +  
                -  -  + ]
           [ +  +  #  # ]
           [ +  -  -  -  
          -  -  -  -  -  
                -  -  - ]
      63                 :        2046 :     std::string toString() const { return strprintf("Inactive (abandoned=%i)", abandoned); }
      64                 :             : };
      65                 :             : 
      66                 :             : //! State of transaction loaded in an unrecognized state with unexpected hash or
      67                 :             : //! index values. Treated as inactive (with serialized hash and index values
      68                 :             : //! preserved) by default, but may enter another state if transaction is added
      69                 :             : //! to the mempool, or confirmed, or abandoned, or found conflicting.
      70                 :             : struct TxStateUnrecognized {
      71                 :             :     uint256 block_hash;
      72                 :             :     int index;
      73                 :             : 
      74                 :        7688 :     TxStateUnrecognized(const uint256& block_hash, int index) : block_hash(block_hash), index(index) {}
      75         [ #  # ]:           0 :     std::string toString() const { return strprintf("Unrecognized (block=%s, index=%i)", block_hash.ToString(), index); }
      76                 :             : };
      77                 :             : 
      78                 :             : //! All possible CWalletTx states
      79                 :             : using TxState = std::variant<TxStateConfirmed, TxStateInMempool, TxStateBlockConflicted, TxStateInactive, TxStateUnrecognized>;
      80                 :             : 
      81                 :             : //! Subset of states transaction sync logic is implemented to handle.
      82                 :             : using SyncTxState = std::variant<TxStateConfirmed, TxStateInMempool, TxStateInactive>;
      83                 :             : 
      84                 :             : //! Try to interpret deserialized TxStateUnrecognized data as a recognized state.
      85                 :        7688 : static inline TxState TxStateInterpretSerialized(TxStateUnrecognized data)
      86                 :             : {
      87         [ +  + ]:        7688 :     if (data.block_hash == uint256::ZERO) {
      88         [ +  + ]:          80 :         if (data.index == 0) return TxStateInactive{};
      89         [ +  + ]:        7608 :     } else if (data.block_hash == uint256::ONE) {
      90         [ +  + ]:         125 :         if (data.index == -1) return TxStateInactive{/*abandoned=*/true};
      91         [ +  + ]:        7483 :     } else if (data.index >= 0) {
      92                 :        7383 :         return TxStateConfirmed{data.block_hash, /*height=*/-1, data.index};
      93         [ +  + ]:         100 :     } else if (data.index == -1) {
      94                 :          97 :         return TxStateBlockConflicted{data.block_hash, /*height=*/-1};
      95                 :             :     }
      96                 :          11 :     return data;
      97                 :             : }
      98                 :             : 
      99                 :             : //! Get TxState serialized block hash. Inverse of TxStateInterpretSerialized.
     100                 :       26768 : static inline uint256 TxStateSerializedBlockHash(const TxState& state)
     101                 :             : {
     102         [ +  + ]:       26768 :     return std::visit(util::Overloaded{
     103         [ +  + ]:        4855 :         [](const TxStateInactive& inactive) { return inactive.abandoned ? uint256::ONE : uint256::ZERO; },
     104                 :        5020 :         [](const TxStateInMempool& in_mempool) { return uint256::ZERO; },
     105                 :       21353 :         [](const TxStateConfirmed& confirmed) { return confirmed.confirmed_block_hash; },
     106                 :         173 :         [](const TxStateBlockConflicted& conflicted) { return conflicted.conflicting_block_hash; },
     107                 :          11 :         [](const TxStateUnrecognized& unrecognized) { return unrecognized.block_hash; }
     108                 :             :     }, state);
     109                 :             : }
     110                 :             : 
     111                 :             : //! Get TxState serialized block index. Inverse of TxStateInterpretSerialized.
     112                 :       26768 : static inline int TxStateSerializedIndex(const TxState& state)
     113                 :             : {
     114         [ +  + ]:       26768 :     return std::visit(util::Overloaded{
     115         [ +  + ]:        3221 :         [](const TxStateInactive& inactive) { return inactive.abandoned ? -1 : 0; },
     116                 :             :         [](const TxStateInMempool& in_mempool) { return 0; },
     117                 :       21353 :         [](const TxStateConfirmed& confirmed) { return confirmed.position_in_block; },
     118                 :             :         [](const TxStateBlockConflicted& conflicted) { return -1; },
     119                 :          11 :         [](const TxStateUnrecognized& unrecognized) { return unrecognized.index; }
     120                 :             :     }, state);
     121                 :             : }
     122                 :             : 
     123                 :             : //! Return TxState or SyncTxState as a string for logging or debugging.
     124                 :             : template<typename T>
     125                 :       25399 : std::string TxStateString(const T& state)
     126                 :             : {
     127                 :       25399 :     return std::visit([](const auto& s) { return s.toString(); }, state);
     128                 :             : }
     129                 :             : 
     130                 :             : /**
     131                 :             :  * Cachable amount subdivided into watchonly and spendable parts.
     132                 :             :  */
     133                 :      298786 : struct CachableAmount
     134                 :             : {
     135                 :             :     // NO and ALL are never (supposed to be) cached
     136                 :             :     std::bitset<ISMINE_ENUM_ELEMENTS> m_cached;
     137                 :             :     CAmount m_value[ISMINE_ENUM_ELEMENTS];
     138                 :       61483 :     inline void Reset()
     139                 :             :     {
     140                 :       61483 :         m_cached.reset();
     141                 :             :     }
     142                 :       10884 :     void Set(isminefilter filter, CAmount value)
     143                 :             :     {
     144                 :       10884 :         m_cached.set(filter);
     145                 :       10884 :         m_value[filter] = value;
     146                 :             :     }
     147                 :             : };
     148                 :             : 
     149                 :             : 
     150                 :             : typedef std::map<std::string, std::string> mapValue_t;
     151                 :             : 
     152                 :             : 
     153                 :             : /** Legacy class used for deserializing vtxPrev for backwards compatibility.
     154                 :             :  * vtxPrev was removed in commit 93a18a3650292afbb441a47d1fa1b94aeb0164e3,
     155                 :             :  * but old wallet.dat files may still contain vtxPrev vectors of CMerkleTxs.
     156                 :             :  * These need to get deserialized for field alignment when deserializing
     157                 :             :  * a CWalletTx, but the deserialized values are discarded.**/
     158                 :             : class CMerkleTx
     159                 :             : {
     160                 :             : public:
     161                 :             :     template<typename Stream>
     162                 :           0 :     void Unserialize(Stream& s)
     163                 :             :     {
     164                 :           0 :         CTransactionRef tx;
     165                 :           0 :         uint256 hashBlock;
     166         [ #  # ]:           0 :         std::vector<uint256> vMerkleBranch;
     167                 :             :         int nIndex;
     168                 :             : 
     169   [ #  #  #  #  :           0 :         s >> TX_WITH_WITNESS(tx) >> hashBlock >> vMerkleBranch >> nIndex;
             #  #  #  # ]
     170         [ #  # ]:           0 :     }
     171                 :             : };
     172                 :             : 
     173                 :             : /**
     174                 :             :  * A transaction with a bunch of additional info that only the owner cares about.
     175                 :             :  * It includes any unrecorded transactions needed to link it back to the block chain.
     176                 :             :  */
     177                 :             : class CWalletTx
     178                 :             : {
     179                 :             : public:
     180                 :             :     /**
     181                 :             :      * Key/value map with information about the transaction.
     182                 :             :      *
     183                 :             :      * The following keys can be read and written through the map and are
     184                 :             :      * serialized in the wallet database:
     185                 :             :      *
     186                 :             :      *     "comment", "to"   - comment strings provided to sendtoaddress,
     187                 :             :      *                         and sendmany wallet RPCs
     188                 :             :      *     "replaces_txid"   - txid (as HexStr) of transaction replaced by
     189                 :             :      *                         bumpfee on transaction created by bumpfee
     190                 :             :      *     "replaced_by_txid" - txid (as HexStr) of transaction created by
     191                 :             :      *                         bumpfee on transaction replaced by bumpfee
     192                 :             :      *     "from", "message" - obsolete fields that could be set in UI prior to
     193                 :             :      *                         2011 (removed in commit 4d9b223)
     194                 :             :      *
     195                 :             :      * The following keys are serialized in the wallet database, but shouldn't
     196                 :             :      * be read or written through the map (they will be temporarily added and
     197                 :             :      * removed from the map during serialization):
     198                 :             :      *
     199                 :             :      *     "fromaccount"     - serialized strFromAccount value
     200                 :             :      *     "n"               - serialized nOrderPos value
     201                 :             :      *     "timesmart"       - serialized nTimeSmart value
     202                 :             :      *     "spent"           - serialized vfSpent value that existed prior to
     203                 :             :      *                         2014 (removed in commit 93a18a3)
     204                 :             :      */
     205                 :             :     mapValue_t mapValue;
     206                 :             :     std::vector<std::pair<std::string, std::string> > vOrderForm;
     207                 :             :     unsigned int nTimeReceived; //!< time received by this node
     208                 :             :     /**
     209                 :             :      * Stable timestamp that never changes, and reflects the order a transaction
     210                 :             :      * was added to the wallet. Timestamp is based on the block time for a
     211                 :             :      * transaction added as part of a block, or else the time when the
     212                 :             :      * transaction was received if it wasn't part of a block, with the timestamp
     213                 :             :      * adjusted in both cases so timestamp order matches the order transactions
     214                 :             :      * were added to the wallet. More details can be found in
     215                 :             :      * CWallet::ComputeTimeSmart().
     216                 :             :      */
     217                 :             :     unsigned int nTimeSmart;
     218                 :             :     int64_t nOrderPos; //!< position in ordered transaction list
     219                 :             :     std::multimap<int64_t, CWalletTx*>::const_iterator m_it_wtxOrdered;
     220                 :             : 
     221                 :             :     // memory only
     222                 :             :     enum AmountType { DEBIT, CREDIT, AMOUNTTYPE_ENUM_ELEMENTS };
     223                 :             :     mutable CachableAmount m_amounts[AMOUNTTYPE_ENUM_ELEMENTS];
     224                 :             :     /**
     225                 :             :      * This flag is true if all m_amounts caches are empty. This is particularly
     226                 :             :      * useful in places where MarkDirty is conditionally called and the
     227                 :             :      * condition can be expensive and thus can be skipped if the flag is true.
     228                 :             :      * See MarkDestinationsDirty.
     229                 :             :      */
     230                 :             :     mutable bool m_is_cache_empty{true};
     231                 :             :     mutable bool fChangeCached;
     232                 :             :     mutable CAmount nChangeCached;
     233                 :             : 
     234         [ +  + ]:      448179 :     CWalletTx(CTransactionRef tx, const TxState& state) : tx(std::move(tx)), m_state(state)
     235                 :             :     {
     236                 :      149393 :         Init();
     237                 :      149393 :     }
     238                 :             : 
     239                 :      157056 :     void Init()
     240                 :             :     {
     241                 :      157056 :         mapValue.clear();
     242                 :      157056 :         vOrderForm.clear();
     243                 :      157056 :         nTimeReceived = 0;
     244                 :      157056 :         nTimeSmart = 0;
     245                 :      157056 :         fChangeCached = false;
     246                 :      157056 :         nChangeCached = 0;
     247                 :      157056 :         nOrderPos = -1;
     248                 :      157056 :     }
     249                 :             : 
     250                 :             :     CTransactionRef tx;
     251                 :             :     TxState m_state;
     252                 :             : 
     253                 :             :     // Set of mempool transactions that conflict
     254                 :             :     // directly with the transaction, or that conflict
     255                 :             :     // with an ancestor transaction. This set will be
     256                 :             :     // empty if state is InMempool or Confirmed, but
     257                 :             :     // can be nonempty if state is Inactive or
     258                 :             :     // BlockConflicted.
     259                 :             :     std::set<Txid> mempool_conflicts;
     260                 :             : 
     261                 :             :     template<typename Stream>
     262                 :       23733 :     void Serialize(Stream& s) const
     263                 :             :     {
     264         [ +  - ]:       23733 :         mapValue_t mapValueCopy = mapValue;
     265                 :             : 
     266   [ +  -  +  -  :       23733 :         mapValueCopy["fromaccount"] = "";
                   +  - ]
     267         [ +  - ]:       23733 :         if (nOrderPos != -1) {
     268   [ +  -  +  -  :       23733 :             mapValueCopy["n"] = util::ToString(nOrderPos);
                   +  - ]
     269                 :             :         }
     270         [ +  - ]:       23733 :         if (nTimeSmart) {
     271   [ +  -  +  -  :       23733 :             mapValueCopy["timesmart"] = strprintf("%u", nTimeSmart);
                   +  - ]
     272                 :             :         }
     273                 :             : 
     274                 :       23733 :         std::vector<uint8_t> dummy_vector1; //!< Used to be vMerkleBranch
     275                 :       23733 :         std::vector<uint8_t> dummy_vector2; //!< Used to be vtxPrev
     276                 :       23733 :         bool dummy_bool = false; //!< Used to be fFromMe, and fSpent
     277                 :       23733 :         uint32_t dummy_int = 0; // Used to be fTimeReceivedIsTxTime
     278         [ +  - ]:       23733 :         uint256 serializedHash = TxStateSerializedBlockHash(m_state);
     279                 :       23733 :         int serializedIndex = TxStateSerializedIndex(m_state);
     280   [ +  -  +  -  :       47466 :         s << TX_WITH_WITNESS(tx) << serializedHash << dummy_vector1 << serializedIndex << dummy_vector2 << mapValueCopy << vOrderForm << dummy_int << nTimeReceived << dummy_bool << dummy_bool;
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
     281                 :       23733 :     }
     282                 :             : 
     283                 :             :     template<typename Stream>
     284                 :        7663 :     void Unserialize(Stream& s)
     285                 :             :     {
     286                 :        7663 :         Init();
     287                 :             : 
     288                 :        7663 :         std::vector<uint256> dummy_vector1; //!< Used to be vMerkleBranch
     289                 :        7663 :         std::vector<CMerkleTx> dummy_vector2; //!< Used to be vtxPrev
     290                 :             :         bool dummy_bool; //! Used to be fFromMe, and fSpent
     291                 :             :         uint32_t dummy_int; // Used to be fTimeReceivedIsTxTime
     292                 :        7663 :         uint256 serialized_block_hash;
     293                 :             :         int serializedIndex;
     294   [ +  -  +  -  :        7663 :         s >> TX_WITH_WITNESS(tx) >> serialized_block_hash >> dummy_vector1 >> serializedIndex >> dummy_vector2 >> mapValue >> vOrderForm >> dummy_int >> nTimeReceived >> dummy_bool >> dummy_bool;
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
                -  +  - ]
     295                 :             : 
     296                 :        7663 :         m_state = TxStateInterpretSerialized({serialized_block_hash, serializedIndex});
     297                 :             : 
     298         [ +  - ]:       15326 :         const auto it_op = mapValue.find("n");
     299   [ +  -  +  - ]:        7663 :         nOrderPos = (it_op != mapValue.end()) ? LocaleIndependentAtoi<int64_t>(it_op->second) : -1;
     300         [ +  - ]:       15326 :         const auto it_ts = mapValue.find("timesmart");
     301   [ +  -  +  - ]:        7663 :         nTimeSmart = (it_ts != mapValue.end()) ? static_cast<unsigned int>(LocaleIndependentAtoi<int64_t>(it_ts->second)) : 0;
     302                 :             : 
     303         [ +  - ]:       15326 :         mapValue.erase("fromaccount");
     304         [ +  - ]:       15326 :         mapValue.erase("spent");
     305         [ +  - ]:       15326 :         mapValue.erase("n");
     306         [ +  - ]:       15326 :         mapValue.erase("timesmart");
     307                 :        7663 :     }
     308                 :             : 
     309                 :          14 :     void SetTx(CTransactionRef arg)
     310                 :             :     {
     311   [ -  +  -  - ]:          14 :         tx = std::move(arg);
     312                 :             :     }
     313                 :             : 
     314                 :             :     //! make sure balances are recalculated
     315                 :       61483 :     void MarkDirty()
     316                 :             :     {
     317   [ +  -  +  +  :       61483 :         m_amounts[DEBIT].Reset();
             +  -  +  - ]
     318                 :       61483 :         m_amounts[CREDIT].Reset();
     319                 :       61483 :         fChangeCached = false;
     320   [ +  -  +  +  :       39519 :         m_is_cache_empty = true;
             +  -  +  - ]
     321                 :       21964 :     }
     322                 :             : 
     323                 :             :     /** True if only scriptSigs are different */
     324                 :             :     bool IsEquivalentTo(const CWalletTx& tx) const;
     325                 :             : 
     326                 :             :     bool InMempool() const;
     327                 :             : 
     328                 :             :     int64_t GetTxTime() const;
     329                 :             : 
     330   [ #  #  #  # ]:     2707697 :     template<typename T> const T* state() const { return std::get_if<T>(&m_state); }
           [ +  +  +  +  
          -  +  -  +  +  
          +  -  +  +  +  
           +  + ][ +  +  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     331   [ +  +  +  +  :       30207 :     template<typename T> T* state() { return std::get_if<T>(&m_state); }
          +  +  +  -  +  
             -  +  +  -  
           + ][ +  +  +  
          +  #  #  #  #  
          #  #  #  #  #  
                      # ]
     332                 :             : 
     333                 :             :     //! Update transaction state when attaching to a chain, filling in heights
     334                 :             :     //! of conflicted and confirmed blocks
     335                 :             :     void updateState(interfaces::Chain& chain);
     336                 :             : 
     337   [ #  #  #  #  :      338804 :     bool isAbandoned() const { return state<TxStateInactive>() && state<TxStateInactive>()->abandoned; }
           #  # ][ +  +  
          +  +  +  -  +  
          -  +  +  +  +  
          +  -  +  +  +  
          +  +  -  +  +  
          +  +  +  +  +  
                      + ]
     338         [ +  + ]:      330625 :     bool isMempoolConflicted() const { return !mempool_conflicts.empty(); }
     339   [ +  +  +  + ]:      409290 :     bool isBlockConflicted() const { return state<TxStateBlockConflicted>(); }
           [ +  +  +  -  
          +  -  +  +  +  
          -  +  -  +  +  
                   +  + ]
     340   [ +  +  +  -  :       33599 :     bool isInactive() const { return state<TxStateInactive>(); }
           +  - ][ +  + ]
     341   [ +  +  +  +  :       13545 :     bool isUnconfirmed() const { return !isAbandoned() && !isBlockConflicted() && !isMempoolConflicted() && !isConfirmed(); }
                   +  - ]
     342   [ +  +  +  +  :      574505 :     bool isConfirmed() const { return state<TxStateConfirmed>(); }
             +  +  +  + ]
                 [ #  # ]
           [ +  -  +  + ]
     343 [ +  + ][ +  -  :      978243 :     const Txid& GetHash() const LIFETIMEBOUND { return tx->GetHash(); }
          -  -  -  -  -  
          -  +  -  +  -  
             +  -  -  - ]
           [ +  -  +  -  
             +  -  +  - ]
     344                 :        1967 :     const Wtxid& GetWitnessHash() const LIFETIMEBOUND { return tx->GetWitnessHash(); }
     345   [ #  #  #  # ]:      770926 :     bool IsCoinBase() const { return tx->IsCoinBase(); }
           [ +  +  +  +  
             +  +  +  + ]
                 [ +  + ]
     346                 :             : 
     347                 :             : private:
     348                 :             :     // Disable copying of CWalletTx objects to prevent bugs where instances get
     349                 :             :     // copied in and out of the mapWallet map, and fields are updated in the
     350                 :             :     // wrong copy.
     351                 :             :     CWalletTx(const CWalletTx&) = default;
     352                 :          14 :     CWalletTx& operator=(const CWalletTx&) = default;
     353                 :             : public:
     354                 :             :     // Instead have an explicit copy function
     355                 :             :     void CopyFrom(const CWalletTx&);
     356                 :             : };
     357                 :             : 
     358                 :             : struct WalletTxOrderComparator {
     359                 :         270 :     bool operator()(const CWalletTx* a, const CWalletTx* b) const
     360                 :             :     {
     361   [ +  +  +  +  :         270 :         return a->nOrderPos < b->nOrderPos;
                   +  - ]
     362                 :             :     }
     363                 :             : };
     364                 :             : 
     365                 :             : class WalletTXO
     366                 :             : {
     367                 :             : private:
     368                 :             :     const CWalletTx& m_wtx;
     369                 :             :     const CTxOut& m_output;
     370                 :             :     isminetype m_ismine;
     371                 :             : 
     372                 :             : public:
     373                 :       44493 :     WalletTXO(const CWalletTx& wtx, const CTxOut& output, const isminetype ismine)
     374                 :       44493 :     : m_wtx(wtx),
     375                 :       44493 :     m_output(output),
     376                 :       44493 :     m_ismine(ismine)
     377                 :             :     {
     378                 :       44493 :         Assume(std::ranges::find(wtx.tx->vout, output) != wtx.tx->vout.end());
     379                 :       44493 :     }
     380                 :             : 
     381   [ +  -  +  - ]:      777160 :     const CWalletTx& GetWalletTx() const { return m_wtx; }
                 [ +  - ]
     382                 :             : 
     383   [ +  -  +  -  :      740222 :     const CTxOut& GetTxOut() const { return m_output; }
           +  - ][ +  - ]
     384                 :             : 
     385         [ +  - ]:       39467 :     isminetype GetIsMine() const { return m_ismine; }
     386                 :       12794 :     void SetIsMine(isminetype ismine) { m_ismine = ismine; }
     387                 :             : };
     388                 :             : } // namespace wallet
     389                 :             : 
     390                 :             : #endif // BITCOIN_WALLET_TRANSACTION_H
        

Generated by: LCOV version 2.0-1