LCOV - code coverage report
Current view: top level - src/wallet - transaction.cpp (source / functions) Coverage Total Hit
Test: fuzz_coverage.info Lines: 5.7 % 53 3
Test Date: 2026-08-21 05:53:24 Functions: 12.5 % 8 1
Branches: 1.8 % 56 1

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2021-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 <wallet/transaction.h>
       6                 :             : 
       7                 :             : #include <consensus/validation.h>
       8                 :             : #include <interfaces/chain.h>
       9                 :             : 
      10                 :             : using interfaces::FoundBlock;
      11                 :             : 
      12                 :             : namespace wallet {
      13                 :           0 : bool CWalletTx::IsEquivalentTo(const CWalletTx& _tx) const
      14                 :             : {
      15         [ #  # ]:           0 :         CMutableTransaction tx1 {*this->GetTx()};
      16   [ #  #  #  # ]:           0 :         CMutableTransaction tx2 {*_tx.GetTx()};
      17         [ #  # ]:           0 :         for (auto& txin : tx1.vin) {
      18                 :           0 :             txin.scriptSig = CScript();
      19                 :           0 :             txin.scriptWitness.SetNull();
      20                 :             :         }
      21         [ #  # ]:           0 :         for (auto& txin : tx2.vin) {
      22                 :           0 :             txin.scriptSig = CScript();
      23                 :           0 :             txin.scriptWitness.SetNull();
      24                 :             :         }
      25   [ #  #  #  # ]:           0 :         return CTransaction(tx1) == CTransaction(tx2);
      26                 :           0 : }
      27                 :             : 
      28                 :           0 : bool CWalletTx::InMempool() const
      29                 :             : {
      30         [ #  # ]:           0 :     return state<TxStateInMempool>();
      31                 :             : }
      32                 :             : 
      33                 :       86000 : int64_t CWalletTx::GetTxTime() const
      34                 :             : {
      35                 :       86000 :     int64_t n = nTimeSmart;
      36         [ +  - ]:       86000 :     return n ? n : nTimeReceived;
      37                 :             : }
      38                 :             : 
      39                 :           0 : void CWalletTx::updateState(interfaces::Chain& chain)
      40                 :             : {
      41                 :           0 :     bool active;
      42                 :           0 :     auto lookup_block = [&](const uint256& hash, int& height, TxState& state) {
      43                 :             :         // If tx block (or conflicting block) was reorged out of chain
      44                 :             :         // while the wallet was shutdown, change tx status to UNCONFIRMED
      45                 :             :         // and reset block height, hash, and index. ABANDONED tx don't have
      46                 :             :         // associated blocks and don't need to be updated. The case where a
      47                 :             :         // transaction was reorged out while online and then reconfirmed
      48                 :             :         // while offline is covered by the rescan logic.
      49   [ #  #  #  # ]:           0 :         if (!chain.findBlock(hash, FoundBlock().inActiveChain(active).height(height)) || !active) {
      50         [ #  # ]:           0 :             state = TxStateInactive{};
      51                 :             :         }
      52                 :           0 :     };
      53         [ #  # ]:           0 :     if (auto* conf = state<TxStateConfirmed>()) {
      54                 :           0 :         lookup_block(conf->confirmed_block_hash, conf->confirmed_block_height, m_state);
      55         [ #  # ]:           0 :     } else if (auto* conf = state<TxStateBlockConflicted>()) {
      56                 :           0 :         lookup_block(conf->conflicting_block_hash, conf->conflicting_block_height, m_state);
      57                 :             :     }
      58                 :             : 
      59                 :             :     // If the above downgraded a previously-confirmed witness variant back to unconfirmed,
      60                 :             :     // the canonical choice is no longer pinned by confirmation. Re-apply the least-weight rule.
      61         [ #  # ]:           0 :     if (!isConfirmed()) RecomputeCanonical();
      62                 :           0 : }
      63                 :             : 
      64                 :           0 : bool CWalletTx::Update(CTransactionRef new_tx, const TxState& new_state)
      65                 :             : {
      66         [ #  # ]:           0 :     Assert(new_tx);
      67   [ #  #  #  # ]:           0 :     if (!Assume(GetHash() == new_tx->GetHash())) {
      68                 :             :         return false;
      69                 :             :     }
      70                 :           0 :     bool ret = false;
      71         [ #  # ]:           0 :     const auto& [tx_pair, inserted] = m_txs.emplace(new_tx->GetWitnessHash(), std::move(new_tx));
      72         [ #  # ]:           0 :     if (inserted) {
      73                 :           0 :         ret = true;
      74                 :             :     }
      75         [ #  # ]:           0 :     const auto& [wtxid, tx] = *tx_pair;
      76                 :             : 
      77         [ #  # ]:           0 :     if (new_state.index() != m_state.index()) {
      78                 :           0 :         m_state = new_state;
      79         [ #  # ]:           0 :         if (state<TxStateConfirmed>()) {
      80                 :           0 :             m_canonical_wtxid = wtxid;
      81                 :             :         }
      82                 :             :         ret = true;
      83                 :             :     } else {
      84         [ #  # ]:           0 :         assert(TxStateSerializedIndex(m_state) == TxStateSerializedIndex(new_state));
      85         [ #  # ]:           0 :         assert(TxStateSerializedBlockHash(m_state) == TxStateSerializedBlockHash(new_state));
      86                 :             :     }
      87                 :             : 
      88                 :             :     // While unconfirmed, derive the canonical variant from all known variants
      89         [ #  # ]:           0 :     if (!isConfirmed()) {
      90                 :           0 :         const Wtxid prev_canonical = m_canonical_wtxid;
      91                 :           0 :         RecomputeCanonical();
      92         [ #  # ]:           0 :         if (m_canonical_wtxid != prev_canonical) {
      93                 :             :             ret = true;
      94                 :             :         }
      95                 :             :     }
      96                 :             : 
      97                 :           0 :     return ret;
      98                 :             : }
      99                 :             : 
     100                 :           0 : void CWalletTx::RecomputeCanonical()
     101                 :             : {
     102                 :             :     // Recompute the canonical variant among the witness variants. They share
     103                 :             :     // the txid but differ in the wtxid. Prefer variant with witness data and
     104                 :             :     // the least weight.
     105         [ #  # ]:           0 :     Assert(!m_txs.empty());
     106                 :             : 
     107                 :           0 :     m_canonical_wtxid = std::ranges::min_element(m_txs, std::less{}, [](const auto& entry) {
     108                 :           0 :                             return std::make_pair(!entry.second->HasWitness(), GetTransactionWeight(*entry.second));
     109                 :           0 :                         })->first;
     110                 :           0 : }
     111                 :             : } // namespace wallet
        

Generated by: LCOV version 2.5.0-full