Skip to content

Commit 86fa149

Browse files
glozowknst
authored andcommitted
[unit test] prioritisation in mining
1 parent 22b5224 commit 86fa149

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

src/test/miner_tests.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ namespace miner_tests {
3838
struct MinerTestingSetup : public TestingSetup {
3939
void TestPackageSelection(const CChainParams& chainparams, const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst) EXCLUSIVE_LOCKS_REQUIRED(::cs_main, m_node.mempool->cs);
4040
void TestBasicMining(const CChainParams& chainparams, const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst, int baseheight) EXCLUSIVE_LOCKS_REQUIRED(::cs_main, m_node.mempool->cs);
41+
void TestPrioritisedMining(const CChainParams& chainparams, const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst) EXCLUSIVE_LOCKS_REQUIRED(::cs_main, m_node.mempool->cs);
4142
bool TestSequenceLocks(const CTransaction& tx) EXCLUSIVE_LOCKS_REQUIRED(::cs_main, m_node.mempool->cs)
4243
{
4344
CCoinsViewMemPool view_mempool(&m_node.chainman->ActiveChainstate().CoinsTip(), *m_node.mempool);
@@ -480,6 +481,81 @@ void MinerTestingSetup::TestBasicMining(const CChainParams& chainparams, const C
480481
}
481482
}
482483

484+
void MinerTestingSetup::TestPrioritisedMining(const CChainParams& chainparams, const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst)
485+
{
486+
TestMemPoolEntryHelper entry;
487+
488+
// Test that a tx below min fee but prioritised is included
489+
CMutableTransaction tx;
490+
tx.vin.resize(1);
491+
tx.vin[0].prevout.hash = txFirst[0]->GetHash();
492+
tx.vin[0].prevout.n = 0;
493+
tx.vin[0].scriptSig = CScript() << OP_1;
494+
tx.vout.resize(1);
495+
tx.vout[0].nValue = 5000000000LL; // 0 fee
496+
uint256 hashFreePrioritisedTx = tx.GetHash();
497+
m_node.mempool->addUnchecked(entry.Fee(0).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx));
498+
m_node.mempool->PrioritiseTransaction(hashFreePrioritisedTx, 5 * COIN);
499+
500+
tx.vin[0].prevout.hash = txFirst[1]->GetHash();
501+
tx.vin[0].prevout.n = 0;
502+
tx.vout[0].nValue = 5000000000LL - 1000;
503+
// This tx has a low fee: 1000 satoshis
504+
uint256 hashParentTx = tx.GetHash(); // save this txid for later use
505+
m_node.mempool->addUnchecked(entry.Fee(1000).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx));
506+
507+
// This tx has a medium fee: 10000 satoshis
508+
tx.vin[0].prevout.hash = txFirst[2]->GetHash();
509+
tx.vout[0].nValue = 5000000000LL - 10000;
510+
uint256 hashMediumFeeTx = tx.GetHash();
511+
m_node.mempool->addUnchecked(entry.Fee(10000).Time(Now<NodeSeconds>()).SpendsCoinbase(true).FromTx(tx));
512+
m_node.mempool->PrioritiseTransaction(hashMediumFeeTx, -5 * COIN);
513+
514+
// This tx also has a low fee, but is prioritised
515+
tx.vin[0].prevout.hash = hashParentTx;
516+
tx.vout[0].nValue = 5000000000LL - 1000 - 1000; // 1000 satoshi fee
517+
uint256 hashPrioritsedChild = tx.GetHash();
518+
m_node.mempool->addUnchecked(entry.Fee(1000).Time(Now<NodeSeconds>()).SpendsCoinbase(false).FromTx(tx));
519+
m_node.mempool->PrioritiseTransaction(hashPrioritsedChild, 2 * COIN);
520+
521+
// Test that transaction selection properly updates ancestor fee calculations as prioritised
522+
// parents get included in a block. Create a transaction with two prioritised ancestors, each
523+
// included by itself: FreeParent <- FreeChild <- FreeGrandchild.
524+
// When FreeParent is added, a modified entry will be created for FreeChild + FreeGrandchild
525+
// FreeParent's prioritisation should not be included in that entry.
526+
// When FreeChild is included, FreeChild's prioritisation should also not be included.
527+
tx.vin[0].prevout.hash = txFirst[3]->GetHash();
528+
tx.vout[0].nValue = 5000000000LL; // 0 fee
529+
uint256 hashFreeParent = tx.GetHash();
530+
m_node.mempool->addUnchecked(entry.Fee(0).SpendsCoinbase(true).FromTx(tx));
531+
m_node.mempool->PrioritiseTransaction(hashFreeParent, 10 * COIN);
532+
533+
tx.vin[0].prevout.hash = hashFreeParent;
534+
tx.vout[0].nValue = 5000000000LL; // 0 fee
535+
uint256 hashFreeChild = tx.GetHash();
536+
m_node.mempool->addUnchecked(entry.Fee(0).SpendsCoinbase(false).FromTx(tx));
537+
m_node.mempool->PrioritiseTransaction(hashFreeChild, 1 * COIN);
538+
539+
tx.vin[0].prevout.hash = hashFreeChild;
540+
tx.vout[0].nValue = 5000000000LL; // 0 fee
541+
uint256 hashFreeGrandchild = tx.GetHash();
542+
m_node.mempool->addUnchecked(entry.Fee(0).SpendsCoinbase(false).FromTx(tx));
543+
544+
auto pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey);
545+
BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 6U);
546+
BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashFreeParent);
547+
BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashFreePrioritisedTx);
548+
BOOST_CHECK(pblocktemplate->block.vtx[3]->GetHash() == hashParentTx);
549+
BOOST_CHECK(pblocktemplate->block.vtx[4]->GetHash() == hashPrioritsedChild);
550+
BOOST_CHECK(pblocktemplate->block.vtx[5]->GetHash() == hashFreeChild);
551+
for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) {
552+
// The FreeParent and FreeChild's prioritisations should not impact the child.
553+
BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeGrandchild);
554+
// De-prioritised transaction should not be included.
555+
BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashMediumFeeTx);
556+
}
557+
}
558+
483559
// NOTE: These tests rely on CreateNewBlock doing its own self-validation!
484560
BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
485561
{
@@ -562,6 +638,12 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
562638
LOCK2(cs_main, m_node.mempool->cs);
563639
TestPackageSelection(chainparams, scriptPubKey, txFirst);
564640

641+
m_node.chainman->ActiveChain().Tip()->nHeight--;
642+
SetMockTime(0);
643+
m_node.mempool->clear();
644+
645+
TestPrioritisedMining(chainparams, scriptPubKey, txFirst);
646+
565647
fCheckpointsEnabled = true;
566648
}
567649

0 commit comments

Comments
 (0)