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.
8 #include "primitives/transaction.h"
9 #include "script/interpreter.h"
10 #include "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 CTxOut
&prevout
= inputs
.AccessCoin(tx
.vin
[i
].prevout
).out
;
130 if (prevout
.scriptPubKey
.IsPayToScriptHash())
131 nSigOps
+= prevout
.scriptPubKey
.GetSigOpCount(tx
.vin
[i
].scriptSig
);
136 int64_t GetTransactionSigOpCost(const CTransaction
& tx
, const CCoinsViewCache
& inputs
, int flags
)
138 int64_t nSigOps
= GetLegacySigOpCount(tx
) * WITNESS_SCALE_FACTOR
;
143 if (flags
& SCRIPT_VERIFY_P2SH
) {
144 nSigOps
+= GetP2SHSigOpCount(tx
, inputs
) * WITNESS_SCALE_FACTOR
;
147 for (unsigned int i
= 0; i
< tx
.vin
.size(); i
++)
149 const CTxOut
&prevout
= inputs
.AccessCoin(tx
.vin
[i
].prevout
).out
;
150 nSigOps
+= CountWitnessSigOps(tx
.vin
[i
].scriptSig
, prevout
.scriptPubKey
, &tx
.vin
[i
].scriptWitness
, flags
);
155 bool CheckTransaction(const CTransaction
& tx
, CValidationState
&state
, bool fCheckDuplicateInputs
)
157 // Basic checks that don't depend on any context
159 return state
.DoS(10, false, REJECT_INVALID
, "bad-txns-vin-empty");
161 return state
.DoS(10, false, REJECT_INVALID
, "bad-txns-vout-empty");
162 // Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability)
163 if (::GetSerializeSize(tx
, SER_NETWORK
, PROTOCOL_VERSION
| SERIALIZE_TRANSACTION_NO_WITNESS
) > MAX_BLOCK_BASE_SIZE
)
164 return state
.DoS(100, false, REJECT_INVALID
, "bad-txns-oversize");
166 // Check for negative or overflow output values
167 CAmount nValueOut
= 0;
168 for (const auto& txout
: tx
.vout
)
170 if (txout
.nValue
< 0)
171 return state
.DoS(100, false, REJECT_INVALID
, "bad-txns-vout-negative");
172 if (txout
.nValue
> MAX_MONEY
)
173 return state
.DoS(100, false, REJECT_INVALID
, "bad-txns-vout-toolarge");
174 nValueOut
+= txout
.nValue
;
175 if (!MoneyRange(nValueOut
))
176 return state
.DoS(100, false, REJECT_INVALID
, "bad-txns-txouttotal-toolarge");
179 // Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock
180 if (fCheckDuplicateInputs
) {
181 std::set
<COutPoint
> vInOutPoints
;
182 for (const auto& txin
: tx
.vin
)
184 if (!vInOutPoints
.insert(txin
.prevout
).second
)
185 return state
.DoS(100, false, REJECT_INVALID
, "bad-txns-inputs-duplicate");
191 if (tx
.vin
[0].scriptSig
.size() < 2 || tx
.vin
[0].scriptSig
.size() > 100)
192 return state
.DoS(100, false, REJECT_INVALID
, "bad-cb-length");
196 for (const auto& txin
: tx
.vin
)
197 if (txin
.prevout
.IsNull())
198 return state
.DoS(10, false, REJECT_INVALID
, "bad-txns-prevout-null");
204 bool Consensus::CheckTxInputs(const CTransaction
& tx
, CValidationState
& state
, const CCoinsViewCache
& inputs
, int nSpendHeight
)
206 // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
207 // for an attacker to attempt to split the network.
208 if (!inputs
.HaveInputs(tx
))
209 return state
.Invalid(false, 0, "", "Inputs unavailable");
211 CAmount nValueIn
= 0;
213 for (unsigned int i
= 0; i
< tx
.vin
.size(); i
++)
215 const COutPoint
&prevout
= tx
.vin
[i
].prevout
;
216 const Coin
& coin
= inputs
.AccessCoin(prevout
);
217 assert(!coin
.IsSpent());
219 // If prev is coinbase, check that it's matured
220 if (coin
.IsCoinBase()) {
221 if (nSpendHeight
- coin
.nHeight
< COINBASE_MATURITY
)
222 return state
.Invalid(false,
223 REJECT_INVALID
, "bad-txns-premature-spend-of-coinbase",
224 strprintf("tried to spend coinbase at depth %d", nSpendHeight
- coin
.nHeight
));
227 // Check for negative or overflow input values
228 nValueIn
+= coin
.out
.nValue
;
229 if (!MoneyRange(coin
.out
.nValue
) || !MoneyRange(nValueIn
))
230 return state
.DoS(100, false, REJECT_INVALID
, "bad-txns-inputvalues-outofrange");
234 if (nValueIn
< tx
.GetValueOut())
235 return state
.DoS(100, false, REJECT_INVALID
, "bad-txns-in-belowout", false,
236 strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn
), FormatMoney(tx
.GetValueOut())));
238 // Tally transaction fees
239 CAmount nTxFee
= nValueIn
- tx
.GetValueOut();
241 return state
.DoS(100, false, REJECT_INVALID
, "bad-txns-fee-negative");
243 if (!MoneyRange(nFees
))
244 return state
.DoS(100, false, REJECT_INVALID
, "bad-txns-fee-outofrange");