22// Distributed under the MIT software license, see the accompanying
33// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44
5- #include " main.h"
65#include " txmempool.h"
76
7+ #include " blockmap.h"
8+ #include " MockUtxoHasher.h"
9+
810#include < boost/test/unit_test.hpp>
911#include < list>
1012
13+ extern CChain chainActive;
14+ extern BlockMap mapBlockIndex;
15+
1116class MempoolTestFixture
1217{
1318
19+ private:
20+
21+ /* * Empty coins view used to back the cached view we actually use. */
22+ CCoinsView emptyView;
23+
24+ /* * Tip of our fake chain. */
25+ CBlockIndex tip;
26+
1427protected:
1528
1629 /* * A parent transaction. */
1730 CMutableTransaction txParent;
1831
19- /* * Three children of the parent. */
32+ /* * Three children of the parent. They use the bare txid for their UTXOs
33+ * in our UTXO hasher. */
2034 CMutableTransaction txChild[3 ];
2135
2236 /* * Three grand children. */
2337 CMutableTransaction txGrandChild[3 ];
2438
39+ /* * Coins view with the parent inputs. */
40+ CCoinsViewCache view;
41+
2542 /* * The test mempool instance. */
2643 CTxMemPool testPool;
2744
2845public:
2946
3047 MempoolTestFixture ()
31- : testPool(CFeeRate(0 ))
48+ : view(&emptyView), testPool(CFeeRate(0 ))
3249 {
50+ std::unique_ptr<MockUtxoHasher> utxoHasher (new MockUtxoHasher ());
51+
52+ CMutableTransaction base;
53+ base.vout .emplace_back (99000LL , CScript () << OP_11 << OP_EQUAL);
54+ view.ModifyCoins (base.GetHash ())->FromTx (base, 0 );
55+
56+ tip.pprev = nullptr ;
57+ tip.nHeight = 0 ;
58+ mapBlockIndex[tip.GetBlockHeader ().GetHash ()] = &tip;
59+ view.SetBestBlock (tip.GetBlockHeader ().GetHash ());
60+ chainActive.SetTip (&tip);
61+
3362 txParent.vin .resize (1 );
3463 txParent.vin [0 ].scriptSig = CScript () << OP_11;
64+ txParent.vin [0 ].prevout .hash = base.GetHash ();
65+ txParent.vin [0 ].prevout .n = 0 ;
3566 txParent.vout .resize (3 );
3667 for (int i = 0 ; i < 3 ; i++)
3768 {
@@ -48,18 +79,39 @@ class MempoolTestFixture
4879 txChild[i].vout .resize (1 );
4980 txChild[i].vout [0 ].scriptPubKey = CScript () << OP_11 << OP_EQUAL;
5081 txChild[i].vout [0 ].nValue = 11000LL ;
82+ utxoHasher->UseBareTxid (txChild[i]);
5183 }
5284
5385 for (int i = 0 ; i < 3 ; i++)
5486 {
5587 txGrandChild[i].vin .resize (1 );
5688 txGrandChild[i].vin [0 ].scriptSig = CScript () << OP_11;
57- txGrandChild[i].vin [0 ].prevout .hash = txChild[i].GetHash ();
89+ txGrandChild[i].vin [0 ].prevout .hash = txChild[i].GetBareTxid ();
5890 txGrandChild[i].vin [0 ].prevout .n = 0 ;
5991 txGrandChild[i].vout .resize (1 );
6092 txGrandChild[i].vout [0 ].scriptPubKey = CScript () << OP_11 << OP_EQUAL;
6193 txGrandChild[i].vout [0 ].nValue = 11000LL ;
6294 }
95+
96+ testPool.setSanityCheck (true );
97+ testPool.SetUtxoHasherForTesting (std::move (utxoHasher));
98+ testPool.clear ();
99+ }
100+
101+ ~MempoolTestFixture ()
102+ {
103+ mapBlockIndex.clear ();
104+ }
105+
106+ /* * Adds the parent, childs and grandchilds to the mempool. */
107+ void AddAll ()
108+ {
109+ testPool.addUnchecked (txParent.GetHash (), CTxMemPoolEntry (txParent, 0 , 0 , 0.0 , 1 ));
110+ for (int i = 0 ; i < 3 ; i++)
111+ {
112+ testPool.addUnchecked (txChild[i].GetHash (), CTxMemPoolEntry (txChild[i], 0 , 0 , 0.0 , 1 ));
113+ testPool.addUnchecked (txGrandChild[i].GetHash (), CTxMemPoolEntry (txGrandChild[i], 0 , 0 , 0.0 , 1 ));
114+ }
63115 }
64116
65117};
@@ -83,12 +135,10 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
83135 removed.clear ();
84136
85137 // Parent, children, grandchildren:
86- testPool.addUnchecked (txParent.GetHash (), CTxMemPoolEntry (txParent, 0 , 0 , 0.0 , 1 ));
87- for (int i = 0 ; i < 3 ; i++)
88- {
89- testPool.addUnchecked (txChild[i].GetHash (), CTxMemPoolEntry (txChild[i], 0 , 0 , 0.0 , 1 ));
90- testPool.addUnchecked (txGrandChild[i].GetHash (), CTxMemPoolEntry (txGrandChild[i], 0 , 0 , 0.0 , 1 ));
91- }
138+ AddAll ();
139+
140+ testPool.check (&view);
141+
92142 // Remove Child[0], GrandChild[0] should be removed:
93143 testPool.remove (txChild[0 ], removed, true );
94144 BOOST_CHECK_EQUAL (removed.size (), 2 );
@@ -123,12 +173,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexByBareTxid)
123173 CTransaction tx;
124174 std::list<CTransaction> removed;
125175
126- testPool.addUnchecked (txParent.GetHash (), CTxMemPoolEntry (txParent, 0 , 0 , 0.0 , 1 ));
127- for (int i = 0 ; i < 3 ; ++i)
128- {
129- testPool.addUnchecked (txChild[i].GetHash (), CTxMemPoolEntry (txChild[i], 0 , 0 , 0.0 , 1 ));
130- testPool.addUnchecked (txGrandChild[i].GetHash (), CTxMemPoolEntry (txGrandChild[i], 0 , 0 , 0.0 , 1 ));
131- }
176+ AddAll ();
132177
133178 BOOST_CHECK (testPool.lookupBareTxid (txParent.GetBareTxid (), tx));
134179 BOOST_CHECK (tx.GetHash () == txParent.GetHash ());
@@ -140,4 +185,28 @@ BOOST_AUTO_TEST_CASE(MempoolIndexByBareTxid)
140185 BOOST_CHECK (!testPool.lookupBareTxid (txGrandChild[0 ].GetBareTxid (), tx));
141186}
142187
188+ BOOST_AUTO_TEST_CASE (MempoolOutpointLookup)
189+ {
190+ CTransaction tx;
191+ CCoins coins;
192+
193+ AddAll ();
194+ CCoinsViewMemPool viewPool (&view, testPool);
195+
196+ BOOST_CHECK (testPool.lookupOutpoint (txParent.GetHash (), tx));
197+ BOOST_CHECK (!testPool.lookupOutpoint (txParent.GetBareTxid (), tx));
198+ BOOST_CHECK (!testPool.lookupOutpoint (txChild[0 ].GetHash (), tx));
199+ BOOST_CHECK (testPool.lookupOutpoint (txChild[0 ].GetBareTxid (), tx));
200+
201+ BOOST_CHECK (viewPool.HaveCoins (txParent.GetHash ()));
202+ BOOST_CHECK (viewPool.GetCoins (txParent.GetHash (), coins));
203+ BOOST_CHECK (!viewPool.HaveCoins (txParent.GetBareTxid ()));
204+ BOOST_CHECK (!viewPool.GetCoins (txParent.GetBareTxid (), coins));
205+
206+ BOOST_CHECK (!viewPool.HaveCoins (txChild[0 ].GetHash ()));
207+ BOOST_CHECK (!viewPool.GetCoins (txChild[0 ].GetHash (), coins));
208+ BOOST_CHECK (viewPool.HaveCoins (txChild[0 ].GetBareTxid ()));
209+ BOOST_CHECK (viewPool.GetCoins (txChild[0 ].GetBareTxid (), coins));
210+ }
211+
143212BOOST_AUTO_TEST_SUITE_END ()
0 commit comments