PRCYCoin  2.0.0.7rc1
P2P Digital Currency
transactionrecord.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2014 The Bitcoin developers
2 // Copyright (c) 2014-2015 The Dash developers
3 // Copyright (c) 2015-2018 The PIVX developers
4 // Copyright (c) 2018-2020 The DAPS Project developers
5 // Distributed under the MIT/X11 software license, see the accompanying
6 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
7 
8 #include "transactionrecord.h"
9 
10 #include "base58.h"
11 #include "swifttx.h"
12 #include "timedata.h"
13 #include "wallet/wallet.h"
14 
15 #include <stdint.h>
16 
17 /*
18  * Decompose CWallet transaction to model transaction records.
19  */
20 QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet* wallet, const CWalletTx& wtx)
21 {
22  QList<TransactionRecord> parts;
23  int64_t nTime = wtx.GetComputedTxTime();
24  CAmount nCredit = wtx.GetCredit(ISMINE_ALL);
25  CAmount nDebit = wtx.GetDebit(ISMINE_ALL);
26  CAmount nNet = nCredit - nDebit;
27  uint256 hash = wtx.GetHash();
28  std::map<std::string, std::string> mapValue = wtx.mapValue;
29  if (wtx.IsCoinStake()) {
30  TransactionRecord sub(hash, nTime);
32  if (!ExtractDestination(wtx.vout[1].scriptPubKey, address))
33  return parts;
34  if (!IsMine(*wallet, address)) {
35  //if the address is not yours then it means you have a tx sent to you in someone elses coinstake tx
36  for (unsigned int i = 1; i < wtx.vout.size(); i++) {
37  CTxDestination outAddress;
38  if (ExtractDestination(wtx.vout[i].scriptPubKey, outAddress)) {
39  if (IsMine(*wallet, outAddress)) {
40  isminetype mine = wallet->IsMine(wtx.vout[i]);
43  sub.address = CBitcoinAddress(outAddress).ToString();
44  sub.credit = wallet->getCTxOutValue(wtx, wtx.vout[i]);
45  }
46  }
47  }
48  } else {
49  //stake reward
50  isminetype mine = wallet->IsMine(wtx.vout[1]);
54  sub.credit = nNet;
55  sub.debit = 0;
56  }
57  parts.append(sub);
58  } else if (nNet > 0 || wtx.IsCoinBase() || wtx.IsCoinAudit()) {
59  //
60  // Credit
61  //
62  for (const CTxOut& txout : wtx.vout) {
63  isminetype mine = wallet->IsMine(txout);
64  if (mine) {
65  TransactionRecord sub(hash, nTime);
67  sub.idx = parts.size(); // sequence number
69  if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address)) {
70  // Received by PRCY Address
71  sub.credit = IsMine(*wallet, address) ? wallet->getCTxOutValue(wtx, txout) : 0;
74  } else {
75  // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
77  sub.address = mapValue["from"];
78  }
79  if (wtx.IsCoinBase() || wtx.IsCoinAudit()) {
80  // Generated
82  }
83 
84  parts.append(sub);
85  }
86  }
87  } else {
88  int nFromMe = 0;
89  bool involvesWatchAddress = false;
90  isminetype fAllFromMe = ISMINE_SPENDABLE;
91  for (const CTxIn& txin : wtx.vin) {
92  if (wallet->IsMine(txin)) {
93  nFromMe++;
94  }
95  isminetype mine = wallet->IsMine(txin);
96  if (mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
97  if (fAllFromMe > mine) fAllFromMe = mine;
98  }
99 
100  isminetype fAllToMe = ISMINE_SPENDABLE;
101  int nToMe = 0;
102  for (const CTxOut& txout : wtx.vout) {
103  if (wallet->IsMine(txout)) {
104  CAmount c = wallet->getCTxOutValue(wtx, txout);
105  nToMe++;
106  }
107  isminetype mine = wallet->IsMine(txout);
108  if (mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
109  if (fAllToMe > mine) fAllToMe = mine;
110  }
111 
112  if (fAllFromMe && fAllToMe) {
113  // Payment to self
114  TransactionRecord sub(hash, nTime);
115  // Payment to self by default
117  sub.address = "";
118 
119  for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++) {
120  const CTxOut& txout = wtx.vout[nOut];
121  sub.idx = parts.size();
122  }
124  if (ExtractDestination(wtx.vout[0].scriptPubKey, address)) {
125  // Sent to PRCY Address
127  }
128 
129  //a sendtoself transaction has second output as change
130  CAmount nChange = 0;
131  if (wtx.vout.size() >= 2) nChange = pwalletMain->getCTxOutValue(wtx, wtx.vout[1]);
132 
133  sub.debit = nCredit - nChange;
134  sub.credit = 0;
135  parts.append(sub);
136  parts.last().involvesWatchAddress = involvesWatchAddress; // maybe pass to TransactionRecord as constructor argument
137  } else if (fAllFromMe) {
138  //
139  // Debit
140  //
141  CAmount nTxFee = 0;//nDebit - wtx.GetValueOut();
142 
143  for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++) {
144  const CTxOut& txout = wtx.vout[nOut];
145  TransactionRecord sub(hash, nTime);
146  sub.idx = parts.size();
148 
149  if (wallet->IsMine(txout)) {
150  // Ignore parts sent to self, as this is usually the change
151  // from a transaction sent back to our own address.
152  continue;
153  }
154 
157  // Sent to PRCY Address
160  } else {
161  // Sent to IP, or other non-address transaction like OP_EVAL
163  sub.address = mapValue["to"];
164  }
165 
166  CAmount nValue = wallet->getCTxOutValue(wtx, txout);
167  /* Add fee to first output */
168  if (nTxFee > 0) {
169  nValue += nTxFee;
170  nTxFee = 0;
171  }
172  sub.debit = nDebit - nCredit - wtx.nTxFee;
173 
174  parts.append(sub);
175  }
176  } else {
177  //
178  // Mixed debit transaction, can't break down payees
179  //
180  parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
181  parts.last().involvesWatchAddress = involvesWatchAddress;
182  }
183  }
184 
185  return parts;
186 }
187 
189 {
191  // Determine transaction status
192 
193  // Find the block the tx is in
194  CBlockIndex* pindex = NULL;
195  BlockMap::iterator mi = mapBlockIndex.find(wtx.hashBlock);
196  if (mi != mapBlockIndex.end())
197  pindex = (*mi).second;
198 
199  // Sort order, unrecorded transactions sort to the top
200  status.sortKey = strprintf("%010d-%01d-%010u-%03d",
201  (pindex ? pindex->nHeight : std::numeric_limits<int>::max()),
202  (wtx.IsCoinBase() ? 1 : 0),
203  wtx.nTimeReceived,
204  idx);
205  status.countsForBalance = wtx.IsTrusted() && !(wtx.GetBlocksToMaturity() > 0);
209 
210  if (!IsFinalTx(wtx, chainActive.Height() + 1)) {
211  if (wtx.nLockTime < LOCKTIME_THRESHOLD) {
214  } else {
216  status.open_for = wtx.nLockTime;
217  }
218  }
219  // For generated transactions, determine maturity
221  if (wtx.GetBlocksToMaturity() > 0) {
223 
224  if (wtx.IsInMainChain()) {
226 
227  // Check if the block was requested by anyone
228  if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
230  } else {
232  }
233  } else {
235  }
236  } else {
237  if (status.depth < 0) {
239  } else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) {
241  } else if (status.depth == 0) {
245  } else {
247  }
248  }
249 }
250 
252 {
255 }
256 
258 {
259  return QString::fromStdString(hash.ToString());
260 }
261 
263 {
264  return idx;
265 }
CTransaction::IsCoinAudit
bool IsCoinAudit() const
Definition: transaction.h:364
CTxIn
An input of a transaction.
Definition: transaction.h:83
TransactionRecord::StakeMint
@ StakeMint
Definition: transactionrecord.h:78
IsMine
isminetype IsMine(const CKeyStore &keystore, const CTxDestination &dest)
Definition: wallet_ismine.cpp:30
TransactionRecord::idx
int idx
Subtransaction index, for sort key.
Definition: transactionrecord.h:119
TransactionRecord::statusUpdateNeeded
bool statusUpdateNeeded()
Return whether a status update is needed.
Definition: transactionrecord.cpp:251
TransactionStatus::sortKey
std::string sortKey
Sorting key based on status.
Definition: transactionrecord.h:46
TransactionStatus::OpenUntilDate
@ OpenUntilDate
Normal (sent/received) transactions.
Definition: transactionrecord.h:31
CWallet::IsMine
isminetype IsMine(const CTxIn &txin) const
Definition: wallet.cpp:1333
TransactionRecord::status
TransactionStatus status
Status: can change with block chain update.
Definition: transactionrecord.h:122
TransactionRecord::hash
uint256 hash
Definition: transactionrecord.h:110
chainActive
CChain chainActive
The currently-connected chain of blocks.
Definition: main.cpp:70
timedata.h
TransactionRecord::RecvWithAddress
@ RecvWithAddress
Definition: transactionrecord.h:81
CWalletTx::mapValue
mapValue_t mapValue
Definition: wallet.h:798
CBitcoinAddress
base58-encoded PRCY addresses.
Definition: base58.h:109
CBlockIndex::nHeight
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:181
TransactionStatus::Conflicted
@ Conflicted
Conflicts with other transaction or mempool.
Definition: transactionrecord.h:36
CTransaction::nLockTime
const uint32_t nLockTime
Definition: transaction.h:287
wallet.h
CWalletTx::GetComputedTxTime
int64_t GetComputedTxTime() const
Definition: wallet.cpp:1439
TransactionRecord::credit
CAmount credit
Definition: transactionrecord.h:115
isminetype
isminetype
IsMine() return codes.
Definition: wallet_ismine.h:16
TransactionRecord::MNReward
@ MNReward
Definition: transactionrecord.h:82
TransactionRecord::updateStatus
void updateStatus(const CWalletTx &wtx)
Update status from core wallet tx.
Definition: transactionrecord.cpp:188
IsFinalTx
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
Check if transaction is final and can be included in a block with the specified height and time.
Definition: tx_verify.cpp:12
CBase58Data::ToString
std::string ToString() const
Definition: base58.cpp:200
TransactionRecord::RecommendedNumConfirmations
static const int RecommendedNumConfirmations
Number of confirmation recommended for accepting a transaction.
Definition: transactionrecord.h:88
nCompleteTXLocks
int nCompleteTXLocks
Definition: swifttx.cpp:30
TransactionRecord::RecvFromOther
@ RecvFromOther
Definition: transactionrecord.h:83
TransactionRecord
UI model for a transaction.
Definition: transactionrecord.h:72
TransactionStatus::MaturesWarning
@ MaturesWarning
Transaction will likely not mature because no nodes have confirmed.
Definition: transactionrecord.h:39
cs_main
RecursiveMutex cs_main
Global state.
Definition: main.cpp:65
CTransaction::IsCoinBase
bool IsCoinBase() const
Definition: transaction.h:359
CWalletTx::nTimeReceived
unsigned int nTimeReceived
Definition: wallet.h:801
TransactionStatus::open_for
qint64 open_for
Timestamp if status==OpenUntilDate, otherwise number of additional blocks that need to be mined befor...
Definition: transactionrecord.h:57
CWalletTx::GetCredit
CAmount GetCredit(const isminefilter &filter) const
Definition: wallet.cpp:1505
CTxOut
An output of a transaction.
Definition: transaction.h:164
TransactionRecord::SendToOther
@ SendToOther
Definition: transactionrecord.h:80
CTransaction::vout
std::vector< CTxOut > vout
Definition: transaction.h:286
CTxOut::scriptPubKey
CScript scriptPubKey
Definition: transaction.h:168
ISMINE_ALL
@ ISMINE_ALL
Definition: wallet_ismine.h:21
CWalletTx::GetDebit
CAmount GetDebit(const isminefilter &filter) const
Definition: wallet.cpp:1478
TransactionRecord::involvesWatchAddress
bool involvesWatchAddress
Whether the transaction was sent/received with a watch-only address.
Definition: transactionrecord.h:125
CAmount
int64_t CAmount
Amount in PRCY (Can be negative)
Definition: amount.h:17
CTransaction::nTxFee
CAmount nTxFee
Definition: transaction.h:298
ISMINE_SPENDABLE
@ ISMINE_SPENDABLE
Definition: wallet_ismine.h:20
TransactionRecord::Generated
@ Generated
Definition: transactionrecord.h:77
AssertLockHeld
#define AssertLockHeld(cs)
Definition: sync.h:71
uint256
256-bit unsigned big integer.
Definition: uint256.h:38
TransactionRecord::debit
CAmount debit
Definition: transactionrecord.h:114
TransactionRecord::SendToSelf
@ SendToSelf
Definition: transactionrecord.h:84
TransactionStatus::Immature
@ Immature
Generated (mined) transactions.
Definition: transactionrecord.h:38
ExtractDestination
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Definition: standard.cpp:199
ISMINE_WATCH_ONLY
@ ISMINE_WATCH_ONLY
Indicates that we dont know how to create a scriptSig that would solve this if we were given the appr...
Definition: wallet_ismine.h:19
CTxDestination
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:81
CMerkleTx::GetDepthInMainChain
int GetDepthInMainChain(const CBlockIndex *&pindexRet, bool enableIX=true) const
Return depth of transaction in blockchain: -1 : not in blockchain, and not in memory pool (conflicted...
Definition: wallet.cpp:6006
CChain::Height
int Height() const
Return the maximal height in the chain.
Definition: chain.h:641
TransactionStatus::OpenUntilBlock
@ OpenUntilBlock
Transaction not yet final, waiting for block.
Definition: transactionrecord.h:32
TransactionRecord::type
Type type
Definition: transactionrecord.h:112
TransactionStatus::Confirmed
@ Confirmed
Have 6 or more confirmations (normal tx) or fully mature (mined tx)
Definition: transactionrecord.h:29
TransactionStatus::cur_num_ix_locks
int cur_num_ix_locks
Definition: transactionrecord.h:66
transactionrecord.h
TransactionRecord::address
std::string address
Definition: transactionrecord.h:113
strprintf
#define strprintf
Definition: tinyformat.h:1056
GetAdjustedTime
int64_t GetAdjustedTime()
Definition: timedata.cpp:30
TransactionStatus::Confirming
@ Confirming
Confirmed, but waiting for the recommended number of confirmations.
Definition: transactionrecord.h:35
CMerkleTx::GetBlocksToMaturity
int GetBlocksToMaturity() const
Definition: wallet.cpp:6025
TransactionRecord::decomposeTransaction
static QList< TransactionRecord > decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx)
Decompose CWallet transaction to model transaction records.
Definition: transactionrecord.cpp:20
TransactionStatus::status
Status status
Definition: transactionrecord.h:55
CTransaction::vin
std::vector< CTxIn > vin
Definition: transaction.h:285
TransactionStatus::matures_in
int matures_in
Definition: transactionrecord.h:50
swifttx.h
CWallet
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,...
Definition: wallet.h:243
CWalletTx
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:792
TransactionRecord::getOutputIndex
int getOutputIndex() const
Return the output index of the subtransaction
Definition: transactionrecord.cpp:262
TransactionStatus::Offline
@ Offline
Not sent to any other nodes.
Definition: transactionrecord.h:33
TransactionRecord::SendToAddress
@ SendToAddress
Definition: transactionrecord.h:79
CMerkleTx::IsInMainChain
bool IsInMainChain() const
Definition: wallet.cpp:6033
CWalletTx::IsTrusted
bool IsTrusted() const
Definition: wallet.cpp:6295
base58.h
CTransaction::GetHash
const uint256 & GetHash() const
Definition: transaction.h:342
TransactionStatus::depth
qint64 depth
Definition: transactionrecord.h:56
CMerkleTx::hashBlock
uint256 hashBlock
Definition: wallet.h:737
TransactionStatus::NotAccepted
@ NotAccepted
Mined but not accepted.
Definition: transactionrecord.h:40
CWalletTx::GetRequestCount
int GetRequestCount() const
Definition: wallet.cpp:1445
TransactionStatus::countsForBalance
bool countsForBalance
Transaction counts towards available balance.
Definition: transactionrecord.h:44
TransactionStatus::Unconfirmed
@ Unconfirmed
Not yet mined into a block.
Definition: transactionrecord.h:34
TransactionRecord::getTxID
QString getTxID() const
Return the unique identifier for this transaction (part)
Definition: transactionrecord.cpp:257
CBlockIndex
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:162
TransactionRecord::TransactionRecord
TransactionRecord()
Definition: transactionrecord.h:90
pwalletMain
CWallet * pwalletMain
Definition: wallet.cpp:49
TransactionStatus::cur_num_blocks
int cur_num_blocks
Current number of blocks (to know whether cached status is still valid)
Definition: transactionrecord.h:63
CWallet::getCTxOutValue
CAmount getCTxOutValue(const CTransaction &tx, const CTxOut &out) const
Definition: wallet.cpp:7202
mapBlockIndex
BlockMap mapBlockIndex
Definition: main.cpp:67
TransactionRecord::Other
@ Other
Definition: transactionrecord.h:76
CTransaction::IsCoinStake
bool IsCoinStake() const
Definition: transaction.cpp:143
base_uint::ToString
std::string ToString() const
Definition: arith_uint256.cpp:199