@@ -1104,7 +1104,7 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i
11041104
11051105
11061106
1107- bool CheckTransaction (const CTransaction& tx, CValidationState &state)
1107+ bool CheckTransaction (const CTransaction& tx, CValidationState &state, bool fCheckDuplicateInputs )
11081108{
11091109 // Basic checks that don't depend on any context
11101110 if (tx.vin .empty ())
@@ -1128,13 +1128,15 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
11281128 return state.DoS (100 , false , REJECT_INVALID, " bad-txns-txouttotal-toolarge" );
11291129 }
11301130
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+ }
11381140 }
11391141
11401142 if (tx.IsCoinBase ())
@@ -3461,7 +3463,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
34613463
34623464 // Check transactions
34633465 for (const auto & tx : block.vtx )
3464- if (!CheckTransaction (tx, state))
3466+ if (!CheckTransaction (tx, state, false ))
34653467 return state.Invalid (false , state.GetRejectCode (), state.GetRejectReason (),
34663468 strprintf (" Transaction check failed (tx hash %s) %s" , tx.GetHash ().ToString (), state.GetDebugMessage ()));
34673469
0 commit comments