|
|
@ -7,7 +7,7 @@
|
|
|
|
#include <primitives/transaction.h>
|
|
|
|
#include <primitives/transaction.h>
|
|
|
|
#include <consensus/validation.h>
|
|
|
|
#include <consensus/validation.h>
|
|
|
|
|
|
|
|
|
|
|
|
bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fCheckDuplicateInputs)
|
|
|
|
bool CheckTransaction(const CTransaction& tx, CValidationState& state)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Basic checks that don't depend on any context
|
|
|
|
// Basic checks that don't depend on any context
|
|
|
|
if (tx.vin.empty())
|
|
|
|
if (tx.vin.empty())
|
|
|
@ -31,14 +31,15 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe
|
|
|
|
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "bad-txns-txouttotal-toolarge");
|
|
|
|
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "bad-txns-txouttotal-toolarge");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock
|
|
|
|
// Check for duplicate inputs (see CVE-2018-17144)
|
|
|
|
if (fCheckDuplicateInputs) {
|
|
|
|
// While Consensus::CheckTxInputs does check if all inputs of a tx are available, and UpdateCoins marks all inputs
|
|
|
|
std::set<COutPoint> vInOutPoints;
|
|
|
|
// of a tx as spent, it does not check if the tx has duplicate inputs.
|
|
|
|
for (const auto& txin : tx.vin)
|
|
|
|
// Failure to run this check will result in either a crash or an inflation bug, depending on the implementation of
|
|
|
|
{
|
|
|
|
// the underlying coins database.
|
|
|
|
if (!vInOutPoints.insert(txin.prevout).second)
|
|
|
|
std::set<COutPoint> vInOutPoints;
|
|
|
|
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "bad-txns-inputs-duplicate");
|
|
|
|
for (const auto& txin : tx.vin) {
|
|
|
|
}
|
|
|
|
if (!vInOutPoints.insert(txin.prevout).second)
|
|
|
|
|
|
|
|
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "bad-txns-inputs-duplicate");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (tx.IsCoinBase())
|
|
|
|
if (tx.IsCoinBase())
|
|
|
|