tx_verify.cpp raw

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