LCOV - code coverage report
Current view: top level - src/consensus - tx_verify.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 78 80 97.5 %
Date: 2000-01-01 12:00:00 Functions: 8 8 100.0 %
Branches: 112 210 53.3 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (c) 2017-2018 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 <consensus/tx_verify.h>
       6                 :            : 
       7                 :            : #include <consensus/consensus.h>
       8                 :            : #include <primitives/transaction.h>
       9                 :            : #include <script/interpreter.h>
      10                 :            : #include <consensus/validation.h>
      11                 :            : 
      12                 :            : // TODO remove the following dependencies
      13                 :            : #include <chain.h>
      14                 :            : #include <coins.h>
      15                 :            : #include <util/moneystr.h>
      16                 :            : 
      17                 :     422769 : bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
      18                 :            : {
      19         [ +  + ]:     422769 :     if (tx.nLockTime == 0)
      20                 :            :         return true;
      21 [ +  + ][ +  + ]:      50041 :     if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
      22                 :            :         return true;
      23 [ +  + ][ +  + ]:        173 :     for (const auto& txin : tx.vin) {
      24         [ +  + ]:         56 :         if (!(txin.nSequence == CTxIn::SEQUENCE_FINAL))
      25                 :            :             return false;
      26                 :            :     }
      27                 :            :     return true;
      28                 :            : }
      29                 :            : 
      30                 :      71102 : std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector<int>* prevHeights, const CBlockIndex& block)
      31                 :            : {
      32 [ -  + ][ -  + ]:     213306 :     assert(prevHeights->size() == tx.vin.size());
                 [ -  + ]
      33                 :            : 
      34                 :            :     // Will be set to the equivalent height- and time-based nLockTime
      35                 :            :     // values that would be necessary to satisfy all relative lock-
      36                 :            :     // time constraints given our view of block chain history.
      37                 :            :     // The semantics of nLockTime are the last invalid height/time, so
      38                 :            :     // use -1 to have the effect of any height or time being valid.
      39                 :      71102 :     int nMinHeight = -1;
      40                 :      71102 :     int64_t nMinTime = -1;
      41                 :            : 
      42                 :            :     // tx.nVersion is signed integer so requires cast to unsigned otherwise
      43                 :            :     // we would be doing a signed comparison and half the range of nVersion
      44                 :            :     // wouldn't support BIP 68.
      45                 :     139590 :     bool fEnforceBIP68 = static_cast<uint32_t>(tx.nVersion) >= 2
      46 [ +  + ][ +  + ]:      71102 :                       && flags & LOCKTIME_VERIFY_SEQUENCE;
      47                 :            : 
      48                 :            :     // Do not enforce sequence numbers as a relative lock time
      49                 :            :     // unless we have been instructed to
      50                 :      68488 :     if (!fEnforceBIP68) {
      51                 :      68488 :         return std::make_pair(nMinHeight, nMinTime);
      52                 :            :     }
      53                 :            : 
      54 [ +  + ][ +  + ]:      12269 :     for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
      55         [ +  + ]:       7041 :         const CTxIn& txin = tx.vin[txinIndex];
      56                 :            : 
      57                 :            :         // Sequence numbers with the most significant bit set are not
      58                 :            :         // treated as relative lock-times, nor are they given any
      59                 :            :         // consensus-enforced meaning at this point.
      60         [ +  + ]:       7041 :         if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) {
      61                 :            :             // The height of this input is not relevant for sequence locks
      62                 :       5809 :             (*prevHeights)[txinIndex] = 0;
      63                 :       5809 :             continue;
      64                 :            :         }
      65                 :            : 
      66         [ +  + ]:       1232 :         int nCoinHeight = (*prevHeights)[txinIndex];
      67                 :            : 
      68         [ +  + ]:       1232 :         if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) {
      69         [ -  + ]:        580 :             int64_t nCoinTime = block.GetAncestor(std::max(nCoinHeight-1, 0))->GetMedianTimePast();
      70                 :            :             // NOTE: Subtract 1 to maintain nLockTime semantics
      71                 :            :             // BIP 68 relative lock times have the semantics of calculating
      72                 :            :             // the first block or time at which the transaction would be
      73                 :            :             // valid. When calculating the effective block time or height
      74                 :            :             // for the entire transaction, we switch to using the
      75                 :            :             // semantics of nLockTime which is the last invalid block
      76                 :            :             // time or height.  Thus we subtract 1 from the calculated
      77                 :            :             // time or height.
      78                 :            : 
      79                 :            :             // Time-based relative lock-times are measured from the
      80                 :            :             // smallest allowed timestamp of the block containing the
      81                 :            :             // txout being spent, which is the median time past of the
      82                 :            :             // block prior.
      83         [ +  + ]:       1020 :             nMinTime = std::max(nMinTime, nCoinTime + (int64_t)((txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) << CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) - 1);
      84                 :            :         } else {
      85         [ +  + ]:       1045 :             nMinHeight = std::max(nMinHeight, nCoinHeight + (int)(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1);
      86                 :            :         }
      87                 :            :     }
      88                 :            : 
      89                 :       2614 :     return std::make_pair(nMinHeight, nMinTime);
      90                 :            : }
      91                 :            : 
      92                 :      71624 : bool EvaluateSequenceLocks(const CBlockIndex& block, std::pair<int, int64_t> lockPair)
      93                 :            : {
      94         [ -  + ]:      71624 :     assert(block.pprev);
      95                 :      71624 :     int64_t nBlockTime = block.pprev->GetMedianTimePast();
      96 [ +  + ][ +  + ]:      71624 :     if (lockPair.first >= block.nHeight || lockPair.second >= nBlockTime)
      97                 :        398 :         return false;
      98                 :            : 
      99                 :            :     return true;
     100                 :            : }
     101                 :            : 
     102                 :      54164 : bool SequenceLocks(const CTransaction &tx, int flags, std::vector<int>* prevHeights, const CBlockIndex& block)
     103                 :            : {
     104                 :      54164 :     return EvaluateSequenceLocks(block, CalculateSequenceLocks(tx, flags, prevHeights, block));
     105                 :            : }
     106                 :            : 
     107                 :     266259 : unsigned int GetLegacySigOpCount(const CTransaction& tx)
     108                 :            : {
     109                 :     266259 :     unsigned int nSigOps = 0;
     110 [ +  + ][ +  + ]:    1480339 :     for (const auto& txin : tx.vin)
     111                 :            :     {
     112                 :     340781 :         nSigOps += txin.scriptSig.GetSigOpCount(false);
     113                 :            :     }
     114 [ +  + ][ +  + ]:    2283537 :     for (const auto& txout : tx.vout)
     115                 :            :     {
     116                 :     742380 :         nSigOps += txout.scriptPubKey.GetSigOpCount(false);
     117                 :            :     }
     118                 :     266259 :     return nSigOps;
     119                 :            : }
     120                 :            : 
     121                 :      70685 : unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
     122                 :            : {
     123         [ +  + ]:      70685 :     if (tx.IsCoinBase())
     124                 :            :         return 0;
     125                 :            : 
     126                 :            :     unsigned int nSigOps = 0;
     127 [ +  + ][ +  + ]:     251512 :     for (unsigned int i = 0; i < tx.vin.size(); i++)
     128                 :            :     {
     129                 :     220284 :         const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
     130   [ -  +  -  + ]:     220284 :         assert(!coin.IsSpent());
     131                 :     110142 :         const CTxOut &prevout = coin.out;
     132         [ +  + ]:     110142 :         if (prevout.scriptPubKey.IsPayToScriptHash())
     133                 :     119082 :             nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
     134                 :            :     }
     135                 :            :     return nSigOps;
     136                 :            : }
     137                 :            : 
     138                 :     117993 : int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, int flags)
     139                 :            : {
     140                 :     117993 :     int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR;
     141                 :            : 
     142         [ +  + ]:     117993 :     if (tx.IsCoinBase())
     143                 :            :         return nSigOps;
     144                 :            : 
     145         [ +  - ]:      70682 :     if (flags & SCRIPT_VERIFY_P2SH) {
     146                 :      70682 :         nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR;
     147                 :            :     }
     148                 :            : 
     149 [ +  + ][ +  + ]:     361634 :     for (unsigned int i = 0; i < tx.vin.size(); i++)
     150                 :            :     {
     151                 :     220270 :         const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
     152   [ -  +  -  + ]:     220270 :         assert(!coin.IsSpent());
     153                 :     110135 :         const CTxOut &prevout = coin.out;
     154                 :     220270 :         nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, &tx.vin[i].scriptWitness, flags);
     155                 :            :     }
     156                 :            :     return nSigOps;
     157                 :            : }
     158                 :            : 
     159                 :    3069340 : bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee)
     160                 :            : {
     161                 :            :     // are the actual inputs available?
     162         [ +  + ]:    3069340 :     if (!inputs.HaveInputs(tx)) {
     163 [ +  - ][ +  - ]:         63 :         return state.Invalid(ValidationInvalidReason::TX_MISSING_INPUTS, false, REJECT_INVALID, "bad-txns-inputs-missingorspent",
         [ +  - ][ #  # ]
         [ #  # ][ +  - ]
     164 [ +  - ][ +  - ]:         42 :                          strprintf("%s: inputs missing/spent", __func__));
                 [ #  # ]
     165                 :            :     }
     166                 :            : 
     167                 :    3069319 :     CAmount nValueIn = 0;
     168 [ +  + ][ +  + ]:    7200451 :     for (unsigned int i = 0; i < tx.vin.size(); ++i) {
     169                 :    4131138 :         const COutPoint &prevout = tx.vin[i].prevout;
     170                 :    4131138 :         const Coin& coin = inputs.AccessCoin(prevout);
     171   [ -  +  -  + ]:    8262276 :         assert(!coin.IsSpent());
     172                 :            : 
     173                 :            :         // If prev is coinbase, check that it's matured
     174 [ +  + ][ +  + ]:    8262276 :         if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
                 [ +  + ]
     175 [ +  - ][ +  - ]:         18 :             return state.Invalid(ValidationInvalidReason::TX_PREMATURE_SPEND, false, REJECT_INVALID, "bad-txns-premature-spend-of-coinbase",
         [ +  - ][ #  # ]
         [ #  # ][ +  - ]
     176 [ +  - ][ +  - ]:         12 :                 strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
                 [ #  # ]
     177                 :            :         }
     178                 :            : 
     179                 :            :         // Check for negative or overflow input values
     180                 :    4131132 :         nValueIn += coin.out.nValue;
     181 [ +  - ][ +  - ]:    8262264 :         if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) {
         [ +  - ][ +  - ]
     182   [ #  #  #  # ]:          0 :             return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-txns-inputvalues-outofrange");
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     183                 :            :         }
     184                 :            :     }
     185                 :            : 
     186                 :    3069313 :     const CAmount value_out = tx.GetValueOut();
     187         [ +  + ]:    3069313 :     if (nValueIn < value_out) {
     188 [ +  - ][ +  - ]:         16 :         return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-txns-in-belowout",
         [ +  - ][ +  - ]
         [ +  - ][ #  # ]
                 [ #  # ]
     189 [ +  - ][ +  - ]:         12 :             strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out)));
         [ +  - ][ -  + ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
     190                 :            :     }
     191                 :            : 
     192                 :            :     // Tally transaction fees
     193                 :    3069309 :     const CAmount txfee_aux = nValueIn - value_out;
     194 [ -  + ][ -  + ]:    6138618 :     if (!MoneyRange(txfee_aux)) {
     195   [ #  #  #  # ]:          0 :         return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-txns-fee-outofrange");
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     196                 :            :     }
     197                 :            : 
     198                 :    3069309 :     txfee = txfee_aux;
     199                 :    3069309 :     return true;
     200                 :            : }

Generated by: LCOV version 1.14