LCOV - code coverage report
Current view: top level - src/qt - transactionrecord.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 0 109 0.0 %
Date: 2015-10-12 22:39:14 Functions: 0 5 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2011-2014 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 "main.h"
      10             : #include "timedata.h"
      11             : #include "wallet/wallet.h"
      12             : 
      13             : #include <stdint.h>
      14             : 
      15             : #include <boost/foreach.hpp>
      16             : 
      17             : /* Return positive answer if transaction should be shown in list.
      18             :  */
      19           0 : bool TransactionRecord::showTransaction(const CWalletTx &wtx)
      20             : {
      21           0 :     if (wtx.IsCoinBase())
      22             :     {
      23             :         // Ensures we show generated coins / mined transactions at depth 1
      24           0 :         if (!wtx.IsInMainChain())
      25             :         {
      26             :             return false;
      27             :         }
      28             :     }
      29             :     return true;
      30             : }
      31             : 
      32             : /*
      33             :  * Decompose CWallet transaction to model transaction records.
      34             :  */
      35           0 : QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx)
      36             : {
      37             :     QList<TransactionRecord> parts;
      38           0 :     int64_t nTime = wtx.GetTxTime();
      39           0 :     CAmount nCredit = wtx.GetCredit(ISMINE_ALL);
      40           0 :     CAmount nDebit = wtx.GetDebit(ISMINE_ALL);
      41           0 :     CAmount nNet = nCredit - nDebit;
      42           0 :     uint256 hash = wtx.GetHash();
      43           0 :     std::map<std::string, std::string> mapValue = wtx.mapValue;
      44             : 
      45           0 :     if (nNet > 0 || wtx.IsCoinBase())
      46             :     {
      47             :         //
      48             :         // Credit
      49             :         //
      50           0 :         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
      51             :         {
      52           0 :             isminetype mine = wallet->IsMine(txout);
      53           0 :             if(mine)
      54             :             {
      55           0 :                 TransactionRecord sub(hash, nTime);
      56             :                 CTxDestination address;
      57           0 :                 sub.idx = parts.size(); // sequence number
      58           0 :                 sub.credit = txout.nValue;
      59           0 :                 sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY;
      60           0 :                 if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
      61             :                 {
      62             :                     // Received by Bitcoin Address
      63           0 :                     sub.type = TransactionRecord::RecvWithAddress;
      64           0 :                     sub.address = CBitcoinAddress(address).ToString();
      65             :                 }
      66             :                 else
      67             :                 {
      68             :                     // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
      69           0 :                     sub.type = TransactionRecord::RecvFromOther;
      70           0 :                     sub.address = mapValue["from"];
      71             :                 }
      72           0 :                 if (wtx.IsCoinBase())
      73             :                 {
      74             :                     // Generated
      75           0 :                     sub.type = TransactionRecord::Generated;
      76             :                 }
      77             : 
      78           0 :                 parts.append(sub);
      79             :             }
      80             :         }
      81             :     }
      82             :     else
      83             :     {
      84           0 :         bool involvesWatchAddress = false;
      85           0 :         isminetype fAllFromMe = ISMINE_SPENDABLE;
      86           0 :         BOOST_FOREACH(const CTxIn& txin, wtx.vin)
      87             :         {
      88           0 :             isminetype mine = wallet->IsMine(txin);
      89           0 :             if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
      90           0 :             if(fAllFromMe > mine) fAllFromMe = mine;
      91             :         }
      92             : 
      93           0 :         isminetype fAllToMe = ISMINE_SPENDABLE;
      94           0 :         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
      95             :         {
      96           0 :             isminetype mine = wallet->IsMine(txout);
      97           0 :             if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true;
      98           0 :             if(fAllToMe > mine) fAllToMe = mine;
      99             :         }
     100             : 
     101           0 :         if (fAllFromMe && fAllToMe)
     102             :         {
     103             :             // Payment to self
     104           0 :             CAmount nChange = wtx.GetChange();
     105             : 
     106             :             parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "",
     107           0 :                             -(nDebit - nChange), nCredit - nChange));
     108           0 :             parts.last().involvesWatchAddress = involvesWatchAddress;   // maybe pass to TransactionRecord as constructor argument
     109             :         }
     110           0 :         else if (fAllFromMe)
     111             :         {
     112             :             //
     113             :             // Debit
     114             :             //
     115           0 :             CAmount nTxFee = nDebit - wtx.GetValueOut();
     116             : 
     117           0 :             for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++)
     118             :             {
     119           0 :                 const CTxOut& txout = wtx.vout[nOut];
     120           0 :                 TransactionRecord sub(hash, nTime);
     121           0 :                 sub.idx = parts.size();
     122           0 :                 sub.involvesWatchAddress = involvesWatchAddress;
     123             : 
     124           0 :                 if(wallet->IsMine(txout))
     125             :                 {
     126             :                     // Ignore parts sent to self, as this is usually the change
     127             :                     // from a transaction sent back to our own address.
     128           0 :                     continue;
     129             :                 }
     130             : 
     131             :                 CTxDestination address;
     132           0 :                 if (ExtractDestination(txout.scriptPubKey, address))
     133             :                 {
     134             :                     // Sent to Bitcoin Address
     135           0 :                     sub.type = TransactionRecord::SendToAddress;
     136           0 :                     sub.address = CBitcoinAddress(address).ToString();
     137             :                 }
     138             :                 else
     139             :                 {
     140             :                     // Sent to IP, or other non-address transaction like OP_EVAL
     141           0 :                     sub.type = TransactionRecord::SendToOther;
     142           0 :                     sub.address = mapValue["to"];
     143             :                 }
     144             : 
     145           0 :                 CAmount nValue = txout.nValue;
     146             :                 /* Add fee to first output */
     147           0 :                 if (nTxFee > 0)
     148             :                 {
     149           0 :                     nValue += nTxFee;
     150           0 :                     nTxFee = 0;
     151             :                 }
     152           0 :                 sub.debit = -nValue;
     153             : 
     154           0 :                 parts.append(sub);
     155           0 :             }
     156             :         }
     157             :         else
     158             :         {
     159             :             //
     160             :             // Mixed debit transaction, can't break down payees
     161             :             //
     162           0 :             parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
     163           0 :             parts.last().involvesWatchAddress = involvesWatchAddress;
     164             :         }
     165             :     }
     166             : 
     167           0 :     return parts;
     168             : }
     169             : 
     170           0 : void TransactionRecord::updateStatus(const CWalletTx &wtx)
     171             : {
     172           0 :     AssertLockHeld(cs_main);
     173             :     // Determine transaction status
     174             : 
     175             :     // Find the block the tx is in
     176           0 :     CBlockIndex* pindex = NULL;
     177           0 :     BlockMap::iterator mi = mapBlockIndex.find(wtx.hashBlock);
     178           0 :     if (mi != mapBlockIndex.end())
     179           0 :         pindex = (*mi).second;
     180             : 
     181             :     // Sort order, unrecorded transactions sort to the top
     182           0 :     status.sortKey = strprintf("%010d-%01d-%010u-%03d",
     183             :         (pindex ? pindex->nHeight : std::numeric_limits<int>::max()),
     184           0 :         (wtx.IsCoinBase() ? 1 : 0),
     185             :         wtx.nTimeReceived,
     186             :         idx);
     187           0 :     status.countsForBalance = wtx.IsTrusted() && !(wtx.GetBlocksToMaturity() > 0);
     188           0 :     status.depth = wtx.GetDepthInMainChain();
     189           0 :     status.cur_num_blocks = chainActive.Height();
     190             : 
     191           0 :     if (!CheckFinalTx(wtx))
     192             :     {
     193           0 :         if (wtx.nLockTime < LOCKTIME_THRESHOLD)
     194             :         {
     195           0 :             status.status = TransactionStatus::OpenUntilBlock;
     196           0 :             status.open_for = wtx.nLockTime - chainActive.Height();
     197             :         }
     198             :         else
     199             :         {
     200           0 :             status.status = TransactionStatus::OpenUntilDate;
     201           0 :             status.open_for = wtx.nLockTime;
     202             :         }
     203             :     }
     204             :     // For generated transactions, determine maturity
     205           0 :     else if(type == TransactionRecord::Generated)
     206             :     {
     207           0 :         if (wtx.GetBlocksToMaturity() > 0)
     208             :         {
     209           0 :             status.status = TransactionStatus::Immature;
     210             : 
     211           0 :             if (wtx.IsInMainChain())
     212             :             {
     213           0 :                 status.matures_in = wtx.GetBlocksToMaturity();
     214             : 
     215             :                 // Check if the block was requested by anyone
     216           0 :                 if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
     217           0 :                     status.status = TransactionStatus::MaturesWarning;
     218             :             }
     219             :             else
     220             :             {
     221           0 :                 status.status = TransactionStatus::NotAccepted;
     222             :             }
     223             :         }
     224             :         else
     225             :         {
     226           0 :             status.status = TransactionStatus::Confirmed;
     227             :         }
     228             :     }
     229             :     else
     230             :     {
     231           0 :         if (status.depth < 0)
     232             :         {
     233           0 :             status.status = TransactionStatus::Conflicted;
     234             :         }
     235           0 :         else if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
     236             :         {
     237           0 :             status.status = TransactionStatus::Offline;
     238             :         }
     239           0 :         else if (status.depth == 0)
     240             :         {
     241           0 :             status.status = TransactionStatus::Unconfirmed;
     242             :         }
     243           0 :         else if (status.depth < RecommendedNumConfirmations)
     244             :         {
     245           0 :             status.status = TransactionStatus::Confirming;
     246             :         }
     247             :         else
     248             :         {
     249           0 :             status.status = TransactionStatus::Confirmed;
     250             :         }
     251             :     }
     252             : 
     253           0 : }
     254             : 
     255           0 : bool TransactionRecord::statusUpdateNeeded()
     256             : {
     257           0 :     AssertLockHeld(cs_main);
     258           0 :     return status.cur_num_blocks != chainActive.Height();
     259             : }
     260             : 
     261           0 : QString TransactionRecord::getTxID() const
     262             : {
     263           0 :     return formatSubTxId(hash, idx);
     264             : }
     265             : 
     266           0 : QString TransactionRecord::formatSubTxId(const uint256 &hash, int vout)
     267             : {
     268           0 :     return QString::fromStdString(hash.ToString() + strprintf("-%03d", vout));
     269           0 : }
     270             : 

Generated by: LCOV version 1.11