Merge #9226: Remove fNetworkNode and pnodeLocalHost.
[bitcoinplatinum.git] / src / qt / transactionrecord.cpp
blob4fe47181f626e3077f815aea1dc2625c61bb0297
1 // Copyright (c) 2011-2015 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.
5 #include "transactionrecord.h"
7 #include "base58.h"
8 #include "consensus/consensus.h"
9 #include "main.h"
10 #include "timedata.h"
11 #include "wallet/wallet.h"
13 #include <stdint.h>
15 #include <boost/foreach.hpp>
17 /* Return positive answer if transaction should be shown in list.
19 bool TransactionRecord::showTransaction(const CWalletTx &wtx)
21 if (wtx.IsCoinBase())
23 // Ensures we show generated coins / mined transactions at depth 1
24 if (!wtx.IsInMainChain())
26 return false;
29 return true;
33 * Decompose CWallet transaction to model transaction records.
35 QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx)
37 QList<TransactionRecord> parts;
38 int64_t nTime = wtx.GetTxTime();
39 CAmount nCredit = wtx.GetCredit(ISMINE_ALL);
40 CAmount nDebit = wtx.GetDebit(ISMINE_ALL);
41 CAmount nNet = nCredit - nDebit;
42 uint256 hash = wtx.GetHash();
43 std::map<std::string, std::string> mapValue = wtx.mapValue;
45 if (nNet > 0 || wtx.IsCoinBase())
48 // Credit
50 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
52 isminetype mine = wallet->IsMine(txout);
53 if(mine)
55 TransactionRecord sub(hash, nTime);
56 CTxDestination address;
57 sub.idx = parts.size(); // sequence number
58 sub.credit = txout.nValue;
59 sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY;
60 if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
62 // Received by Bitcoin Address
63 sub.type = TransactionRecord::RecvWithAddress;
64 sub.address = CBitcoinAddress(address).ToString();
66 else
68 // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
69 sub.type = TransactionRecord::RecvFromOther;
70 sub.address = mapValue["from"];
72 if (wtx.IsCoinBase())
74 // Generated
75 sub.type = TransactionRecord::Generated;
78 parts.append(sub);
82 else
84 bool involvesWatchAddress = false;
85 isminetype fAllFromMe = ISMINE_SPENDABLE;
86 BOOST_FOREACH(const CTxIn& txin, wtx.vin)
88 isminetype mine = wallet->IsMine(txin);
89 if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
90 if(fAllFromMe > mine) fAllFromMe = mine;
93 isminetype fAllToMe = ISMINE_SPENDABLE;
94 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
96 isminetype mine = wallet->IsMine(txout);
97 if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
98 if(fAllToMe > mine) fAllToMe = mine;
101 if (fAllFromMe && fAllToMe)
103 // Payment to self
104 CAmount nChange = wtx.GetChange();
106 parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "",
107 -(nDebit - nChange), nCredit - nChange));
108 parts.last().involvesWatchAddress = involvesWatchAddress; // maybe pass to TransactionRecord as constructor argument
110 else if (fAllFromMe)
113 // Debit
115 CAmount nTxFee = nDebit - wtx.GetValueOut();
117 for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++)
119 const CTxOut& txout = wtx.vout[nOut];
120 TransactionRecord sub(hash, nTime);
121 sub.idx = parts.size();
122 sub.involvesWatchAddress = involvesWatchAddress;
124 if(wallet->IsMine(txout))
126 // Ignore parts sent to self, as this is usually the change
127 // from a transaction sent back to our own address.
128 continue;
131 CTxDestination address;
132 if (ExtractDestination(txout.scriptPubKey, address))
134 // Sent to Bitcoin Address
135 sub.type = TransactionRecord::SendToAddress;
136 sub.address = CBitcoinAddress(address).ToString();
138 else
140 // Sent to IP, or other non-address transaction like OP_EVAL
141 sub.type = TransactionRecord::SendToOther;
142 sub.address = mapValue["to"];
145 CAmount nValue = txout.nValue;
146 /* Add fee to first output */
147 if (nTxFee > 0)
149 nValue += nTxFee;
150 nTxFee = 0;
152 sub.debit = -nValue;
154 parts.append(sub);
157 else
160 // Mixed debit transaction, can't break down payees
162 parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
163 parts.last().involvesWatchAddress = involvesWatchAddress;
167 return parts;
170 void TransactionRecord::updateStatus(const CWalletTx &wtx)
172 AssertLockHeld(cs_main);
173 // Determine transaction status
175 // Find the block the tx is in
176 CBlockIndex* pindex = NULL;
177 BlockMap::iterator mi = mapBlockIndex.find(wtx.hashBlock);
178 if (mi != mapBlockIndex.end())
179 pindex = (*mi).second;
181 // Sort order, unrecorded transactions sort to the top
182 status.sortKey = strprintf("%010d-%01d-%010u-%03d",
183 (pindex ? pindex->nHeight : std::numeric_limits<int>::max()),
184 (wtx.IsCoinBase() ? 1 : 0),
185 wtx.nTimeReceived,
186 idx);
187 status.countsForBalance = wtx.IsTrusted() && !(wtx.GetBlocksToMaturity() > 0);
188 status.depth = wtx.GetDepthInMainChain();
189 status.cur_num_blocks = chainActive.Height();
191 if (!CheckFinalTx(wtx))
193 if (wtx.nLockTime < LOCKTIME_THRESHOLD)
195 status.status = TransactionStatus::OpenUntilBlock;
196 status.open_for = wtx.nLockTime - chainActive.Height();
198 else
200 status.status = TransactionStatus::OpenUntilDate;
201 status.open_for = wtx.nLockTime;
204 // For generated transactions, determine maturity
205 else if(type == TransactionRecord::Generated)
207 if (wtx.GetBlocksToMaturity() > 0)
209 status.status = TransactionStatus::Immature;
211 if (wtx.IsInMainChain())
213 status.matures_in = wtx.GetBlocksToMaturity();
215 // Check if the block was requested by anyone
216 if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
217 status.status = TransactionStatus::MaturesWarning;
219 else
221 status.status = TransactionStatus::NotAccepted;
224 else
226 status.status = TransactionStatus::Confirmed;
229 else
231 if (status.depth < 0)
233 status.status = TransactionStatus::Conflicted;
235 else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
237 status.status = TransactionStatus::Offline;
239 else if (status.depth == 0)
241 status.status = TransactionStatus::Unconfirmed;
242 if (wtx.isAbandoned())
243 status.status = TransactionStatus::Abandoned;
245 else if (status.depth < RecommendedNumConfirmations)
247 status.status = TransactionStatus::Confirming;
249 else
251 status.status = TransactionStatus::Confirmed;
257 bool TransactionRecord::statusUpdateNeeded()
259 AssertLockHeld(cs_main);
260 return status.cur_num_blocks != chainActive.Height();
263 QString TransactionRecord::getTxID() const
265 return QString::fromStdString(hash.ToString());
268 int TransactionRecord::getOutputIndex() const
270 return idx;