LCOV - code coverage report
Current view: top level - src/primitives - transaction.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 106 118 89.8 %
Date: 2025-02-23 09:33:43 Functions: 27 29 93.1 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2014 The Bitcoin developers
       3             : // Copyright (c) 2015-2021 The PIVX Core developers
       4             : // Distributed under the MIT software license, see the accompanying
       5             : // file COPYING or https://www.opensource.org/licenses/mit-license.php.
       6             : 
       7             : #include "primitives/transaction.h"
       8             : 
       9             : #include "hash.h"
      10             : #include "tinyformat.h"
      11             : #include "utilstrencodings.h"
      12             : 
      13        1167 : std::string BaseOutPoint::ToStringShort() const
      14             : {
      15        3501 :     return strprintf("%s-%u", hash.ToString().substr(0,64), n);
      16             : }
      17             : 
      18        2333 : std::string COutPoint::ToString() const
      19             : {
      20        6999 :     return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n);
      21             : }
      22             : 
      23           0 : std::string SaplingOutPoint::ToString() const
      24             : {
      25           0 :     return strprintf("SaplingOutPoint(%s, %u)", hash.ToString().substr(0, 10), n);
      26             : }
      27             : 
      28             : 
      29        9320 : CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, uint32_t nSequenceIn)
      30             : {
      31        9320 :     prevout = prevoutIn;
      32        9320 :     scriptSig = scriptSigIn;
      33        9320 :     nSequence = nSequenceIn;
      34        9320 : }
      35             : 
      36        8493 : CTxIn::CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn, uint32_t nSequenceIn)
      37             : {
      38        8493 :     prevout = COutPoint(hashPrevTx, nOut);
      39        8493 :     scriptSig = scriptSigIn;
      40        8493 :     nSequence = nSequenceIn;
      41        8493 : }
      42             : 
      43    41022345 : bool CTxIn::IsZerocoinSpend() const
      44             : {
      45    82044690 :     return prevout.hash.IsNull() && scriptSig.IsZerocoinSpend();
      46             : }
      47             : 
      48    24358407 : bool CTxIn::IsZerocoinPublicSpend() const
      49             : {
      50    24358407 :     return scriptSig.IsZerocoinPublicSpend();
      51             : }
      52             : 
      53        2144 : std::string CTxIn::ToString() const
      54             : {
      55        2144 :     std::string str;
      56        2144 :     str += "CTxIn(";
      57        4288 :     str += prevout.ToString();
      58        2144 :     if (prevout.IsNull())
      59           1 :         if(IsZerocoinSpend())
      60           0 :             str += strprintf(", zerocoinspend %s...", HexStr(scriptSig).substr(0, 25));
      61             :         else
      62           4 :             str += strprintf(", coinbase %s", HexStr(scriptSig));
      63             :     else
      64       11139 :         str += strprintf(", scriptSig=%s", HexStr(scriptSig).substr(0, 24));
      65        2144 :     if (nSequence != std::numeric_limits<unsigned int>::max())
      66           0 :         str += strprintf(", nSequence=%u", nSequence);
      67        2144 :     str += ")";
      68        2144 :     return str;
      69             : }
      70             : 
      71       23434 : CTxOut::CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn)
      72             : {
      73       23434 :     nValue = nValueIn;
      74       23434 :     scriptPubKey = scriptPubKeyIn;
      75       23434 :     nRounds = -10;
      76       23434 : }
      77             : 
      78           0 : uint256 CTxOut::GetHash() const
      79             : {
      80           0 :     return SerializeHash(*this);
      81             : }
      82             : 
      83    10244713 : bool CTxOut::IsZerocoinMint() const
      84             : {
      85    10244713 :     return scriptPubKey.IsZerocoinMint();
      86             : }
      87             : 
      88        1810 : std::string CTxOut::ToString() const
      89             : {
      90        7238 :     return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0,30));
      91             : }
      92             : 
      93      826888 : CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nType(CTransaction::TxType::NORMAL), nLockTime(0) {}
      94      157442 : CMutableTransaction::CMutableTransaction(const CTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nType(tx.nType), nLockTime(tx.nLockTime), sapData(tx.sapData), extraPayload(tx.extraPayload) {}
      95             : 
      96      278559 : uint256 CMutableTransaction::GetHash() const
      97             : {
      98      278559 :     return SerializeHash(*this);
      99             : }
     100             : 
     101     2358266 : uint256 CTransaction::ComputeHash() const
     102             : {
     103     2358266 :     return SerializeHash(*this);
     104             : }
     105             : 
     106      310116 : size_t CTransaction::DynamicMemoryUsage() const
     107             : {
     108      310116 :     return memusage::RecursiveDynamicUsage(vin) + memusage::RecursiveDynamicUsage(vout);
     109             : }
     110             : 
     111             : /* For backward compatibility, the hash is initialized to 0. TODO: remove the need for this default constructor entirely. */
     112       13610 : CTransaction::CTransaction() : vin(), vout(), nVersion(CTransaction::CURRENT_VERSION), nType(TxType::NORMAL), nLockTime(0), hash() {}
     113     2086709 : CTransaction::CTransaction(const CMutableTransaction &tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nType(tx.nType), nLockTime(tx.nLockTime), sapData(tx.sapData), extraPayload(tx.extraPayload), hash(ComputeHash()) {}
     114     2641518 : CTransaction::CTransaction(CMutableTransaction &&tx) : vin(std::move(tx.vin)), vout(std::move(tx.vout)), nVersion(tx.nVersion), nType(tx.nType), nLockTime(tx.nLockTime), sapData(tx.sapData), extraPayload(tx.extraPayload), hash(ComputeHash()) {}
     115             : 
     116    13875074 : bool CTransaction::HasZerocoinSpendInputs() const
     117             : {
     118    35246804 :     for (const CTxIn& txin: vin) {
     119    21371630 :         if (txin.IsZerocoinSpend() || txin.IsZerocoinPublicSpend())
     120           0 :             return true;
     121             :     }
     122    13875074 :     return false;
     123             : }
     124             : 
     125      317463 : bool CTransaction::HasZerocoinMintOutputs() const
     126             : {
     127     1170868 :     for(const CTxOut& txout : vout) {
     128      853406 :         if (txout.IsZerocoinMint())
     129           0 :             return true;
     130             :     }
     131      317463 :     return false;
     132             : }
     133             : 
     134    14314003 : bool CTransaction::IsCoinStake() const
     135             : {
     136    14314003 :     if (vin.empty())
     137             :         return false;
     138             : 
     139    14266757 :     bool fAllowNull = vin[0].IsZerocoinSpend();
     140    14335548 :     if (vin[0].prevout.IsNull() && !fAllowNull)
     141             :         return false;
     142             : 
     143    14197966 :     return (vout.size() >= 2 && vout[0].IsEmpty());
     144             : }
     145             : 
     146      895579 : bool CTransaction::HasExchangeAddr() const
     147             : {
     148     3280996 :     return std::any_of(vout.begin(), vout.end(), [](const auto& txout) { return txout.scriptPubKey.IsPayToExchangeAddress(); });
     149             : }
     150             : 
     151       11689 : bool CTransaction::HasP2CSOutputs() const
     152             : {
     153       25129 :     for(const CTxOut& txout : vout) {
     154       14321 :         if (txout.scriptPubKey.IsPayToColdStaking())
     155         881 :             return true;
     156             :     }
     157       10808 :     return false;
     158             : }
     159             : 
     160     8341608 : CAmount CTransaction::GetValueOut() const
     161             : {
     162     8341608 :     CAmount nValueOut = 0;
     163    25844474 :     for (const CTxOut& out : vout) {
     164             :         // PIVX: previously MoneyRange() was called here. This has been replaced with negative check and boundary wrap check.
     165    17502936 :         if (out.nValue < 0)
     166           0 :             throw std::runtime_error("CTransaction::GetValueOut() : value out of range : less than 0");
     167             : 
     168    17502936 :         if (nValueOut + out.nValue < nValueOut)
     169             :             throw std::runtime_error("CTransaction::GetValueOut() : value out of range : wraps the int64_t boundary");
     170             : 
     171    17502936 :         nValueOut += out.nValue;
     172             :     }
     173             : 
     174             :     // Sapling
     175     8341608 :     if (hasSaplingData() && sapData->valueBalance < 0) {
     176             :         // NB: negative valueBalance "takes" money from the transparent value pool just as outputs do
     177     1019071 :         nValueOut += -sapData->valueBalance;
     178             : 
     179             :         // Verify Sapling version
     180     1019071 :         if (!isSaplingVersion())
     181           0 :             throw std::runtime_error("GetValueOut(): invalid tx version");
     182             :     }
     183             : 
     184     8341608 :     return nValueOut;
     185             : }
     186             : 
     187     4449043 : CAmount CTransaction::GetShieldedValueIn() const
     188             : {
     189     4449043 :     CAmount nValue = 0;
     190             : 
     191     4449043 :     if (hasSaplingData() && sapData->valueBalance > 0) {
     192             :         // NB: positive valueBalance "gives" money to the transparent value pool just as inputs do
     193         690 :         nValue += sapData->valueBalance;
     194             : 
     195             :         // Verify Sapling
     196         690 :         if (!isSaplingVersion())
     197           0 :             throw std::runtime_error("GetValueOut(): invalid tx version");
     198             :     }
     199             : 
     200     4449043 :     return nValue;
     201             : }
     202             : 
     203     1069554 : unsigned int CTransaction::GetTotalSize() const
     204             : {
     205     1069554 :     return ::GetSerializeSize(*this, PROTOCOL_VERSION);
     206             : }
     207             : 
     208        1442 : std::string CTransaction::ToString() const
     209             : {
     210        1442 :     std::ostringstream ss;
     211        2884 :     ss << "CTransaction(hash=" << GetHash().ToString().substr(0, 10)
     212        2884 :        << ", ver=" << nVersion
     213        1442 :        << ", type=" << nType
     214        1442 :        << ", vin.size=" << vin.size()
     215        1442 :        << ", vout.size=" << vout.size()
     216        1442 :        << ", nLockTime=" << nLockTime;
     217        1442 :     if (IsShieldedTx()) {
     218        1066 :         ss << ", valueBalance=" << sapData->valueBalance
     219        1066 :            << ", vShieldedSpend.size=" << sapData->vShieldedSpend.size()
     220        1066 :            << ", vShieldedOutput.size=" << sapData->vShieldedOutput.size();
     221             :     }
     222        1442 :     if (IsSpecialTx()) {
     223           0 :         ss << ", extraPayload.size=" << extraPayload->size();
     224             :     }
     225        1442 :     ss << ")\n";
     226        3013 :     for (const auto& in : vin)
     227        4713 :         ss << "    " << in.ToString() << "\n";
     228        3252 :     for (const auto& out : vout)
     229        5430 :         ss << "    " << out.ToString() << "\n";
     230        1442 :     return ss.str();
     231             : }

Generated by: LCOV version 1.14