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
15 #include <utilmoneystr.h>
17 bool IsFinalTx(const CTransaction
&tx
, int nBlockHeight
, int64_t nBlockTime
)
19 if (tx
.nLockTime
== 0)
21 if ((int64_t)tx
.nLockTime
< ((int64_t)tx
.nLockTime
< LOCKTIME_THRESHOLD
? (int64_t)nBlockHeight
: nBlockTime
))
23 for (const auto& txin
: tx
.vin
) {
24 if (!(txin
.nSequence
== CTxIn::SEQUENCE_FINAL
))
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.
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
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;
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
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
83 nMinTime
= std::max(nMinTime
, nCoinTime
+ (int64_t)((txin
.nSequence
& CTxIn::SEQUENCE_LOCKTIME_MASK
) << CTxIn::SEQUENCE_LOCKTIME_GRANULARITY
) - 1);
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
)
95 int64_t nBlockTime
= block
.pprev
->GetMedianTimePast();
96 if (lockPair
.first
>= block
.nHeight
|| lockPair
.second
>= nBlockTime
)
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);
121 unsigned int GetP2SHSigOpCount(const CTransaction
& tx
, const CCoinsViewCache
& inputs
)
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
);
138 int64_t GetTransactionSigOpCost(const CTransaction
& tx
, const CCoinsViewCache
& inputs
, int flags
)
140 int64_t nSigOps
= GetLegacySigOpCount(tx
) * WITNESS_SCALE_FACTOR
;
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
);
159 bool CheckTransaction(const CTransaction
& tx
, CValidationState
&state
, bool fCheckDuplicateInputs
)
161 // Basic checks that don't depend on any context
163 return state
.DoS(10, false, REJECT_INVALID
, "bad-txns-vin-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");
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");
200 for (const auto& txin
: tx
.vin
)
201 if (txin
.prevout
.IsNull())
202 return state
.DoS(10, false, REJECT_INVALID
, "bad-txns-prevout-null");
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");