diff --git a/src/coins.h b/src/coins.h
--- a/src/coins.h
+++ b/src/coins.h
@@ -512,10 +512,10 @@
     bool Flush();
 
     /**
-     * Removes the transaction with the given hash from the cache, if it is
-     * not modified.
+     * Removes the UTXO with the given outpoint from the cache, if it is not
+     * modified.
      */
-    void Uncache(const uint256 &txid);
+    void Uncache(const COutPoint &outpoint);
 
     //! Calculate the size of the cache (in number of transactions)
     unsigned int GetCacheSize() const;
diff --git a/src/coins.cpp b/src/coins.cpp
--- a/src/coins.cpp
+++ b/src/coins.cpp
@@ -289,8 +289,8 @@
     return fOk;
 }
 
-void CCoinsViewCache::Uncache(const uint256 &hash) {
-    CCoinsMap::iterator it = cacheCoins.find(hash);
+void CCoinsViewCache::Uncache(const COutPoint &outpoint) {
+    CCoinsMap::iterator it = cacheCoins.find(outpoint.hash);
     if (it != cacheCoins.end() && it->second.flags == 0) {
         cachedCoinsUsage -= it->second.coins.DynamicMemoryUsage();
         cacheCoins.erase(it);
diff --git a/src/txmempool.h b/src/txmempool.h
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -656,11 +656,11 @@
     /**
      * Remove transactions from the mempool until its dynamic size is <=
      * sizelimit. pvNoSpendsRemaining, if set, will be populated with the list
-     * of transactions which are not in mempool which no longer have any spends
-     * in this mempool.
+     * of outpoints which are not in mempool which no longer have any spends in
+     * this mempool.
      */
     void TrimToSize(size_t sizelimit,
-                    std::vector<uint256> *pvNoSpendsRemaining = nullptr);
+                    std::vector<COutPoint> *pvNoSpendsRemaining = nullptr);
 
     /** Expire all transaction (and their dependencies) in the mempool older
      * than time. Return the number of removed transactions. */
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -1150,7 +1150,7 @@
 }
 
 void CTxMemPool::TrimToSize(size_t sizelimit,
-                            std::vector<uint256> *pvNoSpendsRemaining) {
+                            std::vector<COutPoint> *pvNoSpendsRemaining) {
     LOCK(cs);
 
     unsigned nTxnRemoved = 0;
@@ -1185,12 +1185,15 @@
         if (pvNoSpendsRemaining) {
             for (const CTransaction &tx : txn) {
                 for (const CTxIn &txin : tx.vin) {
-                    if (exists(txin.prevout.hash)) continue;
+                    if (exists(txin.prevout.hash)) {
+                        continue;
+                    }
+
                     auto iter =
                         mapNextTx.lower_bound(COutPoint(txin.prevout.hash, 0));
                     if (iter == mapNextTx.end() ||
                         iter->first->hash != txin.prevout.hash)
-                        pvNoSpendsRemaining->push_back(txin.prevout.hash);
+                        pvNoSpendsRemaining->push_back(txin.prevout);
                 }
             }
         }
diff --git a/src/validation.h b/src/validation.h
--- a/src/validation.h
+++ b/src/validation.h
@@ -385,13 +385,6 @@
                         bool fOverrideMempoolLimit = false,
                         const CAmount nAbsurdFee = 0);
 
-/** (try to) add transaction to memory pool with a specified acceptance time **/
-bool AcceptToMemoryPoolWithTime(
-    const Config &config, CTxMemPool &pool, CValidationState &state,
-    const CTransactionRef &tx, bool fLimitFree, bool *pfMissingInputs,
-    int64_t nAcceptTime, std::list<CTransactionRef> *plTxnReplaced = nullptr,
-    bool fOverrideMempoolLimit = false, const CAmount nAbsurdFee = 0);
-
 /** Convert CValidationState to a human-readable message for logging */
 std::string FormatStateMessage(const CValidationState &state);
 
diff --git a/src/validation.cpp b/src/validation.cpp
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -564,13 +564,14 @@
 
 void LimitMempoolSize(CTxMemPool &pool, size_t limit, unsigned long age) {
     int expired = pool.Expire(GetTime() - age);
-    if (expired != 0)
+    if (expired != 0) {
         LogPrint("mempool", "Expired %i transactions from the memory pool\n",
                  expired);
+    }
 
-    std::vector<uint256> vNoSpendsRemaining;
+    std::vector<COutPoint> vNoSpendsRemaining;
     pool.TrimToSize(limit, &vNoSpendsRemaining);
-    for (const uint256 &removed : vNoSpendsRemaining) {
+    for (const COutPoint &removed : vNoSpendsRemaining) {
         pcoinsTip->Uncache(removed);
     }
 }
@@ -615,7 +616,7 @@
     const CTransactionRef &ptx, bool fLimitFree, bool *pfMissingInputs,
     int64_t nAcceptTime, std::list<CTransactionRef> *plTxnReplaced,
     bool fOverrideMempoolLimit, const CAmount &nAbsurdFee,
-    std::vector<uint256> &vHashTxnToUncache) {
+    std::vector<COutPoint> &coins_to_uncache) {
     AssertLockHeld(cs_main);
 
     const CTransaction &tx = *ptx;
@@ -679,10 +680,10 @@
             // Do we already have it?
             for (size_t out = 0; out < tx.vout.size(); out++) {
                 COutPoint outpoint(txid, out);
-                bool fHadTxInCache = pcoinsTip->HaveCoinInCache(outpoint);
+                bool had_coin_in_cache = pcoinsTip->HaveCoinInCache(outpoint);
                 if (view.HaveCoin(outpoint)) {
-                    if (!fHadTxInCache) {
-                        vHashTxnToUncache.push_back(txid);
+                    if (!had_coin_in_cache) {
+                        coins_to_uncache.push_back(outpoint);
                     }
 
                     return state.Invalid(false, REJECT_ALREADY_KNOWN,
@@ -690,13 +691,10 @@
                 }
             }
 
-            // Do all inputs exist? Note that this does not check for the
-            // presence of actual outputs (see the next check for that), and
-            // only helps with filling in pfMissingInputs (to determine missing
-            // vs spent).
+            // Do all inputs exist?
             for (const CTxIn txin : tx.vin) {
                 if (!pcoinsTip->HaveCoinInCache(txin.prevout)) {
-                    vHashTxnToUncache.push_back(txin.prevout.hash);
+                    coins_to_uncache.push_back(txin.prevout);
                 }
 
                 if (!view.HaveCoin(txin.prevout)) {
@@ -918,22 +916,21 @@
     return true;
 }
 
-bool AcceptToMemoryPoolWithTime(const Config &config, CTxMemPool &pool,
-                                CValidationState &state,
-                                const CTransactionRef &tx, bool fLimitFree,
-                                bool *pfMissingInputs, int64_t nAcceptTime,
-                                std::list<CTransactionRef> *plTxnReplaced,
-                                bool fOverrideMempoolLimit,
-                                const CAmount nAbsurdFee) {
-    std::vector<uint256> vHashTxToUncache;
+static bool AcceptToMemoryPoolWithTime(
+    const Config &config, CTxMemPool &pool, CValidationState &state,
+    const CTransactionRef &tx, bool fLimitFree, bool *pfMissingInputs,
+    int64_t nAcceptTime, std::list<CTransactionRef> *plTxnReplaced = nullptr,
+    bool fOverrideMempoolLimit = false, const CAmount nAbsurdFee = 0) {
+    std::vector<COutPoint> coins_to_uncache;
     bool res = AcceptToMemoryPoolWorker(
         config, pool, state, tx, fLimitFree, pfMissingInputs, nAcceptTime,
-        plTxnReplaced, fOverrideMempoolLimit, nAbsurdFee, vHashTxToUncache);
+        plTxnReplaced, fOverrideMempoolLimit, nAbsurdFee, coins_to_uncache);
     if (!res) {
-        for (const uint256 &txid : vHashTxToUncache) {
-            pcoinsTip->Uncache(txid);
+        for (const COutPoint &outpoint : coins_to_uncache) {
+            pcoinsTip->Uncache(outpoint);
         }
     }
+
     // After we've (potentially) uncached entries, ensure our coins cache is
     // still within its size limits
     CValidationState stateDummy;