Test suite for ancestor feerate transaction selection. Implemented as an additional function, rather than a separate test case, to allow reusing the blockchain created in CreateNewBlock_validity.
| 87 | // Implemented as an additional function, rather than a separate test case, |
| 88 | // to allow reusing the blockchain created in CreateNewBlock_validity. |
| 89 | void MinerTestingSetup::TestPackageSelection(const CChainParams& chainparams, const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst) |
| 90 | { |
| 91 | // Test the ancestor feerate transaction selection. |
| 92 | TestMemPoolEntryHelper entry; |
| 93 | |
| 94 | // Test that a medium fee transaction will be selected after a higher fee |
| 95 | // rate package with a low fee rate parent. |
| 96 | CMutableTransaction tx; |
| 97 | tx.vin.resize(1); |
| 98 | tx.vin[0].scriptSig = CScript() << OP_1; |
| 99 | tx.vin[0].prevout.hash = txFirst[0]->GetHash(); |
| 100 | tx.vin[0].prevout.n = 0; |
| 101 | tx.vout.resize(1); |
| 102 | tx.vout[0].nValue = 5000000000LL - 1000; |
| 103 | // This tx has a low fee: 1000 satoshis |
| 104 | uint256 hashParentTx = tx.GetHash(); // save this txid for later use |
| 105 | m_node.mempool->addUnchecked(entry.Fee(1000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); |
| 106 | |
| 107 | // This tx has a medium fee: 10000 satoshis |
| 108 | tx.vin[0].prevout.hash = txFirst[1]->GetHash(); |
| 109 | tx.vout[0].nValue = 5000000000LL - 10000; |
| 110 | uint256 hashMediumFeeTx = tx.GetHash(); |
| 111 | m_node.mempool->addUnchecked(entry.Fee(10000).Time(GetTime()).SpendsCoinbase(true).FromTx(tx)); |
| 112 | |
| 113 | // This tx has a high fee, but depends on the first transaction |
| 114 | tx.vin[0].prevout.hash = hashParentTx; |
| 115 | tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 50k satoshi fee |
| 116 | uint256 hashHighFeeTx = tx.GetHash(); |
| 117 | m_node.mempool->addUnchecked(entry.Fee(50000).Time(GetTime()).SpendsCoinbase(false).FromTx(tx)); |
| 118 | |
| 119 | std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); |
| 120 | BOOST_REQUIRE_EQUAL(pblocktemplate->block.vtx.size(), 4U); |
| 121 | BOOST_CHECK(pblocktemplate->block.vtx[1]->GetHash() == hashParentTx); |
| 122 | BOOST_CHECK(pblocktemplate->block.vtx[2]->GetHash() == hashHighFeeTx); |
| 123 | BOOST_CHECK(pblocktemplate->block.vtx[3]->GetHash() == hashMediumFeeTx); |
| 124 | |
| 125 | // Test that a package below the block min tx fee doesn't get included |
| 126 | tx.vin[0].prevout.hash = hashHighFeeTx; |
| 127 | tx.vout[0].nValue = 5000000000LL - 1000 - 50000; // 0 fee |
| 128 | uint256 hashFreeTx = tx.GetHash(); |
| 129 | m_node.mempool->addUnchecked(entry.Fee(0).FromTx(tx)); |
| 130 | size_t freeTxSize = ::GetSerializeSize(tx, PROTOCOL_VERSION); |
| 131 | |
| 132 | // Calculate a fee on child transaction that will put the package just |
| 133 | // below the block min tx fee (assuming 1 child tx of the same size). |
| 134 | CAmount feeToUse = blockMinFeeRate.GetFee(2*freeTxSize) - 1; |
| 135 | |
| 136 | tx.vin[0].prevout.hash = hashFreeTx; |
| 137 | tx.vout[0].nValue = 5000000000LL - 1000 - 50000 - feeToUse; |
| 138 | uint256 hashLowFeeTx = tx.GetHash(); |
| 139 | m_node.mempool->addUnchecked(entry.Fee(feeToUse).FromTx(tx)); |
| 140 | pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey); |
| 141 | // Verify that the free tx and the low fee tx didn't get selected |
| 142 | for (size_t i=0; i<pblocktemplate->block.vtx.size(); ++i) { |
| 143 | BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashFreeTx); |
| 144 | BOOST_CHECK(pblocktemplate->block.vtx[i]->GetHash() != hashLowFeeTx); |
| 145 | } |
| 146 |
nothing calls this directly
no test coverage detected