Fabcoin Core  0.16.2
P2P Digital Currency
transactionrecord.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2017 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 
5 #include <transactionrecord.h>
6 
7 #include <base58.h>
8 #include <consensus/consensus.h>
9 #include <validation.h>
10 #include <timedata.h>
11 #include <wallet/wallet.h>
12 
13 #include <stdint.h>
14 
15 /* Convert the destination into hash160 string for contract.
16  */
18 {
19  CFabcoinAddress txAdress(address);
20  CKeyID keyid;
21  txAdress.GetKeyID(keyid);
22  return HexStr(valtype(keyid.begin(),keyid.end()));
23 }
24 
25 /* Return positive answer if transaction should be shown in list.
26  */
28 {
29  if (wtx.IsCoinBase() || wtx.IsCoinStake())
30  {
31  // Ensures we show generated coins / mined transactions at depth 1
32  if (!wtx.IsInMainChain())
33  {
34  return false;
35  }
36  }
37  return true;
38 }
39 
40 /*
41  * Decompose CWallet transaction to model transaction records.
42  */
43 QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx)
44 {
45  QList<TransactionRecord> parts;
46  int64_t nTime = wtx.GetTxTime();
47  CAmount nCredit = wtx.GetCredit(ISMINE_ALL);
48  CAmount nDebit = wtx.GetDebit(ISMINE_ALL);
49  CAmount nNet = nCredit - nDebit;
50  uint256 hash = wtx.GetHash();
51  std::map<std::string, std::string> mapValue = wtx.mapValue;
52 
53  if (nNet > 0 || wtx.IsCoinBase() || wtx.IsCoinStake())
54  {
55  //
56  // Credit
57  //
58  for(unsigned int i = 0; i < wtx.tx->vout.size(); i++)
59  {
60  const CTxOut& txout = wtx.tx->vout[i];
61  isminetype mine = wallet->IsMine(txout);
62  if(mine)
63  {
64  TransactionRecord sub(hash, nTime);
66  if(wtx.IsCoinStake()) // Combine into single output for coinstake
67  {
68  sub.idx = 1; // vout index
69  sub.credit = nNet;
70  }
71  else
72  {
73  sub.idx = i; // vout index
74  sub.credit = txout.nValue;
75  }
77  if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
78  {
79  // Received by Fabcoin Address
80  if(wtx.tx->HasCreateOrCall())
81  {
83  sub.address = toStringHash160(address);
84  }
85  else
86  {
88  sub.address = CFabcoinAddress(address).ToString();
89  }
90  }
91  else
92  {
93  // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
95  sub.address = mapValue["from"];
96  }
97  if (wtx.IsCoinBase() || wtx.IsCoinStake())
98  {
99  // Generated
101  }
102 
103  parts.append(sub);
104 
105  if(wtx.IsCoinStake())
106  break; // Single output for coinstake
107  }
108  }
109  }
110  else
111  {
112  bool involvesWatchAddress = false;
113  isminetype fAllFromMe = ISMINE_SPENDABLE;
114  for (const CTxIn& txin : wtx.tx->vin)
115  {
116  isminetype mine = wallet->IsMine(txin);
117  if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
118  if(fAllFromMe > mine) fAllFromMe = mine;
119  }
120 
121  isminetype fAllToMe = ISMINE_SPENDABLE;
122  for (const CTxOut& txout : wtx.tx->vout)
123  {
124  isminetype mine = wallet->IsMine(txout);
125  if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
126  if(fAllToMe > mine) fAllToMe = mine;
127  }
128 
129  if (fAllFromMe && fAllToMe)
130  {
131  // Payment to self
132  CAmount nChange = wtx.GetChange();
133 
134  parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "",
135  -(nDebit - nChange), nCredit - nChange));
136  parts.last().involvesWatchAddress = involvesWatchAddress; // maybe pass to TransactionRecord as constructor argument
137  }
138  else if (fAllFromMe)
139  {
140  //
141  // Debit
142  //
143  CAmount nTxFee = nDebit - wtx.tx->GetValueOut();
144 
145  for (unsigned int nOut = 0; nOut < wtx.tx->vout.size(); nOut++)
146  {
147  const CTxOut& txout = wtx.tx->vout[nOut];
148  TransactionRecord sub(hash, nTime);
149  sub.idx = nOut;
151 
152  if(wallet->IsMine(txout))
153  {
154  // Ignore parts sent to self, as this is usually the change
155  // from a transaction sent back to our own address.
156  continue;
157  }
158 
159  if(wtx.tx->HasCreateOrCall())
160  break;
161 
163  if (ExtractDestination(txout.scriptPubKey, address))
164  {
165  // Sent to Fabcoin Address
167  sub.address = CFabcoinAddress(address).ToString();
168  }
169  else
170  {
171  // Sent to IP, or other non-address transaction like OP_EVAL
173  sub.address = mapValue["to"];
174  }
175 
176  CAmount nValue = txout.nValue;
177  /* Add fee to first output */
178  if (nTxFee > 0)
179  {
180  nValue += nTxFee;
181  nTxFee = 0;
182  }
183  sub.debit = -nValue;
184 
185  parts.append(sub);
186  }
187 
188  if(wtx.tx->HasCreateOrCall()){
189  TransactionRecord sub(hash, nTime);
190  sub.idx = 0;
191  sub.credit = nNet;
193 
195  // Use the same destination address as in the contract RPCs
196  CWallet * const pwallet = const_cast<CWallet*>(wallet);
197  if(ExtractDestination(pwallet->mapWallet[wtx.tx->vin[0].prevout.hash].tx->vout[wtx.tx->vin[0].prevout.n].scriptPubKey, address))
198  {
199  sub.address = toStringHash160(address);
200  }
201 
202  parts.append(sub);
203  }
204  }
205  else
206  {
207  //
208  // Mixed debit transaction, can't break down payees
209  //
210  parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
211  parts.last().involvesWatchAddress = involvesWatchAddress;
212  }
213  }
214 
215  return parts;
216 }
217 
219 {
221  // Determine transaction status
222 
223  // Find the block the tx is in
224  CBlockIndex* pindex = nullptr;
225  BlockMap::iterator mi = mapBlockIndex.find(wtx.hashBlock);
226  if (mi != mapBlockIndex.end())
227  pindex = (*mi).second;
228 
229  // Sort order, unrecorded transactions sort to the top
230  status.sortKey = strprintf("%010d-%01d-%010u-%03d",
231  (pindex ? pindex->nHeight : std::numeric_limits<int>::max()),
232  ((wtx.IsCoinBase() || wtx.IsCoinStake()) ? 1 : 0),
233  wtx.nTimeReceived,
234  idx);
235  status.countsForBalance = wtx.IsTrusted() && !(wtx.GetBlocksToMaturity() > 0);
238 
239  if (!CheckFinalTx(wtx))
240  {
241  if (wtx.tx->nLockTime < LOCKTIME_THRESHOLD)
242  {
244  status.open_for = wtx.tx->nLockTime - chainActive.Height();
245  }
246  else
247  {
249  status.open_for = wtx.tx->nLockTime;
250  }
251  }
252  // For generated transactions, determine maturity
254  {
255  if (wtx.GetBlocksToMaturity() > 0)
256  {
258 
259  if (wtx.IsInMainChain())
260  {
262 
263  // Check if the block was requested by anyone
264  if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
266  }
267  else
268  {
270  }
271  }
272  else
273  {
275  }
276  }
277  else
278  {
279  if (status.depth < 0)
280  {
282  }
283  else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
284  {
286  }
287  else if (status.depth == 0)
288  {
290  if (wtx.isAbandoned())
292  }
294  {
296  }
297  else
298  {
300  }
301  }
302  status.needsUpdate = false;
303 }
304 
306 {
309 }
310 
312 {
313  return QString::fromStdString(hash.ToString());
314 }
315 
317 {
318  return idx;
319 }
CAmount nValue
Definition: transaction.h:134
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:79
Confirmed, but waiting for the recommended number of confirmations.
int GetDepthInMainChain(const CBlockIndex *&pindexRet) const
Return depth of transaction in blockchain: <0 : conflicts with a transaction this deep in the blockch...
Definition: wallet.cpp:4504
Transaction not yet final, waiting for block.
int idx
Subtransaction index, for sort key.
CScript scriptPubKey
Definition: transaction.h:135
QString getTxID() const
Return the unique identifier for this transaction (part)
Not sent to any other nodes.
Generated (mined) transactions.
const uint256 & GetHash() const
Definition: wallet.h:278
#define strprintf
Definition: tinyformat.h:1054
int getOutputIndex() const
Return the output index of the subtransaction.
bool IsCoinStake() const
Definition: wallet.h:280
Have 6 or more confirmations (normal tx) or fully mature (mined tx)
std::string sortKey
Sorting key based on status.
uint256 hashBlock
Definition: wallet.h:212
CCriticalSection cs_main
Definition: validation.cpp:77
base58-encoded Fabcoin addresses.
Definition: base58.h:104
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
std::string toStringHash160(const CTxDestination &address)
Mined but not accepted.
Not yet mined into a block.
isminetype IsMine(const CKeyStore &keystore, const CScript &scriptPubKey, SigVersion sigversion)
Definition: ismine.cpp:29
bool IsTrusted() const
Definition: wallet.cpp:1920
int64_t GetTxTime() const
Definition: wallet.cpp:1505
static bool showTransaction(const CWalletTx &wtx)
Decompose CWallet transaction to model transaction records.
CAmount GetCredit(const isminefilter &filter) const
Definition: wallet.cpp:1785
unsigned char * begin()
Definition: uint256.h:65
CAmount GetDebit(const isminefilter &filter) const
filter decides which addresses will count towards the debit
Definition: wallet.cpp:1754
unsigned char * end()
Definition: uint256.h:70
mapValue_t mapValue
Key/value map with information about the transaction.
Definition: wallet.h:318
std::string ToString() const
Definition: uint256.cpp:95
int64_t CAmount
Amount in lius (Can be negative)
Definition: amount.h:15
#define AssertLockHeld(cs)
Definition: sync.h:85
int GetBlocksToMaturity() const
Definition: wallet.cpp:4523
int Height() const
Return the maximal height in the chain.
Definition: chain.h:543
bool IsInMainChain() const
Definition: wallet.h:270
UI model for a transaction.
bool CheckFinalTx(const CTransaction &tx, int flags)
Check if transaction will be final in the next block to be created.
Definition: validation.cpp:271
TransactionStatus status
Status: can change with block chain update.
static QList< TransactionRecord > decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx)
CTransactionRef tx
Definition: wallet.h:211
isminetype
IsMine() return codes.
Definition: ismine.h:17
An input of a transaction.
Definition: transaction.h:61
ExecStats::duration max
Definition: ExecStats.cpp:36
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet, txnouttype *typeRet)
Definition: standard.cpp:268
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:193
An output of a transaction.
Definition: transaction.h:131
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:80
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:287
bool GetKeyID(CKeyID &keyID) const
Definition: base58.cpp:274
256-bit opaque blob.
Definition: uint256.h:132
int GetRequestCount() const
Definition: wallet.cpp:1511
Conflicts with other transaction or mempool.
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:177
int64_t GetAdjustedTime()
Definition: timedata.cpp:35
bool involvesWatchAddress
Whether the transaction was sent/received with a watch-only address.
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:29
bool isAbandoned() const
Definition: wallet.h:275
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:672
bool statusUpdateNeeded()
Return whether a status update is needed.
std::map< uint256, CWalletTx > mapWallet
Definition: wallet.h:815
std::vector< unsigned char > valtype
Definition: fascstate.h:17
isminetype IsMine(const CTxIn &txin) const
Definition: wallet.cpp:1302
unsigned int nTimeReceived
time received by this node
Definition: wallet.h:321
struct evm_uint160be address(struct evm_env *env)
Definition: capi.c:13
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:193
qint64 open_for
Timestamp if status==OpenUntilDate, otherwise number of additional blocks that need to be mined befor...
Abandoned from the wallet.
void mine(Client &c, int numBlocks)
Definition: TestHelper.cpp:39
BlockMap mapBlockIndex
Definition: validation.cpp:79
static const int RecommendedNumConfirmations
Number of confirmation recommended for accepting a transaction.
Transaction will likely not mature because no nodes have confirmed.
CAmount GetChange() const
Definition: wallet.cpp:1905
bool IsCoinBase() const
Definition: wallet.h:279