/root/bitcoin/src/consensus/tx_verify.cpp
| Line | Count | Source | 
| 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/check.h> | 
| 15 |  | #include <util/moneystr.h> | 
| 16 |  |  | 
| 17 |  | bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime) | 
| 18 | 0 | { | 
| 19 | 0 |     if (tx.nLockTime == 0) | 
| 20 | 0 |         return true; | 
| 21 | 0 |     if ((int64_t)tx.nLockTime < ((int64_t)tx.nLockTime < LOCKTIME_THRESHOLD ? (int64_t)nBlockHeight : nBlockTime)) | 
| 22 | 0 |         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 | 0 |     for (const auto& txin : tx.vin) { | 
| 33 | 0 |         if (!(txin.nSequence == CTxIn::SEQUENCE_FINAL)) | 
| 34 | 0 |             return false; | 
| 35 | 0 |     } | 
| 36 | 0 |     return true; | 
| 37 | 0 | } | 
| 38 |  |  | 
| 39 |  | std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block) | 
| 40 | 0 | { | 
| 41 | 0 |     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 | 0 |     int nMinHeight = -1; | 
| 49 | 0 |     int64_t nMinTime = -1; | 
| 50 |  | 
 | 
| 51 | 0 |     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 | 0 |     if (!fEnforceBIP68) { | 
| 56 | 0 |         return std::make_pair(nMinHeight, nMinTime); | 
| 57 | 0 |     } | 
| 58 |  |  | 
| 59 | 0 |     for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) { | 
| 60 | 0 |         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 | 0 |         if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) { | 
| 66 |  |             // The height of this input is not relevant for sequence locks | 
| 67 | 0 |             prevHeights[txinIndex] = 0; | 
| 68 | 0 |             continue; | 
| 69 | 0 |         } | 
| 70 |  |  | 
| 71 | 0 |         int nCoinHeight = prevHeights[txinIndex]; | 
| 72 |  | 
 | 
| 73 | 0 |         if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) { | 
| 74 | 0 |             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 | 0 |             nMinTime = std::max(nMinTime, nCoinTime + (int64_t)((txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) << CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) - 1); | 
| 89 | 0 |         } else { | 
| 90 | 0 |             nMinHeight = std::max(nMinHeight, nCoinHeight + (int)(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1); | 
| 91 | 0 |         } | 
| 92 | 0 |     } | 
| 93 |  | 
 | 
| 94 | 0 |     return std::make_pair(nMinHeight, nMinTime); | 
| 95 | 0 | } | 
| 96 |  |  | 
| 97 |  | bool EvaluateSequenceLocks(const CBlockIndex& block, std::pair<int, int64_t> lockPair) | 
| 98 | 0 | { | 
| 99 | 0 |     assert(block.pprev); | 
| 100 | 0 |     int64_t nBlockTime = block.pprev->GetMedianTimePast(); | 
| 101 | 0 |     if (lockPair.first >= block.nHeight || lockPair.second >= nBlockTime) | 
| 102 | 0 |         return false; | 
| 103 |  |  | 
| 104 | 0 |     return true; | 
| 105 | 0 | } | 
| 106 |  |  | 
| 107 |  | bool SequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block) | 
| 108 | 0 | { | 
| 109 | 0 |     return EvaluateSequenceLocks(block, CalculateSequenceLocks(tx, flags, prevHeights, block)); | 
| 110 | 0 | } | 
| 111 |  |  | 
| 112 |  | unsigned int GetLegacySigOpCount(const CTransaction& tx) | 
| 113 | 0 | { | 
| 114 | 0 |     unsigned int nSigOps = 0; | 
| 115 | 0 |     for (const auto& txin : tx.vin) | 
| 116 | 0 |     { | 
| 117 | 0 |         nSigOps += txin.scriptSig.GetSigOpCount(false); | 
| 118 | 0 |     } | 
| 119 | 0 |     for (const auto& txout : tx.vout) | 
| 120 | 0 |     { | 
| 121 | 0 |         nSigOps += txout.scriptPubKey.GetSigOpCount(false); | 
| 122 | 0 |     } | 
| 123 | 0 |     return nSigOps; | 
| 124 | 0 | } | 
| 125 |  |  | 
| 126 |  | unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs) | 
| 127 | 0 | { | 
| 128 | 0 |     if (tx.IsCoinBase()) | 
| 129 | 0 |         return 0; | 
| 130 |  |  | 
| 131 | 0 |     unsigned int nSigOps = 0; | 
| 132 | 0 |     for (unsigned int i = 0; i < tx.vin.size(); i++) | 
| 133 | 0 |     { | 
| 134 | 0 |         const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout); | 
| 135 | 0 |         assert(!coin.IsSpent()); | 
| 136 | 0 |         const CTxOut &prevout = coin.out; | 
| 137 | 0 |         if (prevout.scriptPubKey.IsPayToScriptHash()) | 
| 138 | 0 |             nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig); | 
| 139 | 0 |     } | 
| 140 | 0 |     return nSigOps; | 
| 141 | 0 | } | 
| 142 |  |  | 
| 143 |  | int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, uint32_t flags) | 
| 144 | 0 | { | 
| 145 | 0 |     int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR; | 
| 146 |  | 
 | 
| 147 | 0 |     if (tx.IsCoinBase()) | 
| 148 | 0 |         return nSigOps; | 
| 149 |  |  | 
| 150 | 0 |     if (flags & SCRIPT_VERIFY_P2SH) { | 
| 151 | 0 |         nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR; | 
| 152 | 0 |     } | 
| 153 |  | 
 | 
| 154 | 0 |     for (unsigned int i = 0; i < tx.vin.size(); i++) | 
| 155 | 0 |     { | 
| 156 | 0 |         const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout); | 
| 157 | 0 |         assert(!coin.IsSpent()); | 
| 158 | 0 |         const CTxOut &prevout = coin.out; | 
| 159 | 0 |         nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, &tx.vin[i].scriptWitness, flags); | 
| 160 | 0 |     } | 
| 161 | 0 |     return nSigOps; | 
| 162 | 0 | } | 
| 163 |  |  | 
| 164 |  | bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee) | 
| 165 | 0 | { | 
| 166 |  |     // are the actual inputs available? | 
| 167 | 0 |     if (!inputs.HaveInputs(tx)) { | 
| 168 | 0 |         return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent", | 
| 169 | 0 |                          strprintf("%s: inputs missing/spent", __func__)); | 
| 170 | 0 |     } | 
| 171 |  |  | 
| 172 | 0 |     CAmount nValueIn = 0; | 
| 173 | 0 |     for (unsigned int i = 0; i < tx.vin.size(); ++i) { | 
| 174 | 0 |         const COutPoint &prevout = tx.vin[i].prevout; | 
| 175 | 0 |         const Coin& coin = inputs.AccessCoin(prevout); | 
| 176 | 0 |         assert(!coin.IsSpent()); | 
| 177 |  |  | 
| 178 |  |         // If prev is coinbase, check that it's matured | 
| 179 | 0 |         if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) { | 
| 180 | 0 |             return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "bad-txns-premature-spend-of-coinbase", | 
| 181 | 0 |                 strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight)); | 
| 182 | 0 |         } | 
| 183 |  |  | 
| 184 |  |         // Check for negative or overflow input values | 
| 185 | 0 |         nValueIn += coin.out.nValue; | 
| 186 | 0 |         if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) { | 
| 187 | 0 |             return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputvalues-outofrange"); | 
| 188 | 0 |         } | 
| 189 | 0 |     } | 
| 190 |  |  | 
| 191 | 0 |     const CAmount value_out = tx.GetValueOut(); | 
| 192 | 0 |     if (nValueIn < value_out) { | 
| 193 | 0 |         return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-in-belowout", | 
| 194 | 0 |             strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out))); | 
| 195 | 0 |     } | 
| 196 |  |  | 
| 197 |  |     // Tally transaction fees | 
| 198 | 0 |     const CAmount txfee_aux = nValueIn - value_out; | 
| 199 | 0 |     if (!MoneyRange(txfee_aux)) { | 
| 200 | 0 |         return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-fee-outofrange"); | 
| 201 | 0 |     } | 
| 202 |  |  | 
| 203 | 0 |     txfee = txfee_aux; | 
| 204 | 0 |     return true; | 
| 205 | 0 | } |