aboutsummaryrefslogtreecommitdiff
path: root/src/consensus/tx_verify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/consensus/tx_verify.cpp')
-rw-r--r--src/consensus/tx_verify.cpp76
1 files changed, 38 insertions, 38 deletions
diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp
index 0a71915d1d..70aa9d7006 100644
--- a/src/consensus/tx_verify.cpp
+++ b/src/consensus/tx_verify.cpp
@@ -13,7 +13,7 @@
#include "chain.h"
#include "coins.h"
#include "utilmoneystr.h"
-
+
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
{
if (tx.nLockTime == 0)
@@ -205,46 +205,46 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe
return true;
}
-bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight)
+bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee)
{
- // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
- // for an attacker to attempt to split the network.
- if (!inputs.HaveInputs(tx))
- return state.Invalid(false, 0, "", "Inputs unavailable");
-
- CAmount nValueIn = 0;
- CAmount nFees = 0;
- for (unsigned int i = 0; i < tx.vin.size(); i++)
- {
- const COutPoint &prevout = tx.vin[i].prevout;
- const Coin& coin = inputs.AccessCoin(prevout);
- assert(!coin.IsSpent());
-
- // If prev is coinbase, check that it's matured
- if (coin.IsCoinBase()) {
- if (nSpendHeight - coin.nHeight < COINBASE_MATURITY)
- return state.Invalid(false,
- REJECT_INVALID, "bad-txns-premature-spend-of-coinbase",
- strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
- }
-
- // Check for negative or overflow input values
- nValueIn += coin.out.nValue;
- if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn))
- return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputvalues-outofrange");
+ // are the actual inputs available?
+ if (!inputs.HaveInputs(tx)) {
+ return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-missingorspent", false,
+ strprintf("%s: inputs missing/spent", __func__));
+ }
+
+ CAmount nValueIn = 0;
+ for (unsigned int i = 0; i < tx.vin.size(); ++i) {
+ const COutPoint &prevout = tx.vin[i].prevout;
+ const Coin& coin = inputs.AccessCoin(prevout);
+ assert(!coin.IsSpent());
+
+ // If prev is coinbase, check that it's matured
+ if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
+ return state.Invalid(false,
+ REJECT_INVALID, "bad-txns-premature-spend-of-coinbase",
+ strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
+ }
+ // Check for negative or overflow input values
+ nValueIn += coin.out.nValue;
+ if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) {
+ return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputvalues-outofrange");
}
+ }
+
+ const CAmount value_out = tx.GetValueOut();
+ if (nValueIn < value_out) {
+ return state.DoS(100, false, REJECT_INVALID, "bad-txns-in-belowout", false,
+ strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out)));
+ }
+
+ // Tally transaction fees
+ const CAmount txfee_aux = nValueIn - value_out;
+ if (!MoneyRange(txfee_aux)) {
+ return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-outofrange");
+ }
- if (nValueIn < tx.GetValueOut())
- return state.DoS(100, false, REJECT_INVALID, "bad-txns-in-belowout", false,
- strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(tx.GetValueOut())));
-
- // Tally transaction fees
- CAmount nTxFee = nValueIn - tx.GetValueOut();
- if (nTxFee < 0)
- return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-negative");
- nFees += nTxFee;
- if (!MoneyRange(nFees))
- return state.DoS(100, false, REJECT_INVALID, "bad-txns-fee-outofrange");
+ txfee = txfee_aux;
return true;
}