Bitcoin Core 28.99.0
P2P Digital Currency
transactionrecord.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-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
6
7#include <chain.h>
8#include <interfaces/wallet.h>
9#include <key_io.h>
10#include <wallet/types.h>
11
12#include <stdint.h>
13
14#include <QDateTime>
15
20
21/* Return positive answer if transaction should be shown in list.
22 */
24{
25 // There are currently no cases where we hide transactions, but
26 // we may want to use this in the future for things like RBF.
27 return true;
28}
29
30/*
31 * Decompose CWallet transaction to model transaction records.
32 */
34{
35 QList<TransactionRecord> parts;
36 int64_t nTime = wtx.time;
37 CAmount nCredit = wtx.credit;
38 CAmount nDebit = wtx.debit;
39 CAmount nNet = nCredit - nDebit;
40 uint256 hash = wtx.tx->GetHash();
41 std::map<std::string, std::string> mapValue = wtx.value_map;
42
43 bool involvesWatchAddress = false;
44 isminetype fAllFromMe = ISMINE_SPENDABLE;
45 bool any_from_me = false;
46 if (wtx.is_coinbase) {
47 fAllFromMe = ISMINE_NO;
48 } else {
49 for (const isminetype mine : wtx.txin_is_mine)
50 {
52 if(fAllFromMe > mine) fAllFromMe = mine;
53 if (mine) any_from_me = true;
54 }
55 }
56
57 if (fAllFromMe || !any_from_me) {
58 for (const isminetype mine : wtx.txout_is_mine)
59 {
61 }
62
63 CAmount nTxFee = nDebit - wtx.tx->GetValueOut();
64
65 for(unsigned int i = 0; i < wtx.tx->vout.size(); i++)
66 {
67 const CTxOut& txout = wtx.tx->vout[i];
68
69 if (fAllFromMe) {
70 // Change is only really possible if we're the sender
71 // Otherwise, someone just sent bitcoins to a change address, which should be shown
72 if (wtx.txout_is_change[i]) {
73 continue;
74 }
75
76 //
77 // Debit
78 //
79
80 TransactionRecord sub(hash, nTime);
81 sub.idx = i;
83
84 if (!std::get_if<CNoDestination>(&wtx.txout_address[i]))
85 {
86 // Sent to Bitcoin Address
89 }
90 else
91 {
92 // Sent to IP, or other non-address transaction like OP_EVAL
94 sub.address = mapValue["to"];
95 }
96
97 CAmount nValue = txout.nValue;
98 /* Add fee to first output */
99 if (nTxFee > 0)
100 {
101 nValue += nTxFee;
102 nTxFee = 0;
103 }
104 sub.debit = -nValue;
105
106 parts.append(sub);
107 }
108
109 isminetype mine = wtx.txout_is_mine[i];
110 if(mine)
111 {
112 //
113 // Credit
114 //
115
116 TransactionRecord sub(hash, nTime);
117 sub.idx = i; // vout index
118 sub.credit = txout.nValue;
120 if (wtx.txout_address_is_mine[i])
121 {
122 // Received by Bitcoin Address
125 }
126 else
127 {
128 // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
130 sub.address = mapValue["from"];
131 }
132 if (wtx.is_coinbase)
133 {
134 // Generated
136 }
137
138 parts.append(sub);
139 }
140 }
141 } else {
142 //
143 // Mixed debit transaction, can't break down payees
144 //
145 parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
146 parts.last().involvesWatchAddress = involvesWatchAddress;
147 }
148
149 return parts;
150}
151
152void TransactionRecord::updateStatus(const interfaces::WalletTxStatus& wtx, const uint256& block_hash, int numBlocks, int64_t block_time)
153{
154 // Determine transaction status
155
156 // Sort order, unrecorded transactions sort to the top
157 int typesort;
158 switch (type) {
159 case SendToAddress: case SendToOther:
160 typesort = 2; break;
162 typesort = 3; break;
163 default:
164 typesort = 9;
165 }
166 status.sortKey = strprintf("%010d-%01d-%010u-%03d-%d",
167 wtx.block_height,
168 wtx.is_coinbase ? 1 : 0,
169 wtx.time_received,
170 idx,
171 typesort);
174 status.m_cur_block_hash = block_hash;
175
176 // For generated transactions, determine maturity
178 if (wtx.blocks_to_maturity > 0)
179 {
181
182 if (wtx.is_in_main_chain)
183 {
185 }
186 else
187 {
189 }
190 }
191 else
192 {
194 }
195 }
196 else
197 {
198 if (status.depth < 0)
199 {
201 }
202 else if (status.depth == 0)
203 {
205 if (wtx.is_abandoned)
207 }
209 {
211 }
212 else
213 {
215 }
216 }
217 status.needsUpdate = false;
218}
219
221{
222 assert(!block_hash.IsNull());
223 return status.m_cur_block_hash != block_hash || status.needsUpdate;
224}
225
227{
228 return QString::fromStdString(hash.ToString());
229}
230
232{
233 return idx;
234}
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
An output of a transaction.
Definition: transaction.h:150
CAmount nValue
Definition: transaction.h:152
UI model for a transaction.
int idx
Subtransaction index, for sort key.
static QList< TransactionRecord > decomposeTransaction(const interfaces::WalletTx &wtx)
static const int RecommendedNumConfirmations
Number of confirmation recommended for accepting a transaction.
static bool showTransaction()
Decompose CWallet transaction to model transaction records.
TransactionStatus status
Status: can change with block chain update.
int getOutputIndex() const
Return the output index of the subtransaction
QString getTxHash() const
Return the unique identifier for this transaction (part)
bool statusUpdateNeeded(const uint256 &block_hash) const
Return whether a status update is needed.
void updateStatus(const interfaces::WalletTxStatus &wtx, const uint256 &block_hash, int numBlocks, int64_t block_time)
Update status from core wallet tx.
bool involvesWatchAddress
Whether the transaction was sent/received with a watch-only address.
constexpr bool IsNull() const
Definition: uint256.h:48
std::string ToString() const
Definition: uint256.cpp:47
256-bit opaque blob.
Definition: uint256.h:190
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:294
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
Definition: types.h:41
@ ISMINE_NO
Definition: types.h:42
@ ISMINE_SPENDABLE
Definition: types.h:44
@ ISMINE_WATCH_ONLY
Definition: types.h:43
bool countsForBalance
Transaction counts towards available balance.
uint256 m_cur_block_hash
Current block hash (to know whether cached status is still valid)
@ Confirmed
Have 6 or more confirmations (normal tx) or fully mature (mined tx)
@ Unconfirmed
Normal (sent/received) transactions.
@ Immature
Generated (mined) transactions.
@ Confirming
Confirmed, but waiting for the recommended number of confirmations.
@ NotAccepted
Mined but not accepted.
@ Conflicted
Conflicts with other transaction or mempool.
@ Abandoned
Abandoned from the wallet.
std::string sortKey
Sorting key based on status.
std::vector< wallet::isminetype > txin_is_mine
Definition: wallet.h:402
std::vector< CTxDestination > txout_address
Definition: wallet.h:405
std::vector< wallet::isminetype > txout_address_is_mine
Definition: wallet.h:406
CTransactionRef tx
Definition: wallet.h:401
std::vector< bool > txout_is_change
Definition: wallet.h:404
std::map< std::string, std::string > value_map
Definition: wallet.h:411
std::vector< wallet::isminetype > txout_is_mine
Definition: wallet.h:403
Updated transaction status.
Definition: wallet.h:419
unsigned int time_received
Definition: wallet.h:423
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1165
assert(!tx.IsCoinBase())
is a home for public enum and struct type definitions that are used by internally by wallet code,...