Bitcoin Core  21.99.0
P2P Digital Currency
transaction.h
Go to the documentation of this file.
1 // Copyright (c) 2021 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 <amount.h>
10 #include <serialize.h>
11 #include <wallet/ismine.h>
12 #include <threadsafety.h>
13 #include <tinyformat.h>
14 #include <util/strencodings.h>
15 #include <util/string.h>
16 
17 #include <list>
18 #include <vector>
19 
20 struct COutputEntry;
21 
22 typedef std::map<std::string, std::string> mapValue_t;
23 
24 //Get the marginal bytes of spending the specified output
25 int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* pwallet, bool use_max_sig = false);
26 
27 static inline void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue)
28 {
29  if (!mapValue.count("n"))
30  {
31  nOrderPos = -1; // TODO: calculate elsewhere
32  return;
33  }
34  nOrderPos = atoi64(mapValue["n"]);
35 }
36 
37 static inline void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue)
38 {
39  if (nOrderPos == -1)
40  return;
41  mapValue["n"] = ToString(nOrderPos);
42 }
43 
49 class CMerkleTx
50 {
51 public:
52  template<typename Stream>
53  void Unserialize(Stream& s)
54  {
55  CTransactionRef tx;
56  uint256 hashBlock;
57  std::vector<uint256> vMerkleBranch;
58  int nIndex;
59 
60  s >> tx >> hashBlock >> vMerkleBranch >> nIndex;
61  }
62 };
63 
68 class CWalletTx
69 {
70 private:
71  const CWallet* const pwallet;
72 
76  static constexpr const uint256& ABANDON_HASH = uint256::ONE;
77 
78 public:
105  std::vector<std::pair<std::string, std::string> > vOrderForm;
106  unsigned int fTimeReceivedIsTxTime;
107  unsigned int nTimeReceived;
108 
117  unsigned int nTimeSmart;
123  bool fFromMe;
124  int64_t nOrderPos;
125  std::multimap<int64_t, CWalletTx*>::const_iterator m_it_wtxOrdered;
126 
127  // memory only
129  CAmount GetCachableAmount(AmountType type, const isminefilter& filter, bool recalculate = false) const;
137  mutable bool m_is_cache_empty{true};
138  mutable bool fChangeCached;
139  mutable bool fInMempool;
141 
143  : pwallet(wallet),
144  tx(std::move(arg))
145  {
146  Init();
147  }
148 
149  void Init()
150  {
151  mapValue.clear();
152  vOrderForm.clear();
153  fTimeReceivedIsTxTime = false;
154  nTimeReceived = 0;
155  nTimeSmart = 0;
156  fFromMe = false;
157  fChangeCached = false;
158  fInMempool = false;
159  nChangeCached = 0;
160  nOrderPos = -1;
162  }
163 
165 
174  enum Status {
179  };
180 
186  struct Confirmation {
190  int nIndex;
191  Confirmation(Status s = UNCONFIRMED, int b = 0, uint256 h = uint256(), int i = 0) : status(s), block_height(b), hashBlock(h), nIndex(i) {}
192  };
193 
195 
196  template<typename Stream>
197  void Serialize(Stream& s) const
198  {
199  mapValue_t mapValueCopy = mapValue;
200 
201  mapValueCopy["fromaccount"] = "";
202  WriteOrderPos(nOrderPos, mapValueCopy);
203  if (nTimeSmart) {
204  mapValueCopy["timesmart"] = strprintf("%u", nTimeSmart);
205  }
206 
207  std::vector<uint8_t> dummy_vector1;
208  std::vector<uint8_t> dummy_vector2;
209  bool dummy_bool = false;
210  uint256 serializedHash = isAbandoned() ? ABANDON_HASH : m_confirm.hashBlock;
211  int serializedIndex = isAbandoned() || isConflicted() ? -1 : m_confirm.nIndex;
212  s << tx << serializedHash << dummy_vector1 << serializedIndex << dummy_vector2 << mapValueCopy << vOrderForm << fTimeReceivedIsTxTime << nTimeReceived << fFromMe << dummy_bool;
213  }
214 
215  template<typename Stream>
216  void Unserialize(Stream& s)
217  {
218  Init();
219 
220  std::vector<uint256> dummy_vector1;
221  std::vector<CMerkleTx> dummy_vector2;
222  bool dummy_bool;
223  int serializedIndex;
224  s >> tx >> m_confirm.hashBlock >> dummy_vector1 >> serializedIndex >> dummy_vector2 >> mapValue >> vOrderForm >> fTimeReceivedIsTxTime >> nTimeReceived >> fFromMe >> dummy_bool;
225 
226  /* At serialization/deserialization, an nIndex == -1 means that hashBlock refers to
227  * the earliest block in the chain we know this or any in-wallet ancestor conflicts
228  * with. If nIndex == -1 and hashBlock is ABANDON_HASH, it means transaction is abandoned.
229  * In same context, an nIndex >= 0 refers to a confirmed transaction (if hashBlock set) or
230  * unconfirmed one. Older clients interpret nIndex == -1 as unconfirmed for backward
231  * compatibility (pre-commit 9ac63d6).
232  */
233  if (serializedIndex == -1 && m_confirm.hashBlock == ABANDON_HASH) {
234  setAbandoned();
235  } else if (serializedIndex == -1) {
236  setConflicted();
237  } else if (!m_confirm.hashBlock.IsNull()) {
238  m_confirm.nIndex = serializedIndex;
239  setConfirmed();
240  }
241 
243  nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(mapValue["timesmart"]) : 0;
244 
245  mapValue.erase("fromaccount");
246  mapValue.erase("spent");
247  mapValue.erase("n");
248  mapValue.erase("timesmart");
249  }
250 
252  {
253  tx = std::move(arg);
254  }
255 
257  void MarkDirty()
258  {
259  m_amounts[DEBIT].Reset();
263  fChangeCached = false;
264  m_is_cache_empty = true;
265  }
266 
268  CAmount GetDebit(const isminefilter& filter) const;
269  CAmount GetCredit(const isminefilter& filter) const;
270  CAmount GetImmatureCredit(bool fUseCache = true) const;
271  // TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
272  // annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The
273  // annotation "NO_THREAD_SAFETY_ANALYSIS" was temporarily added to avoid
274  // having to resolve the issue of member access into incomplete type CWallet.
275  CAmount GetAvailableCredit(bool fUseCache = true, const isminefilter& filter = ISMINE_SPENDABLE) const NO_THREAD_SAFETY_ANALYSIS;
276  CAmount GetImmatureWatchOnlyCredit(const bool fUseCache = true) const;
277  CAmount GetChange() const;
278 
280  int GetSpendSize(unsigned int out, bool use_max_sig = false) const
281  {
282  return CalculateMaximumSignedInputSize(tx->vout[out], pwallet, use_max_sig);
283  }
284 
285  void GetAmounts(std::list<COutputEntry>& listReceived,
286  std::list<COutputEntry>& listSent, CAmount& nFee, const isminefilter& filter) const;
287 
288  bool IsFromMe(const isminefilter& filter) const
289  {
290  return (GetDebit(filter) > 0);
291  }
292 
294  bool IsEquivalentTo(const CWalletTx& tx) const;
295 
296  bool InMempool() const;
297  bool IsTrusted() const;
298 
299  int64_t GetTxTime() const;
300 
302  bool SubmitMemoryPoolAndRelay(std::string& err_string, bool relay);
303 
304  // TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
305  // annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The annotation
306  // "NO_THREAD_SAFETY_ANALYSIS" was temporarily added to avoid having to
307  // resolve the issue of member access into incomplete type CWallet. Note
308  // that we still have the runtime check "AssertLockHeld(pwallet->cs_wallet)"
309  // in place.
310  std::set<uint256> GetConflicts() const NO_THREAD_SAFETY_ANALYSIS;
311 
318  // TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
319  // annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The annotation
320  // "NO_THREAD_SAFETY_ANALYSIS" was temporarily added to avoid having to
321  // resolve the issue of member access into incomplete type CWallet. Note
322  // that we still have the runtime check "AssertLockHeld(pwallet->cs_wallet)"
323  // in place.
325  bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
326 
332  int GetBlocksToMaturity() const;
333  bool isAbandoned() const { return m_confirm.status == CWalletTx::ABANDONED; }
335  {
339  m_confirm.nIndex = 0;
340  }
345  bool isConfirmed() const { return m_confirm.status == CWalletTx::CONFIRMED; }
347  const uint256& GetHash() const { return tx->GetHash(); }
348  bool IsCoinBase() const { return tx->IsCoinBase(); }
349  bool IsImmatureCoinBase() const;
350 
351  // Disable copying of CWalletTx objects to prevent bugs where instances get
352  // copied in and out of the mapWallet map, and fields are updated in the
353  // wrong copy.
354  CWalletTx(CWalletTx const &) = delete;
355  void operator=(CWalletTx const &x) = delete;
356 };
357 
358 #endif // BITCOIN_WALLET_TRANSACTION_H
CWalletTx::GetDebit
CAmount GetDebit(const isminefilter &filter) const
filter decides which addresses will count towards the debit
Definition: receive.cpp:139
atoi64
int64_t atoi64(const std::string &str)
Definition: strencodings.cpp:440
CWalletTx::GetBlocksToMaturity
int GetBlocksToMaturity() const
Definition: wallet.cpp:2875
CWalletTx::CONFLICTED
@ CONFLICTED
Definition: transaction.h:177
ToString
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:79
CWalletTx::setConflicted
void setConflicted()
Definition: transaction.h:342
isminefilter
uint8_t isminefilter
Definition: wallet.h:36
CWalletTx::fTimeReceivedIsTxTime
unsigned int fTimeReceivedIsTxTime
Definition: transaction.h:106
CWalletTx::AVAILABLE_CREDIT
@ AVAILABLE_CREDIT
Definition: transaction.h:128
transaction.h
CWalletTx::Serialize
void Serialize(Stream &s) const
Definition: transaction.h:197
string.h
CWalletTx::mapValue
mapValue_t mapValue
Key/value map with information about the transaction.
Definition: transaction.h:104
CWalletTx::ABANDONED
@ ABANDONED
Definition: transaction.h:178
CWalletTx::IsImmatureCoinBase
bool IsImmatureCoinBase() const
Definition: wallet.cpp:2884
WriteOrderPos
static void WriteOrderPos(const int64_t &nOrderPos, mapValue_t &mapValue)
Definition: transaction.h:37
CWalletTx::setConfirmed
void setConfirmed()
Definition: transaction.h:346
CWalletTx::Init
void Init()
Definition: transaction.h:149
CWalletTx::CWalletTx
CWalletTx(const CWallet *wallet, CTransactionRef arg)
Definition: transaction.h:142
CWalletTx::setUnconfirmed
void setUnconfirmed()
Definition: transaction.h:344
CWalletTx::AmountType
AmountType
Definition: transaction.h:128
CWalletTx::GetDepthInMainChain
int GetDepthInMainChain() const NO_THREAD_SAFETY_ANALYSIS
Return depth of transaction in blockchain: <0 : conflicts with a transaction this deep in the blockch...
Definition: wallet.cpp:2866
CWalletTx::isConfirmed
bool isConfirmed() const
Definition: transaction.h:345
CWalletTx::m_confirm
Confirmation m_confirm
Definition: transaction.h:194
wallet
Definition: interfaces.cpp:47
CWalletTx::m_is_cache_empty
bool m_is_cache_empty
This flag is true if all m_amounts caches are empty.
Definition: transaction.h:137
CWalletTx::Unserialize
void Unserialize(Stream &s)
Definition: transaction.h:216
CTransactionRef
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:386
CWalletTx::GetSpendSize
int GetSpendSize(unsigned int out, bool use_max_sig=false) const
Get the marginal bytes if spending the specified output from this transaction.
Definition: transaction.h:280
CWalletTx::Confirmation::block_height
int block_height
Definition: transaction.h:188
CWalletTx::GetTxTime
int64_t GetTxTime() const
Definition: transaction.cpp:21
CWalletTx::nChangeCached
CAmount nChangeCached
Definition: transaction.h:140
CWalletTx::nTimeSmart
unsigned int nTimeSmart
Stable timestamp that never changes, and reflects the order a transaction was added to the wallet.
Definition: transaction.h:117
tinyformat.h
CWalletTx::SetTx
void SetTx(CTransactionRef arg)
Definition: transaction.h:251
CWalletTx::GetCredit
CAmount GetCredit(const isminefilter &filter) const
Definition: receive.cpp:122
ismine.h
strencodings.h
CWalletTx::IsEquivalentTo
bool IsEquivalentTo(const CWalletTx &tx) const
True if only scriptSigs are different.
Definition: transaction.cpp:7
CWalletTx::nTimeReceived
unsigned int nTimeReceived
time received by this node
Definition: transaction.h:107
NO_THREAD_SAFETY_ANALYSIS
#define NO_THREAD_SAFETY_ANALYSIS
Definition: threadsafety.h:51
CMerkleTx
Legacy class used for deserializing vtxPrev for backwards compatibility.
Definition: transaction.h:49
CWalletTx::isAbandoned
bool isAbandoned() const
Definition: transaction.h:333
CWalletTx::Confirmation::status
Status status
Definition: transaction.h:187
threadsafety.h
CWalletTx::nOrderPos
int64_t nOrderPos
position in ordered transaction list
Definition: transaction.h:124
CTxOut
An output of a transaction.
Definition: transaction.h:128
CWalletTx::fChangeCached
bool fChangeCached
Definition: transaction.h:138
CalculateMaximumSignedInputSize
int CalculateMaximumSignedInputSize(const CTxOut &txout, const CWallet *pwallet, bool use_max_sig=false)
Definition: spend.cpp:29
CWalletTx::ABANDON_HASH
static constexpr const uint256 & ABANDON_HASH
Constant used in hashBlock to indicate tx has been abandoned, only used at serialization/deserializat...
Definition: transaction.h:76
CWalletTx::tx
CTransactionRef tx
Definition: transaction.h:164
CWalletTx::GetAmounts
void GetAmounts(std::list< COutputEntry > &listReceived, std::list< COutputEntry > &listSent, CAmount &nFee, const isminefilter &filter) const
Definition: receive.cpp:218
CWalletTx::pwallet
const CWallet *const pwallet
Definition: transaction.h:71
COutputEntry
Definition: receive.h:13
CWalletTx::isUnconfirmed
bool isUnconfirmed() const
Definition: transaction.h:343
CAmount
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
CWalletTx::vOrderForm
std::vector< std::pair< std::string, std::string > > vOrderForm
Definition: transaction.h:105
uint256
256-bit opaque blob.
Definition: uint256.h:124
CWalletTx::CONFIRMED
@ CONFIRMED
Definition: transaction.h:176
CWalletTx::Confirmation::Confirmation
Confirmation(Status s=UNCONFIRMED, int b=0, uint256 h=uint256(), int i=0)
Definition: transaction.h:191
CWalletTx::Confirmation
Confirmation includes tx status and a triplet of {block height/block hash/tx index in block} at which...
Definition: transaction.h:186
CWalletTx::Confirmation::hashBlock
uint256 hashBlock
Definition: transaction.h:189
CWalletTx::GetCachableAmount
CAmount GetCachableAmount(AmountType type, const isminefilter &filter, bool recalculate=false) const
Definition: receive.cpp:112
mapValue_t
std::map< std::string, std::string > mapValue_t
Definition: transaction.h:20
CWalletTx::GetConflicts
std::set< uint256 > GetConflicts() const NO_THREAD_SAFETY_ANALYSIS
Definition: wallet.cpp:1723
ISMINE_SPENDABLE
@ ISMINE_SPENDABLE
Definition: ismine.h:42
CWalletTx::Confirmation::nIndex
int nIndex
Definition: transaction.h:190
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
CWalletTx::setAbandoned
void setAbandoned()
Definition: transaction.h:334
base_blob::IsNull
bool IsNull() const
Definition: uint256.h:31
CWalletTx::m_it_wtxOrdered
std::multimap< int64_t, CWalletTx * >::const_iterator m_it_wtxOrdered
Definition: transaction.h:125
CWalletTx::IsCoinBase
bool IsCoinBase() const
Definition: transaction.h:348
CWalletTx::IsInMainChain
bool IsInMainChain() const
Definition: transaction.h:325
CWalletTx::CREDIT
@ CREDIT
Definition: transaction.h:128
CWalletTx::GetChange
CAmount GetChange() const
Definition: receive.cpp:154
CWalletTx::isConflicted
bool isConflicted() const
Definition: transaction.h:341
CWallet
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:225
CWalletTx::GetHash
const uint256 & GetHash() const
Definition: transaction.h:347
CWalletTx
A transaction with a bunch of additional info that only the owner cares about.
Definition: transaction.h:68
CWalletTx::Status
Status
New transactions start as UNCONFIRMED.
Definition: transaction.h:174
serialize.h
CWalletTx::GetImmatureWatchOnlyCredit
CAmount GetImmatureWatchOnlyCredit(const bool fUseCache=true) const
Definition: receive.cpp:172
CWalletTx::fFromMe
bool fFromMe
From me flag is set to 1 for transactions that were created by the wallet on this bitcoin node,...
Definition: transaction.h:123
CWalletTx::IsTrusted
bool IsTrusted() const
Definition: receive.cpp:306
CWalletTx::fInMempool
bool fInMempool
Definition: transaction.h:139
CachableAmount::Reset
void Reset()
Definition: ismine.h:59
CWalletTx::MarkDirty
void MarkDirty()
make sure balances are recalculated
Definition: transaction.h:257
CWalletTx::operator=
void operator=(CWalletTx const &x)=delete
CWalletTx::IMMATURE_CREDIT
@ IMMATURE_CREDIT
Definition: transaction.h:128
CachableAmount
Cachable amount subdivided into watchonly and spendable parts.
Definition: ismine.h:54
CWalletTx::DEBIT
@ DEBIT
Definition: transaction.h:128
CWalletTx::m_amounts
CachableAmount m_amounts[AMOUNTTYPE_ENUM_ELEMENTS]
Definition: transaction.h:130
CMerkleTx::Unserialize
void Unserialize(Stream &s)
Definition: transaction.h:53
CWalletTx::GetAvailableCredit
CAmount GetAvailableCredit(bool fUseCache=true, const isminefilter &filter=ISMINE_SPENDABLE) const NO_THREAD_SAFETY_ANALYSIS
Definition: receive.cpp:181
amount.h
CWalletTx::UNCONFIRMED
@ UNCONFIRMED
Definition: transaction.h:175
CWalletTx::AMOUNTTYPE_ENUM_ELEMENTS
@ AMOUNTTYPE_ENUM_ELEMENTS
Definition: transaction.h:128
CWalletTx::GetImmatureCredit
CAmount GetImmatureCredit(bool fUseCache=true) const
Definition: receive.cpp:163
ReadOrderPos
static void ReadOrderPos(int64_t &nOrderPos, mapValue_t &mapValue)
Definition: transaction.h:27
CWalletTx::SubmitMemoryPoolAndRelay
bool SubmitMemoryPoolAndRelay(std::string &err_string, bool relay)
Pass this transaction to node for mempool insertion and relay to peers if flag set to true.
Definition: wallet.cpp:1695
CWalletTx::InMempool
bool InMempool() const
Definition: transaction.cpp:16
CWalletTx::IsFromMe
bool IsFromMe(const isminefilter &filter) const
Definition: transaction.h:288
uint256::ONE
static const uint256 ONE
Definition: uint256.h:130