LCOV - code coverage report
Current view: top level - src/qt - transactionrecord.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 0 119 0.0 %
Date: 2020-09-26 01:30:44 Functions: 0 6 0.0 %

          Line data    Source code
       1             : // Copyright (c) 2011-2019 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 <qt/transactionrecord.h>
       6             : 
       7             : #include <chain.h>
       8             : #include <interfaces/wallet.h>
       9             : #include <key_io.h>
      10             : #include <wallet/ismine.h>
      11             : 
      12             : #include <stdint.h>
      13             : 
      14             : #include <QDateTime>
      15             : 
      16             : /* Return positive answer if transaction should be shown in list.
      17             :  */
      18           0 : bool TransactionRecord::showTransaction()
      19             : {
      20             :     // There are currently no cases where we hide transactions, but
      21             :     // we may want to use this in the future for things like RBF.
      22           0 :     return true;
      23             : }
      24             : 
      25             : /*
      26             :  * Decompose CWallet transaction to model transaction records.
      27             :  */
      28           0 : QList<TransactionRecord> TransactionRecord::decomposeTransaction(const interfaces::WalletTx& wtx)
      29             : {
      30           0 :     QList<TransactionRecord> parts;
      31           0 :     int64_t nTime = wtx.time;
      32           0 :     CAmount nCredit = wtx.credit;
      33           0 :     CAmount nDebit = wtx.debit;
      34           0 :     CAmount nNet = nCredit - nDebit;
      35           0 :     uint256 hash = wtx.tx->GetHash();
      36           0 :     std::map<std::string, std::string> mapValue = wtx.value_map;
      37             : 
      38           0 :     if (nNet > 0 || wtx.is_coinbase)
      39             :     {
      40             :         //
      41             :         // Credit
      42             :         //
      43           0 :         for(unsigned int i = 0; i < wtx.tx->vout.size(); i++)
      44             :         {
      45           0 :             const CTxOut& txout = wtx.tx->vout[i];
      46           0 :             isminetype mine = wtx.txout_is_mine[i];
      47           0 :             if(mine)
      48             :             {
      49           0 :                 TransactionRecord sub(hash, nTime);
      50           0 :                 sub.idx = i; // vout index
      51           0 :                 sub.credit = txout.nValue;
      52           0 :                 sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY;
      53           0 :                 if (wtx.txout_address_is_mine[i])
      54             :                 {
      55             :                     // Received by Bitcoin Address
      56           0 :                     sub.type = TransactionRecord::RecvWithAddress;
      57           0 :                     sub.address = EncodeDestination(wtx.txout_address[i]);
      58           0 :                 }
      59             :                 else
      60             :                 {
      61             :                     // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
      62           0 :                     sub.type = TransactionRecord::RecvFromOther;
      63           0 :                     sub.address = mapValue["from"];
      64             :                 }
      65           0 :                 if (wtx.is_coinbase)
      66             :                 {
      67             :                     // Generated
      68           0 :                     sub.type = TransactionRecord::Generated;
      69           0 :                 }
      70             : 
      71           0 :                 parts.append(sub);
      72           0 :             }
      73             :         }
      74           0 :     }
      75             :     else
      76             :     {
      77             :         bool involvesWatchAddress = false;
      78             :         isminetype fAllFromMe = ISMINE_SPENDABLE;
      79           0 :         for (const isminetype mine : wtx.txin_is_mine)
      80             :         {
      81           0 :             if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
      82           0 :             if(fAllFromMe > mine) fAllFromMe = mine;
      83             :         }
      84             : 
      85             :         isminetype fAllToMe = ISMINE_SPENDABLE;
      86           0 :         for (const isminetype mine : wtx.txout_is_mine)
      87             :         {
      88           0 :             if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
      89           0 :             if(fAllToMe > mine) fAllToMe = mine;
      90             :         }
      91             : 
      92           0 :         if (fAllFromMe && fAllToMe)
      93             :         {
      94             :             // Payment to self
      95           0 :             std::string address;
      96           0 :             for (auto it = wtx.txout_address.begin(); it != wtx.txout_address.end(); ++it) {
      97           0 :                 if (it != wtx.txout_address.begin()) address += ", ";
      98           0 :                 address += EncodeDestination(*it);
      99             :             }
     100             : 
     101           0 :             CAmount nChange = wtx.change;
     102           0 :             parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, address, -(nDebit - nChange), nCredit - nChange));
     103           0 :             parts.last().involvesWatchAddress = involvesWatchAddress;   // maybe pass to TransactionRecord as constructor argument
     104           0 :         }
     105           0 :         else if (fAllFromMe)
     106             :         {
     107             :             //
     108             :             // Debit
     109             :             //
     110           0 :             CAmount nTxFee = nDebit - wtx.tx->GetValueOut();
     111             : 
     112           0 :             for (unsigned int nOut = 0; nOut < wtx.tx->vout.size(); nOut++)
     113             :             {
     114           0 :                 const CTxOut& txout = wtx.tx->vout[nOut];
     115           0 :                 TransactionRecord sub(hash, nTime);
     116           0 :                 sub.idx = nOut;
     117           0 :                 sub.involvesWatchAddress = involvesWatchAddress;
     118             : 
     119           0 :                 if(wtx.txout_is_mine[nOut])
     120             :                 {
     121             :                     // Ignore parts sent to self, as this is usually the change
     122             :                     // from a transaction sent back to our own address.
     123           0 :                     continue;
     124             :                 }
     125             : 
     126           0 :                 if (!boost::get<CNoDestination>(&wtx.txout_address[nOut]))
     127             :                 {
     128             :                     // Sent to Bitcoin Address
     129           0 :                     sub.type = TransactionRecord::SendToAddress;
     130           0 :                     sub.address = EncodeDestination(wtx.txout_address[nOut]);
     131           0 :                 }
     132             :                 else
     133             :                 {
     134             :                     // Sent to IP, or other non-address transaction like OP_EVAL
     135           0 :                     sub.type = TransactionRecord::SendToOther;
     136           0 :                     sub.address = mapValue["to"];
     137             :                 }
     138             : 
     139           0 :                 CAmount nValue = txout.nValue;
     140             :                 /* Add fee to first output */
     141           0 :                 if (nTxFee > 0)
     142             :                 {
     143           0 :                     nValue += nTxFee;
     144             :                     nTxFee = 0;
     145           0 :                 }
     146           0 :                 sub.debit = -nValue;
     147             : 
     148           0 :                 parts.append(sub);
     149           0 :             }
     150           0 :         }
     151             :         else
     152             :         {
     153             :             //
     154             :             // Mixed debit transaction, can't break down payees
     155             :             //
     156           0 :             parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
     157           0 :             parts.last().involvesWatchAddress = involvesWatchAddress;
     158             :         }
     159           0 :     }
     160             : 
     161             :     return parts;
     162           0 : }
     163             : 
     164           0 : void TransactionRecord::updateStatus(const interfaces::WalletTxStatus& wtx, const uint256& block_hash, int numBlocks, int64_t block_time)
     165             : {
     166             :     // Determine transaction status
     167             : 
     168             :     // Sort order, unrecorded transactions sort to the top
     169           0 :     status.sortKey = strprintf("%010d-%01d-%010u-%03d",
     170           0 :         wtx.block_height,
     171           0 :         wtx.is_coinbase ? 1 : 0,
     172           0 :         wtx.time_received,
     173           0 :         idx);
     174           0 :     status.countsForBalance = wtx.is_trusted && !(wtx.blocks_to_maturity > 0);
     175           0 :     status.depth = wtx.depth_in_main_chain;
     176           0 :     status.m_cur_block_hash = block_hash;
     177             : 
     178           0 :     const bool up_to_date = ((int64_t)QDateTime::currentMSecsSinceEpoch() / 1000 - block_time < MAX_BLOCK_TIME_GAP);
     179           0 :     if (up_to_date && !wtx.is_final) {
     180           0 :         if (wtx.lock_time < LOCKTIME_THRESHOLD) {
     181           0 :             status.status = TransactionStatus::OpenUntilBlock;
     182           0 :             status.open_for = wtx.lock_time - numBlocks;
     183           0 :         }
     184             :         else
     185             :         {
     186           0 :             status.status = TransactionStatus::OpenUntilDate;
     187           0 :             status.open_for = wtx.lock_time;
     188             :         }
     189             :     }
     190             :     // For generated transactions, determine maturity
     191           0 :     else if(type == TransactionRecord::Generated)
     192             :     {
     193           0 :         if (wtx.blocks_to_maturity > 0)
     194             :         {
     195           0 :             status.status = TransactionStatus::Immature;
     196             : 
     197           0 :             if (wtx.is_in_main_chain)
     198             :             {
     199           0 :                 status.matures_in = wtx.blocks_to_maturity;
     200           0 :             }
     201             :             else
     202             :             {
     203           0 :                 status.status = TransactionStatus::NotAccepted;
     204             :             }
     205             :         }
     206             :         else
     207             :         {
     208           0 :             status.status = TransactionStatus::Confirmed;
     209             :         }
     210             :     }
     211             :     else
     212             :     {
     213           0 :         if (status.depth < 0)
     214             :         {
     215           0 :             status.status = TransactionStatus::Conflicted;
     216           0 :         }
     217           0 :         else if (status.depth == 0)
     218             :         {
     219           0 :             status.status = TransactionStatus::Unconfirmed;
     220           0 :             if (wtx.is_abandoned)
     221           0 :                 status.status = TransactionStatus::Abandoned;
     222             :         }
     223           0 :         else if (status.depth < RecommendedNumConfirmations)
     224             :         {
     225           0 :             status.status = TransactionStatus::Confirming;
     226           0 :         }
     227             :         else
     228             :         {
     229           0 :             status.status = TransactionStatus::Confirmed;
     230             :         }
     231             :     }
     232           0 :     status.needsUpdate = false;
     233           0 : }
     234             : 
     235           0 : bool TransactionRecord::statusUpdateNeeded(const uint256& block_hash) const
     236             : {
     237           0 :     assert(!block_hash.IsNull());
     238           0 :     return status.m_cur_block_hash != block_hash || status.needsUpdate;
     239             : }
     240             : 
     241           0 : QString TransactionRecord::getTxHash() const
     242             : {
     243           0 :     return QString::fromStdString(hash.ToString());
     244           0 : }
     245             : 
     246           0 : int TransactionRecord::getOutputIndex() const
     247             : {
     248           0 :     return idx;
     249             : }

Generated by: LCOV version 1.15