diff options
author | glozow <gloriajzhao@gmail.com> | 2023-01-17 15:37:25 +0000 |
---|---|---|
committer | glozow <gloriajzhao@gmail.com> | 2023-04-17 09:52:25 +0100 |
commit | c4554fe894d7af8e666f5d424deccddf516713ef (patch) | |
tree | e77c446b853e1bef05e8802ccc3780d96b9f775a /src/test | |
parent | ac463e87df728689701810c3961155c49fdc5b31 (diff) |
[test] package cpfp bumps parents <mempoolminfee but >=minrelaytxfee
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/txpackage_tests.cpp | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/src/test/txpackage_tests.cpp b/src/test/txpackage_tests.cpp index 024526497c..af29c955bc 100644 --- a/src/test/txpackage_tests.cpp +++ b/src/test/txpackage_tests.cpp @@ -16,6 +16,9 @@ #include <boost/test/unit_test.hpp> BOOST_AUTO_TEST_SUITE(txpackage_tests) +// A fee amount that is above 1sat/vB but below 5sat/vB for most transactions created within these +// unit tests. +static const CAmount low_fee_amt{200}; // Create placeholder transactions that have no meaning. inline CTransactionRef create_placeholder_tx(size_t num_inputs, size_t num_outputs) @@ -373,6 +376,7 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup) { // Mine blocks to mature coinbases. mineBlocks(5); + MockMempoolMinFee(CFeeRate(5000)); LOCK(cs_main); // Transactions with a same-txid-different-witness transaction in the mempool should be ignored, @@ -560,13 +564,15 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup) BOOST_CHECK(parent2_v2_result.m_result_type == MempoolAcceptResult::ResultType::VALID); package_mixed.push_back(ptx_parent2_v1); - // parent3 will be a new transaction. Put 0 fees on it to make it invalid on its own. + // parent3 will be a new transaction. Put a low feerate to make it invalid on its own. auto mtx_parent3 = CreateValidMempoolTransaction(/*input_transaction=*/m_coinbase_txns[3], /*input_vout=*/0, /*input_height=*/0, /*input_signing_key=*/coinbaseKey, /*output_destination=*/acs_spk, - /*output_amount=*/CAmount(50 * COIN), /*submit=*/false); + /*output_amount=*/CAmount(50 * COIN - low_fee_amt), /*submit=*/false); CTransactionRef ptx_parent3 = MakeTransactionRef(mtx_parent3); package_mixed.push_back(ptx_parent3); + BOOST_CHECK(m_node.mempool->GetMinFee().GetFee(GetVirtualTransactionSize(*ptx_parent3)) > low_fee_amt); + BOOST_CHECK(m_node.mempool->m_min_relay_feerate.GetFee(GetVirtualTransactionSize(*ptx_parent3)) <= low_fee_amt); // child spends parent1, parent2, and parent3 CKey mixed_grandchild_key; @@ -627,6 +633,7 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup) BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup) { mineBlocks(5); + MockMempoolMinFee(CFeeRate(5000)); LOCK(::cs_main); size_t expected_pool_size = m_node.mempool->size(); CKey child_key; @@ -636,9 +643,9 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup) grandchild_key.MakeNewKey(true); CScript child_spk = GetScriptForDestination(WitnessV0KeyHash(grandchild_key.GetPubKey())); - // zero-fee parent and high-fee child package + // low-fee parent and high-fee child package const CAmount coinbase_value{50 * COIN}; - const CAmount parent_value{coinbase_value - 0}; + const CAmount parent_value{coinbase_value - low_fee_amt}; const CAmount child_value{parent_value - COIN}; Package package_cpfp; @@ -657,9 +664,9 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup) package_cpfp.push_back(tx_child); // Package feerate is calculated using modified fees, and prioritisetransaction accepts negative - // fee deltas. This should be taken into account. De-prioritise the parent transaction by -1BTC, - // bringing the package feerate to 0. - m_node.mempool->PrioritiseTransaction(tx_parent->GetHash(), -1 * COIN); + // fee deltas. This should be taken into account. De-prioritise the parent transaction + // to bring the package feerate to 0. + m_node.mempool->PrioritiseTransaction(tx_parent->GetHash(), child_value - coinbase_value); { BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); const auto submit_cpfp_deprio = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, @@ -675,8 +682,8 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup) // Clear the prioritisation of the parent transaction. WITH_LOCK(m_node.mempool->cs, m_node.mempool->ClearPrioritisation(tx_parent->GetHash())); - // Package CPFP: Even though the parent pays 0 absolute fees, the child pays 1 BTC which is - // enough for the package feerate to meet the threshold. + // Package CPFP: Even though the parent's feerate is below the mempool minimum feerate, the + // child pays enough for the package feerate to meet the threshold. { BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); const auto submit_cpfp = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, @@ -689,7 +696,7 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup) auto it_child = submit_cpfp.m_tx_results.find(tx_child->GetWitnessHash()); BOOST_CHECK(it_parent != submit_cpfp.m_tx_results.end()); BOOST_CHECK(it_parent->second.m_result_type == MempoolAcceptResult::ResultType::VALID); - BOOST_CHECK(it_parent->second.m_base_fees.value() == 0); + BOOST_CHECK(it_parent->second.m_base_fees.value() == coinbase_value - parent_value); BOOST_CHECK(it_child != submit_cpfp.m_tx_results.end()); BOOST_CHECK(it_child->second.m_result_type == MempoolAcceptResult::ResultType::VALID); BOOST_CHECK(it_child->second.m_base_fees.value() == COIN); @@ -709,22 +716,28 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup) } // Just because we allow low-fee parents doesn't mean we allow low-feerate packages. - // This package just pays 200 satoshis total. This would be enough to pay for the child alone, - // but isn't enough for the entire package to meet the 1sat/vbyte minimum. + // The mempool minimum feerate is 5sat/vB, but this package just pays 800 satoshis total. + // The child fees would be able to pay for itself, but isn't enough for the entire package. Package package_still_too_low; + const CAmount parent_fee{200}; + const CAmount child_fee{600}; auto mtx_parent_cheap = CreateValidMempoolTransaction(/*input_transaction=*/m_coinbase_txns[1], /*input_vout=*/0, /*input_height=*/0, /*input_signing_key=*/coinbaseKey, /*output_destination=*/parent_spk, - /*output_amount=*/coinbase_value, /*submit=*/false); + /*output_amount=*/coinbase_value - parent_fee, /*submit=*/false); CTransactionRef tx_parent_cheap = MakeTransactionRef(mtx_parent_cheap); package_still_too_low.push_back(tx_parent_cheap); + BOOST_CHECK(m_node.mempool->GetMinFee().GetFee(GetVirtualTransactionSize(*tx_parent_cheap)) > parent_fee); + BOOST_CHECK(m_node.mempool->m_min_relay_feerate.GetFee(GetVirtualTransactionSize(*tx_parent_cheap)) <= parent_fee); auto mtx_child_cheap = CreateValidMempoolTransaction(/*input_transaction=*/tx_parent_cheap, /*input_vout=*/0, /*input_height=*/101, /*input_signing_key=*/child_key, /*output_destination=*/child_spk, - /*output_amount=*/coinbase_value - 200, /*submit=*/false); + /*output_amount=*/coinbase_value - parent_fee - child_fee, /*submit=*/false); CTransactionRef tx_child_cheap = MakeTransactionRef(mtx_child_cheap); package_still_too_low.push_back(tx_child_cheap); + BOOST_CHECK(m_node.mempool->GetMinFee().GetFee(GetVirtualTransactionSize(*tx_child_cheap)) <= child_fee); + BOOST_CHECK(m_node.mempool->GetMinFee().GetFee(GetVirtualTransactionSize(*tx_parent_cheap) + GetVirtualTransactionSize(*tx_child_cheap)) > parent_fee + child_fee); // Cheap package should fail with package-fee-too-low. { @@ -735,11 +748,6 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup) BOOST_CHECK_EQUAL(submit_package_too_low.m_state.GetResult(), PackageValidationResult::PCKG_POLICY); BOOST_CHECK_EQUAL(submit_package_too_low.m_state.GetRejectReason(), "package-fee-too-low"); BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size); - const CFeeRate child_feerate(200, GetVirtualTransactionSize(*tx_child_cheap)); - BOOST_CHECK(child_feerate.GetFeePerK() > 1000); - const CFeeRate expected_feerate(200, - GetVirtualTransactionSize(*tx_parent_cheap) + GetVirtualTransactionSize(*tx_child_cheap)); - BOOST_CHECK(expected_feerate.GetFeePerK() < 1000); } // Package feerate includes the modified fees of the transactions. @@ -752,18 +760,18 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup) expected_pool_size += 2; BOOST_CHECK_MESSAGE(submit_prioritised_package.m_state.IsValid(), "Package validation unexpectedly failed" << submit_prioritised_package.m_state.GetRejectReason()); - const CFeeRate expected_feerate(1 * COIN + 200, + const CFeeRate expected_feerate(1 * COIN + parent_fee + child_fee, GetVirtualTransactionSize(*tx_parent_cheap) + GetVirtualTransactionSize(*tx_child_cheap)); BOOST_CHECK_EQUAL(submit_prioritised_package.m_tx_results.size(), package_still_too_low.size()); auto it_parent = submit_prioritised_package.m_tx_results.find(tx_parent_cheap->GetWitnessHash()); auto it_child = submit_prioritised_package.m_tx_results.find(tx_child_cheap->GetWitnessHash()); BOOST_CHECK(it_parent != submit_prioritised_package.m_tx_results.end()); BOOST_CHECK(it_parent->second.m_result_type == MempoolAcceptResult::ResultType::VALID); - BOOST_CHECK(it_parent->second.m_base_fees.value() == 0); + BOOST_CHECK(it_parent->second.m_base_fees.value() == parent_fee); BOOST_CHECK(it_parent->second.m_effective_feerate.value() == expected_feerate); BOOST_CHECK(it_child != submit_prioritised_package.m_tx_results.end()); BOOST_CHECK(it_child->second.m_result_type == MempoolAcceptResult::ResultType::VALID); - BOOST_CHECK(it_child->second.m_base_fees.value() == 200); + BOOST_CHECK(it_child->second.m_base_fees.value() == child_fee); BOOST_CHECK(it_child->second.m_effective_feerate.value() == expected_feerate); std::vector<uint256> expected_wtxids({tx_parent_cheap->GetWitnessHash(), tx_child_cheap->GetWitnessHash()}); BOOST_CHECK(it_parent->second.m_wtxids_fee_calculations.value() == expected_wtxids); |