Bitcoin Core Fuzz Coverage Report for wallet_tx_can_be_bumped

Coverage Report

Created: 2025-11-19 11:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/Users/brunogarcia/projects/bitcoin-core-dev/src/wallet/transaction.h
Line
Count
Source
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
829
    explicit TxStateConfirmed(const uint256& block_hash, int height, int index) : confirmed_block_hash(block_hash), confirmed_block_height(height), position_in_block(index) {}
38
827
    std::string toString() const { return strprintf("Confirmed (block=%s, height=%i, index=%i)", confirmed_block_hash.ToString(), confirmed_block_height, position_in_block); }
Line
Count
Source
1172
827
#define strprintf tfm::format
39
};
40
41
//! State of transaction added to mempool.
42
struct TxStateInMempool {
43
14.6k
    std::string toString() const { return strprintf("InMempool"); }
Line
Count
Source
1172
14.6k
#define strprintf tfm::format
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
652
    explicit TxStateBlockConflicted(const uint256& block_hash, int height) : conflicting_block_hash(block_hash), conflicting_block_height(height) {}
52
331
    std::string toString() const { return strprintf("BlockConflicted (block=%s, height=%i)", conflicting_block_hash.ToString(), conflicting_block_height); }
Line
Count
Source
1172
331
#define strprintf tfm::format
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
9.91k
    explicit TxStateInactive(bool abandoned = false) : abandoned(abandoned) {}
63
0
    std::string toString() const { return strprintf("Inactive (abandoned=%i)", abandoned); }
Line
Count
Source
1172
0
#define strprintf tfm::format
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
0
    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); }
Line
Count
Source
1172
0
#define strprintf tfm::format
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
static inline TxState TxStateInterpretSerialized(TxStateUnrecognized data)
86
0
{
87
0
    if (data.block_hash == uint256::ZERO) {
88
0
        if (data.index == 0) return TxStateInactive{};
89
0
    } else if (data.block_hash == uint256::ONE) {
90
0
        if (data.index == -1) return TxStateInactive{/*abandoned=*/true};
91
0
    } else if (data.index >= 0) {
92
0
        return TxStateConfirmed{data.block_hash, /*height=*/-1, data.index};
93
0
    } else if (data.index == -1) {
94
0
        return TxStateBlockConflicted{data.block_hash, /*height=*/-1};
95
0
    }
96
0
    return data;
97
0
}
Unexecuted instantiation: feebumper.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: fees.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: scriptpubkeyman.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: spend.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: dump.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: interfaces.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: load.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: receive.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: addresses.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: backup.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: coins.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: encrypt.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: signmessage.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: transactions.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: util.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: wallet.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: transaction.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: walletdb.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
Unexecuted instantiation: init.cpp:wallet::TxStateInterpretSerialized(wallet::TxStateUnrecognized)
98
99
//! Get TxState serialized block hash. Inverse of TxStateInterpretSerialized.
100
static inline uint256 TxStateSerializedBlockHash(const TxState& state)
101
17.9k
{
102
17.9k
    return std::visit(util::Overloaded{
103
17.9k
        [](const TxStateInactive& inactive) 
{ return 0
inactive.abandoned0
?
uint256::ONE0
:
uint256::ZERO0
; },
Unexecuted instantiation: wallet.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateInactive const&)::operator()(wallet::TxStateInactive const&) const
Unexecuted instantiation: walletdb.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateInactive const&)::operator()(wallet::TxStateInactive const&) const
104
17.9k
        [](const TxStateInMempool& in_mempool) 
{ return uint256::ZERO; }16.6k
,
wallet.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateInMempool const&)::operator()(wallet::TxStateInMempool const&) const
Line
Count
Source
104
2.67k
        [](const TxStateInMempool& in_mempool) { return uint256::ZERO; },
walletdb.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateInMempool const&)::operator()(wallet::TxStateInMempool const&) const
Line
Count
Source
104
13.9k
        [](const TxStateInMempool& in_mempool) { return uint256::ZERO; },
105
17.9k
        [](const TxStateConfirmed& confirmed) 
{ return confirmed.confirmed_block_hash; }925
,
wallet.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateConfirmed const&)::operator()(wallet::TxStateConfirmed const&) const
Line
Count
Source
105
196
        [](const TxStateConfirmed& confirmed) { return confirmed.confirmed_block_hash; },
walletdb.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateConfirmed const&)::operator()(wallet::TxStateConfirmed const&) const
Line
Count
Source
105
729
        [](const TxStateConfirmed& confirmed) { return confirmed.confirmed_block_hash; },
106
17.9k
        [](const TxStateBlockConflicted& conflicted) 
{ return conflicted.conflicting_block_hash; }368
,
wallet.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateBlockConflicted const&)::operator()(wallet::TxStateBlockConflicted const&) const
Line
Count
Source
106
74
        [](const TxStateBlockConflicted& conflicted) { return conflicted.conflicting_block_hash; },
walletdb.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateBlockConflicted const&)::operator()(wallet::TxStateBlockConflicted const&) const
Line
Count
Source
106
294
        [](const TxStateBlockConflicted& conflicted) { return conflicted.conflicting_block_hash; },
107
17.9k
        [](const TxStateUnrecognized& unrecognized) 
{ return unrecognized.block_hash; }0
Unexecuted instantiation: wallet.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateUnrecognized const&)::operator()(wallet::TxStateUnrecognized const&) const
Unexecuted instantiation: walletdb.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateUnrecognized const&)::operator()(wallet::TxStateUnrecognized const&) const
108
17.9k
    }, state);
109
17.9k
}
Unexecuted instantiation: feebumper.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: fees.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: scriptpubkeyman.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: spend.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: dump.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: interfaces.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: load.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: receive.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: addresses.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: backup.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: coins.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: encrypt.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: signmessage.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: transactions.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: util.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
wallet.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Line
Count
Source
101
2.94k
{
102
2.94k
    return std::visit(util::Overloaded{
103
2.94k
        [](const TxStateInactive& inactive) { return inactive.abandoned ? uint256::ONE : uint256::ZERO; },
104
2.94k
        [](const TxStateInMempool& in_mempool) { return uint256::ZERO; },
105
2.94k
        [](const TxStateConfirmed& confirmed) { return confirmed.confirmed_block_hash; },
106
2.94k
        [](const TxStateBlockConflicted& conflicted) { return conflicted.conflicting_block_hash; },
107
2.94k
        [](const TxStateUnrecognized& unrecognized) { return unrecognized.block_hash; }
108
2.94k
    }, state);
109
2.94k
}
Unexecuted instantiation: transaction.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
walletdb.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Line
Count
Source
101
14.9k
{
102
14.9k
    return std::visit(util::Overloaded{
103
14.9k
        [](const TxStateInactive& inactive) { return inactive.abandoned ? uint256::ONE : uint256::ZERO; },
104
14.9k
        [](const TxStateInMempool& in_mempool) { return uint256::ZERO; },
105
14.9k
        [](const TxStateConfirmed& confirmed) { return confirmed.confirmed_block_hash; },
106
14.9k
        [](const TxStateBlockConflicted& conflicted) { return conflicted.conflicting_block_hash; },
107
14.9k
        [](const TxStateUnrecognized& unrecognized) { return unrecognized.block_hash; }
108
14.9k
    }, state);
109
14.9k
}
Unexecuted instantiation: init.cpp:wallet::TxStateSerializedBlockHash(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
110
111
//! Get TxState serialized block index. Inverse of TxStateInterpretSerialized.
112
static inline int TxStateSerializedIndex(const TxState& state)
113
17.9k
{
114
17.9k
    return std::visit(util::Overloaded{
115
17.9k
        [](const TxStateInactive& inactive) 
{ return 0
inactive.abandoned0
?
-10
:
00
; },
Unexecuted instantiation: wallet.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateInactive const&)::operator()(wallet::TxStateInactive const&) const
Unexecuted instantiation: walletdb.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateInactive const&)::operator()(wallet::TxStateInactive const&) const
116
17.9k
        [](const TxStateInMempool& in_mempool) 
{ return 0; }16.6k
,
wallet.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateInMempool const&)::operator()(wallet::TxStateInMempool const&) const
Line
Count
Source
116
2.67k
        [](const TxStateInMempool& in_mempool) { return 0; },
walletdb.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateInMempool const&)::operator()(wallet::TxStateInMempool const&) const
Line
Count
Source
116
13.9k
        [](const TxStateInMempool& in_mempool) { return 0; },
117
17.9k
        [](const TxStateConfirmed& confirmed) 
{ return confirmed.position_in_block; }925
,
wallet.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateConfirmed const&)::operator()(wallet::TxStateConfirmed const&) const
Line
Count
Source
117
196
        [](const TxStateConfirmed& confirmed) { return confirmed.position_in_block; },
walletdb.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateConfirmed const&)::operator()(wallet::TxStateConfirmed const&) const
Line
Count
Source
117
729
        [](const TxStateConfirmed& confirmed) { return confirmed.position_in_block; },
118
17.9k
        [](const TxStateBlockConflicted& conflicted) 
{ return -1; }368
,
wallet.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateBlockConflicted const&)::operator()(wallet::TxStateBlockConflicted const&) const
Line
Count
Source
118
74
        [](const TxStateBlockConflicted& conflicted) { return -1; },
walletdb.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateBlockConflicted const&)::operator()(wallet::TxStateBlockConflicted const&) const
Line
Count
Source
118
294
        [](const TxStateBlockConflicted& conflicted) { return -1; },
119
17.9k
        [](const TxStateUnrecognized& unrecognized) 
{ return unrecognized.index; }0
Unexecuted instantiation: wallet.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateUnrecognized const&)::operator()(wallet::TxStateUnrecognized const&) const
Unexecuted instantiation: walletdb.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(wallet::TxStateUnrecognized const&)::operator()(wallet::TxStateUnrecognized const&) const
120
17.9k
    }, state);
121
17.9k
}
Unexecuted instantiation: feebumper.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: fees.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: scriptpubkeyman.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: spend.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: dump.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: interfaces.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: load.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: receive.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: addresses.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: backup.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: coins.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: encrypt.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: signmessage.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: transactions.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Unexecuted instantiation: util.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
wallet.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Line
Count
Source
113
2.94k
{
114
2.94k
    return std::visit(util::Overloaded{
115
2.94k
        [](const TxStateInactive& inactive) { return inactive.abandoned ? -1 : 0; },
116
2.94k
        [](const TxStateInMempool& in_mempool) { return 0; },
117
2.94k
        [](const TxStateConfirmed& confirmed) { return confirmed.position_in_block; },
118
2.94k
        [](const TxStateBlockConflicted& conflicted) { return -1; },
119
2.94k
        [](const TxStateUnrecognized& unrecognized) { return unrecognized.index; }
120
2.94k
    }, state);
121
2.94k
}
Unexecuted instantiation: transaction.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
walletdb.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
Line
Count
Source
113
14.9k
{
114
14.9k
    return std::visit(util::Overloaded{
115
14.9k
        [](const TxStateInactive& inactive) { return inactive.abandoned ? -1 : 0; },
116
14.9k
        [](const TxStateInMempool& in_mempool) { return 0; },
117
14.9k
        [](const TxStateConfirmed& confirmed) { return confirmed.position_in_block; },
118
14.9k
        [](const TxStateBlockConflicted& conflicted) { return -1; },
119
14.9k
        [](const TxStateUnrecognized& unrecognized) { return unrecognized.index; }
120
14.9k
    }, state);
121
14.9k
}
Unexecuted instantiation: init.cpp:wallet::TxStateSerializedIndex(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)
122
123
//! Return TxState or SyncTxState as a string for logging or debugging.
124
template<typename T>
125
std::string TxStateString(const T& state)
126
15.8k
{
127
15.8k
    return std::visit([](const auto& s) { return s.toString(); }, state);
auto std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> wallet::TxStateString<std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized>>(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::operator()<wallet::TxStateConfirmed>(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&) const
Line
Count
Source
127
827
    return std::visit([](const auto& s) { return s.toString(); }, state);
auto std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> wallet::TxStateString<std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized>>(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::operator()<wallet::TxStateInMempool>(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&) const
Line
Count
Source
127
14.6k
    return std::visit([](const auto& s) { return s.toString(); }, state);
auto std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> wallet::TxStateString<std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized>>(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::operator()<wallet::TxStateBlockConflicted>(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&) const
Line
Count
Source
127
331
    return std::visit([](const auto& s) { return s.toString(); }, state);
Unexecuted instantiation: auto std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> wallet::TxStateString<std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized>>(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::operator()<wallet::TxStateInactive>(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&) const
Unexecuted instantiation: auto std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> wallet::TxStateString<std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized>>(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::'lambda'(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&)::operator()<wallet::TxStateUnrecognized>(std::__1::variant<wallet::TxStateConfirmed, wallet::TxStateInMempool, wallet::TxStateBlockConflicted, wallet::TxStateInactive, wallet::TxStateUnrecognized> const&) const
128
15.8k
}
129
130
/**
131
 * Cachable amount subdivided into avoid reuse and all balances
132
 */
133
struct CachableAmount
134
{
135
    std::optional<CAmount> m_avoid_reuse_value;
136
    std::optional<CAmount> m_all_value;
137
    inline void Reset()
138
31.6k
    {
139
31.6k
        m_avoid_reuse_value.reset();
140
31.6k
        m_all_value.reset();
141
31.6k
    }
142
    void Set(bool avoid_reuse, CAmount value)
143
0
    {
144
0
        if (avoid_reuse) {
145
0
            m_avoid_reuse_value = value;
146
0
        } else {
147
0
            m_all_value = value;
148
0
        }
149
0
    }
150
    CAmount Get(bool avoid_reuse)
151
0
    {
152
0
        if (avoid_reuse) {
153
0
            Assert(m_avoid_reuse_value.has_value());
Line
Count
Source
113
0
#define Assert(val) inline_assertion_check<true>(val, std::source_location::current(), #val)
154
0
            return m_avoid_reuse_value.value();
155
0
        }
156
0
        Assert(m_all_value.has_value());
Line
Count
Source
113
0
#define Assert(val) inline_assertion_check<true>(val, std::source_location::current(), #val)
157
0
        return m_all_value.value();
158
0
    }
159
    bool IsCached(bool avoid_reuse)
160
0
    {
161
0
        if (avoid_reuse) return m_avoid_reuse_value.has_value();
162
0
        return m_all_value.has_value();
163
0
    }
164
};
165
166
167
typedef std::map<std::string, std::string> mapValue_t;
168
169
170
/** Legacy class used for deserializing vtxPrev for backwards compatibility.
171
 * vtxPrev was removed in commit 93a18a3650292afbb441a47d1fa1b94aeb0164e3,
172
 * but old wallet.dat files may still contain vtxPrev vectors of CMerkleTxs.
173
 * These need to get deserialized for field alignment when deserializing
174
 * a CWalletTx, but the deserialized values are discarded.**/
175
class CMerkleTx
176
{
177
public:
178
    template<typename Stream>
179
    void Unserialize(Stream& s)
180
0
    {
181
0
        CTransactionRef tx;
182
0
        uint256 hashBlock;
183
0
        std::vector<uint256> vMerkleBranch;
184
0
        int nIndex;
185
186
0
        s >> TX_WITH_WITNESS(tx) >> hashBlock >> vMerkleBranch >> nIndex;
187
0
    }
188
};
189
190
/**
191
 * A transaction with a bunch of additional info that only the owner cares about.
192
 * It includes any unrecorded transactions needed to link it back to the block chain.
193
 */
194
class CWalletTx
195
{
196
public:
197
    /**
198
     * Key/value map with information about the transaction.
199
     *
200
     * The following keys can be read and written through the map and are
201
     * serialized in the wallet database:
202
     *
203
     *     "comment", "to"   - comment strings provided to sendtoaddress,
204
     *                         and sendmany wallet RPCs
205
     *     "replaces_txid"   - txid (as HexStr) of transaction replaced by
206
     *                         bumpfee on transaction created by bumpfee
207
     *     "replaced_by_txid" - txid (as HexStr) of transaction created by
208
     *                         bumpfee on transaction replaced by bumpfee
209
     *     "from", "message" - obsolete fields that could be set in UI prior to
210
     *                         2011 (removed in commit 4d9b223)
211
     *
212
     * The following keys are serialized in the wallet database, but shouldn't
213
     * be read or written through the map (they will be temporarily added and
214
     * removed from the map during serialization):
215
     *
216
     *     "fromaccount"     - serialized strFromAccount value
217
     *     "n"               - serialized nOrderPos value
218
     *     "timesmart"       - serialized nTimeSmart value
219
     *     "spent"           - serialized vfSpent value that existed prior to
220
     *                         2014 (removed in commit 93a18a3)
221
     */
222
    mapValue_t mapValue;
223
    std::vector<std::pair<std::string, std::string> > vOrderForm;
224
    unsigned int nTimeReceived; //!< time received by this node
225
    /**
226
     * Stable timestamp that never changes, and reflects the order a transaction
227
     * was added to the wallet. Timestamp is based on the block time for a
228
     * transaction added as part of a block, or else the time when the
229
     * transaction was received if it wasn't part of a block, with the timestamp
230
     * adjusted in both cases so timestamp order matches the order transactions
231
     * were added to the wallet. More details can be found in
232
     * CWallet::ComputeTimeSmart().
233
     */
234
    unsigned int nTimeSmart;
235
    // Cached value for whether the transaction spends any inputs known to the wallet
236
    mutable std::optional<bool> m_cached_from_me{std::nullopt};
237
    int64_t nOrderPos; //!< position in ordered transaction list
238
    std::multimap<int64_t, CWalletTx*>::const_iterator m_it_wtxOrdered;
239
240
    // memory only
241
    enum AmountType { DEBIT, CREDIT, AMOUNTTYPE_ENUM_ELEMENTS };
242
    mutable CachableAmount m_amounts[AMOUNTTYPE_ENUM_ELEMENTS];
243
    /**
244
     * This flag is true if all m_amounts caches are empty. This is particularly
245
     * useful in places where MarkDirty is conditionally called and the
246
     * condition can be expensive and thus can be skipped if the flag is true.
247
     * See MarkDestinationsDirty.
248
     */
249
    mutable bool m_is_cache_empty{true};
250
    mutable bool fChangeCached;
251
    mutable CAmount nChangeCached;
252
253
15.8k
    CWalletTx(CTransactionRef tx, const TxState& state) : tx(std::move(tx)), m_state(state)
254
15.8k
    {
255
15.8k
        Init();
256
15.8k
    }
257
258
    void Init()
259
15.8k
    {
260
15.8k
        mapValue.clear();
261
15.8k
        vOrderForm.clear();
262
15.8k
        nTimeReceived = 0;
263
15.8k
        nTimeSmart = 0;
264
15.8k
        fChangeCached = false;
265
15.8k
        nChangeCached = 0;
266
15.8k
        nOrderPos = -1;
267
15.8k
    }
268
269
    CTransactionRef tx;
270
    TxState m_state;
271
272
    // Set of mempool transactions that conflict
273
    // directly with the transaction, or that conflict
274
    // with an ancestor transaction. This set will be
275
    // empty if state is InMempool or Confirmed, but
276
    // can be nonempty if state is Inactive or
277
    // BlockConflicted.
278
    std::set<Txid> mempool_conflicts;
279
280
    // Track v3 mempool tx that spends from this tx
281
    // so that we don't try to create another unconfirmed child
282
    std::optional<Txid> truc_child_in_mempool;
283
284
    template<typename Stream>
285
    void Serialize(Stream& s) const
286
14.9k
    {
287
14.9k
        mapValue_t mapValueCopy = mapValue;
288
289
14.9k
        mapValueCopy["fromaccount"] = "";
290
14.9k
        if (nOrderPos != -1) {
291
14.9k
            mapValueCopy["n"] = util::ToString(nOrderPos);
292
14.9k
        }
293
14.9k
        if (nTimeSmart) {
294
14.9k
            mapValueCopy["timesmart"] = strprintf("%u", nTimeSmart);
Line
Count
Source
1172
14.9k
#define strprintf tfm::format
295
14.9k
        }
296
297
14.9k
        std::vector<uint8_t> dummy_vector1; //!< Used to be vMerkleBranch
298
14.9k
        std::vector<uint8_t> dummy_vector2; //!< Used to be vtxPrev
299
14.9k
        bool dummy_bool = false; //!< Used to be fFromMe, and fSpent
300
14.9k
        uint32_t dummy_int = 0; // Used to be fTimeReceivedIsTxTime
301
14.9k
        uint256 serializedHash = TxStateSerializedBlockHash(m_state);
302
14.9k
        int serializedIndex = TxStateSerializedIndex(m_state);
303
14.9k
        s << TX_WITH_WITNESS(tx) << serializedHash << dummy_vector1 << serializedIndex << dummy_vector2 << mapValueCopy << vOrderForm << dummy_int << nTimeReceived << dummy_bool << dummy_bool;
304
14.9k
    }
305
306
    template<typename Stream>
307
    void Unserialize(Stream& s)
308
0
    {
309
0
        Init();
310
311
0
        std::vector<uint256> dummy_vector1; //!< Used to be vMerkleBranch
312
0
        std::vector<CMerkleTx> dummy_vector2; //!< Used to be vtxPrev
313
0
        bool dummy_bool; //! Used to be fFromMe, and fSpent
314
0
        uint32_t dummy_int; // Used to be fTimeReceivedIsTxTime
315
0
        uint256 serialized_block_hash;
316
0
        int serializedIndex;
317
0
        s >> TX_WITH_WITNESS(tx) >> serialized_block_hash >> dummy_vector1 >> serializedIndex >> dummy_vector2 >> mapValue >> vOrderForm >> dummy_int >> nTimeReceived >> dummy_bool >> dummy_bool;
318
319
0
        m_state = TxStateInterpretSerialized({serialized_block_hash, serializedIndex});
320
321
0
        const auto it_op = mapValue.find("n");
322
0
        nOrderPos = (it_op != mapValue.end()) ? LocaleIndependentAtoi<int64_t>(it_op->second) : -1;
323
0
        const auto it_ts = mapValue.find("timesmart");
324
0
        nTimeSmart = (it_ts != mapValue.end()) ? static_cast<unsigned int>(LocaleIndependentAtoi<int64_t>(it_ts->second)) : 0;
325
326
0
        mapValue.erase("fromaccount");
327
0
        mapValue.erase("spent");
328
0
        mapValue.erase("n");
329
0
        mapValue.erase("timesmart");
330
0
    }
331
332
    void SetTx(CTransactionRef arg)
333
0
    {
334
0
        tx = std::move(arg);
335
0
    }
336
337
    //! make sure balances are recalculated
338
    void MarkDirty()
339
15.8k
    {
340
15.8k
        m_amounts[DEBIT].Reset();
341
15.8k
        m_amounts[CREDIT].Reset();
342
15.8k
        fChangeCached = false;
343
15.8k
        m_is_cache_empty = true;
344
15.8k
        m_cached_from_me = std::nullopt;
345
15.8k
    }
346
347
    /** True if only scriptSigs are different */
348
    bool IsEquivalentTo(const CWalletTx& tx) const;
349
350
    bool InMempool() const;
351
352
    int64_t GetTxTime() const;
353
354
34.0k
    template<typename T> const T* state() const { return std::get_if<T>(&m_state); }
wallet::TxStateInactive const* wallet::CWalletTx::state<wallet::TxStateInactive>() const
Line
Count
Source
354
202
    template<typename T> const T* state() const { return std::get_if<T>(&m_state); }
wallet::TxStateBlockConflicted const* wallet::CWalletTx::state<wallet::TxStateBlockConflicted>() const
Line
Count
Source
354
16.5k
    template<typename T> const T* state() const { return std::get_if<T>(&m_state); }
wallet::TxStateConfirmed const* wallet::CWalletTx::state<wallet::TxStateConfirmed>() const
Line
Count
Source
354
17.2k
    template<typename T> const T* state() const { return std::get_if<T>(&m_state); }
Unexecuted instantiation: wallet::TxStateInMempool const* wallet::CWalletTx::state<wallet::TxStateInMempool>() const
355
0
    template<typename T> T* state() { return std::get_if<T>(&m_state); }
Unexecuted instantiation: wallet::TxStateConfirmed* wallet::CWalletTx::state<wallet::TxStateConfirmed>()
Unexecuted instantiation: wallet::TxStateBlockConflicted* wallet::CWalletTx::state<wallet::TxStateBlockConflicted>()
Unexecuted instantiation: wallet::TxStateInMempool* wallet::CWalletTx::state<wallet::TxStateInMempool>()
356
357
    //! Update transaction state when attaching to a chain, filling in heights
358
    //! of conflicted and confirmed blocks
359
    void updateState(interfaces::Chain& chain);
360
361
156
    bool isAbandoned() const { return state<TxStateInactive>() && 
state<TxStateInactive>()->abandoned0
; }
362
145
    bool isMempoolConflicted() const { return !mempool_conflicts.empty(); }
363
156
    bool isBlockConflicted() const { return state<TxStateBlockConflicted>(); }
364
46
    bool isInactive() const { return state<TxStateInactive>(); }
365
0
    bool isUnconfirmed() const { return !isAbandoned() && !isBlockConflicted() && !isMempoolConflicted() && !isConfirmed(); }
366
0
    bool isConfirmed() const { return state<TxStateConfirmed>(); }
367
55.7k
    const Txid& GetHash() const LIFETIMEBOUND { return tx->GetHash(); }
368
0
    const Wtxid& GetWitnessHash() const LIFETIMEBOUND { return tx->GetWitnessHash(); }
369
30.1k
    bool IsCoinBase() const { return tx->IsCoinBase(); }
370
371
private:
372
    // Disable copying of CWalletTx objects to prevent bugs where instances get
373
    // copied in and out of the mapWallet map, and fields are updated in the
374
    // wrong copy.
375
    CWalletTx(const CWalletTx&) = default;
376
0
    CWalletTx& operator=(const CWalletTx&) = default;
377
public:
378
    // Instead have an explicit copy function
379
    void CopyFrom(const CWalletTx&);
380
};
381
382
struct WalletTxOrderComparator {
383
    bool operator()(const CWalletTx* a, const CWalletTx* b) const
384
0
    {
385
0
        return a->nOrderPos < b->nOrderPos;
386
0
    }
387
};
388
389
class WalletTXO
390
{
391
private:
392
    const CWalletTx& m_wtx;
393
    const CTxOut& m_output;
394
395
public:
396
    WalletTXO(const CWalletTx& wtx, const CTxOut& output)
397
9.98k
    : m_wtx(wtx),
398
9.98k
    m_output(output)
399
9.98k
    {
400
9.98k
        Assume(std::ranges::find(wtx.tx->vout, output) != wtx.tx->vout.end());
Line
Count
Source
125
9.98k
#define Assume(val) inline_assertion_check<false>(val, std::source_location::current(), #val)
401
9.98k
    }
402
403
0
    const CWalletTx& GetWalletTx() const { return m_wtx; }
404
405
0
    const CTxOut& GetTxOut() const { return m_output; }
406
};
407
} // namespace wallet
408
409
#endif // BITCOIN_WALLET_TRANSACTION_H