@@ -1104,7 +1104,7 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i
1104
1104
1105
1105
1106
1106
1107
- bool CheckTransaction (const CTransaction& tx, CValidationState &state)
1107
+ bool CheckTransaction (const CTransaction& tx, CValidationState &state, bool fCheckDuplicateInputs )
1108
1108
{
1109
1109
// Basic checks that don't depend on any context
1110
1110
if (tx.vin .empty ())
@@ -1128,13 +1128,15 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
1128
1128
return state.DoS (100 , false , REJECT_INVALID, " bad-txns-txouttotal-toolarge" );
1129
1129
}
1130
1130
1131
- // Check for duplicate inputs
1132
- set<COutPoint> vInOutPoints;
1133
- for (const auto & txin : tx.vin )
1134
- {
1135
- if (vInOutPoints.count (txin.prevout ))
1136
- return state.DoS (100 , false , REJECT_INVALID, " bad-txns-inputs-duplicate" );
1137
- vInOutPoints.insert (txin.prevout );
1131
+ // Check for duplicate inputs - note that this check is slow so we skip it in CheckBlock
1132
+ if (fCheckDuplicateInputs ) {
1133
+ set<COutPoint> vInOutPoints;
1134
+ for (const auto & txin : tx.vin )
1135
+ {
1136
+ if (vInOutPoints.count (txin.prevout ))
1137
+ return state.DoS (100 , false , REJECT_INVALID, " bad-txns-inputs-duplicate" );
1138
+ vInOutPoints.insert (txin.prevout );
1139
+ }
1138
1140
}
1139
1141
1140
1142
if (tx.IsCoinBase ())
@@ -3461,7 +3463,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
3461
3463
3462
3464
// Check transactions
3463
3465
for (const auto & tx : block.vtx )
3464
- if (!CheckTransaction (tx, state))
3466
+ if (!CheckTransaction (tx, state, false ))
3465
3467
return state.Invalid (false , state.GetRejectCode (), state.GetRejectReason (),
3466
3468
strprintf (" Transaction check failed (tx hash %s) %s" , tx.GetHash ().ToString (), state.GetDebugMessage ()));
3467
3469
0 commit comments