LCOV - code coverage report
Current view: top level - src/consensus - tx_verify.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 95 98 96.9 %
Date: 2020-09-26 01:30:44 Functions: 8 8 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2017-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 <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     1197456 : bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
      18             : {
      19     1197456 :     if (tx.nLockTime == 0)
      20      879506 :         return true;
      21      317950 :     if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
      22      317855 :         return true;
      23         190 :     for (const auto& txin : tx.vin) {
      24          95 :         if (!(txin.nSequence == CTxIn::SEQUENCE_FINAL))
      25          90 :             return false;
      26           5 :     }
      27           5 :     return true;
      28     1197456 : }
      29             : 
      30       79002 : std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block)
      31             : {
      32       79002 :     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       79002 :     int nMinHeight = -1;
      40       79002 :     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      158004 :     bool fEnforceBIP68 = static_cast<uint32_t>(tx.nVersion) >= 2
      46       79002 :                       && flags & LOCKTIME_VERIFY_SEQUENCE;
      47             : 
      48             :     // Do not enforce sequence numbers as a relative lock time
      49             :     // unless we have been instructed to
      50       79002 :     if (!fEnforceBIP68) {
      51       74365 :         return std::make_pair(nMinHeight, nMinTime);
      52             :     }
      53             : 
      54       22825 :     for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
      55       18188 :         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       18188 :         if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) {
      61             :             // The height of this input is not relevant for sequence locks
      62       16899 :             prevHeights[txinIndex] = 0;
      63       16899 :             continue;
      64             :         }
      65             : 
      66        1289 :         int nCoinHeight = prevHeights[txinIndex];
      67             : 
      68        1289 :         if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) {
      69         453 :             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         453 :             nMinTime = std::max(nMinTime, nCoinTime + (int64_t)((txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) << CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) - 1);
      84         453 :         } else {
      85         836 :             nMinHeight = std::max(nMinHeight, nCoinHeight + (int)(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1);
      86             :         }
      87        1289 :     }
      88             : 
      89        4637 :     return std::make_pair(nMinHeight, nMinTime);
      90       79002 : }
      91             : 
      92       79732 : bool EvaluateSequenceLocks(const CBlockIndex& block, std::pair<int, int64_t> lockPair)
      93             : {
      94       79732 :     assert(block.pprev);
      95       79732 :     int64_t nBlockTime = block.pprev->GetMedianTimePast();
      96       79732 :     if (lockPair.first >= block.nHeight || lockPair.second >= nBlockTime)
      97         396 :         return false;
      98             : 
      99       79336 :     return true;
     100       79732 : }
     101             : 
     102       59613 : bool SequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block)
     103             : {
     104       59613 :     return EvaluateSequenceLocks(block, CalculateSequenceLocks(tx, flags, prevHeights, block));
     105             : }
     106             : 
     107      351777 : unsigned int GetLegacySigOpCount(const CTransaction& tx)
     108             : {
     109             :     unsigned int nSigOps = 0;
     110      847960 :     for (const auto& txin : tx.vin)
     111             :     {
     112      496183 :         nSigOps += txin.scriptSig.GetSigOpCount(false);
     113             :     }
     114     1348474 :     for (const auto& txout : tx.vout)
     115             :     {
     116      996697 :         nSigOps += txout.scriptPubKey.GetSigOpCount(false);
     117             :     }
     118      351777 :     return nSigOps;
     119             : }
     120             : 
     121       78590 : unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
     122             : {
     123       78590 :     if (tx.IsCoinBase())
     124           0 :         return 0;
     125             : 
     126             :     unsigned int nSigOps = 0;
     127      215832 :     for (unsigned int i = 0; i < tx.vin.size(); i++)
     128             :     {
     129      137242 :         const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
     130      137242 :         assert(!coin.IsSpent());
     131      137242 :         const CTxOut &prevout = coin.out;
     132      137242 :         if (prevout.scriptPubKey.IsPayToScriptHash())
     133       57651 :             nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
     134             :     }
     135             :     return nSigOps;
     136       78590 : }
     137             : 
     138      146240 : int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, int flags)
     139             : {
     140      146240 :     int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR;
     141             : 
     142      146240 :     if (tx.IsCoinBase())
     143       67653 :         return nSigOps;
     144             : 
     145       78587 :     if (flags & SCRIPT_VERIFY_P2SH) {
     146       78587 :         nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR;
     147       78587 :     }
     148             : 
     149      215822 :     for (unsigned int i = 0; i < tx.vin.size(); i++)
     150             :     {
     151      137235 :         const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
     152      137235 :         assert(!coin.IsSpent());
     153      137235 :         const CTxOut &prevout = coin.out;
     154      137235 :         nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, &tx.vin[i].scriptWitness, flags);
     155             :     }
     156       78587 :     return nSigOps;
     157      146240 : }
     158             : 
     159     5191532 : bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee)
     160             : {
     161             :     // are the actual inputs available?
     162     5191532 :     if (!inputs.HaveInputs(tx)) {
     163          18 :         return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent",
     164          18 :                          strprintf("%s: inputs missing/spent", __func__));
     165             :     }
     166             : 
     167     5191514 :     CAmount nValueIn = 0;
     168    12062922 :     for (unsigned int i = 0; i < tx.vin.size(); ++i) {
     169     6871414 :         const COutPoint &prevout = tx.vin[i].prevout;
     170     6871414 :         const Coin& coin = inputs.AccessCoin(prevout);
     171     6871414 :         assert(!coin.IsSpent());
     172             : 
     173             :         // If prev is coinbase, check that it's matured
     174     6871414 :         if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
     175           6 :             return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "bad-txns-premature-spend-of-coinbase",
     176           6 :                 strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
     177             :         }
     178             : 
     179             :         // Check for negative or overflow input values
     180     6871408 :         nValueIn += coin.out.nValue;
     181     6871408 :         if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) {
     182           0 :             return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputvalues-outofrange");
     183             :         }
     184     6871408 :     }
     185             : 
     186     5191508 :     const CAmount value_out = tx.GetValueOut();
     187     5191508 :     if (nValueIn < value_out) {
     188           8 :         return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-in-belowout",
     189           4 :             strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out)));
     190             :     }
     191             : 
     192             :     // Tally transaction fees
     193     5191504 :     const CAmount txfee_aux = nValueIn - value_out;
     194     5191504 :     if (!MoneyRange(txfee_aux)) {
     195           0 :         return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-fee-outofrange");
     196             :     }
     197             : 
     198     5191504 :     txfee = txfee_aux;
     199     5191504 :     return true;
     200     5191532 : }

Generated by: LCOV version 1.15