Bitcoin Core  22.99.0
P2P Digital Currency
transactionrecord.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-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 #include <qt/transactionrecord.h>
6 
7 #include <chain.h>
8 #include <interfaces/wallet.h>
9 #include <key_io.h>
10 #include <wallet/ismine.h>
11 
12 #include <stdint.h>
13 
14 #include <QDateTime>
15 
18 using wallet::isminetype;
19 
20 /* Return positive answer if transaction should be shown in list.
21  */
23 {
24  // There are currently no cases where we hide transactions, but
25  // we may want to use this in the future for things like RBF.
26  return true;
27 }
28 
29 /*
30  * Decompose CWallet transaction to model transaction records.
31  */
33 {
34  QList<TransactionRecord> parts;
35  int64_t nTime = wtx.time;
36  CAmount nCredit = wtx.credit;
37  CAmount nDebit = wtx.debit;
38  CAmount nNet = nCredit - nDebit;
39  uint256 hash = wtx.tx->GetHash();
40  std::map<std::string, std::string> mapValue = wtx.value_map;
41 
42  if (nNet > 0 || wtx.is_coinbase)
43  {
44  //
45  // Credit
46  //
47  for(unsigned int i = 0; i < wtx.tx->vout.size(); i++)
48  {
49  const CTxOut& txout = wtx.tx->vout[i];
50  isminetype mine = wtx.txout_is_mine[i];
51  if(mine)
52  {
53  TransactionRecord sub(hash, nTime);
54  sub.idx = i; // vout index
55  sub.credit = txout.nValue;
57  if (wtx.txout_address_is_mine[i])
58  {
59  // Received by Bitcoin Address
62  }
63  else
64  {
65  // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
67  sub.address = mapValue["from"];
68  }
69  if (wtx.is_coinbase)
70  {
71  // Generated
73  }
74 
75  parts.append(sub);
76  }
77  }
78  }
79  else
80  {
81  bool involvesWatchAddress = false;
82  isminetype fAllFromMe = ISMINE_SPENDABLE;
83  for (const isminetype mine : wtx.txin_is_mine)
84  {
85  if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
86  if(fAllFromMe > mine) fAllFromMe = mine;
87  }
88 
89  isminetype fAllToMe = ISMINE_SPENDABLE;
90  for (const isminetype mine : wtx.txout_is_mine)
91  {
92  if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
93  if(fAllToMe > mine) fAllToMe = mine;
94  }
95 
96  if (fAllFromMe && fAllToMe)
97  {
98  // Payment to self
99  std::string address;
100  for (auto it = wtx.txout_address.begin(); it != wtx.txout_address.end(); ++it) {
101  if (it != wtx.txout_address.begin()) address += ", ";
102  address += EncodeDestination(*it);
103  }
104 
105  CAmount nChange = wtx.change;
106  parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, address, -(nDebit - nChange), nCredit - nChange));
107  parts.last().involvesWatchAddress = involvesWatchAddress; // maybe pass to TransactionRecord as constructor argument
108  }
109  else if (fAllFromMe)
110  {
111  //
112  // Debit
113  //
114  CAmount nTxFee = nDebit - wtx.tx->GetValueOut();
115 
116  for (unsigned int nOut = 0; nOut < wtx.tx->vout.size(); nOut++)
117  {
118  const CTxOut& txout = wtx.tx->vout[nOut];
119  TransactionRecord sub(hash, nTime);
120  sub.idx = nOut;
122 
123  if(wtx.txout_is_mine[nOut])
124  {
125  // Ignore parts sent to self, as this is usually the change
126  // from a transaction sent back to our own address.
127  continue;
128  }
129 
130  if (!std::get_if<CNoDestination>(&wtx.txout_address[nOut]))
131  {
132  // Sent to Bitcoin Address
134  sub.address = EncodeDestination(wtx.txout_address[nOut]);
135  }
136  else
137  {
138  // Sent to IP, or other non-address transaction like OP_EVAL
140  sub.address = mapValue["to"];
141  }
142 
143  CAmount nValue = txout.nValue;
144  /* Add fee to first output */
145  if (nTxFee > 0)
146  {
147  nValue += nTxFee;
148  nTxFee = 0;
149  }
150  sub.debit = -nValue;
151 
152  parts.append(sub);
153  }
154  }
155  else
156  {
157  //
158  // Mixed debit transaction, can't break down payees
159  //
160  parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
161  parts.last().involvesWatchAddress = involvesWatchAddress;
162  }
163  }
164 
165  return parts;
166 }
167 
168 void TransactionRecord::updateStatus(const interfaces::WalletTxStatus& wtx, const uint256& block_hash, int numBlocks, int64_t block_time)
169 {
170  // Determine transaction status
171 
172  // Sort order, unrecorded transactions sort to the top
173  status.sortKey = strprintf("%010d-%01d-%010u-%03d",
174  wtx.block_height,
175  wtx.is_coinbase ? 1 : 0,
176  wtx.time_received,
177  idx);
180  status.m_cur_block_hash = block_hash;
181 
182  const bool up_to_date = ((int64_t)QDateTime::currentMSecsSinceEpoch() / 1000 - block_time < MAX_BLOCK_TIME_GAP);
183  if (up_to_date && !wtx.is_final) {
184  if (wtx.lock_time < LOCKTIME_THRESHOLD) {
186  status.open_for = wtx.lock_time - numBlocks;
187  }
188  else
189  {
191  status.open_for = wtx.lock_time;
192  }
193  }
194  // For generated transactions, determine maturity
196  {
197  if (wtx.blocks_to_maturity > 0)
198  {
200 
201  if (wtx.is_in_main_chain)
202  {
204  }
205  else
206  {
208  }
209  }
210  else
211  {
213  }
214  }
215  else
216  {
217  if (status.depth < 0)
218  {
220  }
221  else if (status.depth == 0)
222  {
224  if (wtx.is_abandoned)
226  }
228  {
230  }
231  else
232  {
234  }
235  }
236  status.needsUpdate = false;
237 }
238 
239 bool TransactionRecord::statusUpdateNeeded(const uint256& block_hash) const
240 {
241  assert(!block_hash.IsNull());
242  return status.m_cur_block_hash != block_hash || status.needsUpdate;
243 }
244 
246 {
247  return QString::fromStdString(hash.ToString());
248 }
249 
251 {
252  return idx;
253 }
TransactionRecord::statusUpdateNeeded
bool statusUpdateNeeded(const uint256 &block_hash) const
Return whether a status update is needed.
Definition: transactionrecord.cpp:239
TransactionRecord::getTxHash
QString getTxHash() const
Return the unique identifier for this transaction (part)
Definition: transactionrecord.cpp:245
TransactionRecord::idx
int idx
Subtransaction index, for sort key.
Definition: transactionrecord.h:124
wallet::isminetype
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
Definition: ismine.h:41
wallet::ISMINE_WATCH_ONLY
@ ISMINE_WATCH_ONLY
Definition: ismine.h:43
TransactionRecord::decomposeTransaction
static QList< TransactionRecord > decomposeTransaction(const interfaces::WalletTx &wtx)
Definition: transactionrecord.cpp:32
assert
assert(!tx.IsCoinBase())
TransactionStatus::sortKey
std::string sortKey
Sorting key based on status.
Definition: transactionrecord.h:47
TransactionStatus::OpenUntilDate
@ OpenUntilDate
Normal (sent/received) transactions.
Definition: transactionrecord.h:33
TransactionStatus::needsUpdate
bool needsUpdate
Definition: transactionrecord.h:66
interfaces::WalletTxStatus::depth_in_main_chain
int depth_in_main_chain
Definition: wallet.h:405
MAX_BLOCK_TIME_GAP
static constexpr int64_t MAX_BLOCK_TIME_GAP
Maximum gap between node time and block time used for the "Catching up..." mode in GUI.
Definition: chain.h:38
key_io.h
TransactionRecord::status
TransactionStatus status
Status: can change with block chain update.
Definition: transactionrecord.h:127
TransactionRecord::hash
uint256 hash
Definition: transactionrecord.h:115
TransactionRecord::RecvWithAddress
@ RecvWithAddress
Definition: transactionrecord.h:81
interfaces::WalletTxStatus::is_final
bool is_final
Definition: wallet.h:408
interfaces::WalletTx::is_coinbase
bool is_coinbase
Definition: wallet.h:397
interfaces::WalletTxStatus::block_height
int block_height
Definition: wallet.h:403
TransactionStatus::Conflicted
@ Conflicted
Conflicts with other transaction or mempool.
Definition: transactionrecord.h:37
TransactionRecord::credit
CAmount credit
Definition: transactionrecord.h:120
interfaces::WalletTx::time
int64_t time
Definition: wallet.h:395
TransactionRecord::RecommendedNumConfirmations
static const int RecommendedNumConfirmations
Number of confirmation recommended for accepting a transaction.
Definition: transactionrecord.h:87
TransactionRecord::RecvFromOther
@ RecvFromOther
Definition: transactionrecord.h:82
TransactionRecord
UI model for a transaction.
Definition: transactionrecord.h:72
interfaces::WalletTx::txout_is_mine
std::vector< wallet::isminetype > txout_is_mine
Definition: wallet.h:389
interfaces::WalletTxStatus::is_coinbase
bool is_coinbase
Definition: wallet.h:411
CTxOut::nValue
CAmount nValue
Definition: transaction.h:131
ismine.h
TransactionStatus::m_cur_block_hash
uint256 m_cur_block_hash
Current block hash (to know whether cached status is still valid)
Definition: transactionrecord.h:64
interfaces::WalletTx::value_map
std::map< std::string, std::string > value_map
Definition: wallet.h:396
TransactionStatus::open_for
qint64 open_for
Timestamp if status==OpenUntilDate, otherwise number of additional blocks that need to be mined befor...
Definition: transactionrecord.h:58
CTxOut
An output of a transaction.
Definition: transaction.h:128
interfaces::WalletTx::change
CAmount change
Definition: wallet.h:394
TransactionRecord::SendToOther
@ SendToOther
Definition: transactionrecord.h:80
interfaces::WalletTx::debit
CAmount debit
Definition: wallet.h:393
TransactionRecord::involvesWatchAddress
bool involvesWatchAddress
Whether the transaction was sent/received with a watch-only address.
Definition: transactionrecord.h:130
interfaces::WalletTx
Definition: wallet.h:385
CAmount
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
TransactionRecord::Generated
@ Generated
Definition: transactionrecord.h:78
interfaces::WalletTx::txin_is_mine
std::vector< wallet::isminetype > txin_is_mine
Definition: wallet.h:388
base_blob::ToString
std::string ToString() const
Definition: uint256.cpp:64
uint256
256-bit opaque blob.
Definition: uint256.h:124
interfaces::WalletTxStatus
Updated transaction status.
Definition: wallet.h:401
TransactionRecord::debit
CAmount debit
Definition: transactionrecord.h:119
TransactionStatus::Abandoned
@ Abandoned
Abandoned from the wallet.
Definition: transactionrecord.h:38
TransactionRecord::SendToSelf
@ SendToSelf
Definition: transactionrecord.h:83
interfaces::WalletTxStatus::is_in_main_chain
bool is_in_main_chain
Definition: wallet.h:412
TransactionStatus::Immature
@ Immature
Generated (mined) transactions.
Definition: transactionrecord.h:40
interfaces::WalletTxStatus::blocks_to_maturity
int blocks_to_maturity
Definition: wallet.h:404
LOCKTIME_THRESHOLD
static const unsigned int LOCKTIME_THRESHOLD
Definition: script.h:40
TransactionStatus::OpenUntilBlock
@ OpenUntilBlock
Transaction not yet final, waiting for block.
Definition: transactionrecord.h:34
TransactionRecord::type
Type type
Definition: transactionrecord.h:117
TransactionStatus::Confirmed
@ Confirmed
Have 6 or more confirmations (normal tx) or fully mature (mined tx)
Definition: transactionrecord.h:31
wallet::ISMINE_SPENDABLE
@ ISMINE_SPENDABLE
Definition: ismine.h:44
transactionrecord.h
TransactionRecord::address
std::string address
Definition: transactionrecord.h:118
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
interfaces::WalletTxStatus::is_trusted
bool is_trusted
Definition: wallet.h:409
base_blob::IsNull
bool IsNull() const
Definition: uint256.h:31
TransactionStatus::Confirming
@ Confirming
Confirmed, but waiting for the recommended number of confirmations.
Definition: transactionrecord.h:36
TransactionStatus::status
Status status
Definition: transactionrecord.h:56
TransactionStatus::matures_in
int matures_in
Definition: transactionrecord.h:51
interfaces::WalletTxStatus::lock_time
uint32_t lock_time
Definition: wallet.h:407
interfaces::WalletTx::credit
CAmount credit
Definition: wallet.h:392
TransactionRecord::getOutputIndex
int getOutputIndex() const
Return the output index of the subtransaction
Definition: transactionrecord.cpp:250
interfaces::WalletTxStatus::is_abandoned
bool is_abandoned
Definition: wallet.h:410
interfaces::WalletTx::txout_address
std::vector< CTxDestination > txout_address
Definition: wallet.h:390
TransactionRecord::SendToAddress
@ SendToAddress
Definition: transactionrecord.h:79
wallet.h
interfaces::WalletTx::txout_address_is_mine
std::vector< wallet::isminetype > txout_address_is_mine
Definition: wallet.h:391
TransactionStatus::depth
qint64 depth
Definition: transactionrecord.h:57
TransactionStatus::NotAccepted
@ NotAccepted
Mined but not accepted.
Definition: transactionrecord.h:41
interfaces::WalletTxStatus::time_received
unsigned int time_received
Definition: wallet.h:406
TransactionStatus::countsForBalance
bool countsForBalance
Transaction counts towards available balance.
Definition: transactionrecord.h:45
TransactionStatus::Unconfirmed
@ Unconfirmed
Not yet mined into a block.
Definition: transactionrecord.h:35
TransactionRecord::TransactionRecord
TransactionRecord()
Definition: transactionrecord.h:89
interfaces::WalletTx::tx
CTransactionRef tx
Definition: wallet.h:387
EncodeDestination
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:276
TransactionRecord::updateStatus
void updateStatus(const interfaces::WalletTxStatus &wtx, const uint256 &block_hash, int numBlocks, int64_t block_time)
Update status from core wallet tx.
Definition: transactionrecord.cpp:168
TransactionRecord::Other
@ Other
Definition: transactionrecord.h:77
TransactionRecord::showTransaction
static bool showTransaction()
Decompose CWallet transaction to model transaction records.
Definition: transactionrecord.cpp:22