From 1400df2e58f6d11c37ff4fd939ca250e0532a2a1 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Fri, 1 Feb 2019 08:49:18 +0100 Subject: [PATCH] Invoke CheckSpecialTx after all normal TX checks have passed (#2673) Otherwise duplicate-keys checks for deterministic masternodes triggers for duplicate/identical transactions. --- src/validation.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index bbd17de21fa8a..786dcd9f9f483 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -658,9 +658,6 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C return state.DoS(100, false, REJECT_INVALID, "qc-not-allowed"); } - if (!CheckSpecialTx(tx, chainActive.Tip(), state)) - return false; - // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) return state.DoS(100, false, REJECT_INVALID, "coinbase"); @@ -868,6 +865,12 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C return state.DoS(0, false, REJECT_NONSTANDARD, "too-long-mempool-chain", false, errString); } + // check special TXs after all the other checks. If we'd do this before the other checks, we might end up + // DoS scoring a node for non-critical errors, e.g. duplicate keys because a TX is received that was already + // mined + if (!CheckSpecialTx(tx, chainActive.Tip(), state)) + return false; + // If we aren't going to actually accept it but just were verifying it, we are fine already if(fDryRun) return true;