]> Git Repo - VerusCoin.git/blame - src/qt/transactionrecord.cpp
Includes: Do not include main.h from any other header
[VerusCoin.git] / src / qt / transactionrecord.cpp
CommitLineData
f914f1a7 1// Copyright (c) 2011-2014 The Bitcoin Core developers
78253fcb 2// Distributed under the MIT software license, see the accompanying
e592d43f
WL
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
f488e735
WL
5#include "transactionrecord.h"
6
10254401 7#include "base58.h"
8a893c94 8#include "main.h"
14f888ca 9#include "timedata.h"
50c72f23 10#include "wallet/wallet.h"
51ed9ec9
BD
11
12#include <stdint.h>
f488e735 13
8a893c94
JT
14#include <boost/foreach.hpp>
15
f488e735
WL
16/* Return positive answer if transaction should be shown in list.
17 */
18bool TransactionRecord::showTransaction(const CWalletTx &wtx)
19{
20 if (wtx.IsCoinBase())
21 {
f09e8fcd
PK
22 // Ensures we show generated coins / mined transactions at depth 1
23 if (!wtx.IsInMainChain())
f488e735
WL
24 {
25 return false;
26 }
27 }
28 return true;
29}
30
0f3981be
WL
31/*
32 * Decompose CWallet transaction to model transaction records.
f488e735 33 */
e8ef3da7 34QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx)
f488e735
WL
35{
36 QList<TransactionRecord> parts;
51ed9ec9 37 int64_t nTime = wtx.GetTxTime();
ccca27a7 38 CAmount nCredit = wtx.GetCredit(ISMINE_ALL);
a372168e
MF
39 CAmount nDebit = wtx.GetDebit(ISMINE_ALL);
40 CAmount nNet = nCredit - nDebit;
f488e735
WL
41 uint256 hash = wtx.GetHash();
42 std::map<std::string, std::string> mapValue = wtx.mapValue;
43
fe4a6550 44 if (nNet > 0 || wtx.IsCoinBase())
f488e735 45 {
fe4a6550
WL
46 //
47 // Credit
48 //
49 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
f488e735 50 {
ffd40da3
J
51 isminetype mine = wallet->IsMine(txout);
52 if(mine)
f488e735 53 {
fe4a6550 54 TransactionRecord sub(hash, nTime);
10254401 55 CTxDestination address;
fe4a6550
WL
56 sub.idx = parts.size(); // sequence number
57 sub.credit = txout.nValue;
a3e192a3 58 sub.involvesWatchAddress = mine == ISMINE_WATCH_ONLY;
e07c8e91 59 if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
fe4a6550
WL
60 {
61 // Received by Bitcoin Address
62 sub.type = TransactionRecord::RecvWithAddress;
10254401 63 sub.address = CBitcoinAddress(address).ToString();
fe4a6550
WL
64 }
65 else
66 {
67 // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
68 sub.type = TransactionRecord::RecvFromOther;
69 sub.address = mapValue["from"];
70 }
e07c8e91
LD
71 if (wtx.IsCoinBase())
72 {
73 // Generated
74 sub.type = TransactionRecord::Generated;
75 }
fe4a6550
WL
76
77 parts.append(sub);
f488e735 78 }
f488e735 79 }
fe4a6550
WL
80 }
81 else
82 {
d2692f61 83 bool involvesWatchAddress = false;
a3e192a3 84 isminetype fAllFromMe = ISMINE_SPENDABLE;
fe4a6550 85 BOOST_FOREACH(const CTxIn& txin, wtx.vin)
ffd40da3
J
86 {
87 isminetype mine = wallet->IsMine(txin);
a3e192a3 88 if(mine == ISMINE_WATCH_ONLY) involvesWatchAddress = true;
ffd40da3
J
89 if(fAllFromMe > mine) fAllFromMe = mine;
90 }
fe4a6550 91
a3e192a3 92 isminetype fAllToMe = ISMINE_SPENDABLE;
fe4a6550 93 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
ffd40da3
J
94 {
95 isminetype mine = wallet->IsMine(txout);
a3e192a3 96 if(mine == ISMINE_WATCH_ONLY) involvesWatchAddress = true;
ffd40da3
J
97 if(fAllToMe > mine) fAllToMe = mine;
98 }
fe4a6550
WL
99
100 if (fAllFromMe && fAllToMe)
f488e735 101 {
fe4a6550 102 // Payment to self
a372168e 103 CAmount nChange = wtx.GetChange();
f488e735 104
fe4a6550
WL
105 parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "",
106 -(nDebit - nChange), nCredit - nChange));
23b0506c 107 parts.last().involvesWatchAddress = involvesWatchAddress; // maybe pass to TransactionRecord as constructor argument
fe4a6550
WL
108 }
109 else if (fAllFromMe)
110 {
111 //
112 // Debit
113 //
a372168e 114 CAmount nTxFee = nDebit - wtx.GetValueOut();
f488e735 115
fe4a6550 116 for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++)
f488e735 117 {
fe4a6550
WL
118 const CTxOut& txout = wtx.vout[nOut];
119 TransactionRecord sub(hash, nTime);
120 sub.idx = parts.size();
23b0506c 121 sub.involvesWatchAddress = involvesWatchAddress;
f488e735 122
fe4a6550
WL
123 if(wallet->IsMine(txout))
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 }
f488e735 129
10254401
PW
130 CTxDestination address;
131 if (ExtractDestination(txout.scriptPubKey, address))
f488e735 132 {
fe4a6550
WL
133 // Sent to Bitcoin Address
134 sub.type = TransactionRecord::SendToAddress;
10254401 135 sub.address = CBitcoinAddress(address).ToString();
f488e735 136 }
fe4a6550
WL
137 else
138 {
139 // Sent to IP, or other non-address transaction like OP_EVAL
140 sub.type = TransactionRecord::SendToOther;
141 sub.address = mapValue["to"];
142 }
143
a372168e 144 CAmount nValue = txout.nValue;
fe4a6550
WL
145 /* Add fee to first output */
146 if (nTxFee > 0)
147 {
148 nValue += nTxFee;
149 nTxFee = 0;
150 }
151 sub.debit = -nValue;
152
153 parts.append(sub);
8e86dca2 154 }
fe4a6550
WL
155 }
156 else
157 {
158 //
159 // Mixed debit transaction, can't break down payees
160 //
161 parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
d2692f61 162 parts.last().involvesWatchAddress = involvesWatchAddress;
f488e735
WL
163 }
164 }
165
166 return parts;
167}
64bca50d
WL
168
169void TransactionRecord::updateStatus(const CWalletTx &wtx)
170{
e07c943c 171 AssertLockHeld(cs_main);
64bca50d
WL
172 // Determine transaction status
173
174 // Find the block the tx is in
175 CBlockIndex* pindex = NULL;
145d5be8 176 BlockMap::iterator mi = mapBlockIndex.find(wtx.hashBlock);
64bca50d
WL
177 if (mi != mapBlockIndex.end())
178 pindex = (*mi).second;
179
180 // Sort order, unrecorded transactions sort to the top
181 status.sortKey = strprintf("%010d-%01d-%010u-%03d",
26ce92b3 182 (pindex ? pindex->nHeight : std::numeric_limits<int>::max()),
64bca50d
WL
183 (wtx.IsCoinBase() ? 1 : 0),
184 wtx.nTimeReceived,
185 idx);
f642fd9d 186 status.countsForBalance = wtx.IsTrusted() && !(wtx.GetBlocksToMaturity() > 0);
64bca50d 187 status.depth = wtx.GetDepthInMainChain();
4c6d41b8 188 status.cur_num_blocks = chainActive.Height();
64bca50d 189
665bdd3b 190 if (!IsFinalTx(wtx, chainActive.Height() + 1))
64bca50d 191 {
2eace48d 192 if (wtx.nLockTime < LOCKTIME_THRESHOLD)
64bca50d
WL
193 {
194 status.status = TransactionStatus::OpenUntilBlock;
665bdd3b 195 status.open_for = wtx.nLockTime - chainActive.Height();
8e86dca2
WL
196 }
197 else
198 {
64bca50d
WL
199 status.status = TransactionStatus::OpenUntilDate;
200 status.open_for = wtx.nLockTime;
201 }
202 }
64bca50d 203 // For generated transactions, determine maturity
f642fd9d 204 else if(type == TransactionRecord::Generated)
64bca50d 205 {
f642fd9d 206 if (wtx.GetBlocksToMaturity() > 0)
64bca50d 207 {
f642fd9d 208 status.status = TransactionStatus::Immature;
64bca50d
WL
209
210 if (wtx.IsInMainChain())
211 {
212 status.matures_in = wtx.GetBlocksToMaturity();
213
214 // Check if the block was requested by anyone
215 if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
f642fd9d 216 status.status = TransactionStatus::MaturesWarning;
8e86dca2
WL
217 }
218 else
219 {
f642fd9d 220 status.status = TransactionStatus::NotAccepted;
64bca50d 221 }
8e86dca2
WL
222 }
223 else
224 {
f642fd9d
WL
225 status.status = TransactionStatus::Confirmed;
226 }
227 }
228 else
229 {
230 if (status.depth < 0)
231 {
232 status.status = TransactionStatus::Conflicted;
233 }
234 else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
235 {
236 status.status = TransactionStatus::Offline;
237 }
238 else if (status.depth == 0)
239 {
240 status.status = TransactionStatus::Unconfirmed;
241 }
242 else if (status.depth < RecommendedNumConfirmations)
243 {
244 status.status = TransactionStatus::Confirming;
245 }
246 else
247 {
248 status.status = TransactionStatus::Confirmed;
64bca50d
WL
249 }
250 }
3015e0bc 251
64bca50d
WL
252}
253
3015e0bc 254bool TransactionRecord::statusUpdateNeeded()
64bca50d 255{
e07c943c 256 AssertLockHeld(cs_main);
3015e0bc 257 return status.cur_num_blocks != chainActive.Height();
64bca50d 258}
fbaee7a8 259
ed4c7fd4 260QString TransactionRecord::getTxID() const
fbaee7a8 261{
ed4c7fd4
WL
262 return formatSubTxId(hash, idx);
263}
264
265QString TransactionRecord::formatSubTxId(const uint256 &hash, int vout)
266{
267 return QString::fromStdString(hash.ToString() + strprintf("-%03d", vout));
fbaee7a8
WL
268}
269
This page took 0.179805 seconds and 4 git commands to generate.