LCOV - code coverage report
Current view: top level - src/consensus - tx_verify.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 110 119 92.4 %
Date: 2022-04-21 14:51:19 Functions: 8 8 100.0 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 53 58 91.4 %

           Branch data     Line data    Source code
#       1                 :            : // Copyright (c) 2017-2021 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 <chain.h>
#       8                 :            : #include <coins.h>
#       9                 :            : #include <consensus/amount.h>
#      10                 :            : #include <consensus/consensus.h>
#      11                 :            : #include <consensus/validation.h>
#      12                 :            : #include <primitives/transaction.h>
#      13                 :            : #include <script/interpreter.h>
#      14                 :            : #include <util/moneystr.h>
#      15                 :            : 
#      16                 :            : bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
#      17                 :     201432 : {
#      18         [ +  + ]:     201432 :     if (tx.nLockTime == 0)
#      19                 :     175734 :         return true;
#      20 [ +  + ][ +  + ]:      25698 :     if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
#      21                 :      25606 :         return true;
#      22                 :            : 
#      23                 :            :     // Even if tx.nLockTime isn't satisfied by nBlockHeight/nBlockTime, a
#      24                 :            :     // transaction is still considered final if all inputs' nSequence ==
#      25                 :            :     // SEQUENCE_FINAL (0xffffffff), in which case nLockTime is ignored.
#      26                 :            :     //
#      27                 :            :     // Because of this behavior OP_CHECKLOCKTIMEVERIFY/CheckLockTime() will
#      28                 :            :     // also check that the spending input's nSequence != SEQUENCE_FINAL,
#      29                 :            :     // ensuring that an unsatisfied nLockTime value will actually cause
#      30                 :            :     // IsFinalTx() to return false here:
#      31         [ +  + ]:         92 :     for (const auto& txin : tx.vin) {
#      32         [ +  + ]:         92 :         if (!(txin.nSequence == CTxIn::SEQUENCE_FINAL))
#      33                 :         86 :             return false;
#      34                 :         92 :     }
#      35                 :          6 :     return true;
#      36                 :         92 : }
#      37                 :            : 
#      38                 :            : std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block)
#      39                 :      94389 : {
#      40                 :      94389 :     assert(prevHeights.size() == tx.vin.size());
#      41                 :            : 
#      42                 :            :     // Will be set to the equivalent height- and time-based nLockTime
#      43                 :            :     // values that would be necessary to satisfy all relative lock-
#      44                 :            :     // time constraints given our view of block chain history.
#      45                 :            :     // The semantics of nLockTime are the last invalid height/time, so
#      46                 :            :     // use -1 to have the effect of any height or time being valid.
#      47                 :          0 :     int nMinHeight = -1;
#      48                 :      94389 :     int64_t nMinTime = -1;
#      49                 :            : 
#      50                 :            :     // tx.nVersion is signed integer so requires cast to unsigned otherwise
#      51                 :            :     // we would be doing a signed comparison and half the range of nVersion
#      52                 :            :     // wouldn't support BIP 68.
#      53         [ +  + ]:      94389 :     bool fEnforceBIP68 = static_cast<uint32_t>(tx.nVersion) >= 2
#      54         [ +  + ]:      94389 :                       && flags & LOCKTIME_VERIFY_SEQUENCE;
#      55                 :            : 
#      56                 :            :     // Do not enforce sequence numbers as a relative lock time
#      57                 :            :     // unless we have been instructed to
#      58         [ +  + ]:      94389 :     if (!fEnforceBIP68) {
#      59                 :       6555 :         return std::make_pair(nMinHeight, nMinTime);
#      60                 :       6555 :     }
#      61                 :            : 
#      62         [ +  + ]:     244810 :     for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
#      63                 :     156976 :         const CTxIn& txin = tx.vin[txinIndex];
#      64                 :            : 
#      65                 :            :         // Sequence numbers with the most significant bit set are not
#      66                 :            :         // treated as relative lock-times, nor are they given any
#      67                 :            :         // consensus-enforced meaning at this point.
#      68         [ +  + ]:     156976 :         if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) {
#      69                 :            :             // The height of this input is not relevant for sequence locks
#      70                 :      81571 :             prevHeights[txinIndex] = 0;
#      71                 :      81571 :             continue;
#      72                 :      81571 :         }
#      73                 :            : 
#      74                 :      75405 :         int nCoinHeight = prevHeights[txinIndex];
#      75                 :            : 
#      76         [ +  + ]:      75405 :         if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) {
#      77                 :        464 :             int64_t nCoinTime = block.GetAncestor(std::max(nCoinHeight-1, 0))->GetMedianTimePast();
#      78                 :            :             // NOTE: Subtract 1 to maintain nLockTime semantics
#      79                 :            :             // BIP 68 relative lock times have the semantics of calculating
#      80                 :            :             // the first block or time at which the transaction would be
#      81                 :            :             // valid. When calculating the effective block time or height
#      82                 :            :             // for the entire transaction, we switch to using the
#      83                 :            :             // semantics of nLockTime which is the last invalid block
#      84                 :            :             // time or height.  Thus we subtract 1 from the calculated
#      85                 :            :             // time or height.
#      86                 :            : 
#      87                 :            :             // Time-based relative lock-times are measured from the
#      88                 :            :             // smallest allowed timestamp of the block containing the
#      89                 :            :             // txout being spent, which is the median time past of the
#      90                 :            :             // block prior.
#      91                 :        464 :             nMinTime = std::max(nMinTime, nCoinTime + (int64_t)((txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) << CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) - 1);
#      92                 :      74941 :         } else {
#      93                 :      74941 :             nMinHeight = std::max(nMinHeight, nCoinHeight + (int)(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1);
#      94                 :      74941 :         }
#      95                 :      75405 :     }
#      96                 :            : 
#      97                 :      87834 :     return std::make_pair(nMinHeight, nMinTime);
#      98                 :      94389 : }
#      99                 :            : 
#     100                 :            : bool EvaluateSequenceLocks(const CBlockIndex& block, std::pair<int, int64_t> lockPair)
#     101                 :      95192 : {
#     102                 :      95192 :     assert(block.pprev);
#     103                 :          0 :     int64_t nBlockTime = block.pprev->GetMedianTimePast();
#     104 [ +  + ][ +  + ]:      95192 :     if (lockPair.first >= block.nHeight || lockPair.second >= nBlockTime)
#     105                 :        396 :         return false;
#     106                 :            : 
#     107                 :      94796 :     return true;
#     108                 :      95192 : }
#     109                 :            : 
#     110                 :            : bool SequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block)
#     111                 :      61475 : {
#     112                 :      61475 :     return EvaluateSequenceLocks(block, CalculateSequenceLocks(tx, flags, prevHeights, block));
#     113                 :      61475 : }
#     114                 :            : 
#     115                 :            : unsigned int GetLegacySigOpCount(const CTransaction& tx)
#     116                 :     423496 : {
#     117                 :     423496 :     unsigned int nSigOps = 0;
#     118         [ +  + ]:     423496 :     for (const auto& txin : tx.vin)
#     119                 :     544521 :     {
#     120                 :     544521 :         nSigOps += txin.scriptSig.GetSigOpCount(false);
#     121                 :     544521 :     }
#     122         [ +  + ]:     423496 :     for (const auto& txout : tx.vout)
#     123                 :    1365102 :     {
#     124                 :    1365102 :         nSigOps += txout.scriptPubKey.GetSigOpCount(false);
#     125                 :    1365102 :     }
#     126                 :     423496 :     return nSigOps;
#     127                 :     423496 : }
#     128                 :            : 
#     129                 :            : unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
#     130                 :      93664 : {
#     131         [ -  + ]:      93664 :     if (tx.IsCoinBase())
#     132                 :          0 :         return 0;
#     133                 :            : 
#     134                 :      93664 :     unsigned int nSigOps = 0;
#     135         [ +  + ]:     258568 :     for (unsigned int i = 0; i < tx.vin.size(); i++)
#     136                 :     164904 :     {
#     137                 :     164904 :         const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
#     138                 :     164904 :         assert(!coin.IsSpent());
#     139                 :          0 :         const CTxOut &prevout = coin.out;
#     140         [ +  + ]:     164904 :         if (prevout.scriptPubKey.IsPayToScriptHash())
#     141                 :      10148 :             nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
#     142                 :     164904 :     }
#     143                 :      93664 :     return nSigOps;
#     144                 :      93664 : }
#     145                 :            : 
#     146                 :            : int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, uint32_t flags)
#     147                 :     187641 : {
#     148                 :     187641 :     int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR;
#     149                 :            : 
#     150         [ +  + ]:     187641 :     if (tx.IsCoinBase())
#     151                 :      93983 :         return nSigOps;
#     152                 :            : 
#     153         [ +  - ]:      93658 :     if (flags & SCRIPT_VERIFY_P2SH) {
#     154                 :      93658 :         nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR;
#     155                 :      93658 :     }
#     156                 :            : 
#     157         [ +  + ]:     258548 :     for (unsigned int i = 0; i < tx.vin.size(); i++)
#     158                 :     164890 :     {
#     159                 :     164890 :         const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
#     160                 :     164890 :         assert(!coin.IsSpent());
#     161                 :          0 :         const CTxOut &prevout = coin.out;
#     162                 :     164890 :         nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, &tx.vin[i].scriptWitness, flags);
#     163                 :     164890 :     }
#     164                 :      93658 :     return nSigOps;
#     165                 :     187641 : }
#     166                 :            : 
#     167                 :            : bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee)
#     168                 :   11107126 : {
#     169                 :            :     // are the actual inputs available?
#     170         [ +  + ]:   11107126 :     if (!inputs.HaveInputs(tx)) {
#     171                 :         23 :         return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent",
#     172                 :         23 :                          strprintf("%s: inputs missing/spent", __func__));
#     173                 :         23 :     }
#     174                 :            : 
#     175                 :   11107103 :     CAmount nValueIn = 0;
#     176         [ +  + ]:   25301592 :     for (unsigned int i = 0; i < tx.vin.size(); ++i) {
#     177                 :   14194496 :         const COutPoint &prevout = tx.vin[i].prevout;
#     178                 :   14194496 :         const Coin& coin = inputs.AccessCoin(prevout);
#     179                 :   14194496 :         assert(!coin.IsSpent());
#     180                 :            : 
#     181                 :            :         // If prev is coinbase, check that it's matured
#     182 [ +  + ][ +  + ]:   14194496 :         if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
#     183                 :          7 :             return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "bad-txns-premature-spend-of-coinbase",
#     184                 :          7 :                 strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
#     185                 :          7 :         }
#     186                 :            : 
#     187                 :            :         // Check for negative or overflow input values
#     188                 :   14194489 :         nValueIn += coin.out.nValue;
#     189 [ -  + ][ -  + ]:   14194489 :         if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) {
#     190                 :          0 :             return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputvalues-outofrange");
#     191                 :          0 :         }
#     192                 :   14194489 :     }
#     193                 :            : 
#     194                 :   11107096 :     const CAmount value_out = tx.GetValueOut();
#     195         [ +  + ]:   11107096 :     if (nValueIn < value_out) {
#     196                 :          4 :         return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-in-belowout",
#     197                 :          4 :             strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out)));
#     198                 :          4 :     }
#     199                 :            : 
#     200                 :            :     // Tally transaction fees
#     201                 :   11107092 :     const CAmount txfee_aux = nValueIn - value_out;
#     202         [ -  + ]:   11107092 :     if (!MoneyRange(txfee_aux)) {
#     203                 :          0 :         return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-fee-outofrange");
#     204                 :          0 :     }
#     205                 :            : 
#     206                 :   11107092 :     txfee = txfee_aux;
#     207                 :   11107092 :     return true;
#     208                 :   11107092 : }

Generated by: LCOV version 0-eol-96201-ge66f56f4af6a