diff --git a/src/consensus/tx_verify.h b/src/consensus/tx_verify.h --- a/src/consensus/tx_verify.h +++ b/src/consensus/tx_verify.h @@ -18,10 +18,8 @@ * Context-independent validity checks for coinbase and non-coinbase * transactions. */ -bool CheckRegularTransaction(const CTransaction &tx, CValidationState &state, - bool fCheckDuplicateInputs = true); -bool CheckCoinbase(const CTransaction &tx, CValidationState &state, - bool fCheckDuplicateInputs = true); +bool CheckRegularTransaction(const CTransaction &tx, CValidationState &state); +bool CheckCoinbase(const CTransaction &tx, CValidationState &state); namespace Consensus { diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -186,8 +186,7 @@ } static bool CheckTransactionCommon(const CTransaction &tx, - CValidationState &state, - bool fCheckDuplicateInputs) { + CValidationState &state) { // Basic checks that don't depend on any context if (tx.vin.empty()) { return state.DoS(10, false, REJECT_INVALID, "bad-txns-vin-empty"); @@ -227,29 +226,16 @@ return state.DoS(100, false, REJECT_INVALID, "bad-txn-sigops"); } - // Check for duplicate inputs - note that this check is slow so we skip it - // in CheckBlock - if (fCheckDuplicateInputs) { - std::set vInOutPoints; - for (const auto &txin : tx.vin) { - if (!vInOutPoints.insert(txin.prevout).second) { - return state.DoS(100, false, REJECT_INVALID, - "bad-txns-inputs-duplicate"); - } - } - } - return true; } -bool CheckCoinbase(const CTransaction &tx, CValidationState &state, - bool fCheckDuplicateInputs) { +bool CheckCoinbase(const CTransaction &tx, CValidationState &state) { if (!tx.IsCoinBase()) { return state.DoS(100, false, REJECT_INVALID, "bad-cb-missing", false, "first tx is not coinbase"); } - if (!CheckTransactionCommon(tx, state, fCheckDuplicateInputs)) { + if (!CheckTransactionCommon(tx, state)) { // CheckTransactionCommon fill in the state. return false; } @@ -262,22 +248,27 @@ return true; } -bool CheckRegularTransaction(const CTransaction &tx, CValidationState &state, - bool fCheckDuplicateInputs) { +bool CheckRegularTransaction(const CTransaction &tx, CValidationState &state) { if (tx.IsCoinBase()) { return state.DoS(100, false, REJECT_INVALID, "bad-tx-coinbase"); } - if (!CheckTransactionCommon(tx, state, fCheckDuplicateInputs)) { + if (!CheckTransactionCommon(tx, state)) { // CheckTransactionCommon fill in the state. return false; } + std::unordered_set vInOutPoints; for (const auto &txin : tx.vin) { if (txin.prevout.IsNull()) { return state.DoS(10, false, REJECT_INVALID, "bad-txns-prevout-null"); } + + if (!vInOutPoints.insert(txin.prevout).second) { + return state.DoS(100, false, REJECT_INVALID, + "bad-txns-inputs-duplicate"); + } } return true; diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -253,7 +253,7 @@ { CValidationState state; - BOOST_CHECK(CheckRegularTransaction(CTransaction(tx), state, false)); + BOOST_CHECK(CheckRegularTransaction(CTransaction(tx), state)); } // Get just before the limit. @@ -263,7 +263,7 @@ { CValidationState state; - BOOST_CHECK(CheckRegularTransaction(CTransaction(tx), state, false)); + BOOST_CHECK(CheckRegularTransaction(CTransaction(tx), state)); } // And go over. @@ -271,7 +271,7 @@ { CValidationState state; - BOOST_CHECK(!CheckRegularTransaction(CTransaction(tx), state, false)); + BOOST_CHECK(!CheckRegularTransaction(CTransaction(tx), state)); BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-txn-sigops"); } } diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -386,7 +386,7 @@ } // Coinbase is only valid in a block, not as a loose transaction. - if (!CheckRegularTransaction(tx, state, true)) { + if (!CheckRegularTransaction(tx, state)) { // state filled in by CheckRegularTransaction. return false; } @@ -3079,7 +3079,7 @@ } // And a valid coinbase. - if (!CheckCoinbase(*block.vtx[0], state, false)) { + if (!CheckCoinbase(*block.vtx[0], state)) { return state.Invalid(false, state.GetRejectCode(), state.GetRejectReason(), strprintf("Coinbase check failed (txid %s) %s", @@ -3113,11 +3113,11 @@ break; } - // Check that the transaction is valid. because this check differs for - // the coinbase, the loos is arranged such as this only runs after at + // Check that the transaction is valid. Because this check differs for + // the coinbase, the loop is arranged such as this only runs after at // least one increment. tx = block.vtx[i].get(); - if (!CheckRegularTransaction(*tx, state, false)) { + if (!CheckRegularTransaction(*tx, state)) { return state.Invalid( false, state.GetRejectCode(), state.GetRejectReason(), strprintf("Transaction check failed (txid %s) %s",