|
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