Changeset View
Changeset View
Standalone View
Standalone View
src/test/mempool_tests.cpp
Show First 20 Lines • Show All 597 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) { | ||||
Amount feeIncrement = MEMPOOL_FULL_FEE_INCREMENT.GetFeePerK(); | Amount feeIncrement = MEMPOOL_FULL_FEE_INCREMENT.GetFeePerK(); | ||||
CMutableTransaction tx1 = CMutableTransaction(); | CMutableTransaction tx1 = CMutableTransaction(); | ||||
tx1.vin.resize(1); | tx1.vin.resize(1); | ||||
tx1.vin[0].scriptSig = CScript() << OP_1; | tx1.vin[0].scriptSig = CScript() << OP_1; | ||||
tx1.vout.resize(1); | tx1.vout.resize(1); | ||||
tx1.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL; | tx1.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL; | ||||
tx1.vout[0].nValue = 10 * COIN; | tx1.vout[0].nValue = 10 * COIN; | ||||
pool.addUnchecked(tx1.GetId(), | pool.addUnchecked(tx1.GetId(), entry.Fee(10000 * SATOSHI).FromTx(tx1)); | ||||
entry.Fee(10000 * SATOSHI).FromTx(tx1, &pool)); | |||||
CMutableTransaction tx2 = CMutableTransaction(); | CMutableTransaction tx2 = CMutableTransaction(); | ||||
tx2.vin.resize(1); | tx2.vin.resize(1); | ||||
tx2.vin[0].scriptSig = CScript() << OP_2; | tx2.vin[0].scriptSig = CScript() << OP_2; | ||||
tx2.vout.resize(1); | tx2.vout.resize(1); | ||||
tx2.vout[0].scriptPubKey = CScript() << OP_2 << OP_EQUAL; | tx2.vout[0].scriptPubKey = CScript() << OP_2 << OP_EQUAL; | ||||
tx2.vout[0].nValue = 10 * COIN; | tx2.vout[0].nValue = 10 * COIN; | ||||
pool.addUnchecked(tx2.GetId(), | pool.addUnchecked(tx2.GetId(), entry.Fee(5000 * SATOSHI).FromTx(tx2)); | ||||
entry.Fee(5000 * SATOSHI).FromTx(tx2, &pool)); | |||||
// should do nothing | // should do nothing | ||||
pool.TrimToSize(pool.DynamicMemoryUsage()); | pool.TrimToSize(pool.DynamicMemoryUsage()); | ||||
BOOST_CHECK(pool.exists(tx1.GetId())); | BOOST_CHECK(pool.exists(tx1.GetId())); | ||||
BOOST_CHECK(pool.exists(tx2.GetId())); | BOOST_CHECK(pool.exists(tx2.GetId())); | ||||
// should remove the lower-feerate transaction | // should remove the lower-feerate transaction | ||||
pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4); | pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4); | ||||
BOOST_CHECK(pool.exists(tx1.GetId())); | BOOST_CHECK(pool.exists(tx1.GetId())); | ||||
BOOST_CHECK(!pool.exists(tx2.GetId())); | BOOST_CHECK(!pool.exists(tx2.GetId())); | ||||
pool.addUnchecked(tx2.GetId(), entry.FromTx(tx2, &pool)); | pool.addUnchecked(tx2.GetId(), entry.FromTx(tx2)); | ||||
CMutableTransaction tx3 = CMutableTransaction(); | CMutableTransaction tx3 = CMutableTransaction(); | ||||
tx3.vin.resize(1); | tx3.vin.resize(1); | ||||
tx3.vin[0].prevout = COutPoint(tx2.GetId(), 0); | tx3.vin[0].prevout = COutPoint(tx2.GetId(), 0); | ||||
tx3.vin[0].scriptSig = CScript() << OP_2; | tx3.vin[0].scriptSig = CScript() << OP_2; | ||||
tx3.vout.resize(1); | tx3.vout.resize(1); | ||||
tx3.vout[0].scriptPubKey = CScript() << OP_3 << OP_EQUAL; | tx3.vout[0].scriptPubKey = CScript() << OP_3 << OP_EQUAL; | ||||
tx3.vout[0].nValue = 10 * COIN; | tx3.vout[0].nValue = 10 * COIN; | ||||
pool.addUnchecked(tx3.GetId(), | pool.addUnchecked(tx3.GetId(), entry.Fee(20000 * SATOSHI).FromTx(tx3)); | ||||
entry.Fee(20000 * SATOSHI).FromTx(tx3, &pool)); | |||||
// tx3 should pay for tx2 (CPFP) | // tx3 should pay for tx2 (CPFP) | ||||
pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4); | pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4); | ||||
BOOST_CHECK(!pool.exists(tx1.GetId())); | BOOST_CHECK(!pool.exists(tx1.GetId())); | ||||
BOOST_CHECK(pool.exists(tx2.GetId())); | BOOST_CHECK(pool.exists(tx2.GetId())); | ||||
BOOST_CHECK(pool.exists(tx3.GetId())); | BOOST_CHECK(pool.exists(tx3.GetId())); | ||||
// mempool is limited to tx1's size in memory usage, so nothing fits | // mempool is limited to tx1's size in memory usage, so nothing fits | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) { | ||||
tx7.vin[1].prevout = COutPoint(tx6.GetId(), 0); | tx7.vin[1].prevout = COutPoint(tx6.GetId(), 0); | ||||
tx7.vin[1].scriptSig = CScript() << OP_6; | tx7.vin[1].scriptSig = CScript() << OP_6; | ||||
tx7.vout.resize(2); | tx7.vout.resize(2); | ||||
tx7.vout[0].scriptPubKey = CScript() << OP_7 << OP_EQUAL; | tx7.vout[0].scriptPubKey = CScript() << OP_7 << OP_EQUAL; | ||||
tx7.vout[0].nValue = 10 * COIN; | tx7.vout[0].nValue = 10 * COIN; | ||||
tx7.vout[1].scriptPubKey = CScript() << OP_7 << OP_EQUAL; | tx7.vout[1].scriptPubKey = CScript() << OP_7 << OP_EQUAL; | ||||
tx7.vout[1].nValue = 10 * COIN; | tx7.vout[1].nValue = 10 * COIN; | ||||
pool.addUnchecked(tx4.GetId(), | pool.addUnchecked(tx4.GetId(), entry.Fee(7000 * SATOSHI).FromTx(tx4)); | ||||
entry.Fee(7000 * SATOSHI).FromTx(tx4, &pool)); | pool.addUnchecked(tx5.GetId(), entry.Fee(1000 * SATOSHI).FromTx(tx5)); | ||||
pool.addUnchecked(tx5.GetId(), | pool.addUnchecked(tx6.GetId(), entry.Fee(1100 * SATOSHI).FromTx(tx6)); | ||||
entry.Fee(1000 * SATOSHI).FromTx(tx5, &pool)); | pool.addUnchecked(tx7.GetId(), entry.Fee(9000 * SATOSHI).FromTx(tx7)); | ||||
pool.addUnchecked(tx6.GetId(), | |||||
entry.Fee(1100 * SATOSHI).FromTx(tx6, &pool)); | |||||
pool.addUnchecked(tx7.GetId(), | |||||
entry.Fee(9000 * SATOSHI).FromTx(tx7, &pool)); | |||||
// we only require this to remove, at max, 2 txn, because it's not clear | // we only require this to remove, at max, 2 txn, because it's not clear | ||||
// what we're really optimizing for aside from that | // what we're really optimizing for aside from that | ||||
pool.TrimToSize(pool.DynamicMemoryUsage() - 1); | pool.TrimToSize(pool.DynamicMemoryUsage() - 1); | ||||
BOOST_CHECK(pool.exists(tx4.GetId())); | BOOST_CHECK(pool.exists(tx4.GetId())); | ||||
BOOST_CHECK(pool.exists(tx6.GetId())); | BOOST_CHECK(pool.exists(tx6.GetId())); | ||||
BOOST_CHECK(!pool.exists(tx7.GetId())); | BOOST_CHECK(!pool.exists(tx7.GetId())); | ||||
if (!pool.exists(tx5.GetId())) | if (!pool.exists(tx5.GetId())) | ||||
pool.addUnchecked(tx5.GetId(), | pool.addUnchecked(tx5.GetId(), entry.Fee(1000 * SATOSHI).FromTx(tx5)); | ||||
entry.Fee(1000 * SATOSHI).FromTx(tx5, &pool)); | pool.addUnchecked(tx7.GetId(), entry.Fee(9000 * SATOSHI).FromTx(tx7)); | ||||
pool.addUnchecked(tx7.GetId(), | |||||
entry.Fee(9000 * SATOSHI).FromTx(tx7, &pool)); | |||||
// should maximize mempool size by only removing 5/7 | // should maximize mempool size by only removing 5/7 | ||||
pool.TrimToSize(pool.DynamicMemoryUsage() / 2); | pool.TrimToSize(pool.DynamicMemoryUsage() / 2); | ||||
BOOST_CHECK(pool.exists(tx4.GetId())); | BOOST_CHECK(pool.exists(tx4.GetId())); | ||||
BOOST_CHECK(!pool.exists(tx5.GetId())); | BOOST_CHECK(!pool.exists(tx5.GetId())); | ||||
BOOST_CHECK(pool.exists(tx6.GetId())); | BOOST_CHECK(pool.exists(tx6.GetId())); | ||||
BOOST_CHECK(!pool.exists(tx7.GetId())); | BOOST_CHECK(!pool.exists(tx7.GetId())); | ||||
pool.addUnchecked(tx5.GetId(), | pool.addUnchecked(tx5.GetId(), entry.Fee(1000 * SATOSHI).FromTx(tx5)); | ||||
entry.Fee(1000 * SATOSHI).FromTx(tx5, &pool)); | pool.addUnchecked(tx7.GetId(), entry.Fee(9000 * SATOSHI).FromTx(tx7)); | ||||
pool.addUnchecked(tx7.GetId(), | |||||
entry.Fee(9000 * SATOSHI).FromTx(tx7, &pool)); | |||||
std::vector<CTransactionRef> vtx; | std::vector<CTransactionRef> vtx; | ||||
SetMockTime(42); | SetMockTime(42); | ||||
SetMockTime(42 + CTxMemPool::ROLLING_FEE_HALFLIFE); | SetMockTime(42 + CTxMemPool::ROLLING_FEE_HALFLIFE); | ||||
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), | BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), | ||||
maxFeeRateRemoved.GetFeePerK() + feeIncrement); | maxFeeRateRemoved.GetFeePerK() + feeIncrement); | ||||
// ... we should keep the same min fee until we get a block | // ... we should keep the same min fee until we get a block | ||||
pool.removeForBlock(vtx, 1); | pool.removeForBlock(vtx, 1); | ||||
▲ Show 20 Lines • Show All 306 Lines • Show Last 20 Lines |