|
|
|
@ -1104,7 +1104,7 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i
@@ -1104,7 +1104,7 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool CheckTransaction(const CTransaction& tx, CValidationState &state) |
|
|
|
|
bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fCheckDuplicateInputs) |
|
|
|
|
{ |
|
|
|
|
// Basic checks that don't depend on any context
|
|
|
|
|
if (tx.vin.empty()) |
|
|
|
@ -1128,13 +1128,15 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
@@ -1128,13 +1128,15 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
|
|
|
|
|
return state.DoS(100, false, REJECT_INVALID, "bad-txns-txouttotal-toolarge"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Check for duplicate inputs
|
|
|
|
|
set<COutPoint> vInOutPoints; |
|
|
|
|
for (const auto& txin : tx.vin) |
|
|
|
|
{ |
|
|
|
|
if (vInOutPoints.count(txin.prevout)) |
|
|
|
|
return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-duplicate"); |
|
|
|
|
vInOutPoints.insert(txin.prevout); |
|
|
|
|
// Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock
|
|
|
|
|
if (fCheckDuplicateInputs) { |
|
|
|
|
set<COutPoint> vInOutPoints; |
|
|
|
|
for (const auto& txin : tx.vin) |
|
|
|
|
{ |
|
|
|
|
if (vInOutPoints.count(txin.prevout)) |
|
|
|
|
return state.DoS(100, false, REJECT_INVALID, "bad-txns-inputs-duplicate"); |
|
|
|
|
vInOutPoints.insert(txin.prevout); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (tx.IsCoinBase()) |
|
|
|
@ -3461,7 +3463,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
@@ -3461,7 +3463,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
|
|
|
|
|
|
|
|
|
|
// Check transactions
|
|
|
|
|
for (const auto& tx : block.vtx) |
|
|
|
|
if (!CheckTransaction(tx, state)) |
|
|
|
|
if (!CheckTransaction(tx, state, false)) |
|
|
|
|
return state.Invalid(false, state.GetRejectCode(), state.GetRejectReason(), |
|
|
|
|
strprintf("Transaction check failed (tx hash %s) %s", tx.GetHash().ToString(), state.GetDebugMessage())); |
|
|
|
|
|
|
|
|
|