|
13 | 13 | #include "chain.h"
|
14 | 14 | #include "coins.h"
|
15 | 15 | #include "utilmoneystr.h"
|
16 |
| - |
| 16 | + |
17 | 17 | bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
|
18 | 18 | {
|
19 | 19 | if (tx.nLockTime == 0)
|
@@ -207,44 +207,46 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe
|
207 | 207 |
|
208 | 208 | bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight)
|
209 | 209 | {
|
210 |
| - // This doesn't trigger the DoS code on purpose; if it did, it would make it easier |
211 |
| - // for an attacker to attempt to split the network. |
212 |
| - if (!inputs.HaveInputs(tx)) |
213 |
| - return state.Invalid(false, 0, "", "Inputs unavailable"); |
214 |
| - |
215 |
| - CAmount nValueIn = 0; |
216 |
| - CAmount nFees = 0; |
217 |
| - for (unsigned int i = 0; i < tx.vin.size(); i++) |
218 |
| - { |
219 |
| - const COutPoint &prevout = tx.vin[i].prevout; |
220 |
| - const Coin& coin = inputs.AccessCoin(prevout); |
221 |
| - assert(!coin.IsSpent()); |
222 |
| - |
223 |
| - // If prev is coinbase, check that it's matured |
224 |
| - if (coin.IsCoinBase()) { |
225 |
| - if (nSpendHeight - coin.nHeight < COINBASE_MATURITY) |
226 |
| - return state.Invalid(false, |
227 |
| - REJECT_INVALID, "bad-txns-premature-spend-of-coinbase", |
228 |
| - strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight)); |
229 |
| - } |
230 |
| - |
231 |
| - // Check for negative or overflow input values |
232 |
| - nValueIn += coin.out.nValue; |
233 |
| - if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) |
234 |
| - return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputvalues-outofrange"); |
| 210 | + // This doesn't trigger the DoS code on purpose; if it did, it would make it easier |
| 211 | + // for an attacker to attempt to split the network. |
| 212 | + if (!inputs.HaveInputs(tx)) { |
| 213 | + return state.Invalid(false, 0, "", "Inputs unavailable"); |
| 214 | + } |
| 215 | + |
| 216 | + CAmount nValueIn = 0; |
| 217 | + CAmount nFees = 0; |
| 218 | + for (unsigned int i = 0; i < tx.vin.size(); ++i) { |
| 219 | + const COutPoint &prevout = tx.vin[i].prevout; |
| 220 | + const Coin& coin = inputs.AccessCoin(prevout); |
| 221 | + assert(!coin.IsSpent()); |
| 222 | + |
| 223 | + // If prev is coinbase, check that it's matured |
| 224 | + if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) { |
| 225 | + return state.Invalid(false, |
| 226 | + REJECT_INVALID, "bad-txns-premature-spend-of-coinbase", |
| 227 | + strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight)); |
| 228 | + } |
235 | 229 |
|
| 230 | + // Check for negative or overflow input values |
| 231 | + nValueIn += coin.out.nValue; |
| 232 | + if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) { |
| 233 | + return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputvalues-outofrange"); |
236 | 234 | }
|
| 235 | + } |
| 236 | + |
| 237 | + if (nValueIn < tx.GetValueOut()) { |
| 238 | + return state.DoS(100, false, REJECT_INVALID, "bad-txns-in-belowout", false, |
| 239 | + strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(tx.GetValueOut()))); |
| 240 | + } |
237 | 241 |
|
238 |
| - if (nValueIn < tx.GetValueOut()) |
239 |
| - return state.DoS(100, false, REJECT_INVALID, "bad-txns-in-belowout", false, |
240 |
| - strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(tx.GetValueOut()))); |
241 |
| - |
242 |
| - // Tally transaction fees |
243 |
| - CAmount nTxFee = nValueIn - tx.GetValueOut(); |
244 |
| - if (nTxFee < 0) |
245 |
| - return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-negative"); |
246 |
| - nFees += nTxFee; |
247 |
| - if (!MoneyRange(nFees)) |
248 |
| - return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-outofrange"); |
| 242 | + // Tally transaction fees |
| 243 | + CAmount nTxFee = nValueIn - tx.GetValueOut(); |
| 244 | + if (nTxFee < 0) { |
| 245 | + return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-negative"); |
| 246 | + } |
| 247 | + nFees += nTxFee; |
| 248 | + if (!MoneyRange(nFees)) { |
| 249 | + return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-outofrange"); |
| 250 | + } |
249 | 251 | return true;
|
250 | 252 | }
|
0 commit comments