Merge #12079: Improve prioritisetransaction test coverage
[bitcoinplatinum.git] / src / consensus / tx_verify.cpp
blobbe73d0a2f9f60305d20f8b91668a78271197f26c
1 // Copyright (c) 2017-2017 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.
5 #include <consensus/tx_verify.h>
7 #include <consensus/consensus.h>
8 #include <primitives/transaction.h>
9 #include <script/interpreter.h>
10 #include <consensus/validation.h>
12 // TODO remove the following dependencies
13 #include <chain.h>
14 #include <coins.h>
15 #include <utilmoneystr.h>
17 bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
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 for (const auto& txin : tx.vin) {
24 if (!(txin.nSequence == CTxIn::SEQUENCE_FINAL))
25 return false;
27 return true;
30 std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector<int>* prevHeights, const CBlockIndex& block)
32 assert(prevHeights->size() == tx.vin.size());
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 int nMinHeight = -1;
40 int64_t nMinTime = -1;
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 bool fEnforceBIP68 = static_cast<uint32_t>(tx.nVersion) >= 2
46 && flags & LOCKTIME_VERIFY_SEQUENCE;
48 // Do not enforce sequence numbers as a relative lock time
49 // unless we have been instructed to
50 if (!fEnforceBIP68) {
51 return std::make_pair(nMinHeight, nMinTime);
54 for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
55 const CTxIn& txin = tx.vin[txinIndex];
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 if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) {
61 // The height of this input is not relevant for sequence locks
62 (*prevHeights)[txinIndex] = 0;
63 continue;
66 int nCoinHeight = (*prevHeights)[txinIndex];
68 if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) {
69 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.
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 nMinTime = std::max(nMinTime, nCoinTime + (int64_t)((txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) << CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) - 1);
84 } else {
85 nMinHeight = std::max(nMinHeight, nCoinHeight + (int)(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1);
89 return std::make_pair(nMinHeight, nMinTime);
92 bool EvaluateSequenceLocks(const CBlockIndex& block, std::pair<int, int64_t> lockPair)
94 assert(block.pprev);
95 int64_t nBlockTime = block.pprev->GetMedianTimePast();
96 if (lockPair.first >= block.nHeight || lockPair.second >= nBlockTime)
97 return false;
99 return true;
102 bool SequenceLocks(const CTransaction &tx, int flags, std::vector<int>* prevHeights, const CBlockIndex& block)
104 return EvaluateSequenceLocks(block, CalculateSequenceLocks(tx, flags, prevHeights, block));
107 unsigned int GetLegacySigOpCount(const CTransaction& tx)
109 unsigned int nSigOps = 0;
110 for (const auto& txin : tx.vin)
112 nSigOps += txin.scriptSig.GetSigOpCount(false);
114 for (const auto& txout : tx.vout)
116 nSigOps += txout.scriptPubKey.GetSigOpCount(false);
118 return nSigOps;
121 unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
123 if (tx.IsCoinBase())
124 return 0;
126 unsigned int nSigOps = 0;
127 for (unsigned int i = 0; i < tx.vin.size(); i++)
129 const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
130 assert(!coin.IsSpent());
131 const CTxOut &prevout = coin.out;
132 if (prevout.scriptPubKey.IsPayToScriptHash())
133 nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
135 return nSigOps;
138 int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, int flags)
140 int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR;
142 if (tx.IsCoinBase())
143 return nSigOps;
145 if (flags & SCRIPT_VERIFY_P2SH) {
146 nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR;
149 for (unsigned int i = 0; i < tx.vin.size(); i++)
151 const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
152 assert(!coin.IsSpent());
153 const CTxOut &prevout = coin.out;
154 nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, &tx.vin[i].scriptWitness, flags);
156 return nSigOps;
159 bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fCheckDuplicateInputs)
161 // Basic checks that don't depend on any context
162 if (tx.vin.empty())
163 return state.DoS(10, false, REJECT_INVALID, "bad-txns-vin-empty");
164 if (tx.vout.empty())
165 return state.DoS(10, false, REJECT_INVALID, "bad-txns-vout-empty");
166 // Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability)
167 if (::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT)
168 return state.DoS(100, false, REJECT_INVALID, "bad-txns-oversize");
170 // Check for negative or overflow output values
171 CAmount nValueOut = 0;
172 for (const auto& txout : tx.vout)
174 if (txout.nValue < 0)
175 return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-negative");
176 if (txout.nValue > MAX_MONEY)
177 return state.DoS(100, false, REJECT_INVALID, "bad-txns-vout-toolarge");
178 nValueOut += txout.nValue;
179 if (!MoneyRange(nValueOut))
180 return state.DoS(100, false, REJECT_INVALID, "bad-txns-txouttotal-toolarge");
183 // Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock
184 if (fCheckDuplicateInputs) {
185 std::set<COutPoint> vInOutPoints;
186 for (const auto& txin : tx.vin)
188 if (!vInOutPoints.insert(txin.prevout).second)
189 return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-duplicate");
193 if (tx.IsCoinBase())
195 if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
196 return state.DoS(100, false, REJECT_INVALID, "bad-cb-length");
198 else
200 for (const auto& txin : tx.vin)
201 if (txin.prevout.IsNull())
202 return state.DoS(10, false, REJECT_INVALID, "bad-txns-prevout-null");
205 return true;
208 bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee)
210 // are the actual inputs available?
211 if (!inputs.HaveInputs(tx)) {
212 return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-missingorspent", false,
213 strprintf("%s: inputs missing/spent", __func__));
216 CAmount nValueIn = 0;
217 for (unsigned int i = 0; i < tx.vin.size(); ++i) {
218 const COutPoint &prevout = tx.vin[i].prevout;
219 const Coin& coin = inputs.AccessCoin(prevout);
220 assert(!coin.IsSpent());
222 // If prev is coinbase, check that it's matured
223 if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
224 return state.Invalid(false,
225 REJECT_INVALID, "bad-txns-premature-spend-of-coinbase",
226 strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
229 // Check for negative or overflow input values
230 nValueIn += coin.out.nValue;
231 if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) {
232 return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputvalues-outofrange");
236 const CAmount value_out = tx.GetValueOut();
237 if (nValueIn < value_out) {
238 return state.DoS(100, false, REJECT_INVALID, "bad-txns-in-belowout", false,
239 strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out)));
242 // Tally transaction fees
243 const CAmount txfee_aux = nValueIn - value_out;
244 if (!MoneyRange(txfee_aux)) {
245 return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-outofrange");
248 txfee = txfee_aux;
249 return true;