mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-08 10:31:50 -05:00
unit test: add CheckConflictTopology case for not the only child
This commit is contained in:
parent
69bd18ca80
commit
a80d80936a
1 changed files with 58 additions and 0 deletions
|
@ -37,6 +37,37 @@ static inline CTransactionRef make_tx(const std::vector<CTransactionRef>& inputs
|
||||||
return MakeTransactionRef(tx);
|
return MakeTransactionRef(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make two child transactions from parent (which must have at least 2 outputs).
|
||||||
|
// Each tx will have the same outputs, using the amounts specified in output_values.
|
||||||
|
static inline std::pair<CTransactionRef, CTransactionRef> make_two_siblings(const CTransactionRef parent,
|
||||||
|
const std::vector<CAmount>& output_values)
|
||||||
|
{
|
||||||
|
assert(parent->vout.size() >= 2);
|
||||||
|
|
||||||
|
// First tx takes first parent output
|
||||||
|
CMutableTransaction tx1 = CMutableTransaction();
|
||||||
|
tx1.vin.resize(1);
|
||||||
|
tx1.vout.resize(output_values.size());
|
||||||
|
|
||||||
|
tx1.vin[0].prevout.hash = parent->GetHash();
|
||||||
|
tx1.vin[0].prevout.n = 0;
|
||||||
|
// Add a witness so wtxid != txid
|
||||||
|
CScriptWitness witness;
|
||||||
|
witness.stack.emplace_back(10);
|
||||||
|
tx1.vin[0].scriptWitness = witness;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < output_values.size(); ++i) {
|
||||||
|
tx1.vout[i].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
|
||||||
|
tx1.vout[i].nValue = output_values[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second tx takes second parent output
|
||||||
|
CMutableTransaction tx2 = tx1;
|
||||||
|
tx2.vin[0].prevout.n = 1;
|
||||||
|
|
||||||
|
return std::make_pair(MakeTransactionRef(tx1), MakeTransactionRef(tx2));
|
||||||
|
}
|
||||||
|
|
||||||
static CTransactionRef add_descendants(const CTransactionRef& tx, int32_t num_descendants, CTxMemPool& pool)
|
static CTransactionRef add_descendants(const CTransactionRef& tx, int32_t num_descendants, CTxMemPool& pool)
|
||||||
EXCLUSIVE_LOCKS_REQUIRED(::cs_main, pool.cs)
|
EXCLUSIVE_LOCKS_REQUIRED(::cs_main, pool.cs)
|
||||||
{
|
{
|
||||||
|
@ -67,6 +98,20 @@ static CTransactionRef add_descendant_to_parents(const std::vector<CTransactionR
|
||||||
return child_tx;
|
return child_tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Makes two children for a single parent
|
||||||
|
static std::pair<CTransactionRef, CTransactionRef> add_children_to_parent(const CTransactionRef parent, CTxMemPool& pool)
|
||||||
|
EXCLUSIVE_LOCKS_REQUIRED(::cs_main, pool.cs)
|
||||||
|
{
|
||||||
|
AssertLockHeld(::cs_main);
|
||||||
|
AssertLockHeld(pool.cs);
|
||||||
|
TestMemPoolEntryHelper entry;
|
||||||
|
// Assumes this isn't already spent in mempool
|
||||||
|
auto children_tx = make_two_siblings(/*parent=*/parent, /*output_values=*/{50 * CENT});
|
||||||
|
pool.addUnchecked(entry.FromTx(children_tx.first));
|
||||||
|
pool.addUnchecked(entry.FromTx(children_tx.second));
|
||||||
|
return children_tx;
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_CASE(rbf_helper_functions, TestChain100Setup)
|
BOOST_FIXTURE_TEST_CASE(rbf_helper_functions, TestChain100Setup)
|
||||||
{
|
{
|
||||||
CTxMemPool& pool = *Assert(m_node.mempool);
|
CTxMemPool& pool = *Assert(m_node.mempool);
|
||||||
|
@ -116,6 +161,10 @@ BOOST_FIXTURE_TEST_CASE(rbf_helper_functions, TestChain100Setup)
|
||||||
const auto tx12 = make_tx(/*inputs=*/ {m_coinbase_txns[8]}, /*output_values=*/ {995 * CENT});
|
const auto tx12 = make_tx(/*inputs=*/ {m_coinbase_txns[8]}, /*output_values=*/ {995 * CENT});
|
||||||
pool.addUnchecked(entry.Fee(normal_fee).FromTx(tx12));
|
pool.addUnchecked(entry.Fee(normal_fee).FromTx(tx12));
|
||||||
|
|
||||||
|
// Will make two children of this single parent
|
||||||
|
const auto tx13 = make_tx(/*inputs=*/ {m_coinbase_txns[9]}, /*output_values=*/ {995 * CENT, 995 * CENT});
|
||||||
|
pool.addUnchecked(entry.Fee(normal_fee).FromTx(tx13));
|
||||||
|
|
||||||
const auto entry1_normal = pool.GetIter(tx1->GetHash()).value();
|
const auto entry1_normal = pool.GetIter(tx1->GetHash()).value();
|
||||||
const auto entry2_normal = pool.GetIter(tx2->GetHash()).value();
|
const auto entry2_normal = pool.GetIter(tx2->GetHash()).value();
|
||||||
const auto entry3_low = pool.GetIter(tx3->GetHash()).value();
|
const auto entry3_low = pool.GetIter(tx3->GetHash()).value();
|
||||||
|
@ -128,6 +177,7 @@ BOOST_FIXTURE_TEST_CASE(rbf_helper_functions, TestChain100Setup)
|
||||||
const auto entry10_unchained = pool.GetIter(tx10->GetHash()).value();
|
const auto entry10_unchained = pool.GetIter(tx10->GetHash()).value();
|
||||||
const auto entry11_unchained = pool.GetIter(tx11->GetHash()).value();
|
const auto entry11_unchained = pool.GetIter(tx11->GetHash()).value();
|
||||||
const auto entry12_unchained = pool.GetIter(tx12->GetHash()).value();
|
const auto entry12_unchained = pool.GetIter(tx12->GetHash()).value();
|
||||||
|
const auto entry13_unchained = pool.GetIter(tx13->GetHash()).value();
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(entry1_normal->GetFee(), normal_fee);
|
BOOST_CHECK_EQUAL(entry1_normal->GetFee(), normal_fee);
|
||||||
BOOST_CHECK_EQUAL(entry2_normal->GetFee(), normal_fee);
|
BOOST_CHECK_EQUAL(entry2_normal->GetFee(), normal_fee);
|
||||||
|
@ -292,6 +342,14 @@ BOOST_FIXTURE_TEST_CASE(rbf_helper_functions, TestChain100Setup)
|
||||||
BOOST_CHECK_EQUAL(pool.CheckConflictTopology({entry11_unchained}).value(), strprintf("%s is not the only parent of child %s", entry11_unchained->GetSharedTx()->GetHash().ToString(), entry_two_parent_child->GetSharedTx()->GetHash().ToString()));
|
BOOST_CHECK_EQUAL(pool.CheckConflictTopology({entry11_unchained}).value(), strprintf("%s is not the only parent of child %s", entry11_unchained->GetSharedTx()->GetHash().ToString(), entry_two_parent_child->GetSharedTx()->GetHash().ToString()));
|
||||||
BOOST_CHECK_EQUAL(pool.CheckConflictTopology({entry12_unchained}).value(), strprintf("%s is not the only parent of child %s", entry12_unchained->GetSharedTx()->GetHash().ToString(), entry_two_parent_child->GetSharedTx()->GetHash().ToString()));
|
BOOST_CHECK_EQUAL(pool.CheckConflictTopology({entry12_unchained}).value(), strprintf("%s is not the only parent of child %s", entry12_unchained->GetSharedTx()->GetHash().ToString(), entry_two_parent_child->GetSharedTx()->GetHash().ToString()));
|
||||||
BOOST_CHECK_EQUAL(pool.CheckConflictTopology({entry_two_parent_child}).value(), strprintf("%s has 2 ancestors, max 1 allowed", entry_two_parent_child->GetSharedTx()->GetHash().ToString()));
|
BOOST_CHECK_EQUAL(pool.CheckConflictTopology({entry_two_parent_child}).value(), strprintf("%s has 2 ancestors, max 1 allowed", entry_two_parent_child->GetSharedTx()->GetHash().ToString()));
|
||||||
|
|
||||||
|
// Single parent with two children, we will conflict with the siblings directly only
|
||||||
|
const auto two_siblings = add_children_to_parent(tx13, pool);
|
||||||
|
const auto entry_sibling_1 = pool.GetIter(two_siblings.first->GetHash()).value();
|
||||||
|
const auto entry_sibling_2 = pool.GetIter(two_siblings.second->GetHash()).value();
|
||||||
|
BOOST_CHECK_EQUAL(pool.CheckConflictTopology({entry_sibling_1}).value(), strprintf("%s is not the only child of parent %s", entry_sibling_1->GetSharedTx()->GetHash().ToString(), entry13_unchained->GetSharedTx()->GetHash().ToString()));
|
||||||
|
BOOST_CHECK_EQUAL(pool.CheckConflictTopology({entry_sibling_2}).value(), strprintf("%s is not the only child of parent %s", entry_sibling_2->GetSharedTx()->GetHash().ToString(), entry13_unchained->GetSharedTx()->GetHash().ToString()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_CASE(improves_feerate, TestChain100Setup)
|
BOOST_FIXTURE_TEST_CASE(improves_feerate, TestChain100Setup)
|
||||||
|
|
Loading…
Add table
Reference in a new issue