diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp
index dc1360724d..e507a2d43a 100644
--- a/src/test/mempool_tests.cpp
+++ b/src/test/mempool_tests.cpp
@@ -1,1141 +1,1139 @@
 // Copyright (c) 2011-2019 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include <txmempool.h>
 
 #include <policy/policy.h>
 #include <reverse_iterator.h>
 #include <util/system.h>
 #include <util/time.h>
 
 #include <test/setup_common.h>
 
 #include <boost/test/unit_test.hpp>
 
 #include <algorithm>
 #include <vector>
 
 BOOST_FIXTURE_TEST_SUITE(mempool_tests, TestingSetup)
 
 BOOST_AUTO_TEST_CASE(TestPackageAccounting) {
     CTxMemPool testPool;
     LOCK2(cs_main, testPool.cs);
     TestMemPoolEntryHelper entry;
     CMutableTransaction parentOfAll;
 
     std::vector<CTxIn> outpoints;
     const size_t maxOutputs = 3;
 
     // Construct a parent for the rest of the chain
     parentOfAll.vin.resize(1);
     parentOfAll.vin[0].scriptSig = CScript();
     // Give us a couple outpoints so we can spend them
     for (size_t i = 0; i < maxOutputs; i++) {
         parentOfAll.vout.emplace_back(10 * SATOSHI, CScript() << OP_TRUE);
     }
     TxId parentOfAllId = parentOfAll.GetId();
     testPool.addUnchecked(entry.SigOpCount(0).FromTx(parentOfAll));
 
     // Add some outpoints to the tracking vector
     for (size_t i = 0; i < maxOutputs; i++) {
         outpoints.emplace_back(COutPoint(parentOfAllId, i));
     }
 
     Amount totalFee = Amount::zero();
     size_t totalSize = CTransaction(parentOfAll).GetTotalSize();
     size_t totalVirtualSize = totalSize;
     int64_t totalSigOpCount = 0;
 
     // Generate 100 transactions
     for (size_t totalTransactions = 0; totalTransactions < 100;
          totalTransactions++) {
         CMutableTransaction tx;
 
         uint64_t minAncestors = std::numeric_limits<size_t>::max();
         uint64_t maxAncestors = 0;
         Amount minFees = MAX_MONEY;
         Amount maxFees = Amount::zero();
         uint64_t minSize = std::numeric_limits<size_t>::max();
         uint64_t maxSize = 0;
         uint64_t minVirtualSize = std::numeric_limits<size_t>::max();
         uint64_t maxVirtualSize = 0;
         int64_t minSigOpCount = std::numeric_limits<int64_t>::max();
         int64_t maxSigOpCount = 0;
         // Consume random inputs, but make sure we don't consume more than
         // available
         for (size_t input = std::min(InsecureRandRange(maxOutputs) + 1,
                                      uint64_t(outpoints.size()));
              input > 0; input--) {
             std::swap(outpoints[InsecureRandRange(outpoints.size())],
                       outpoints.back());
             tx.vin.emplace_back(outpoints.back());
             outpoints.pop_back();
 
             // We don't know exactly how many ancestors this transaction has
             // due to possible duplicates.  Calculate a valid range based on
             // parents.
 
             CTxMemPoolEntry parent =
                 *testPool.mapTx.find(tx.vin.back().prevout.GetTxId());
 
             minAncestors =
                 std::min(minAncestors, parent.GetCountWithAncestors());
             maxAncestors += parent.GetCountWithAncestors();
             minFees = std::min(minFees, parent.GetModFeesWithAncestors());
             maxFees += parent.GetModFeesWithAncestors();
             minSize = std::min(minSize, parent.GetSizeWithAncestors());
             maxSize += parent.GetSizeWithAncestors();
             minVirtualSize =
                 std::min(minSize, parent.GetVirtualSizeWithAncestors());
             maxVirtualSize += parent.GetVirtualSizeWithAncestors();
             minSigOpCount =
                 std::min(minSigOpCount, parent.GetSigOpCountWithAncestors());
             maxSigOpCount += parent.GetSigOpCountWithAncestors();
         }
 
         // Produce random number of outputs
         for (size_t output = InsecureRandRange(maxOutputs) + 1; output > 0;
              output--) {
             tx.vout.emplace_back(10 * SATOSHI, CScript() << OP_TRUE);
         }
 
         TxId curId = tx.GetId();
 
         // Record the outputs
         for (size_t output = tx.vout.size(); output > 0; output--) {
             outpoints.emplace_back(COutPoint(curId, output));
         }
 
         Amount randFee = int64_t(InsecureRandRange(300)) * SATOSHI;
         int randSigOpCount = InsecureRandRange(5);
 
         testPool.addUnchecked(
             entry.Fee(randFee).SigOpCount(randSigOpCount).FromTx(tx));
 
         // Add this transaction to the totals.
         minAncestors += 1;
         maxAncestors += 1;
         minFees += randFee;
         maxFees += randFee;
         minSize += CTransaction(tx).GetTotalSize();
         maxSize += CTransaction(tx).GetTotalSize();
         // virtualsize is a nonlinear function of its arguments, so we can't
         // make as strong guarantees about its range; but assuming virtualsize
         // is monotonically increasing in each argument, we can say the
         // following:
         minVirtualSize += 0;
         maxVirtualSize += GetVirtualTransactionSize(
             CTransaction(tx).GetTotalSize(), randSigOpCount);
         minSigOpCount += randSigOpCount;
         maxSigOpCount += randSigOpCount;
 
         // Calculate overall values
         totalFee += randFee;
         totalSize += CTransaction(tx).GetTotalSize();
         totalVirtualSize += GetVirtualTransactionSize(
             CTransaction(tx).GetTotalSize(), randSigOpCount);
         totalSigOpCount += randSigOpCount;
         CTxMemPoolEntry parentEntry = *testPool.mapTx.find(parentOfAllId);
         CTxMemPoolEntry latestEntry = *testPool.mapTx.find(curId);
 
         // Based on size/sigops ranges we can compute more strict bounds for the
         // virtual size ranges/totals, assuming virtualsize is monotonic in each
         // argument.
         uint64_t minVirtualSize_strict =
             GetVirtualTransactionSize(minSize, minSigOpCount);
         uint64_t maxVirtualSize_strict =
             GetVirtualTransactionSize(maxSize, maxSigOpCount);
         uint64_t totalVirtualSize_strict =
             GetVirtualTransactionSize(totalSize, totalSigOpCount);
         // these are as-good or better than the earlier estimations.
         BOOST_CHECK(minVirtualSize_strict >= minVirtualSize);
         BOOST_CHECK(maxVirtualSize_strict <= maxVirtualSize);
         BOOST_CHECK(totalVirtualSize_strict <= totalVirtualSize);
 
         // Ensure values are within the expected ranges
         BOOST_CHECK(latestEntry.GetCountWithAncestors() >= minAncestors);
         BOOST_CHECK(latestEntry.GetCountWithAncestors() <= maxAncestors);
 
         BOOST_CHECK(latestEntry.GetSizeWithAncestors() >= minSize);
         BOOST_CHECK(latestEntry.GetSizeWithAncestors() <= maxSize);
 
         BOOST_CHECK(latestEntry.GetVirtualSizeWithAncestors() >=
                     minVirtualSize_strict);
         BOOST_CHECK(latestEntry.GetVirtualSizeWithAncestors() <=
                     maxVirtualSize_strict);
 
         BOOST_CHECK(latestEntry.GetSigOpCountWithAncestors() >= minSigOpCount);
         BOOST_CHECK(latestEntry.GetSigOpCountWithAncestors() <= maxSigOpCount);
 
         BOOST_CHECK(latestEntry.GetModFeesWithAncestors() >= minFees);
         BOOST_CHECK(latestEntry.GetModFeesWithAncestors() <= maxFees);
 
         BOOST_CHECK_EQUAL(parentEntry.GetCountWithDescendants(),
                           testPool.mapTx.size());
         BOOST_CHECK_EQUAL(parentEntry.GetSizeWithDescendants(), totalSize);
         BOOST_CHECK_EQUAL(parentEntry.GetVirtualSizeWithDescendants(),
                           totalVirtualSize_strict);
         BOOST_CHECK_EQUAL(parentEntry.GetModFeesWithDescendants(), totalFee);
         BOOST_CHECK_EQUAL(parentEntry.GetSigOpCountWithDescendants(),
                           totalSigOpCount);
     }
 }
 
 BOOST_AUTO_TEST_CASE(MempoolRemoveTest) {
     // Test CTxMemPool::remove functionality
 
     TestMemPoolEntryHelper entry;
     // Parent transaction with three children, and three grand-children:
     CMutableTransaction txParent;
     txParent.vin.resize(1);
     txParent.vin[0].scriptSig = CScript() << OP_11;
     txParent.vout.resize(3);
     for (int i = 0; i < 3; i++) {
         txParent.vout[i].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
         txParent.vout[i].nValue = 33000 * SATOSHI;
     }
     CMutableTransaction txChild[3];
     for (int i = 0; i < 3; i++) {
         txChild[i].vin.resize(1);
         txChild[i].vin[0].scriptSig = CScript() << OP_11;
         txChild[i].vin[0].prevout = COutPoint(txParent.GetId(), i);
         txChild[i].vout.resize(1);
         txChild[i].vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
         txChild[i].vout[0].nValue = 11000 * SATOSHI;
     }
     CMutableTransaction txGrandChild[3];
     for (int i = 0; i < 3; i++) {
         txGrandChild[i].vin.resize(1);
         txGrandChild[i].vin[0].scriptSig = CScript() << OP_11;
         txGrandChild[i].vin[0].prevout = COutPoint(txChild[i].GetId(), 0);
         txGrandChild[i].vout.resize(1);
         txGrandChild[i].vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
         txGrandChild[i].vout[0].nValue = 11000 * SATOSHI;
     }
 
     CTxMemPool testPool;
     LOCK2(cs_main, testPool.cs);
 
     // Nothing in pool, remove should do nothing:
     unsigned int poolSize = testPool.size();
     testPool.removeRecursive(CTransaction(txParent));
     BOOST_CHECK_EQUAL(testPool.size(), poolSize);
 
     // Just the parent:
     testPool.addUnchecked(entry.FromTx(txParent));
     poolSize = testPool.size();
     testPool.removeRecursive(CTransaction(txParent));
     BOOST_CHECK_EQUAL(testPool.size(), poolSize - 1);
 
     // Parent, children, grandchildren:
     testPool.addUnchecked(entry.FromTx(txParent));
     for (int i = 0; i < 3; i++) {
         testPool.addUnchecked(entry.FromTx(txChild[i]));
         testPool.addUnchecked(entry.FromTx(txGrandChild[i]));
     }
     // Remove Child[0], GrandChild[0] should be removed:
     poolSize = testPool.size();
     testPool.removeRecursive(CTransaction(txChild[0]));
     BOOST_CHECK_EQUAL(testPool.size(), poolSize - 2);
     // ... make sure grandchild and child are gone:
     poolSize = testPool.size();
     testPool.removeRecursive(CTransaction(txGrandChild[0]));
     BOOST_CHECK_EQUAL(testPool.size(), poolSize);
     poolSize = testPool.size();
     testPool.removeRecursive(CTransaction(txChild[0]));
     BOOST_CHECK_EQUAL(testPool.size(), poolSize);
     // Remove parent, all children/grandchildren should go:
     poolSize = testPool.size();
     testPool.removeRecursive(CTransaction(txParent));
     BOOST_CHECK_EQUAL(testPool.size(), poolSize - 5);
     BOOST_CHECK_EQUAL(testPool.size(), 0UL);
 
     // Add children and grandchildren, but NOT the parent (simulate the parent
     // being in a block)
     for (int i = 0; i < 3; i++) {
         testPool.addUnchecked(entry.FromTx(txChild[i]));
         testPool.addUnchecked(entry.FromTx(txGrandChild[i]));
     }
 
     // Now remove the parent, as might happen if a block-re-org occurs but the
     // parent cannot be put into the mempool (maybe because it is non-standard):
     poolSize = testPool.size();
     testPool.removeRecursive(CTransaction(txParent));
     BOOST_CHECK_EQUAL(testPool.size(), poolSize - 6);
     BOOST_CHECK_EQUAL(testPool.size(), 0UL);
 }
 
 BOOST_AUTO_TEST_CASE(MempoolClearTest) {
     // Test CTxMemPool::clear functionality
 
     TestMemPoolEntryHelper entry;
     // Create a transaction
     CMutableTransaction txParent;
     txParent.vin.resize(1);
     txParent.vin[0].scriptSig = CScript() << OP_11;
     txParent.vout.resize(3);
     for (int i = 0; i < 3; i++) {
         txParent.vout[i].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
         txParent.vout[i].nValue = 33000 * SATOSHI;
     }
 
     CTxMemPool testPool;
     LOCK2(cs_main, testPool.cs);
 
     // Nothing in pool, clear should do nothing:
     testPool.clear();
     BOOST_CHECK_EQUAL(testPool.size(), 0UL);
 
     // Add the transaction
     testPool.addUnchecked(entry.FromTx(txParent));
     BOOST_CHECK_EQUAL(testPool.size(), 1UL);
     BOOST_CHECK_EQUAL(testPool.mapTx.size(), 1UL);
     BOOST_CHECK_EQUAL(testPool.mapNextTx.size(), 1UL);
     BOOST_CHECK_EQUAL(testPool.vTxHashes.size(), 1UL);
 
     // CTxMemPool's members should be empty after a clear
     testPool.clear();
     BOOST_CHECK_EQUAL(testPool.size(), 0UL);
     BOOST_CHECK_EQUAL(testPool.mapTx.size(), 0UL);
     BOOST_CHECK_EQUAL(testPool.mapNextTx.size(), 0UL);
     BOOST_CHECK_EQUAL(testPool.vTxHashes.size(), 0UL);
 }
 
 template <typename name>
 static void CheckSort(CTxMemPool &pool, std::vector<std::string> &sortedOrder,
                       const std::string &testcase)
     EXCLUSIVE_LOCKS_REQUIRED(pool.cs) {
     BOOST_CHECK_EQUAL(pool.size(), sortedOrder.size());
     typename CTxMemPool::indexed_transaction_set::index<name>::type::iterator
         it = pool.mapTx.get<name>().begin();
     int count = 0;
     for (; it != pool.mapTx.get<name>().end(); ++it, ++count) {
         BOOST_CHECK_MESSAGE(it->GetTx().GetId().ToString() ==
                                 sortedOrder[count],
                             it->GetTx().GetId().ToString()
                                 << " != " << sortedOrder[count] << " in test "
                                 << testcase << ":" << count);
     }
 }
 
 BOOST_AUTO_TEST_CASE(MempoolIndexingTest) {
     CTxMemPool pool;
     LOCK2(cs_main, pool.cs);
     TestMemPoolEntryHelper entry;
 
     /**
      * Remove the default nonzero sigops, since the below tests are focussing on
      * fee-based ordering and involve some artificially very tiny 21-byte
      * transactions without any inputs.
      */
     entry.SigOpCount(0);
 
     /* 3rd highest fee */
     CMutableTransaction tx1 = CMutableTransaction();
     tx1.vout.resize(1);
     tx1.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx1.vout[0].nValue = 10 * COIN;
     pool.addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(tx1));
 
     /* highest fee */
     CMutableTransaction tx2 = CMutableTransaction();
     tx2.vout.resize(1);
     tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx2.vout[0].nValue = 2 * COIN;
     pool.addUnchecked(entry.Fee(20000 * SATOSHI).FromTx(tx2));
 
     /* lowest fee */
     CMutableTransaction tx3 = CMutableTransaction();
     tx3.vout.resize(1);
     tx3.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx3.vout[0].nValue = 5 * COIN;
     pool.addUnchecked(entry.Fee(Amount::zero()).FromTx(tx3));
 
     /* 2nd highest fee */
     CMutableTransaction tx4 = CMutableTransaction();
     tx4.vout.resize(1);
     tx4.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx4.vout[0].nValue = 6 * COIN;
     pool.addUnchecked(entry.Fee(15000 * SATOSHI).FromTx(tx4));
 
     /* equal fee rate to tx1, but newer */
     CMutableTransaction tx5 = CMutableTransaction();
     tx5.vout.resize(1);
     tx5.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx5.vout[0].nValue = 11 * COIN;
     entry.nTime = 1;
     pool.addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(tx5));
     BOOST_CHECK_EQUAL(pool.size(), 5UL);
 
     std::vector<std::string> sortedOrder;
     sortedOrder.resize(5);
     sortedOrder[0] = tx3.GetId().ToString(); // 0
     sortedOrder[1] = tx5.GetId().ToString(); // 10000
     sortedOrder[2] = tx1.GetId().ToString(); // 10000
     sortedOrder[3] = tx4.GetId().ToString(); // 15000
     sortedOrder[4] = tx2.GetId().ToString(); // 20000
     CheckSort<descendant_score>(pool, sortedOrder, "MempoolIndexingTest1");
 
     /* low fee but with high fee child */
     /* tx6 -> tx7 -> tx8, tx9 -> tx10 */
     CMutableTransaction tx6 = CMutableTransaction();
     tx6.vout.resize(1);
     tx6.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx6.vout[0].nValue = 20 * COIN;
     pool.addUnchecked(entry.Fee(Amount::zero()).FromTx(tx6));
     BOOST_CHECK_EQUAL(pool.size(), 6UL);
     // Check that at this point, tx6 is sorted low
     sortedOrder.insert(sortedOrder.begin(), tx6.GetId().ToString());
     CheckSort<descendant_score>(pool, sortedOrder, "MempoolIndexingTest2");
 
     CTxMemPool::setEntries setAncestors;
     setAncestors.insert(pool.mapTx.find(tx6.GetId()));
     CMutableTransaction tx7 = CMutableTransaction();
     tx7.vin.resize(1);
     tx7.vin[0].prevout = COutPoint(tx6.GetId(), 0);
     tx7.vin[0].scriptSig = CScript() << OP_11;
     tx7.vout.resize(2);
     tx7.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx7.vout[0].nValue = 10 * COIN;
     tx7.vout[1].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx7.vout[1].nValue = 1 * COIN;
 
     CTxMemPool::setEntries setAncestorsCalculated;
     std::string dummy;
     BOOST_CHECK_EQUAL(
         pool.CalculateMemPoolAncestors(entry.Fee(2000000 * SATOSHI).FromTx(tx7),
                                        setAncestorsCalculated, 100, 1000000,
                                        1000, 1000000, dummy),
         true);
     BOOST_CHECK(setAncestorsCalculated == setAncestors);
 
     pool.addUnchecked(entry.FromTx(tx7), setAncestors);
     BOOST_CHECK_EQUAL(pool.size(), 7UL);
 
     // Now tx6 should be sorted higher (high fee child): tx7, tx6, tx2, ...
     sortedOrder.erase(sortedOrder.begin());
     sortedOrder.push_back(tx6.GetId().ToString());
     sortedOrder.push_back(tx7.GetId().ToString());
     CheckSort<descendant_score>(pool, sortedOrder, "MempoolIndexingTest3");
 
     /* low fee child of tx7 */
     CMutableTransaction tx8 = CMutableTransaction();
     tx8.vin.resize(1);
     tx8.vin[0].prevout = COutPoint(tx7.GetId(), 0);
     tx8.vin[0].scriptSig = CScript() << OP_11;
     tx8.vout.resize(1);
     tx8.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx8.vout[0].nValue = 10 * COIN;
     setAncestors.insert(pool.mapTx.find(tx7.GetId()));
     pool.addUnchecked(entry.Fee(Amount::zero()).Time(2).FromTx(tx8),
                       setAncestors);
 
     // Now tx8 should be sorted low, but tx6/tx both high
     sortedOrder.insert(sortedOrder.begin(), tx8.GetId().ToString());
     CheckSort<descendant_score>(pool, sortedOrder, "MempoolIndexingTest4");
 
     /* low fee child of tx7 */
     CMutableTransaction tx9 = CMutableTransaction();
     tx9.vin.resize(1);
     tx9.vin[0].prevout = COutPoint(tx7.GetId(), 1);
     tx9.vin[0].scriptSig = CScript() << OP_11;
     tx9.vout.resize(1);
     tx9.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx9.vout[0].nValue = 1 * COIN;
     pool.addUnchecked(entry.Fee(Amount::zero()).Time(3).FromTx(tx9),
                       setAncestors);
 
     // tx9 should be sorted low
     BOOST_CHECK_EQUAL(pool.size(), 9UL);
     sortedOrder.insert(sortedOrder.begin(), tx9.GetId().ToString());
     CheckSort<descendant_score>(pool, sortedOrder, "MempoolIndexingTest5");
 
     std::vector<std::string> snapshotOrder = sortedOrder;
 
     setAncestors.insert(pool.mapTx.find(tx8.GetId()));
     setAncestors.insert(pool.mapTx.find(tx9.GetId()));
     /* tx10 depends on tx8 and tx9 and has a high fee*/
     CMutableTransaction tx10 = CMutableTransaction();
     tx10.vin.resize(2);
     tx10.vin[0].prevout = COutPoint(tx8.GetId(), 0);
     tx10.vin[0].scriptSig = CScript() << OP_11;
     tx10.vin[1].prevout = COutPoint(tx9.GetId(), 0);
     tx10.vin[1].scriptSig = CScript() << OP_11;
     tx10.vout.resize(1);
     tx10.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx10.vout[0].nValue = 10 * COIN;
 
     setAncestorsCalculated.clear();
     BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(
                           entry.Fee(200000 * SATOSHI).Time(4).FromTx(tx10),
                           setAncestorsCalculated, 100, 1000000, 1000, 1000000,
                           dummy),
                       true);
     BOOST_CHECK(setAncestorsCalculated == setAncestors);
 
     pool.addUnchecked(entry.FromTx(tx10), setAncestors);
 
     /**
      *  tx8 and tx9 should both now be sorted higher
      *  Final order after tx10 is added:
      *
      *  tx3 = 0 (1)
      *  tx5 = 10000 (1)
      *  tx1 = 10000 (1)
      *  tx4 = 15000 (1)
      *  tx2 = 20000 (1)
      *  tx9 = 200k (2 txs)
      *  tx8 = 200k (2 txs)
      *  tx10 = 200k (1 tx)
      *  tx6 = 2.2M (5 txs)
      *  tx7 = 2.2M (4 txs)
      */
     // take out tx9, tx8 from the beginning
     sortedOrder.erase(sortedOrder.begin(), sortedOrder.begin() + 2);
     sortedOrder.insert(sortedOrder.begin() + 5, tx9.GetId().ToString());
     sortedOrder.insert(sortedOrder.begin() + 6, tx8.GetId().ToString());
     // tx10 is just before tx6
     sortedOrder.insert(sortedOrder.begin() + 7, tx10.GetId().ToString());
     CheckSort<descendant_score>(pool, sortedOrder, "MempoolIndexingTest6");
 
     // there should be 10 transactions in the mempool
     BOOST_CHECK_EQUAL(pool.size(), 10UL);
 
     // Now try removing tx10 and verify the sort order returns to normal
     pool.removeRecursive(pool.mapTx.find(tx10.GetId())->GetTx());
     CheckSort<descendant_score>(pool, snapshotOrder, "MempoolIndexingTest7");
 
     pool.removeRecursive(pool.mapTx.find(tx9.GetId())->GetTx());
     pool.removeRecursive(pool.mapTx.find(tx8.GetId())->GetTx());
 }
 
 BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) {
     CTxMemPool pool;
     LOCK2(cs_main, pool.cs);
     TestMemPoolEntryHelper entry;
 
     /**
      * Remove the default nonzero sigops, since the below tests are focussing on
      * fee-based ordering and involve some artificially very tiny 21-byte
      * transactions without any inputs.
      */
     entry.SigOpCount(0);
 
     /* 3rd highest fee */
     CMutableTransaction tx1 = CMutableTransaction();
     tx1.vout.resize(1);
     tx1.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx1.vout[0].nValue = 10 * COIN;
     pool.addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(tx1));
 
     /* highest fee */
     CMutableTransaction tx2 = CMutableTransaction();
     tx2.vout.resize(1);
     tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx2.vout[0].nValue = 2 * COIN;
     pool.addUnchecked(entry.Fee(20000 * SATOSHI).FromTx(tx2));
     uint64_t tx2Size = CTransaction(tx2).GetTotalSize();
 
     /* lowest fee */
     CMutableTransaction tx3 = CMutableTransaction();
     tx3.vout.resize(1);
     tx3.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx3.vout[0].nValue = 5 * COIN;
     pool.addUnchecked(entry.Fee(Amount::zero()).FromTx(tx3));
 
     /* 2nd highest fee */
     CMutableTransaction tx4 = CMutableTransaction();
     tx4.vout.resize(1);
     tx4.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx4.vout[0].nValue = 6 * COIN;
     pool.addUnchecked(entry.Fee(15000 * SATOSHI).FromTx(tx4));
 
     /* equal fee rate to tx1, but newer */
     CMutableTransaction tx5 = CMutableTransaction();
     tx5.vout.resize(1);
     tx5.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx5.vout[0].nValue = 11 * COIN;
     pool.addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(tx5));
     BOOST_CHECK_EQUAL(pool.size(), 5UL);
 
     std::vector<std::string> sortedOrder;
     sortedOrder.resize(5);
     sortedOrder[0] = tx2.GetId().ToString(); // 20000
     sortedOrder[1] = tx4.GetId().ToString(); // 15000
     // tx1 and tx5 are both 10000
     // Ties are broken by hash, not timestamp, so determine which hash comes
     // first.
     if (tx1.GetId() < tx5.GetId()) {
         sortedOrder[2] = tx1.GetId().ToString();
         sortedOrder[3] = tx5.GetId().ToString();
     } else {
         sortedOrder[2] = tx5.GetId().ToString();
         sortedOrder[3] = tx1.GetId().ToString();
     }
     sortedOrder[4] = tx3.GetId().ToString(); // 0
 
     CheckSort<ancestor_score>(pool, sortedOrder,
                               "MempoolAncestorIndexingTest1");
 
     /* low fee parent with high fee child */
     /* tx6 (0) -> tx7 (high) */
     CMutableTransaction tx6 = CMutableTransaction();
     tx6.vout.resize(1);
     tx6.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx6.vout[0].nValue = 20 * COIN;
     uint64_t tx6Size = CTransaction(tx6).GetTotalSize();
 
     pool.addUnchecked(entry.Fee(Amount::zero()).FromTx(tx6));
     BOOST_CHECK_EQUAL(pool.size(), 6UL);
     // Ties are broken by hash
     if (tx3.GetId() < tx6.GetId()) {
         sortedOrder.push_back(tx6.GetId().ToString());
     } else {
         sortedOrder.insert(sortedOrder.end() - 1, tx6.GetId().ToString());
     }
 
     CheckSort<ancestor_score>(pool, sortedOrder,
                               "MempoolAncestorIndexingTest2");
 
     CMutableTransaction tx7 = CMutableTransaction();
     tx7.vin.resize(1);
     tx7.vin[0].prevout = COutPoint(tx6.GetId(), 0);
     tx7.vin[0].scriptSig = CScript() << OP_11;
     tx7.vout.resize(1);
     tx7.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx7.vout[0].nValue = 10 * COIN;
     uint64_t tx7Size = CTransaction(tx7).GetTotalSize();
 
     /* set the fee to just below tx2's feerate when including ancestor */
     Amount fee = int64_t((20000 / tx2Size) * (tx7Size + tx6Size) - 1) * SATOSHI;
 
     // CTxMemPoolEntry entry7(tx7, fee, 2, 10.0, 1, true);
     pool.addUnchecked(entry.Fee(Amount(fee)).FromTx(tx7));
     BOOST_CHECK_EQUAL(pool.size(), 7UL);
     sortedOrder.insert(sortedOrder.begin() + 1, tx7.GetId().ToString());
     CheckSort<ancestor_score>(pool, sortedOrder,
                               "MempoolAncestorIndexingTest3");
 
     /* after tx6 is mined, tx7 should move up in the sort */
     std::vector<CTransactionRef> vtx;
     vtx.push_back(MakeTransactionRef(tx6));
     pool.removeForBlock(vtx, 1);
 
     sortedOrder.erase(sortedOrder.begin() + 1);
     // Ties are broken by hash
     if (tx3.GetId() < tx6.GetId()) {
         sortedOrder.pop_back();
     } else {
         sortedOrder.erase(sortedOrder.end() - 2);
     }
     sortedOrder.insert(sortedOrder.begin(), tx7.GetId().ToString());
     CheckSort<ancestor_score>(pool, sortedOrder,
                               "MempoolAncestorIndexingTest4");
 
     // High-fee parent, low-fee child
     // tx7 -> tx8
     CMutableTransaction tx8 = CMutableTransaction();
     tx8.vin.resize(1);
     tx8.vin[0].prevout = COutPoint(tx7.GetId(), 0);
     tx8.vin[0].scriptSig = CScript() << OP_11;
     tx8.vout.resize(1);
     tx8.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
     tx8.vout[0].nValue = 10 * COIN;
 
     // Check that we sort by min(feerate, ancestor_feerate):
     // set the fee so that the ancestor feerate is above tx1/5,
     // but the transaction's own feerate is lower
     pool.addUnchecked(entry.Fee(Amount(5000 * SATOSHI)).FromTx(tx8));
     sortedOrder.insert(sortedOrder.end() - 1, tx8.GetId().ToString());
     CheckSort<ancestor_score>(pool, sortedOrder,
                               "MempoolAncestorIndexingTest5");
 }
 
 BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) {
     CTxMemPool pool;
     LOCK2(cs_main, pool.cs);
     TestMemPoolEntryHelper entry;
     Amount feeIncrement = MEMPOOL_FULL_FEE_INCREMENT.GetFeePerK();
 
     CMutableTransaction tx1 = CMutableTransaction();
     tx1.vin.resize(1);
     tx1.vin[0].scriptSig = CScript() << OP_1;
     tx1.vout.resize(1);
     tx1.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL;
     tx1.vout[0].nValue = 10 * COIN;
     pool.addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(tx1));
 
     CMutableTransaction tx2 = CMutableTransaction();
     tx2.vin.resize(1);
     tx2.vin[0].scriptSig = CScript() << OP_2;
     tx2.vout.resize(1);
     tx2.vout[0].scriptPubKey = CScript() << OP_2 << OP_EQUAL;
     tx2.vout[0].nValue = 10 * COIN;
     pool.addUnchecked(entry.Fee(5000 * SATOSHI).FromTx(tx2));
 
     // should do nothing
     pool.TrimToSize(pool.DynamicMemoryUsage());
     BOOST_CHECK(pool.exists(tx1.GetId()));
     BOOST_CHECK(pool.exists(tx2.GetId()));
 
     // should remove the lower-feerate transaction
     pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4);
     BOOST_CHECK(pool.exists(tx1.GetId()));
     BOOST_CHECK(!pool.exists(tx2.GetId()));
 
     pool.addUnchecked(entry.FromTx(tx2));
     CMutableTransaction tx3 = CMutableTransaction();
     tx3.vin.resize(1);
     tx3.vin[0].prevout = COutPoint(tx2.GetId(), 0);
     tx3.vin[0].scriptSig = CScript() << OP_2;
     tx3.vout.resize(1);
     tx3.vout[0].scriptPubKey = CScript() << OP_3 << OP_EQUAL;
     tx3.vout[0].nValue = 10 * COIN;
     pool.addUnchecked(entry.Fee(20000 * SATOSHI).FromTx(tx3));
 
     // tx3 should pay for tx2 (CPFP)
     pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4);
     BOOST_CHECK(!pool.exists(tx1.GetId()));
     BOOST_CHECK(pool.exists(tx2.GetId()));
     BOOST_CHECK(pool.exists(tx3.GetId()));
 
     // mempool is limited to tx1's size in memory usage, so nothing fits
     pool.TrimToSize(CTransaction(tx1).GetTotalSize());
     BOOST_CHECK(!pool.exists(tx1.GetId()));
     BOOST_CHECK(!pool.exists(tx2.GetId()));
     BOOST_CHECK(!pool.exists(tx3.GetId()));
 
     CFeeRate maxFeeRateRemoved(25000 * SATOSHI,
                                CTransaction(tx3).GetTotalSize() +
                                    CTransaction(tx2).GetTotalSize());
     BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(),
                       maxFeeRateRemoved.GetFeePerK() + feeIncrement);
 
     CMutableTransaction tx4 = CMutableTransaction();
     tx4.vin.resize(2);
     tx4.vin[0].prevout = COutPoint();
     tx4.vin[0].scriptSig = CScript() << OP_4;
     tx4.vin[1].prevout = COutPoint();
     tx4.vin[1].scriptSig = CScript() << OP_4;
     tx4.vout.resize(2);
     tx4.vout[0].scriptPubKey = CScript() << OP_4 << OP_EQUAL;
     tx4.vout[0].nValue = 10 * COIN;
     tx4.vout[1].scriptPubKey = CScript() << OP_4 << OP_EQUAL;
     tx4.vout[1].nValue = 10 * COIN;
 
     CMutableTransaction tx5 = CMutableTransaction();
     tx5.vin.resize(2);
     tx5.vin[0].prevout = COutPoint(tx4.GetId(), 0);
     tx5.vin[0].scriptSig = CScript() << OP_4;
     tx5.vin[1].prevout = COutPoint();
     tx5.vin[1].scriptSig = CScript() << OP_5;
     tx5.vout.resize(2);
     tx5.vout[0].scriptPubKey = CScript() << OP_5 << OP_EQUAL;
     tx5.vout[0].nValue = 10 * COIN;
     tx5.vout[1].scriptPubKey = CScript() << OP_5 << OP_EQUAL;
     tx5.vout[1].nValue = 10 * COIN;
 
     CMutableTransaction tx6 = CMutableTransaction();
     tx6.vin.resize(2);
     tx6.vin[0].prevout = COutPoint(tx4.GetId(), 1);
     tx6.vin[0].scriptSig = CScript() << OP_4;
     tx6.vin[1].prevout = COutPoint();
     tx6.vin[1].scriptSig = CScript() << OP_6;
     tx6.vout.resize(2);
     tx6.vout[0].scriptPubKey = CScript() << OP_6 << OP_EQUAL;
     tx6.vout[0].nValue = 10 * COIN;
     tx6.vout[1].scriptPubKey = CScript() << OP_6 << OP_EQUAL;
     tx6.vout[1].nValue = 10 * COIN;
 
     CMutableTransaction tx7 = CMutableTransaction();
     tx7.vin.resize(2);
     tx7.vin[0].prevout = COutPoint(tx5.GetId(), 0);
     tx7.vin[0].scriptSig = CScript() << OP_5;
     tx7.vin[1].prevout = COutPoint(tx6.GetId(), 0);
     tx7.vin[1].scriptSig = CScript() << OP_6;
     tx7.vout.resize(2);
     tx7.vout[0].scriptPubKey = CScript() << OP_7 << OP_EQUAL;
     tx7.vout[0].nValue = 10 * COIN;
     tx7.vout[1].scriptPubKey = CScript() << OP_7 << OP_EQUAL;
     tx7.vout[1].nValue = 10 * COIN;
 
     pool.addUnchecked(entry.Fee(7000 * SATOSHI).FromTx(tx4));
     pool.addUnchecked(entry.Fee(1000 * SATOSHI).FromTx(tx5));
     pool.addUnchecked(entry.Fee(1100 * SATOSHI).FromTx(tx6));
     pool.addUnchecked(entry.Fee(9000 * SATOSHI).FromTx(tx7));
 
     // we only require this to remove, at max, 2 txn, because it's not clear
     // what we're really optimizing for aside from that
     pool.TrimToSize(pool.DynamicMemoryUsage() - 1);
     BOOST_CHECK(pool.exists(tx4.GetId()));
     BOOST_CHECK(pool.exists(tx6.GetId()));
     BOOST_CHECK(!pool.exists(tx7.GetId()));
 
     if (!pool.exists(tx5.GetId())) {
         pool.addUnchecked(entry.Fee(1000 * SATOSHI).FromTx(tx5));
     }
     pool.addUnchecked(entry.Fee(9000 * SATOSHI).FromTx(tx7));
 
     // should maximize mempool size by only removing 5/7
     pool.TrimToSize(pool.DynamicMemoryUsage() / 2);
     BOOST_CHECK(pool.exists(tx4.GetId()));
     BOOST_CHECK(!pool.exists(tx5.GetId()));
     BOOST_CHECK(pool.exists(tx6.GetId()));
     BOOST_CHECK(!pool.exists(tx7.GetId()));
 
     pool.addUnchecked(entry.Fee(1000 * SATOSHI).FromTx(tx5));
     pool.addUnchecked(entry.Fee(9000 * SATOSHI).FromTx(tx7));
 
     std::vector<CTransactionRef> vtx;
     SetMockTime(42);
     SetMockTime(42 + CTxMemPool::ROLLING_FEE_HALFLIFE);
     BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(),
                       maxFeeRateRemoved.GetFeePerK() + feeIncrement);
     // ... we should keep the same min fee until we get a block
     pool.removeForBlock(vtx, 1);
     SetMockTime(42 + 2 * CTxMemPool::ROLLING_FEE_HALFLIFE);
     BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(),
                       (maxFeeRateRemoved.GetFeePerK() + feeIncrement) / 2);
     // ... then feerate should drop 1/2 each halflife
 
     SetMockTime(42 + 2 * CTxMemPool::ROLLING_FEE_HALFLIFE +
                 CTxMemPool::ROLLING_FEE_HALFLIFE / 2);
     BOOST_CHECK_EQUAL(
         pool.GetMinFee(pool.DynamicMemoryUsage() * 5 / 2).GetFeePerK(),
         (maxFeeRateRemoved.GetFeePerK() + feeIncrement) / 4);
     // ... with a 1/2 halflife when mempool is < 1/2 its target size
 
     SetMockTime(42 + 2 * CTxMemPool::ROLLING_FEE_HALFLIFE +
                 CTxMemPool::ROLLING_FEE_HALFLIFE / 2 +
                 CTxMemPool::ROLLING_FEE_HALFLIFE / 4);
     BOOST_CHECK_EQUAL(
         pool.GetMinFee(pool.DynamicMemoryUsage() * 9 / 2).GetFeePerK(),
         (maxFeeRateRemoved.GetFeePerK() + feeIncrement) / 8 + SATOSHI);
     // ... with a 1/4 halflife when mempool is < 1/4 its target size
-
-    SetMockTime(0);
 }
 
 // expectedSize can be smaller than correctlyOrderedIds.size(), since we
 // might be testing intermediary states. Just avoiding some slice operations,
 void CheckDisconnectPoolOrder(DisconnectedBlockTransactions &disconnectPool,
                               std::vector<TxId> correctlyOrderedIds,
                               unsigned int expectedSize) {
     int i = 0;
     BOOST_CHECK_EQUAL(disconnectPool.GetQueuedTx().size(), expectedSize);
     // Txns in queuedTx's insertion_order index are sorted from children to
     // parent txn
     for (const CTransactionRef &tx :
          reverse_iterate(disconnectPool.GetQueuedTx().get<insertion_order>())) {
         BOOST_CHECK(tx->GetId() == correctlyOrderedIds[i]);
         i++;
     }
 }
 
 typedef std::vector<CMutableTransaction *> vecptx;
 
 BOOST_AUTO_TEST_CASE(TestImportMempool) {
     CMutableTransaction chainedTxn[5];
     std::vector<TxId> correctlyOrderedIds;
     COutPoint lastOutpoint;
 
     // Construct a chain of 5 transactions
     for (int i = 0; i < 5; i++) {
         chainedTxn[i].vin.emplace_back(lastOutpoint);
         chainedTxn[i].vout.emplace_back(10 * SATOSHI, CScript() << OP_TRUE);
         correctlyOrderedIds.push_back(chainedTxn[i].GetId());
         lastOutpoint = COutPoint(correctlyOrderedIds[i], 0);
     }
 
     // The first 3 txns simulate once confirmed transactions that have been
     // disconnected. We test 3 different orders: in order, one case of mixed
     // order and inverted order.
     vecptx disconnectedTxnsInOrder = {&chainedTxn[0], &chainedTxn[1],
                                       &chainedTxn[2]};
     vecptx disconnectedTxnsMixedOrder = {&chainedTxn[1], &chainedTxn[2],
                                          &chainedTxn[0]};
     vecptx disconnectedTxnsInvertedOrder = {&chainedTxn[2], &chainedTxn[1],
                                             &chainedTxn[0]};
 
     // The last 2 txns simulate a chain of unconfirmed transactions in the
     // mempool. We test 2 different orders: in and out of order.
     vecptx unconfTxnsInOrder = {&chainedTxn[3], &chainedTxn[4]};
     vecptx unconfTxnsOutOfOrder = {&chainedTxn[4], &chainedTxn[3]};
 
     // Now we test all combinations of the previously defined orders for
     // disconnected and unconfirmed txns. The expected outcome is to have these
     // transactions in the correct order in queuedTx, as defined in
     // correctlyOrderedIds.
     for (auto &disconnectedTxns :
          {disconnectedTxnsInOrder, disconnectedTxnsMixedOrder,
           disconnectedTxnsInvertedOrder}) {
         for (auto &unconfTxns : {unconfTxnsInOrder, unconfTxnsOutOfOrder}) {
             // addForBlock inserts disconnectTxns in disconnectPool. They
             // simulate transactions that were once confirmed in a block
             std::vector<CTransactionRef> vtx;
             for (auto tx : disconnectedTxns) {
                 vtx.push_back(MakeTransactionRef(*tx));
             }
             DisconnectedBlockTransactions disconnectPool;
             disconnectPool.addForBlock(vtx);
             CheckDisconnectPoolOrder(disconnectPool, correctlyOrderedIds,
                                      disconnectedTxns.size());
 
             // If the mempool is empty, importMempool doesn't change
             // disconnectPool
             CTxMemPool testPool;
 
             disconnectPool.importMempool(testPool);
             CheckDisconnectPoolOrder(disconnectPool, correctlyOrderedIds,
                                      disconnectedTxns.size());
 
             {
                 LOCK2(cs_main, testPool.cs);
                 // Add all unconfirmed transactions in testPool
                 for (auto tx : unconfTxns) {
                     TestMemPoolEntryHelper entry;
                     testPool.addUnchecked(entry.FromTx(*tx));
                 }
             }
 
             // Now we test importMempool with a non empty mempool
             disconnectPool.importMempool(testPool);
             CheckDisconnectPoolOrder(disconnectPool, correctlyOrderedIds,
                                      disconnectedTxns.size() +
                                          unconfTxns.size());
             // We must clear disconnectPool to not trigger the assert in its
             // destructor
             disconnectPool.clear();
         }
     }
 }
 
 inline CTransactionRef
 make_tx(std::vector<Amount> &&output_values,
         std::vector<CTransactionRef> &&inputs = std::vector<CTransactionRef>(),
         std::vector<uint32_t> &&input_indices = std::vector<uint32_t>()) {
     CMutableTransaction tx = CMutableTransaction();
     tx.vin.resize(inputs.size());
     tx.vout.resize(output_values.size());
     for (size_t i = 0; i < inputs.size(); ++i) {
         tx.vin[i].prevout =
             COutPoint(inputs[i]->GetId(),
                       input_indices.size() > i ? input_indices[i] : 0);
     }
     for (size_t i = 0; i < output_values.size(); ++i) {
         tx.vout[i].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
         tx.vout[i].nValue = output_values[i];
     }
     return MakeTransactionRef(tx);
 }
 
 #define MK_OUTPUTS(amounts...)                                                 \
     std::vector<Amount> { amounts }
 #define MK_INPUTS(txs...)                                                      \
     std::vector<CTransactionRef> { txs }
 #define MK_INPUT_IDX(idxes...)                                                 \
     std::vector<uint32_t> { idxes }
 
 BOOST_AUTO_TEST_CASE(MempoolAncestryTests) {
     size_t ancestors, descendants;
 
     CTxMemPool pool;
     LOCK2(cs_main, pool.cs);
     TestMemPoolEntryHelper entry;
 
     /* Base transaction */
     //
     // [tx1]
     //
     CTransactionRef tx1 = make_tx(MK_OUTPUTS(10 * COIN));
     pool.addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(tx1));
 
     // Ancestors / descendants should be 1 / 1 (itself / itself)
     pool.GetTransactionAncestry(tx1->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 1ULL);
     BOOST_CHECK_EQUAL(descendants, 1ULL);
 
     /* Child transaction */
     //
     // [tx1].0 <- [tx2]
     //
     CTransactionRef tx2 =
         make_tx(MK_OUTPUTS(495 * CENT, 5 * COIN), MK_INPUTS(tx1));
     pool.addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(tx2));
 
     // Ancestors / descendants should be:
     // transaction  ancestors   descendants
     // ============ =========== ===========
     // tx1          1 (tx1)     2 (tx1,2)
     // tx2          2 (tx1,2)   2 (tx1,2)
     pool.GetTransactionAncestry(tx1->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 1ULL);
     BOOST_CHECK_EQUAL(descendants, 2ULL);
     pool.GetTransactionAncestry(tx2->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 2ULL);
     BOOST_CHECK_EQUAL(descendants, 2ULL);
 
     /* Grand-child 1 */
     //
     // [tx1].0 <- [tx2].0 <- [tx3]
     //
     CTransactionRef tx3 =
         make_tx(MK_OUTPUTS(290 * CENT, 200 * CENT), MK_INPUTS(tx2));
     pool.addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(tx3));
 
     // Ancestors / descendants should be:
     // transaction  ancestors   descendants
     // ============ =========== ===========
     // tx1          1 (tx1)     3 (tx1,2,3)
     // tx2          2 (tx1,2)   3 (tx1,2,3)
     // tx3          3 (tx1,2,3) 3 (tx1,2,3)
     pool.GetTransactionAncestry(tx1->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 1ULL);
     BOOST_CHECK_EQUAL(descendants, 3ULL);
     pool.GetTransactionAncestry(tx2->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 2ULL);
     BOOST_CHECK_EQUAL(descendants, 3ULL);
     pool.GetTransactionAncestry(tx3->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 3ULL);
     BOOST_CHECK_EQUAL(descendants, 3ULL);
 
     /* Grand-child 2 */
     //
     // [tx1].0 <- [tx2].0 <- [tx3]
     //              |
     //              \---1 <- [tx4]
     //
     CTransactionRef tx4 = make_tx(MK_OUTPUTS(290 * CENT, 250 * CENT),
                                   MK_INPUTS(tx2), MK_INPUT_IDX(1));
     pool.addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(tx4));
 
     // Ancestors / descendants should be:
     // transaction  ancestors   descendants
     // ============ =========== ===========
     // tx1          1 (tx1)     4 (tx1,2,3,4)
     // tx2          2 (tx1,2)   4 (tx1,2,3,4)
     // tx3          3 (tx1,2,3) 4 (tx1,2,3,4)
     // tx4          3 (tx1,2,4) 4 (tx1,2,3,4)
     pool.GetTransactionAncestry(tx1->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 1ULL);
     BOOST_CHECK_EQUAL(descendants, 4ULL);
     pool.GetTransactionAncestry(tx2->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 2ULL);
     BOOST_CHECK_EQUAL(descendants, 4ULL);
     pool.GetTransactionAncestry(tx3->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 3ULL);
     BOOST_CHECK_EQUAL(descendants, 4ULL);
     pool.GetTransactionAncestry(tx4->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 3ULL);
     BOOST_CHECK_EQUAL(descendants, 4ULL);
 
     /* Make an alternate branch that is longer and connect it to tx3 */
     //
     // [ty1].0 <- [ty2].0 <- [ty3].0 <- [ty4].0 <- [ty5].0
     //                                              |
     // [tx1].0 <- [tx2].0 <- [tx3].0 <- [ty6] --->--/
     //              |
     //              \---1 <- [tx4]
     //
     CTransactionRef ty1, ty2, ty3, ty4, ty5;
     CTransactionRef *ty[5] = {&ty1, &ty2, &ty3, &ty4, &ty5};
     Amount v = 5 * COIN;
     for (uint64_t i = 0; i < 5; i++) {
         CTransactionRef &tyi = *ty[i];
         tyi = make_tx(MK_OUTPUTS(v), i > 0 ? MK_INPUTS(*ty[i - 1])
                                            : std::vector<CTransactionRef>());
         v -= 50 * CENT;
         pool.addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(tyi));
         pool.GetTransactionAncestry(tyi->GetId(), ancestors, descendants);
         BOOST_CHECK_EQUAL(ancestors, i + 1);
         BOOST_CHECK_EQUAL(descendants, i + 1);
     }
     CTransactionRef ty6 = make_tx(MK_OUTPUTS(5 * COIN), MK_INPUTS(tx3, ty5));
     pool.addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(ty6));
 
     // Ancestors / descendants should be:
     // transaction  ancestors           descendants
     // ============ =================== ===========
     // tx1          1 (tx1)             5 (tx1,2,3,4, ty6)
     // tx2          2 (tx1,2)           5 (tx1,2,3,4, ty6)
     // tx3          3 (tx1,2,3)         5 (tx1,2,3,4, ty6)
     // tx4          3 (tx1,2,4)         5 (tx1,2,3,4, ty6)
     // ty1          1 (ty1)             6 (ty1,2,3,4,5,6)
     // ty2          2 (ty1,2)           6 (ty1,2,3,4,5,6)
     // ty3          3 (ty1,2,3)         6 (ty1,2,3,4,5,6)
     // ty4          4 (y1234)           6 (ty1,2,3,4,5,6)
     // ty5          5 (y12345)          6 (ty1,2,3,4,5,6)
     // ty6          9 (tx123, ty123456) 6 (ty1,2,3,4,5,6)
     pool.GetTransactionAncestry(tx1->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 1ULL);
     BOOST_CHECK_EQUAL(descendants, 5ULL);
     pool.GetTransactionAncestry(tx2->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 2ULL);
     BOOST_CHECK_EQUAL(descendants, 5ULL);
     pool.GetTransactionAncestry(tx3->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 3ULL);
     BOOST_CHECK_EQUAL(descendants, 5ULL);
     pool.GetTransactionAncestry(tx4->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 3ULL);
     BOOST_CHECK_EQUAL(descendants, 5ULL);
     pool.GetTransactionAncestry(ty1->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 1ULL);
     BOOST_CHECK_EQUAL(descendants, 6ULL);
     pool.GetTransactionAncestry(ty2->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 2ULL);
     BOOST_CHECK_EQUAL(descendants, 6ULL);
     pool.GetTransactionAncestry(ty3->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 3ULL);
     BOOST_CHECK_EQUAL(descendants, 6ULL);
     pool.GetTransactionAncestry(ty4->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 4ULL);
     BOOST_CHECK_EQUAL(descendants, 6ULL);
     pool.GetTransactionAncestry(ty5->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 5ULL);
     BOOST_CHECK_EQUAL(descendants, 6ULL);
     pool.GetTransactionAncestry(ty6->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 9ULL);
     BOOST_CHECK_EQUAL(descendants, 6ULL);
 
     /* Ancestors represented more than once ("diamond") */
     //
     // [ta].0 <- [tb].0 -----<------- [td].0
     //            |                    |
     //            \---1 <- [tc].0 --<--/
     //
     CTransactionRef ta, tb, tc, td;
     ta = make_tx(/* output_values */ {10 * COIN});
     tb = make_tx(/* output_values */ {5 * COIN, 3 * COIN}, /* inputs */ {ta});
     tc = make_tx(/* output_values */ {2 * COIN}, /* inputs */ {tb},
                  /* input_indices */ {1});
     td = make_tx(/* output_values */ {6 * COIN}, /* inputs */ {tb, tc},
                  /* input_indices */ {0, 0});
     pool.clear();
     pool.addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(ta));
     pool.addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(tb));
     pool.addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(tc));
     pool.addUnchecked(entry.Fee(10000 * SATOSHI).FromTx(td));
 
     // Ancestors / descendants should be:
     // transaction  ancestors           descendants
     // ============ =================== ===========
     // ta           1 (ta               4 (ta,tb,tc,td)
     // tb           2 (ta,tb)           4 (ta,tb,tc,td)
     // tc           3 (ta,tb,tc)        4 (ta,tb,tc,td)
     // td           4 (ta,tb,tc,td)     4 (ta,tb,tc,td)
     pool.GetTransactionAncestry(ta->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 1ULL);
     BOOST_CHECK_EQUAL(descendants, 4ULL);
     pool.GetTransactionAncestry(tb->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 2ULL);
     BOOST_CHECK_EQUAL(descendants, 4ULL);
     pool.GetTransactionAncestry(tc->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 3ULL);
     BOOST_CHECK_EQUAL(descendants, 4ULL);
     pool.GetTransactionAncestry(td->GetId(), ancestors, descendants);
     BOOST_CHECK_EQUAL(ancestors, 4ULL);
     BOOST_CHECK_EQUAL(descendants, 4ULL);
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/setup_common.cpp b/src/test/setup_common.cpp
index da0acccfd3..1319119c8c 100644
--- a/src/test/setup_common.cpp
+++ b/src/test/setup_common.cpp
@@ -1,322 +1,323 @@
 // Copyright (c) 2011-2019 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include <test/setup_common.h>
 
 #include <banman.h>
 #include <chainparams.h>
 #include <config.h>
 #include <consensus/consensus.h>
 #include <consensus/validation.h>
 #include <crypto/sha256.h>
 #include <fs.h>
 #include <init.h>
 #include <key.h>
 #include <logging.h>
 #include <miner.h>
 #include <net.h>
 #include <noui.h>
 #include <pow.h>
 #include <pubkey.h>
 #include <random.h>
 #include <rpc/register.h>
 #include <rpc/server.h>
 #include <script/script_error.h>
 #include <script/scriptcache.h>
 #include <script/sigcache.h>
 #include <streams.h>
 #include <txdb.h>
 #include <txmempool.h>
 #include <util/strencodings.h>
 #include <util/time.h>
 #include <validation.h>
 #include <validationinterface.h>
 
 #include <memory>
 
 const std::function<std::string(const char *)> G_TRANSLATION_FUN = nullptr;
 
 FastRandomContext g_insecure_rand_ctx;
 
 std::ostream &operator<<(std::ostream &os, const uint256 &num) {
     os << num.ToString();
     return os;
 }
 
 std::ostream &operator<<(std::ostream &os, const ScriptError &err) {
     os << ScriptErrorString(err);
     return os;
 }
 
 BasicTestingSetup::BasicTestingSetup(const std::string &chainName)
     : m_path_root(fs::temp_directory_path() / "test_common_" PACKAGE_NAME /
                   strprintf("%lu_%i", static_cast<unsigned long>(GetTime()),
                             int(InsecureRandRange(1 << 30)))) {
+    SetMockTime(0);
     fs::create_directories(m_path_root);
     gArgs.ForceSetArg("-datadir", m_path_root.string());
     ClearDatadirCache();
     SelectParams(chainName);
     gArgs.ForceSetArg("-printtoconsole", "0");
     InitLogging();
     LogInstance().StartLogging();
     SHA256AutoDetect();
     ECC_Start();
     SetupEnvironment();
     SetupNetworking();
     InitSignatureCache();
     InitScriptExecutionCache();
 
     fCheckBlockIndex = true;
     static bool noui_connected = false;
     if (!noui_connected) {
         noui_connect();
         noui_connected = true;
     }
 }
 
 BasicTestingSetup::~BasicTestingSetup() {
     LogInstance().DisconnectTestLogger();
     fs::remove_all(m_path_root);
     ECC_Stop();
 }
 
 TestingSetup::TestingSetup(const std::string &chainName)
     : BasicTestingSetup(chainName) {
     const Config &config = GetConfig();
     const CChainParams &chainparams = config.GetChainParams();
 
     // Ideally we'd move all the RPC tests to the functional testing framework
     // instead of unit tests, but for now we need these here.
     RPCServer rpcServer;
     RegisterAllRPCCommands(config, rpcServer, tableRPC);
 
     /**
      * RPC does not come out of the warmup state on its own. Normally, this is
      * handled in bitcoind's init path, but unit tests do not trigger this
      * codepath, so we call it explicitly as part of setup.
      */
     std::string rpcWarmupStatus;
     if (RPCIsInWarmup(&rpcWarmupStatus)) {
         SetRPCWarmupFinished();
     }
 
     // We have to run a scheduler thread to prevent ActivateBestChain
     // from blocking due to queue overrun.
     threadGroup.create_thread(std::bind(&CScheduler::serviceQueue, &scheduler));
     GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
 
     g_mempool.setSanityCheck(1.0);
     pblocktree.reset(new CBlockTreeDB(1 << 20, true));
     pcoinsdbview.reset(new CCoinsViewDB(1 << 23, true));
     pcoinsTip.reset(new CCoinsViewCache(pcoinsdbview.get()));
     if (!LoadGenesisBlock(chainparams)) {
         throw std::runtime_error("LoadGenesisBlock failed.");
     }
     {
         CValidationState state;
         if (!ActivateBestChain(config, state)) {
             throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)",
                                                FormatStateMessage(state)));
         }
     }
     nScriptCheckThreads = 3;
     for (int i = 0; i < nScriptCheckThreads - 1; i++) {
         threadGroup.create_thread([i]() { return ThreadScriptCheck(i); });
     }
 
     g_banman =
         std::make_unique<BanMan>(GetDataDir() / "banlist.dat", chainparams,
                                  nullptr, DEFAULT_MISBEHAVING_BANTIME);
     // Deterministic randomness for tests.
     g_connman = std::make_unique<CConnman>(config, 0x1337, 0x1337);
 }
 
 TestingSetup::~TestingSetup() {
     threadGroup.interrupt_all();
     threadGroup.join_all();
     GetMainSignals().FlushBackgroundCallbacks();
     GetMainSignals().UnregisterBackgroundSignalScheduler();
     g_connman.reset();
     g_banman.reset();
     UnloadBlockIndex();
     pcoinsTip.reset();
     pcoinsdbview.reset();
     pblocktree.reset();
 }
 
 TestChain100Setup::TestChain100Setup()
     : TestingSetup(CBaseChainParams::REGTEST) {
     // Generate a 100-block chain:
     coinbaseKey.MakeNewKey(true);
     CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey())
                                      << OP_CHECKSIG;
     for (int i = 0; i < COINBASE_MATURITY; i++) {
         std::vector<CMutableTransaction> noTxns;
         CBlock b = CreateAndProcessBlock(noTxns, scriptPubKey);
         m_coinbase_txns.push_back(b.vtx[0]);
     }
 }
 
 //
 // Create a new block with just given transactions, coinbase paying to
 // scriptPubKey, and try to add it to the current chain.
 //
 CBlock TestChain100Setup::CreateAndProcessBlock(
     const std::vector<CMutableTransaction> &txns, const CScript &scriptPubKey) {
     const Config &config = GetConfig();
     std::unique_ptr<CBlockTemplate> pblocktemplate =
         BlockAssembler(config, g_mempool).CreateNewBlock(scriptPubKey);
     CBlock &block = pblocktemplate->block;
 
     // Replace mempool-selected txns with just coinbase plus passed-in txns:
     block.vtx.resize(1);
     for (const CMutableTransaction &tx : txns) {
         block.vtx.push_back(MakeTransactionRef(tx));
     }
 
     // Order transactions by canonical order
     std::sort(std::begin(block.vtx) + 1, std::end(block.vtx),
               [](const std::shared_ptr<const CTransaction> &txa,
                  const std::shared_ptr<const CTransaction> &txb) -> bool {
                   return txa->GetId() < txb->GetId();
               });
 
     // IncrementExtraNonce creates a valid coinbase and merkleRoot
     {
         LOCK(cs_main);
         unsigned int extraNonce = 0;
         IncrementExtraNonce(&block, ::ChainActive().Tip(),
                             config.GetMaxBlockSize(), extraNonce);
     }
 
     const Consensus::Params &params = config.GetChainParams().GetConsensus();
     while (!CheckProofOfWork(block.GetHash(), block.nBits, params)) {
         ++block.nNonce;
     }
 
     std::shared_ptr<const CBlock> shared_pblock =
         std::make_shared<const CBlock>(block);
     ProcessNewBlock(config, shared_pblock, true, nullptr);
 
     CBlock result = block;
     return result;
 }
 
 TestChain100Setup::~TestChain100Setup() {}
 
 CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CMutableTransaction &tx) {
     return FromTx(MakeTransactionRef(tx));
 }
 
 CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransactionRef &tx) {
     return CTxMemPoolEntry(tx, nFee, nTime, nHeight, spendsCoinbase,
                            nSigOpCount, LockPoints());
 }
 
 /**
  * @returns a real block
  * (0000000000013b8ab2cd513b0261a14096412195a72a0c4827d229dcc7e0f7af) with 9
  * txs.
  */
 CBlock getBlock13b8a() {
     CBlock block;
     CDataStream stream(
         ParseHex(
             "0100000090f0a9f110702f808219ebea1173056042a714bad51b916cb680000000"
             "0000005275289558f51c9966699404ae2294730c3c9f9bda53523ce50e9b95e558"
             "da2fdb261b4d4c86041b1ab1bf9309010000000100000000000000000000000000"
             "00000000000000000000000000000000000000ffffffff07044c86041b0146ffff"
             "ffff0100f2052a01000000434104e18f7afbe4721580e81e8414fc8c24d7cfacf2"
             "54bb5c7b949450c3e997c2dc1242487a8169507b631eb3771f2b425483fb13102c"
             "4eb5d858eef260fe70fbfae0ac00000000010000000196608ccbafa16abada9027"
             "80da4dc35dafd7af05fa0da08cf833575f8cf9e836000000004a493046022100da"
             "b24889213caf43ae6adc41cf1c9396c08240c199f5225acf45416330fd7dbd0221"
             "00fe37900e0644bf574493a07fc5edba06dbc07c311b947520c2d514bc5725dcb4"
             "01ffffffff0100f2052a010000001976a914f15d1921f52e4007b146dfa60f369e"
             "d2fc393ce288ac000000000100000001fb766c1288458c2bafcfec81e48b24d98e"
             "c706de6b8af7c4e3c29419bfacb56d000000008c493046022100f268ba165ce0ad"
             "2e6d93f089cfcd3785de5c963bb5ea6b8c1b23f1ce3e517b9f022100da7c0f21ad"
             "c6c401887f2bfd1922f11d76159cbc597fbd756a23dcbb00f4d7290141042b4e86"
             "25a96127826915a5b109852636ad0da753c9e1d5606a50480cd0c40f1f8b8d8982"
             "35e571fe9357d9ec842bc4bba1827daaf4de06d71844d0057707966affffffff02"
             "80969800000000001976a9146963907531db72d0ed1a0cfb471ccb63923446f388"
             "ac80d6e34c000000001976a914f0688ba1c0d1ce182c7af6741e02658c7d4dfcd3"
             "88ac000000000100000002c40297f730dd7b5a99567eb8d27b78758f607507c522"
             "92d02d4031895b52f2ff010000008b483045022100f7edfd4b0aac404e5bab4fd3"
             "889e0c6c41aa8d0e6fa122316f68eddd0a65013902205b09cc8b2d56e1cd1f7f2f"
             "afd60a129ed94504c4ac7bdc67b56fe67512658b3e014104732012cb962afa90d3"
             "1b25d8fb0e32c94e513ab7a17805c14ca4c3423e18b4fb5d0e676841733cb83aba"
             "f975845c9f6f2a8097b7d04f4908b18368d6fc2d68ecffffffffca5065ff9617cb"
             "cba45eb23726df6498a9b9cafed4f54cbab9d227b0035ddefb000000008a473044"
             "022068010362a13c7f9919fa832b2dee4e788f61f6f5d344a7c2a0da6ae7406056"
             "58022006d1af525b9a14a35c003b78b72bd59738cd676f845d1ff3fc25049e0100"
             "3614014104732012cb962afa90d31b25d8fb0e32c94e513ab7a17805c14ca4c342"
             "3e18b4fb5d0e676841733cb83abaf975845c9f6f2a8097b7d04f4908b18368d6fc"
             "2d68ecffffffff01001ec4110200000043410469ab4181eceb28985b9b4e895c13"
             "fa5e68d85761b7eee311db5addef76fa8621865134a221bd01f28ec9999ee3e021"
             "e60766e9d1f3458c115fb28650605f11c9ac000000000100000001cdaf2f758e91"
             "c514655e2dc50633d1e4c84989f8aa90a0dbc883f0d23ed5c2fa010000008b4830"
             "4502207ab51be6f12a1962ba0aaaf24a20e0b69b27a94fac5adf45aa7d2d18ffd9"
             "236102210086ae728b370e5329eead9accd880d0cb070aea0c96255fae6c4f1ddc"
             "ce1fd56e014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d78990"
             "4f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8"
             "ebbb12dcd4ffffffff02404b4c00000000001976a9142b6ba7c9d796b75eef7942"
             "fc9288edd37c32f5c388ac002d3101000000001976a9141befba0cdc1ad5652937"
             "1864d9f6cb042faa06b588ac000000000100000001b4a47603e71b61bc3326efd9"
             "0111bf02d2f549b067f4c4a8fa183b57a0f800cb010000008a4730440220177c37"
             "f9a505c3f1a1f0ce2da777c339bd8339ffa02c7cb41f0a5804f473c9230220585b"
             "25a2ee80eb59292e52b987dad92acb0c64eced92ed9ee105ad153cdb12d0014104"
             "43bd44f683467e549dae7d20d1d79cbdb6df985c6e9c029c8d0c6cb46cc1a4d3cf"
             "7923c5021b27f7a0b562ada113bc85d5fda5a1b41e87fe6e8802817cf69996ffff"
             "ffff0280651406000000001976a9145505614859643ab7b547cd7f1f5e7e2a1232"
             "2d3788ac00aa0271000000001976a914ea4720a7a52fc166c55ff2298e07baf70a"
             "e67e1b88ac00000000010000000586c62cd602d219bb60edb14a3e204de0705176"
             "f9022fe49a538054fb14abb49e010000008c493046022100f2bc2aba2534becbdf"
             "062eb993853a42bbbc282083d0daf9b4b585bd401aa8c9022100b1d7fd7ee0b956"
             "00db8535bbf331b19eed8d961f7a8e54159c53675d5f69df8c014104462e76fd40"
             "67b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c6"
             "9b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff03ad0e"
             "58ccdac3df9dc28a218bcf6f1997b0a93306faaa4b3a28ae83447b217901000000"
             "8b483045022100be12b2937179da88599e27bb31c3525097a07cdb52422d165b3c"
             "a2f2020ffcf702200971b51f853a53d644ebae9ec8f3512e442b1bcb6c315a5b49"
             "1d119d10624c83014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33"
             "d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312e"
             "f1c0e8ebbb12dcd4ffffffff2acfcab629bbc8685792603762c921580030ba144a"
             "f553d271716a95089e107b010000008b483045022100fa579a840ac258871365dd"
             "48cd7552f96c8eea69bd00d84f05b283a0dab311e102207e3c0ee9234814cfbb1b"
             "659b83671618f45abc1326b9edcc77d552a4f2a805c0014104462e76fd4067b3a0"
             "aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc3"
             "1895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffffdcdc6023bbc9"
             "944a658ddc588e61eacb737ddf0a3cd24f113b5a8634c517fcd2000000008b4830"
             "450221008d6df731df5d32267954bd7d2dda2302b74c6c2a6aa5c0ca64ecbabc1a"
             "f03c75022010e55c571d65da7701ae2da1956c442df81bbf076cdbac25133f99d9"
             "8a9ed34c014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d78990"
             "4f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8"
             "ebbb12dcd4ffffffffe15557cd5ce258f479dfd6dc6514edf6d7ed5b21fcfa4a03"
             "8fd69f06b83ac76e010000008b483045022023b3e0ab071eb11de2eb1cc3a67261"
             "b866f86bf6867d4558165f7c8c8aca2d86022100dc6e1f53a91de3efe8f6351285"
             "0811f26284b62f850c70ca73ed5de8771fb451014104462e76fd4067b3a0aa4207"
             "0082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0"
             "c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff01404b4c0000000000"
             "1976a9142b6ba7c9d796b75eef7942fc9288edd37c32f5c388ac00000000010000"
             "000166d7577163c932b4f9690ca6a80b6e4eb001f0a2fa9023df5595602aae96ed"
             "8d000000008a4730440220262b42546302dfb654a229cefc86432b89628ff259dc"
             "87edd1154535b16a67e102207b4634c020a97c3e7bbd0d4d19da6aa2269ad9dded"
             "4026e896b213d73ca4b63f014104979b82d02226b3a4597523845754d44f13639e"
             "3bf2df5e82c6aab2bdc79687368b01b1ab8b19875ae3c90d661a3d0a33161dab29"
             "934edeb36aa01976be3baf8affffffff02404b4c00000000001976a9144854e695"
             "a02af0aeacb823ccbc272134561e0a1688ac40420f00000000001976a914abee93"
             "376d6b37b5c2940655a6fcaf1c8e74237988ac0000000001000000014e3f8ef2e9"
             "1349a9059cb4f01e54ab2597c1387161d3da89919f7ea6acdbb371010000008c49"
             "304602210081f3183471a5ca22307c0800226f3ef9c353069e0773ac76bb580654"
             "d56aa523022100d4c56465bdc069060846f4fbf2f6b20520b2a80b08b168b31e66"
             "ddb9c694e240014104976c79848e18251612f8940875b2b08d06e6dc73b9840e88"
             "60c066b7e87432c477e9a59a453e71e6d76d5fe34058b800a098fc1740ce3012e8"
             "fc8a00c96af966ffffffff02c0e1e400000000001976a9144134e75a6fcb604203"
             "4aab5e18570cf1f844f54788ac404b4c00000000001976a9142b6ba7c9d796b75e"
             "ef7942fc9288edd37c32f5c388ac00000000"),
         SER_NETWORK, PROTOCOL_VERSION);
     stream >> block;
     return block;
 }
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index a9af6e041c..d30543e294 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -1,492 +1,490 @@
 // Copyright (c) 2012-2016 The Bitcoin Core developers
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
 #include <chain.h>
 #include <chainparams.h>
 #include <config.h>
 #include <consensus/validation.h>
 #include <interfaces/chain.h>
 #include <rpc/server.h>
 #include <validation.h>
 #include <wallet/coincontrol.h>
 #include <wallet/rpcdump.h>
 #include <wallet/wallet.h>
 
 #include <test/setup_common.h>
 #include <wallet/test/wallet_test_fixture.h>
 
 #include <boost/test/unit_test.hpp>
 
 #include <univalue.h>
 
 #include <cstdint>
 #include <memory>
 #include <vector>
 
 BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup)
 
 static void AddKey(CWallet &wallet, const CKey &key) {
     LOCK(wallet.cs_wallet);
     wallet.AddKeyPubKey(key, key.GetPubKey());
 }
 
 BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) {
     auto chain = interfaces::MakeChain();
 
     // Cap last block file size, and mine new block in a new block file.
     CBlockIndex *oldTip = ::ChainActive().Tip();
     GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE;
     CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
     CBlockIndex *newTip = ::ChainActive().Tip();
 
     LockAnnotation lock(::cs_main);
     auto locked_chain = chain->lock();
 
     // Verify ScanForWalletTransactions accommodates a null start block.
     {
         CWallet wallet(Params(), *chain, WalletLocation(),
                        WalletDatabase::CreateDummy());
         AddKey(wallet, coinbaseKey);
         WalletRescanReserver reserver(&wallet);
         reserver.reserve();
         CWallet::ScanResult result = wallet.ScanForWalletTransactions(
             BlockHash(), BlockHash(), reserver, false /* update */);
         BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS);
         BOOST_CHECK(result.failed_block.IsNull());
         BOOST_CHECK(result.stop_block.IsNull());
         BOOST_CHECK(!result.stop_height);
         BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), Amount::zero());
     }
 
     // Verify ScanForWalletTransactions picks up transactions in both the old
     // and new block files.
     {
         CWallet wallet(Params(), *chain, WalletLocation(),
                        WalletDatabase::CreateDummy());
         AddKey(wallet, coinbaseKey);
         WalletRescanReserver reserver(&wallet);
         reserver.reserve();
         CWallet::ScanResult result = wallet.ScanForWalletTransactions(
             oldTip->GetBlockHash(), BlockHash(), reserver, false /* update */);
         BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS);
         BOOST_CHECK(result.failed_block.IsNull());
         BOOST_CHECK_EQUAL(result.stop_block, newTip->GetBlockHash());
         BOOST_CHECK_EQUAL(*result.stop_height, newTip->nHeight);
         BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 100 * COIN);
     }
 
     // Prune the older block file.
     PruneOneBlockFile(oldTip->GetBlockPos().nFile);
     UnlinkPrunedFiles({oldTip->GetBlockPos().nFile});
 
     // Verify ScanForWalletTransactions only picks transactions in the new block
     // file.
     {
         CWallet wallet(Params(), *chain, WalletLocation(),
                        WalletDatabase::CreateDummy());
         AddKey(wallet, coinbaseKey);
         WalletRescanReserver reserver(&wallet);
         reserver.reserve();
         CWallet::ScanResult result = wallet.ScanForWalletTransactions(
             oldTip->GetBlockHash(), BlockHash(), reserver, false /* update */);
         BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::FAILURE);
         BOOST_CHECK_EQUAL(result.failed_block, oldTip->GetBlockHash());
         BOOST_CHECK_EQUAL(result.stop_block, newTip->GetBlockHash());
         BOOST_CHECK_EQUAL(*result.stop_height, newTip->nHeight);
         BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 50 * COIN);
     }
 
     // Prune the remaining block file.
     PruneOneBlockFile(newTip->GetBlockPos().nFile);
     UnlinkPrunedFiles({newTip->GetBlockPos().nFile});
 
     // Verify ScanForWalletTransactions scans no blocks.
     {
         CWallet wallet(Params(), *chain, WalletLocation(),
                        WalletDatabase::CreateDummy());
         AddKey(wallet, coinbaseKey);
         WalletRescanReserver reserver(&wallet);
         reserver.reserve();
         CWallet::ScanResult result = wallet.ScanForWalletTransactions(
             oldTip->GetBlockHash(), BlockHash(), reserver, false /* update */);
         BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::FAILURE);
         BOOST_CHECK_EQUAL(result.failed_block, newTip->GetBlockHash());
         BOOST_CHECK(result.stop_block.IsNull());
         BOOST_CHECK(!result.stop_height);
         BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), Amount::zero());
     }
 }
 
 BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup) {
     auto chain = interfaces::MakeChain();
 
     // Cap last block file size, and mine new block in a new block file.
     CBlockIndex *oldTip = ::ChainActive().Tip();
     GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE;
     CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
     CBlockIndex *newTip = ::ChainActive().Tip();
 
     LockAnnotation lock(::cs_main);
     auto locked_chain = chain->lock();
 
     // Prune the older block file.
     PruneOneBlockFile(oldTip->GetBlockPos().nFile);
     UnlinkPrunedFiles({oldTip->GetBlockPos().nFile});
 
     // Verify importmulti RPC returns failure for a key whose creation time is
     // before the missing block, and success for a key whose creation time is
     // after.
     {
         std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(
             Params(), *chain, WalletLocation(), WalletDatabase::CreateDummy());
         AddWallet(wallet);
         UniValue keys;
         keys.setArray();
         UniValue key;
         key.setObject();
         key.pushKV("scriptPubKey",
                    HexStr(GetScriptForRawPubKey(coinbaseKey.GetPubKey())));
         key.pushKV("timestamp", 0);
         key.pushKV("internal", UniValue(true));
         keys.push_back(key);
         key.clear();
         key.setObject();
         CKey futureKey;
         futureKey.MakeNewKey(true);
         key.pushKV("scriptPubKey",
                    HexStr(GetScriptForRawPubKey(futureKey.GetPubKey())));
         key.pushKV("timestamp",
                    newTip->GetBlockTimeMax() + TIMESTAMP_WINDOW + 1);
         key.pushKV("internal", UniValue(true));
         keys.push_back(key);
         JSONRPCRequest request;
         request.params.setArray();
         request.params.push_back(keys);
 
         UniValue response = importmulti(GetConfig(), request);
         BOOST_CHECK_EQUAL(
             response.write(),
             strprintf("[{\"success\":false,\"error\":{\"code\":-1,\"message\":"
                       "\"Rescan failed for key with creation timestamp %d. "
                       "There was an error reading a block from time %d, which "
                       "is after or within %d seconds of key creation, and "
                       "could contain transactions pertaining to the key. As a "
                       "result, transactions and coins using this key may not "
                       "appear in the wallet. This error could be caused by "
                       "pruning or data corruption (see bitcoind log for "
                       "details) and could be dealt with by downloading and "
                       "rescanning the relevant blocks (see -reindex and "
                       "-rescan options).\"}},{\"success\":true}]",
                       0, oldTip->GetBlockTimeMax(), TIMESTAMP_WINDOW));
         RemoveWallet(wallet);
     }
 }
 
 // Verify importwallet RPC starts rescan at earliest block with timestamp
 // greater or equal than key birthday. Previously there was a bug where
 // importwallet RPC would start the scan at the latest block with timestamp less
 // than or equal to key birthday.
 BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) {
     auto chain = interfaces::MakeChain();
 
     // Create two blocks with same timestamp to verify that importwallet rescan
     // will pick up both blocks, not just the first.
     const int64_t BLOCK_TIME = ::ChainActive().Tip()->GetBlockTimeMax() + 5;
     SetMockTime(BLOCK_TIME);
     m_coinbase_txns.emplace_back(
         CreateAndProcessBlock({},
                               GetScriptForRawPubKey(coinbaseKey.GetPubKey()))
             .vtx[0]);
     m_coinbase_txns.emplace_back(
         CreateAndProcessBlock({},
                               GetScriptForRawPubKey(coinbaseKey.GetPubKey()))
             .vtx[0]);
 
     // Set key birthday to block time increased by the timestamp window, so
     // rescan will start at the block time.
     const int64_t KEY_TIME = BLOCK_TIME + TIMESTAMP_WINDOW;
     SetMockTime(KEY_TIME);
     m_coinbase_txns.emplace_back(
         CreateAndProcessBlock({},
                               GetScriptForRawPubKey(coinbaseKey.GetPubKey()))
             .vtx[0]);
 
     auto locked_chain = chain->lock();
 
     std::string backup_file = (GetDataDir() / "wallet.backup").string();
 
     // Import key into wallet and call dumpwallet to create backup file.
     {
         std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(
             Params(), *chain, WalletLocation(), WalletDatabase::CreateDummy());
         LOCK(wallet->cs_wallet);
         wallet->mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime =
             KEY_TIME;
         wallet->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey());
 
         JSONRPCRequest request;
         request.params.setArray();
         request.params.push_back(backup_file);
         AddWallet(wallet);
         ::dumpwallet(GetConfig(), request);
         RemoveWallet(wallet);
     }
 
     // Call importwallet RPC and verify all blocks with timestamps >= BLOCK_TIME
     // were scanned, and no prior blocks were scanned.
     {
         std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(
             Params(), *chain, WalletLocation(), WalletDatabase::CreateDummy());
 
         JSONRPCRequest request;
         request.params.setArray();
         request.params.push_back(backup_file);
         AddWallet(wallet);
         ::importwallet(GetConfig(), request);
         RemoveWallet(wallet);
 
         LOCK(wallet->cs_wallet);
         BOOST_CHECK_EQUAL(wallet->mapWallet.size(), 3U);
         BOOST_CHECK_EQUAL(m_coinbase_txns.size(), 103U);
         for (size_t i = 0; i < m_coinbase_txns.size(); ++i) {
             bool found = wallet->GetWalletTx(m_coinbase_txns[i]->GetId());
             bool expected = i >= 100;
             BOOST_CHECK_EQUAL(found, expected);
         }
     }
-
-    SetMockTime(0);
 }
 
 // Check that GetImmatureCredit() returns a newly calculated value instead of
 // the cached value after a MarkDirty() call.
 //
 // This is a regression test written to verify a bugfix for the immature credit
 // function. Similar tests probably should be written for the other credit and
 // debit functions.
 BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup) {
     auto chain = interfaces::MakeChain();
     CWallet wallet(Params(), *chain, WalletLocation(),
                    WalletDatabase::CreateDummy());
     CWalletTx wtx(&wallet, m_coinbase_txns.back());
     auto locked_chain = chain->lock();
     LOCK(wallet.cs_wallet);
     wtx.hashBlock = ::ChainActive().Tip()->GetBlockHash();
     wtx.nIndex = 0;
 
     // Call GetImmatureCredit() once before adding the key to the wallet to
     // cache the current immature credit amount, which is 0.
     BOOST_CHECK_EQUAL(wtx.GetImmatureCredit(*locked_chain), Amount::zero());
 
     // Invalidate the cached value, add the key, and make sure a new immature
     // credit amount is calculated.
     wtx.MarkDirty();
     wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey());
     BOOST_CHECK_EQUAL(wtx.GetImmatureCredit(*locked_chain), 50 * COIN);
 }
 
 static int64_t AddTx(CWallet &wallet, uint32_t lockTime, int64_t mockTime,
                      int64_t blockTime) {
     CMutableTransaction tx;
     tx.nLockTime = lockTime;
     SetMockTime(mockTime);
     CBlockIndex *block = nullptr;
     if (blockTime > 0) {
         LockAnnotation lock(::cs_main);
         auto locked_chain = wallet.chain().lock();
         auto inserted =
             mapBlockIndex.emplace(BlockHash(GetRandHash()), new CBlockIndex);
         assert(inserted.second);
         const BlockHash &hash = inserted.first->first;
         block = inserted.first->second;
         block->nTime = blockTime;
         block->phashBlock = &hash;
     }
 
     CWalletTx wtx(&wallet, MakeTransactionRef(tx));
     if (block) {
         wtx.SetMerkleBranch(block->GetBlockHash(), 0);
     }
     {
         LOCK(cs_main);
         wallet.AddToWallet(wtx);
     }
     LOCK(wallet.cs_wallet);
     return wallet.mapWallet.at(wtx.GetId()).nTimeSmart;
 }
 
 // Simple test to verify assignment of CWalletTx::nSmartTime value. Could be
 // expanded to cover more corner cases of smart time logic.
 BOOST_AUTO_TEST_CASE(ComputeTimeSmart) {
     // New transaction should use clock time if lower than block time.
     BOOST_CHECK_EQUAL(AddTx(m_wallet, 1, 100, 120), 100);
 
     // Test that updating existing transaction does not change smart time.
     BOOST_CHECK_EQUAL(AddTx(m_wallet, 1, 200, 220), 100);
 
     // New transaction should use clock time if there's no block time.
     BOOST_CHECK_EQUAL(AddTx(m_wallet, 2, 300, 0), 300);
 
     // New transaction should use block time if lower than clock time.
     BOOST_CHECK_EQUAL(AddTx(m_wallet, 3, 420, 400), 400);
 
     // New transaction should use latest entry time if higher than
     // min(block time, clock time).
     BOOST_CHECK_EQUAL(AddTx(m_wallet, 4, 500, 390), 400);
 
     // If there are future entries, new transaction should use time of the
     // newest entry that is no more than 300 seconds ahead of the clock time.
     BOOST_CHECK_EQUAL(AddTx(m_wallet, 5, 50, 600), 300);
 
     // Reset mock time for other tests.
     SetMockTime(0);
 }
 
 BOOST_AUTO_TEST_CASE(LoadReceiveRequests) {
     CTxDestination dest = CKeyID();
     LOCK(m_wallet.cs_wallet);
     m_wallet.AddDestData(dest, "misc", "val_misc");
     m_wallet.AddDestData(dest, "rr0", "val_rr0");
     m_wallet.AddDestData(dest, "rr1", "val_rr1");
 
     auto values = m_wallet.GetDestValues("rr");
     BOOST_CHECK_EQUAL(values.size(), 2U);
     BOOST_CHECK_EQUAL(values[0], "val_rr0");
     BOOST_CHECK_EQUAL(values[1], "val_rr1");
 }
 
 class ListCoinsTestingSetup : public TestChain100Setup {
 public:
     ListCoinsTestingSetup() {
         CreateAndProcessBlock({},
                               GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
         wallet = std::make_unique<CWallet>(Params(), *m_chain, WalletLocation(),
                                            WalletDatabase::CreateMock());
         bool firstRun;
         wallet->LoadWallet(firstRun);
         AddKey(*wallet, coinbaseKey);
         WalletRescanReserver reserver(wallet.get());
         reserver.reserve();
         CWallet::ScanResult result = wallet->ScanForWalletTransactions(
             ::ChainActive().Genesis()->GetBlockHash(), BlockHash(), reserver,
             false /* update */);
         BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS);
         BOOST_CHECK_EQUAL(result.stop_block,
                           ::ChainActive().Tip()->GetBlockHash());
         BOOST_CHECK_EQUAL(*result.stop_height, ::ChainActive().Height());
         BOOST_CHECK(result.failed_block.IsNull());
     }
 
     ~ListCoinsTestingSetup() { wallet.reset(); }
 
     CWalletTx &AddTx(CRecipient recipient) {
         CTransactionRef tx;
         CReserveKey reservekey(wallet.get());
         Amount fee;
         int changePos = -1;
         std::string error;
         CCoinControl dummy;
         BOOST_CHECK(wallet->CreateTransaction(*m_locked_chain, {recipient}, tx,
                                               reservekey, fee, changePos, error,
                                               dummy));
         CValidationState state;
         BOOST_CHECK(wallet->CommitTransaction(tx, {}, {}, reservekey, state));
         CMutableTransaction blocktx;
         {
             LOCK(wallet->cs_wallet);
             blocktx =
                 CMutableTransaction(*wallet->mapWallet.at(tx->GetId()).tx);
         }
         CreateAndProcessBlock({CMutableTransaction(blocktx)},
                               GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
         LOCK(wallet->cs_wallet);
         auto it = wallet->mapWallet.find(tx->GetId());
         BOOST_CHECK(it != wallet->mapWallet.end());
         it->second.SetMerkleBranch(::ChainActive().Tip()->GetBlockHash(), 1);
         return it->second;
     }
 
     std::unique_ptr<interfaces::Chain> m_chain = interfaces::MakeChain();
     // Temporary. Removed in upcoming lock cleanup
     std::unique_ptr<interfaces::Chain::Lock> m_locked_chain =
         m_chain->assumeLocked();
     std::unique_ptr<CWallet> wallet;
 };
 
 BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup) {
     std::string coinbaseAddress = coinbaseKey.GetPubKey().GetID().ToString();
 
     // Confirm ListCoins initially returns 1 coin grouped under coinbaseKey
     // address.
     std::map<CTxDestination, std::vector<COutput>> list;
     {
         LOCK2(cs_main, wallet->cs_wallet);
         list = wallet->ListCoins(*m_locked_chain);
     }
     BOOST_CHECK_EQUAL(list.size(), 1U);
     BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(),
                       coinbaseAddress);
     BOOST_CHECK_EQUAL(list.begin()->second.size(), 1U);
 
     // Check initial balance from one mature coinbase transaction.
     BOOST_CHECK_EQUAL(50 * COIN, wallet->GetAvailableBalance());
 
     // Add a transaction creating a change address, and confirm ListCoins still
     // returns the coin associated with the change address underneath the
     // coinbaseKey pubkey, even though the change address has a different
     // pubkey.
     AddTx(CRecipient{GetScriptForRawPubKey({}), 1 * COIN,
                      false /* subtract fee */});
     {
         LOCK2(cs_main, wallet->cs_wallet);
         list = wallet->ListCoins(*m_locked_chain);
     }
     BOOST_CHECK_EQUAL(list.size(), 1U);
     BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(),
                       coinbaseAddress);
     BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U);
 
     // Lock both coins. Confirm number of available coins drops to 0.
     {
         LOCK2(cs_main, wallet->cs_wallet);
         std::vector<COutput> available;
         wallet->AvailableCoins(*m_locked_chain, available);
         BOOST_CHECK_EQUAL(available.size(), 2U);
     }
     for (const auto &group : list) {
         for (const auto &coin : group.second) {
             LOCK(wallet->cs_wallet);
             wallet->LockCoin(COutPoint(coin.tx->GetId(), coin.i));
         }
     }
     {
         LOCK2(cs_main, wallet->cs_wallet);
         std::vector<COutput> available;
         wallet->AvailableCoins(*m_locked_chain, available);
         BOOST_CHECK_EQUAL(available.size(), 0U);
     }
     // Confirm ListCoins still returns same result as before, despite coins
     // being locked.
     {
         LOCK2(cs_main, wallet->cs_wallet);
         list = wallet->ListCoins(*m_locked_chain);
     }
     BOOST_CHECK_EQUAL(list.size(), 1U);
     BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(),
                       coinbaseAddress);
     BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U);
 }
 
 BOOST_FIXTURE_TEST_CASE(wallet_disableprivkeys, TestChain100Setup) {
     auto chain = interfaces::MakeChain();
     std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(
         Params(), *chain, WalletLocation(), WalletDatabase::CreateDummy());
     wallet->SetMinVersion(FEATURE_LATEST);
     wallet->SetWalletFlag(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
     BOOST_CHECK(!wallet->TopUpKeyPool(1000));
     CPubKey pubkey;
     BOOST_CHECK(!wallet->GetKeyFromPool(pubkey, false));
 }
 
 BOOST_AUTO_TEST_SUITE_END()