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