Anoncoin  0.9.4
P2P Digital Currency
transactionrecord.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2014 The Bitcoin developers
2 // Copyright (c) 2013-2014 The Anoncoin Core developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "transactionrecord.h"
7 
8 #include "base58.h"
9 #include "wallet.h"
10 
11 #include <stdint.h>
12 
13 /* Return positive answer if transaction should be shown in list.
14  */
16 {
17  if (wtx.IsCoinBase())
18  {
19  // Ensures we show generated coins / mined transactions at depth 1
20  if (!wtx.IsInMainChain())
21  {
22  return false;
23  }
24  }
25  return true;
26 }
27 
28 /*
29  * Decompose CWallet transaction to model transaction records.
30  */
31 QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx)
32 {
33  QList<TransactionRecord> parts;
34  int64_t nTime = wtx.GetTxTime();
35  int64_t nCredit = wtx.GetCredit(ISMINE_ALL);
36  int64_t nDebit = wtx.GetDebit(ISMINE_ALL);
37  int64_t nNet = nCredit - nDebit;
38  uint256 hash = wtx.GetHash();
39  std::map<std::string, std::string> mapValue = wtx.mapValue;
40 
41  if (nNet > 0 || wtx.IsCoinBase())
42  {
43  //
44  // Credit
45  //
46  BOOST_FOREACH(const CTxOut& txout, wtx.vout)
47  {
48  isminetype mine = wallet->IsMine(txout);
49  if(mine)
50  {
51  TransactionRecord sub(hash, nTime);
53  sub.idx = parts.size(); // sequence number
54  sub.credit = txout.nValue;
56  if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
57  {
58  // Received by Anoncoin Address
60  sub.address = CAnoncoinAddress(address).ToString();
61  }
62  else
63  {
64  // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
66  sub.address = mapValue["from"];
67  }
68  if (wtx.IsCoinBase())
69  {
70  // Generated
72  }
73 
74  parts.append(sub);
75  }
76  }
77  }
78  else
79  {
80  bool involvesWatchAddress = false;
81  isminetype fAllFromMe = ISMINE_SPENDABLE;
82  BOOST_FOREACH(const CTxIn& txin, wtx.vin)
83  {
84  isminetype mine = wallet->IsMine(txin);
85  if(mine == ISMINE_WATCH_ONLY) involvesWatchAddress = true;
86  if(fAllFromMe > mine) fAllFromMe = mine;
87  }
88 
89  isminetype fAllToMe = ISMINE_SPENDABLE;
90  BOOST_FOREACH(const CTxOut& txout, wtx.vout)
91  {
92  isminetype mine = wallet->IsMine(txout);
93  if(mine == ISMINE_WATCH_ONLY) involvesWatchAddress = true;
94  if(fAllToMe > mine) fAllToMe = mine;
95  }
96 
97  if (fAllFromMe && fAllToMe)
98  {
99  // Payment to self
100  int64_t nChange = wtx.GetChange();
101 
102  parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "",
103  -(nDebit - nChange), nCredit - nChange));
104  parts.last().involvesWatchAddress = involvesWatchAddress; // maybe pass to TransactionRecord as constructor argument
105  }
106  else if (fAllFromMe)
107  {
108  //
109  // Debit
110  //
111  int64_t nTxFee = nDebit - wtx.GetValueOut();
112 
113  for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++)
114  {
115  const CTxOut& txout = wtx.vout[nOut];
116  TransactionRecord sub(hash, nTime);
117  sub.idx = parts.size();
119 
120  if(wallet->IsMine(txout))
121  {
122  // Ignore parts sent to self, as this is usually the change
123  // from a transaction sent back to our own address.
124  continue;
125  }
126 
128  if (ExtractDestination(txout.scriptPubKey, address))
129  {
130  // Sent to Anoncoin Address
132  sub.address = CAnoncoinAddress(address).ToString();
133  }
134  else
135  {
136  // Sent to IP, or other non-address transaction like OP_EVAL
138  sub.address = mapValue["to"];
139  }
140 
141  int64_t nValue = txout.nValue;
142  /* Add fee to first output */
143  if (nTxFee > 0)
144  {
145  nValue += nTxFee;
146  nTxFee = 0;
147  }
148  sub.debit = -nValue;
149 
150  parts.append(sub);
151  }
152  }
153  else
154  {
155  //
156  // Mixed debit transaction, can't break down payees
157  //
158  parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
159  parts.last().involvesWatchAddress = involvesWatchAddress;
160  }
161  }
162 
163  return parts;
164 }
165 
167 {
169  // Determine transaction status
170 
171  // Find the block the tx is in
172  CBlockIndex* pindex = NULL;
173  std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(wtx.hashBlock);
174  if (mi != mapBlockIndex.end())
175  pindex = (*mi).second;
176 
177  // Sort order, unrecorded transactions sort to the top
178  status.sortKey = strprintf("%010d-%01d-%010u-%03d",
179  (pindex ? pindex->nHeight : std::numeric_limits<int>::max()),
180  (wtx.IsCoinBase() ? 1 : 0),
181  wtx.nTimeReceived,
182  idx);
183  status.countsForBalance = wtx.IsTrusted() && !(wtx.GetBlocksToMaturity() > 0);
186 
187  if (!IsFinalTx(wtx, chainActive.Height() + 1))
188  {
189  if (wtx.nLockTime < LOCKTIME_THRESHOLD)
190  {
193  }
194  else
195  {
197  status.open_for = wtx.nLockTime;
198  }
199  }
200  // For generated transactions, determine maturity
202  {
203  if (wtx.GetBlocksToMaturity() > 0)
204  {
206 
207  if (wtx.IsInMainChain())
208  {
210 
211  // Check if the block was requested by anyone
212  if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
214  }
215  else
216  {
218  }
219  }
220  else
221  {
223  }
224  }
225  else
226  {
227  if (status.depth < 0)
228  {
230  }
231  else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
232  {
234  }
235  else if (status.depth == 0)
236  {
238  }
240  {
242  }
243  else
244  {
246  }
247  }
248 
249 }
250 
252 {
255 }
256 
258 {
259  return formatSubTxId(hash, idx);
260 }
261 
262 QString TransactionRecord::formatSubTxId(const uint256 &hash, int vout)
263 {
264  return QString::fromStdString(hash.ToString() + strprintf("-%03d", vout));
265 }
266 
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
Definition: main.cpp:617
int64_t GetValueOut() const
Definition: core.cpp:110
Confirmed, but waiting for the recommended number of confirmations.
isminetype IsMine(const CTxIn &txin) const
Definition: wallet.cpp:691
Transaction not yet final, waiting for block.
int idx
Subtransaction index, for sort key.
CScript scriptPubKey
Definition: core.h:125
int64_t GetChange() const
Definition: wallet.h:764
QString getTxID() const
Return the unique identifier for this transaction (part)
Not sent to any other nodes.
Generated (mined) transactions.
#define strprintf
Definition: tinyformat.h:1011
isminetype IsMine(const CKeyStore &keystore, const CTxDestination &dest)
Definition: script.cpp:1450
Have 6 or more confirmations (normal tx) or fully mature (mined tx)
std::string sortKey
Sorting key based on status.
uint256 hashBlock
Definition: main.h:442
CCriticalSection cs_main
Definition: main.cpp:38
Mined but not accepted.
uint256 GetHash() const
Definition: core.cpp:76
Not yet mined into a block.
static bool showTransaction(const CWalletTx &wtx)
Decompose CWallet transaction to model transaction records.
bool IsTrusted() const
Definition: wallet.h:784
CChain chainActive
The currently-connected chain of blocks.
Definition: main.cpp:43
mapValue_t mapValue
Definition: wallet.h:470
isminetype
IsMine() return codes.
Definition: script.h:197
#define AssertLockHeld(cs)
Definition: sync.h:98
int GetBlocksToMaturity() const
Definition: main.cpp:1059
int GetRequestCount() const
Definition: wallet.cpp:750
int Height() const
Return the maximal height in the chain.
Definition: main.h:1055
bool IsInMainChain() const
Definition: main.h:486
UI model for a transaction.
int64_t GetAdjustedTime()
Definition: util.cpp:1241
TransactionStatus status
Status: can change with block chain update.
unsigned int nLockTime
Definition: core.h:188
static QList< TransactionRecord > decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx)
An input of a transaction.
Definition: core.h:72
std::vector< CTxOut > vout
Definition: core.h:187
static QString formatSubTxId(const uint256 &hash, int vout)
Format subtransaction id.
std::vector< CTxIn > vin
Definition: core.h:186
base58-encoded Anoncoin addresses.
Definition: base58.h:102
bool countsForBalance
Transaction counts towards available balance.
void updateStatus(const CWalletTx &wtx)
Update status from core wallet tx.
std::string ToString() const
Definition: base58.cpp:175
An output of a transaction.
Definition: core.h:121
int cur_num_blocks
Current number of blocks (to know whether cached status is still valid)
Normal (sent/received) transactions.
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:464
int64_t GetTxTime() const
Definition: wallet.cpp:744
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: keystore.h:17
int64_t GetCredit(const isminefilter &filter) const
Definition: wallet.h:644
int64_t GetDebit(const isminefilter &filter) const
Definition: wallet.h:613
256-bit unsigned integer
Definition: uint256.h:532
Conflicts with other transaction or mempool.
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: main.h:698
std::string ToString() const
Definition: uint256.h:341
bool involvesWatchAddress
Whether the transaction was sent/received with a watch-only address.
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Definition: script.cpp:1513
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:101
int GetDepthInMainChain(CBlockIndex *&pindexRet) const
Definition: main.cpp:1049
bool statusUpdateNeeded()
Return whether a status update is needed.
bool IsCoinBase() const
Definition: core.h:228
unsigned int nTimeReceived
Definition: wallet.h:473
int nHeight
Definition: main.h:708
qint64 open_for
Timestamp if status==OpenUntilDate, otherwise number of additional blocks that need to be mined befor...
map< uint256, CBlockIndex * > mapBlockIndex
Definition: main.cpp:42
static const int RecommendedNumConfirmations
Number of confirmation recommended for accepting a transaction.
Transaction will likely not mature because no nodes have confirmed.
int64_t nValue
Definition: core.h:124