test: Add MempoolAncestryTests
This commit is contained in:
parent
a08d76bcfe
commit
f77e1d34fd
1 changed files with 178 additions and 0 deletions
|
@ -571,4 +571,182 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
|
||||||
SetMockTime(0);
|
SetMockTime(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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>())
|
||||||
|
{
|
||||||
|
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.hash = inputs[i]->GetHash();
|
||||||
|
tx.vin[i].prevout.n = 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<CAmount>{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;
|
||||||
|
TestMemPoolEntryHelper entry;
|
||||||
|
|
||||||
|
/* Base transaction */
|
||||||
|
//
|
||||||
|
// [tx1]
|
||||||
|
//
|
||||||
|
CTransactionRef tx1 = make_tx(MK_OUTPUTS(10 * COIN));
|
||||||
|
pool.addUnchecked(tx1->GetHash(), entry.Fee(10000LL).FromTx(tx1));
|
||||||
|
|
||||||
|
// Ancestors / descendants should be 1 / 1 (itself / itself)
|
||||||
|
pool.GetTransactionAncestry(tx1->GetHash(), 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(tx2->GetHash(), entry.Fee(10000LL).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->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 1ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 2ULL);
|
||||||
|
pool.GetTransactionAncestry(tx2->GetHash(), 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(tx3->GetHash(), entry.Fee(10000LL).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->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 1ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 3ULL);
|
||||||
|
pool.GetTransactionAncestry(tx2->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 2ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 3ULL);
|
||||||
|
pool.GetTransactionAncestry(tx3->GetHash(), 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(tx4->GetHash(), entry.Fee(10000LL).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->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 1ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 4ULL);
|
||||||
|
pool.GetTransactionAncestry(tx2->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 2ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 4ULL);
|
||||||
|
pool.GetTransactionAncestry(tx3->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 3ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 4ULL);
|
||||||
|
pool.GetTransactionAncestry(tx4->GetHash(), 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};
|
||||||
|
CAmount 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(tyi->GetHash(), entry.Fee(10000LL).FromTx(tyi));
|
||||||
|
pool.GetTransactionAncestry(tyi->GetHash(), 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(ty6->GetHash(), entry.Fee(10000LL).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->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 1ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 5ULL);
|
||||||
|
pool.GetTransactionAncestry(tx2->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 2ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 5ULL);
|
||||||
|
pool.GetTransactionAncestry(tx3->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 3ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 5ULL);
|
||||||
|
pool.GetTransactionAncestry(tx4->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 3ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 5ULL);
|
||||||
|
pool.GetTransactionAncestry(ty1->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 1ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 6ULL);
|
||||||
|
pool.GetTransactionAncestry(ty2->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 2ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 6ULL);
|
||||||
|
pool.GetTransactionAncestry(ty3->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 3ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 6ULL);
|
||||||
|
pool.GetTransactionAncestry(ty4->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 4ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 6ULL);
|
||||||
|
pool.GetTransactionAncestry(ty5->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 5ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 6ULL);
|
||||||
|
pool.GetTransactionAncestry(ty6->GetHash(), ancestors, descendants);
|
||||||
|
BOOST_CHECK_EQUAL(ancestors, 9ULL);
|
||||||
|
BOOST_CHECK_EQUAL(descendants, 6ULL);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
Loading…
Reference in a new issue