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