diff --git a/src/txmempool.cpp b/src/txmempool.cpp index d49891d9ef9..77099708994 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -582,25 +582,42 @@ void CTxMemPool::removeForBlock(const std::vector& vtx, unsigne std::set txsToRemove; CCoinsViewCache mempoolDuplicate(const_cast(&::ChainstateActive().CoinsTip())); CAmount txfee = 0; + bool accountConflict{false}; - // Check custom TX consensus types are now not in conflict with account layer + // Check if any custom TXs are in mempool with conflict for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); ++it) { - CValidationState state; - if (!Consensus::CheckTxInputs(it->GetTx(), state, mempoolDuplicate, pcustomcsview.get(), nBlockHeight, txfee, Params())) { - LogPrintf("%s: Remove conflicting TX: %s\n", __func__, it->GetTx().GetHash().GetHex()); - txsToRemove.insert(it->GetSharedTx()); + std::vector metadata; + CustomTxType txType = GuessCustomTxType(it->GetTx(), metadata); + if (NotAllowedToFail(txType)) { + auto res = ApplyCustomTx(*pcustomcsview, g_chainstate->CoinsTip(), it->GetTx(), Params().GetConsensus(), nBlockHeight, 0, true); + if (!res.ok && (res.code & CustomTxErrCodes::Fatal)) { + accountConflict = true; + break; + } } } - for (auto& tx : txsToRemove) { - txiter it = mapTx.find(tx->GetHash()); - if (it != mapTx.end()) { - setEntries stage; - stage.insert(it); - RemoveStaged(stage, true, MemPoolRemovalReason::CONFLICT); + // Account conflict, check entire mempool + if (accountConflict) { + // Check custom TX consensus types are now not in conflict with account layer + for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); ++it) { + CValidationState state; + if (!Consensus::CheckTxInputs(it->GetTx(), state, mempoolDuplicate, pcustomcsview.get(), nBlockHeight, txfee, Params())) { + LogPrintf("%s: Remove conflicting TX: %s\n", __func__, it->GetTx().GetHash().GetHex()); + txsToRemove.insert(it->GetSharedTx()); + } + } + + for (auto& tx : txsToRemove) { + txiter it = mapTx.find(tx->GetHash()); + if (it != mapTx.end()) { + setEntries stage; + stage.insert(it); + RemoveStaged(stage, true, MemPoolRemovalReason::CONFLICT); + } + removeConflicts(*tx); + ClearPrioritisation(tx->GetHash()); } - removeConflicts(*tx); - ClearPrioritisation(tx->GetHash()); } lastRollingFeeUpdate = GetTime();