12 #include <boost/test/unit_test.hpp> 33 txParent.
vin.resize(1);
35 txParent.
vout.resize(3);
36 for (
int i = 0; i < 3; i++)
39 txParent.
vout[i].nValue = 33000LL;
42 for (
int i = 0; i < 3; i++)
44 txChild[i].
vin.resize(1);
46 txChild[i].
vin[0].prevout.hash = txParent.
GetHash();
47 txChild[i].
vin[0].prevout.n = i;
48 txChild[i].
vout.resize(1);
50 txChild[i].
vout[0].nValue = 11000LL;
53 for (
int i = 0; i < 3; i++)
55 txGrandChild[i].
vin.resize(1);
57 txGrandChild[i].
vin[0].prevout.hash = txChild[i].
GetHash();
58 txGrandChild[i].
vin[0].prevout.n = 0;
59 txGrandChild[i].
vout.resize(1);
61 txGrandChild[i].
vout[0].nValue = 11000LL;
69 unsigned int poolSize = testPool.
size();
75 poolSize = testPool.
size();
81 for (
int i = 0; i < 3; i++)
87 poolSize = testPool.
size();
91 poolSize = testPool.
size();
94 poolSize = testPool.
size();
98 poolSize = testPool.
size();
104 for (
int i = 0; i < 3; i++)
111 poolSize = testPool.
size();
117 template <
typename name>
121 typename CTxMemPool::indexed_transaction_set::index<name>::type::iterator it = pool.mapTx.get<
name>().begin();
123 for (; it != pool.mapTx.get<
name>().end(); ++it, ++
count) {
171 std::vector<std::string> sortedOrder;
172 sortedOrder.resize(5);
178 CheckSort<descendant_score>(pool, sortedOrder);
185 tx6.vout[0].nValue = 20 *
COIN;
186 pool.addUnchecked(entry.
Fee(0LL).
FromTx(tx6));
189 sortedOrder.insert(sortedOrder.begin(), tx6.GetHash().ToString());
190 CheckSort<descendant_score>(pool, sortedOrder);
193 setAncestors.insert(pool.mapTx.find(tx6.GetHash()));
206 BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry.
Fee(2000000LL).
FromTx(tx7), setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy),
true);
207 BOOST_CHECK(setAncestorsCalculated == setAncestors);
209 pool.addUnchecked(entry.
FromTx(tx7), setAncestors);
213 sortedOrder.erase(sortedOrder.begin());
214 sortedOrder.push_back(tx6.GetHash().ToString());
216 CheckSort<descendant_score>(pool, sortedOrder);
225 tx8.vout[0].nValue = 10 *
COIN;
226 setAncestors.insert(pool.mapTx.find(tx7.
GetHash()));
227 pool.addUnchecked(entry.
Fee(0LL).
Time(2).
FromTx(tx8), setAncestors);
230 sortedOrder.insert(sortedOrder.begin(), tx8.GetHash().ToString());
231 CheckSort<descendant_score>(pool, sortedOrder);
240 tx9.vout[0].nValue = 1 *
COIN;
241 pool.addUnchecked(entry.
Fee(0LL).
Time(3).
FromTx(tx9), setAncestors);
245 sortedOrder.insert(sortedOrder.begin(), tx9.GetHash().ToString());
246 CheckSort<descendant_score>(pool, sortedOrder);
248 std::vector<std::string> snapshotOrder = sortedOrder;
250 setAncestors.insert(pool.mapTx.find(tx8.GetHash()));
251 setAncestors.insert(pool.mapTx.find(tx9.GetHash()));
263 setAncestorsCalculated.clear();
264 BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry.
Fee(200000LL).
Time(4).
FromTx(tx10), setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy),
true);
265 BOOST_CHECK(setAncestorsCalculated == setAncestors);
267 pool.addUnchecked(entry.
FromTx(tx10), setAncestors);
284 sortedOrder.erase(sortedOrder.begin(), sortedOrder.begin()+2);
285 sortedOrder.insert(sortedOrder.begin()+5, tx9.GetHash().ToString());
286 sortedOrder.insert(sortedOrder.begin()+6, tx8.GetHash().ToString());
288 CheckSort<descendant_score>(pool, sortedOrder);
295 CheckSort<descendant_score>(pool, snapshotOrder);
344 std::vector<std::string> sortedOrder;
345 sortedOrder.resize(5);
360 CheckSort<ancestor_score>(pool, sortedOrder);
367 tx6.vout[0].nValue = 20 *
COIN;
370 pool.addUnchecked(entry.
Fee(0LL).
FromTx(tx6));
373 if (tx3.
GetHash() < tx6.GetHash())
374 sortedOrder.push_back(tx6.GetHash().ToString());
376 sortedOrder.insert(sortedOrder.end()-1,tx6.GetHash().ToString());
378 CheckSort<ancestor_score>(pool, sortedOrder);
382 tx7.vin[0].prevout =
COutPoint(tx6.GetHash(), 0);
386 tx7.vout[0].nValue = 10 *
COIN;
390 CAmount fee = (20000/tx2Size)*(tx7Size + tx6Size) - 1;
392 pool.addUnchecked(entry.
Fee(fee).
FromTx(tx7));
394 sortedOrder.insert(sortedOrder.begin()+1, tx7.GetHash().ToString());
395 CheckSort<ancestor_score>(pool, sortedOrder);
398 std::vector<CTransactionRef> vtx;
400 pool.removeForBlock(vtx, 1);
402 sortedOrder.erase(sortedOrder.begin()+1);
404 if (tx3.
GetHash() < tx6.GetHash())
405 sortedOrder.pop_back();
407 sortedOrder.erase(sortedOrder.end()-2);
408 sortedOrder.insert(sortedOrder.begin(), tx7.GetHash().ToString());
409 CheckSort<ancestor_score>(pool, sortedOrder);
415 tx8.vin[0].prevout =
COutPoint(tx7.GetHash(), 0);
419 tx8.vout[0].nValue = 10*
COIN;
424 pool.addUnchecked(entry.
Fee(5000LL).
FromTx(tx8));
425 sortedOrder.insert(sortedOrder.end()-1, tx8.GetHash().ToString());
426 CheckSort<ancestor_score>(pool, sortedOrder);
442 pool.addUnchecked(entry.
Fee(10000LL).
FromTx(tx1));
450 pool.addUnchecked(entry.
Fee(5000LL).
FromTx(tx2));
452 pool.TrimToSize(pool.DynamicMemoryUsage());
456 pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4);
460 pool.addUnchecked(entry.
FromTx(tx2));
468 pool.addUnchecked(entry.
Fee(20000LL).
FromTx(tx3));
470 pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4);
481 BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + 1000);
485 tx4.vin[0].prevout.SetNull();
487 tx4.vin[1].prevout.SetNull();
491 tx4.vout[0].nValue = 10 *
COIN;
493 tx4.vout[1].nValue = 10 *
COIN;
499 tx5.
vin[1].prevout.SetNull();
511 tx6.
vin[1].prevout.SetNull();
531 pool.addUnchecked(entry.
Fee(7000LL).
FromTx(tx4));
532 pool.addUnchecked(entry.
Fee(1000LL).
FromTx(tx5));
533 pool.addUnchecked(entry.
Fee(1100LL).
FromTx(tx6));
534 pool.addUnchecked(entry.
Fee(9000LL).
FromTx(tx7));
537 pool.TrimToSize(pool.DynamicMemoryUsage() - 1);
543 pool.addUnchecked(entry.
Fee(1000LL).
FromTx(tx5));
544 pool.addUnchecked(entry.
Fee(9000LL).
FromTx(tx7));
546 pool.TrimToSize(pool.DynamicMemoryUsage() / 2);
552 pool.addUnchecked(entry.
Fee(1000LL).
FromTx(tx5));
553 pool.addUnchecked(entry.
Fee(9000LL).
FromTx(tx7));
555 std::vector<CTransactionRef> vtx;
558 BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + 1000);
560 pool.removeForBlock(vtx, 1);
562 BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), llround((maxFeeRateRemoved.GetFeePerK() + 1000)/2.0));
566 BOOST_CHECK_EQUAL(pool.GetMinFee(pool.DynamicMemoryUsage() * 5 / 2).GetFeePerK(), llround((maxFeeRateRemoved.GetFeePerK() + 1000)/4.0));
570 BOOST_CHECK_EQUAL(pool.GetMinFee(pool.DynamicMemoryUsage() * 9 / 2).GetFeePerK(), llround((maxFeeRateRemoved.GetFeePerK() + 1000)/8.0));
582 inline CTransactionRef make_tx(std::vector<CAmount>&& output_values, std::vector<CTransactionRef>&& inputs=std::vector<CTransactionRef>(), std::vector<uint32_t>&& input_indices=std::vector<uint32_t>())
585 tx.
vin.resize(inputs.size());
586 tx.
vout.resize(output_values.size());
587 for (
size_t i = 0; i < inputs.size(); ++i) {
588 tx.
vin[i].prevout.hash = inputs[i]->GetHash();
589 tx.
vin[i].prevout.n = input_indices.size() > i ? input_indices[i] : 0;
591 for (
size_t i = 0; i < output_values.size(); ++i) {
593 tx.
vout[i].nValue = output_values[i];
601 size_t ancestors, descendants;
701 for (uint64_t i = 0; i < 5; i++) {
703 tyi =
make_tx({v}, i > 0 ? std::vector<CTransactionRef>{*ty[i - 1]} : std::vector<CTransactionRef>{});
760 size_t ancestors, descendants;
std::shared_ptr< const CTransaction > CTransactionRef
TestMemPoolEntryHelper & Fee(CAmount _fee)
unsigned long size() const
std::set< txiter, CompareIteratorByHash > setEntries
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal...
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop)
Compute the virtual transaction size (weight reinterpreted as bytes).
CTxMemPoolEntry FromTx(const CMutableTransaction &tx) const
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
CFeeRate GetMinFee() const
The minimum fee to get into the mempool, which may itself not be enough for larger-sized transactions...
CTransactionRef make_tx(std::vector< CAmount > &&output_values, std::vector< CTransactionRef > &&inputs=std::vector< CTransactionRef >(), std::vector< uint32_t > &&input_indices=std::vector< uint32_t >())
std::unique_ptr< CTxMemPool > mempool
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void addUnchecked(const CTxMemPoolEntry &entry, bool validFeeEstimate=true) EXCLUSIVE_LOCKS_REQUIRED(cs
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
int64_t CAmount
Amount in satoshis (Can be negative)
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
static constexpr auto REMOVAL_REASON_DUMMY
BOOST_AUTO_TEST_SUITE_END()
static const int ROLLING_FEE_HALFLIFE
std::string ToString() const
An outpoint - a combination of a transaction hash and an index n into its vout.
std::vector< CTxOut > vout
static CTransactionRef MakeTransactionRef(Tx &&txIn)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
uint256 GetHash() const
Compute the hash of this CMutableTransaction.
#define BOOST_CHECK_EQUAL(v1, v2)
Serialized script, used inside transaction inputs and outputs.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
TestMemPoolEntryHelper & Time(int64_t _time)
void GetTransactionAncestry(const uint256 &txid, size_t &ancestors, size_t &descendants, size_t *ancestorsize=nullptr, CAmount *ancestorfees=nullptr) const
Calculate the ancestor and descendant count for the given transaction.
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
static void CheckSort(CTxMemPool &pool, std::vector< std::string > &sortedOrder) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
A mutable version of CTransaction.
static constexpr CAmount CENT
BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
The basic transaction that is broadcasted on the network and contained in blocks. ...
Testing setup that configures a complete environment.
static GenTxid Txid(const uint256 &hash)
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...
#define Assert(val)
Identity function.
#define BOOST_CHECK(expr)
static constexpr CAmount COIN
The amount of satoshis in one BTC.