tx_verify.cpp raw

   1  // Copyright (c) 2017-2021 The Limenka 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/ct.h>
  12  #include <consensus/validation.h>
  13  #include <crypto/bulletproofs.h>
  14  #include <hash.h>
  15  #include <primitives/transaction.h>
  16  #include <script/interpreter.h>
  17  #include <uint256.h>
  18  #include <util/check.h>
  19  #include <util/moneystr.h>
  20  
  21  bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
  22  {
  23      if (tx.nLockTime == 0)
  24          return true;
  25      if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime))
  26          return true;
  27  
  28      // Even if tx.nLockTime isn't satisfied by nBlockHeight/nBlockTime, a
  29      // transaction is still considered final if all inputs' nSequence ==
  30      // SEQUENCE_FINAL (0xffffffff), in which case nLockTime is ignored.
  31      //
  32      // Because of this behavior OP_CHECKLOCKTIMEVERIFY/CheckLockTime() will
  33      // also check that the spending input's nSequence != SEQUENCE_FINAL,
  34      // ensuring that an unsatisfied nLockTime value will actually cause
  35      // IsFinalTx() to return false here:
  36      for (const auto& txin : tx.vin) {
  37          if (!(txin.nSequence == CTxIn::SEQUENCE_FINAL))
  38              return false;
  39      }
  40      return true;
  41  }
  42  
  43  std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block)
  44  {
  45      assert(prevHeights.size() == tx.vin.size());
  46  
  47      // Will be set to the equivalent height- and time-based nLockTime
  48      // values that would be necessary to satisfy all relative lock-
  49      // time constraints given our view of block chain history.
  50      // The semantics of nLockTime are the last invalid height/time, so
  51      // use -1 to have the effect of any height or time being valid.
  52      int nMinHeight = -1;
  53      int64_t nMinTime = -1;
  54  
  55      bool fEnforceBIP68 = tx.version >= 2 && flags & LOCKTIME_VERIFY_SEQUENCE;
  56  
  57      // Do not enforce sequence numbers as a relative lock time
  58      // unless we have been instructed to
  59      if (!fEnforceBIP68) {
  60          return std::make_pair(nMinHeight, nMinTime);
  61      }
  62  
  63      for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
  64          const CTxIn& txin = tx.vin[txinIndex];
  65  
  66          // Sequence numbers with the most significant bit set are not
  67          // treated as relative lock-times, nor are they given any
  68          // consensus-enforced meaning at this point.
  69          if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) {
  70              // The height of this input is not relevant for sequence locks
  71              prevHeights[txinIndex] = 0;
  72              continue;
  73          }
  74  
  75          int nCoinHeight = prevHeights[txinIndex];
  76  
  77          if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) {
  78              const int64_t nCoinTime{Assert(block.GetAncestor(std::max(nCoinHeight - 1, 0)))->GetMedianTimePast()};
  79              // NOTE: Subtract 1 to maintain nLockTime semantics
  80              // BIP 68 relative lock times have the semantics of calculating
  81              // the first block or time at which the transaction would be
  82              // valid. When calculating the effective block time or height
  83              // for the entire transaction, we switch to using the
  84              // semantics of nLockTime which is the last invalid block
  85              // time or height.  Thus we subtract 1 from the calculated
  86              // time or height.
  87  
  88              // Time-based relative lock-times are measured from the
  89              // smallest allowed timestamp of the block containing the
  90              // txout being spent, which is the median time past of the
  91              // block prior.
  92              nMinTime = std::max(nMinTime, nCoinTime + (int64_t)((txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) << CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) - 1);
  93          } else {
  94              nMinHeight = std::max(nMinHeight, nCoinHeight + (int)(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1);
  95          }
  96      }
  97  
  98      return std::make_pair(nMinHeight, nMinTime);
  99  }
 100  
 101  bool EvaluateSequenceLocks(const CBlockIndex& block, std::pair<int, int64_t> lockPair)
 102  {
 103      assert(block.pprev);
 104      int64_t nBlockTime = block.pprev->GetMedianTimePast();
 105      if (lockPair.first >= block.nHeight || lockPair.second >= nBlockTime)
 106          return false;
 107  
 108      return true;
 109  }
 110  
 111  bool SequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block)
 112  {
 113      return EvaluateSequenceLocks(block, CalculateSequenceLocks(tx, flags, prevHeights, block));
 114  }
 115  
 116  unsigned int GetLegacySigOpCount(const CTransaction& tx)
 117  {
 118      unsigned int nSigOps = 0;
 119      for (const auto& txin : tx.vin)
 120      {
 121          nSigOps += txin.scriptSig.GetSigOpCount(false);
 122      }
 123      for (const auto& txout : tx.vout)
 124      {
 125          nSigOps += txout.scriptPubKey.GetSigOpCount(false);
 126      }
 127      return nSigOps;
 128  }
 129  
 130  unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
 131  {
 132      if (tx.IsCoinBase())
 133          return 0;
 134  
 135      unsigned int nSigOps = 0;
 136      for (unsigned int i = 0; i < tx.vin.size(); i++)
 137      {
 138          const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
 139          assert(!coin.IsSpent());
 140          const CTxOut &prevout = coin.out;
 141          if (prevout.scriptPubKey.IsPayToScriptHash())
 142              nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
 143      }
 144      return nSigOps;
 145  }
 146  
 147  int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, uint32_t flags)
 148  {
 149      int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR;
 150  
 151      if (tx.IsCoinBase())
 152          return nSigOps;
 153  
 154      if (flags & SCRIPT_VERIFY_P2SH) {
 155          nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR;
 156      }
 157  
 158      for (unsigned int i = 0; i < tx.vin.size(); i++)
 159      {
 160          const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
 161          assert(!coin.IsSpent());
 162          const CTxOut &prevout = coin.out;
 163          nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, &tx.vin[i].scriptWitness, flags);
 164      }
 165      return nSigOps;
 166  }
 167  
 168  static bool IsP2BPCT(const CScript& spk)
 169  {
 170      int witver; std::vector<uint8_t> witprog;
 171      return spk.IsWitnessProgram(witver, witprog) &&
 172             witver == 4 && witprog.size() == WITNESS_V4_BPCT_SIZE;
 173  }
 174  
 175  bool Consensus::CheckOutputSizes(const CTransaction& tx, TxValidationState& state)
 176  {
 177      for (const auto& txout : tx.vout) {
 178          if (txout.scriptPubKey.empty()) continue;
 179          // CT outputs (witness v4 commitments, 35 bytes) and CT kernel
 180          // outputs (OP_RETURN "BK" ...) exceed the RDTS reduced-data caps
 181          // by construction; their own consensus rules bound their size.
 182          if (IsP2BPCT(txout.scriptPubKey) || IsCTKernelScript(txout.scriptPubKey)) continue;
 183          if (txout.scriptPubKey.size() > ((txout.scriptPubKey[0] == OP_RETURN) ? MAX_OUTPUT_DATA_SIZE : MAX_OUTPUT_SCRIPT_SIZE)) {
 184              return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-script-toolarge");
 185          }
 186      }
 187      return true;
 188  }
 189  
 190  // Fork confidential-transaction rules.  A CT transaction has CT outputs
 191  // (and optionally CT inputs); transparent inputs are allowed as a mint
 192  // path: their visible value enters the kernel balance with zero blinding
 193  // and their script signatures authorize the spend separately.
 194  // On success sets ct_fee to the explicit fee from the kernel output.
 195  static bool CheckCTTransaction(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, CAmount& ct_fee, bool& is_ct_tx)
 196  {
 197      bool has_ct_input = false, has_ct_output = false;
 198      for (const auto& txin : tx.vin) {
 199          if (IsP2BPCT(inputs.AccessCoin(txin.prevout).out.scriptPubKey)) { has_ct_input = true; break; }
 200      }
 201      for (const auto& txout : tx.vout) {
 202          if (IsP2BPCT(txout.scriptPubKey)) { has_ct_output = true; break; }
 203      }
 204      // CT-ness is defined by inputs/outputs, NOT by the presence of a
 205      // kernel-shaped output: a transparent tx carrying a bare OP_RETURN
 206      // "BK" output must not have its fee zeroed (and a real CT tx without
 207      // a kernel is rejected below).
 208      is_ct_tx = has_ct_input || has_ct_output;
 209      if (!has_ct_input && !has_ct_output) return true; // not a confidential transaction
 210  
 211      std::vector<std::vector<uint8_t>> in_commitments, out_commitments;
 212      std::vector<CAmount> transparent_in_values;
 213      for (const auto& txin : tx.vin) {
 214          const Coin& coin = inputs.AccessCoin(txin.prevout);
 215          int witver; std::vector<uint8_t> witprog;
 216          if (coin.out.scriptPubKey.IsWitnessProgram(witver, witprog) &&
 217              witver == 4 && witprog.size() == WITNESS_V4_BPCT_SIZE) {
 218              in_commitments.push_back(std::move(witprog));
 219              continue;
 220          }
 221          // Transparent mint input: its value is visible and enters the
 222          // balance equation; script verification handles authorization.
 223          const CAmount value_attosats = coin.out.nValue * ATTOSATS_PER_SATOSHI;
 224          if (coin.out.nValue < 0) {
 225              return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-ct-mint-value",
 226                  "confidential transaction has a negative transparent input");
 227          }
 228          transparent_in_values.push_back(value_attosats);
 229      }
 230  
 231      const int kernel_index = GetCTKernelOutputIndex(tx);
 232      if (kernel_index == NO_CT_KERNEL_OUTPUT) {
 233          return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-ct-no-kernel",
 234              "confidential transaction missing kernel output");
 235      }
 236      for (size_t i = 0; i < tx.vout.size(); i++) {
 237          if (static_cast<int>(i) == kernel_index) continue;
 238          const CTxOut& txout = tx.vout[i];
 239          int witver; std::vector<uint8_t> witprog;
 240          if (!(txout.scriptPubKey.IsWitnessProgram(witver, witprog) &&
 241                witver == 4 && witprog.size() == WITNESS_V4_BPCT_SIZE)) {
 242              return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-ct-mixed-output",
 243                  "confidential transaction has a non-confidential output");
 244          }
 245          if (txout.nValue != 0) {
 246              return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-ct-value",
 247                  "confidential output has non-zero nValue");
 248          }
 249          out_commitments.push_back(std::move(witprog));
 250      }
 251  
 252      const auto kernel = ParseCTKernelOutput(tx.vout[kernel_index]);
 253      if (!kernel) {
 254          return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-ct-kernel-format",
 255              "malformed confidential transaction kernel output");
 256      }
 257      // The kernel output carries no spendable value; a non-zero nValue would
 258      // be silently burned (OP_RETURN), so reject it outright.
 259      if (tx.vout[kernel_index].nValue != 0) {
 260          return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-ct-kernel-value",
 261              "confidential transaction kernel output has non-zero nValue");
 262      }
 263  
 264      const uint256 msg = ComputeCTKernelMessage(tx, kernel_index, *kernel, transparent_in_values);
 265      if (!VerifyCTBalance(in_commitments, out_commitments, kernel->fee,
 266                           {msg.begin(), msg.end()}, kernel->sig,
 267                           transparent_in_values)) {
 268          return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-ct-balance",
 269              "confidential transaction balance check failed");
 270      }
 271      ct_fee = kernel->fee;
 272      return true;
 273  }
 274  
 275  bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee, const CheckTxInputsRules rules, const Consensus::Params& consensusParams, bool fork_active)
 276  {
 277      // are the actual inputs available?
 278      if (!inputs.HaveInputs(tx)) {
 279          return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent",
 280                           strprintf("%s: inputs missing/spent", __func__));
 281      }
 282  
 283      // NOTE: CheckTransaction is arguably the more logical place to do this, but it's context-independent, so this is probably the next best place for now
 284      if (rules.test(CheckTxInputsRules::OutputSizeLimit) && !CheckOutputSizes(tx, state)) {
 285          return false;
 286      }
 287  
 288      // Post-activation opcode whitelist: reject outputs with disallowed opcodes
 289      if (fork_active) {
 290          for (unsigned int i = 0; i < tx.vout.size(); ++i) {
 291              if (!CheckScriptOpcodeWhitelist(tx.vout[i].scriptPubKey)) {
 292                  return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-output-opcode-whitelist",
 293                      strprintf("%s: output %d contains disallowed opcode", __func__, i));
 294              }
 295          }
 296      }
 297  
 298      CAmount nValueIn = 0;
 299      for (unsigned int i = 0; i < tx.vin.size(); ++i) {
 300          const COutPoint &prevout = tx.vin[i].prevout;
 301          const Coin& coin = inputs.AccessCoin(prevout);
 302          assert(!coin.IsSpent());
 303  
 304          // If prev is coinbase, check that it's matured
 305          if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
 306              return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "bad-txns-premature-spend-of-coinbase",
 307                  strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
 308          }
 309  
 310          // Check for negative or overflow input values
 311          nValueIn += coin.out.nValue;
 312          if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) {
 313              return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputvalues-outofrange");
 314          }
 315      }
 316  
 317      const CAmount value_out = tx.GetValueOut();
 318      if (nValueIn < value_out) {
 319          return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-in-belowout",
 320              strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out)));
 321      }
 322  
 323      // Tally transaction fees
 324      const CAmount txfee_aux = nValueIn - value_out;
 325      if (!MoneyRange(txfee_aux)) {
 326          return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-fee-outofrange");
 327      }
 328  
 329      txfee = txfee_aux;
 330  
 331      // Fork confidential-transaction rules (no inflation via hidden amounts).
 332      // The explicit kernel fee is added to the transaction fee so miners
 333      // collect it in the coinbase.
 334      CAmount ct_fee = 0;
 335      bool is_ct_tx = false;
 336      if (fork_active && !CheckCTTransaction(tx, state, inputs, ct_fee, is_ct_tx)) {
 337          return false;
 338      }
 339      if (!fork_active) is_ct_tx = false;
 340      // CT committed values and the kernel fee are in attosats; the
 341      // transparent txfee domain is satoshis.  For a CT transaction the
 342      // kernel fee is the ONLY fee: transparent mint inputs' values move
 343      // into the confidential domain (balance enforced by the kernel), so
 344      // counting them as fee as well would double-pay the miner.  Floor
 345      // conversion keeps the sub-satoshi remainder burned.
 346      // Policy note: a kernel fee below one satoshi floors to txfee == 0,
 347      // so sub-satoshi CT fees cannot relay (minrelay rejects zero-fee
 348      // transactions); they remain consensus-valid for direct block mining.
 349      txfee = is_ct_tx ? ct_fee / ATTOSATS_PER_SATOSHI : txfee_aux;
 350      if (!MoneyRange(txfee)) {
 351          return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-fee-outofrange");
 352      }
 353  
 354      return true;
 355  }
 356  
 357  /** Post-activation opcode whitelist for output creation.
 358   *  Allows only: push ops, IF/ELSE/ENDIF, stack ops, HASH160, EQUAL, CLTV, CSV, CHECKSIG.
 359   *  This prevents creating complex scripts after fork activation. */
 360  bool Consensus::CheckScriptOpcodeWhitelist(const CScript& script)
 361  {
 362      // Whitelist of allowed opcodes
 363      static const std::set<opcodetype> allowed_opcodes = {
 364          // Push values
 365          OP_0, OP_1, OP_2, OP_3, OP_4, OP_5, OP_6, OP_7, OP_8, OP_9, OP_10, OP_11, OP_12, OP_13, OP_14, OP_15, OP_16,
 366          OP_1NEGATE,
 367          // Control
 368          OP_IF, OP_NOTIF, OP_ELSE, OP_ENDIF, OP_RETURN,
 369          // Stack ops (minimal set for basic scripts)
 370          OP_TOALTSTACK, OP_FROMALTSTACK, OP_DROP, OP_DUP, OP_NIP, OP_OVER, OP_PICK, OP_ROLL, OP_ROT, OP_SWAP, OP_TUCK,
 371          OP_IFDUP, OP_DEPTH, OP_2DROP, OP_2DUP, OP_3DUP, OP_2OVER, OP_2ROT, OP_2SWAP,
 372          // Crypto (the core whitelist)
 373          OP_HASH160, OP_HASH256, OP_SHA256, OP_RIPEMD160,
 374          OP_EQUAL, OP_EQUALVERIFY,
 375          OP_CHECKSIG, OP_CHECKSIGVERIFY, OP_CHECKSIGADD,
 376          OP_CHECKMULTISIG, OP_CHECKMULTISIGVERIFY,
 377          // Timelocks
 378          OP_CHECKLOCKTIMEVERIFY, OP_CHECKSEQUENCEVERIFY,
 379          // Numeric (basic)
 380          OP_ADD, OP_SUB, OP_ABS, OP_NOT, OP_0NOTEQUAL,
 381          OP_BOOLAND, OP_BOOLOR, OP_NUMEQUAL, OP_NUMEQUALVERIFY, OP_NUMNOTEQUAL,
 382          OP_LESSTHAN, OP_GREATERTHAN, OP_LESSTHANOREQUAL, OP_GREATERTHANOREQUAL,
 383          OP_MIN, OP_MAX, OP_WITHIN,
 384          OP_SIZE,
 385          // Misc
 386          OP_NOP, OP_VERIFY,
 387          OP_CODESEPARATOR,
 388      };
 389  
 390      CScript::const_iterator pc = script.begin();
 391      opcodetype opcode;
 392      while (pc < script.end()) {
 393          if (!script.GetOp(pc, opcode)) {
 394              return false;
 395          }
 396          // Skip push data (data pushes are always allowed)
 397          if (opcode <= OP_16) continue;
 398          // Check against whitelist
 399          if (allowed_opcodes.find(opcode) == allowed_opcodes.end()) {
 400              return false;
 401          }
 402      }
 403      return true;
 404  }
 405