aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorglozow <gloriajzhao@gmail.com>2023-01-11 13:04:13 +0000
committerglozow <gloriajzhao@gmail.com>2023-01-11 13:25:39 +0000
commit26002570ab600bc653433693b7492b85965ccbce (patch)
tree3c3a44b694b19f4b51ec9aadb18909b3126d8f23 /src/test
parentdbca00ef76e5a004555dbd4cdc9209492f02e358 (diff)
parent264f9ef17f650035882d24083fb419845942a3ac (diff)
Merge bitcoin/bitcoin#26646: validation, bugfix: provide more info in *MempoolAcceptResult
264f9ef17f650035882d24083fb419845942a3ac [validation] return MempoolAcceptResult for every tx on PCKG_TX failure (glozow) dae81e01e8698e04afb0db4d1442659c3b48fcf5 [refactor] rename variables in AcceptPackage for clarity (glozow) da484bc738eca47936a31a2e5ad663417e19f311 [doc] release note effective-feerate and effective-includes RPC results (glozow) 5eab397b9840de5a4729bea723794b529e5fcbb4 [validation] remove PackageMempoolAcceptResult::m_package_feerate (glozow) 601bac88cb95404e7d38ac6348d959c0e06bd922 [rpc] return effective-includes in testmempoolaccept and submitpackage (glozow) 1691eaa818f7a7b22907f756490b842d80a9a21d [rpc] return effective-feerate in testmempoolaccept and submitpackage (glozow) d6c7b78ef2924af72f677ce2a7472c2447141e18 [validation] return wtxids of other transactions whose fees were used (glozow) 1605886380e4d3ff2e1236739fb800fa07322c49 [validation] return effective feerate from mempool validation (glozow) 5d35b4a7dee95ae70bfdcbe79bc39fe488641b23 [test] package validation quits early due to non-policy, non-missing-inputs failure (glozow) be2e4d94e59510e0a98408313feb27e97321b16e [validation] when quitting early in AcceptPackage, set package_state and tx result (glozow) Pull request description: This PR fixes a bug and improves the mempool accept interface to return information more predictably. Bug: In package validation, we first try the transactions individually (see doc/policy/packages.md for more explanation) and, if they all failed for missing inputs and policy-related (i.e. fee) reasons, we'll try package validation. Otherwise, we'll just "quit early" since, for example, if a transaction had an invalid signature, adding a child will not help make it valid. Currently, when we quit early, we're not setting the `package_state` to be invalid, so the caller might think it succeeded. Also, we're returning no results - it makes more sense to return the individual transaction failure. Thanks instagibbs for catching https://github.com/bitcoin/bitcoin/pull/25038#discussion_r1013293248! Also, make the package results interface generally more useful/predictable: - Always return the feerate at which a transaction was considered for `CheckFeeRate` in `MempoolAcceptResult::m_effective_feerate` when it was successful. This can replace the current `PackageMempoolAcceptResult::m_package_feerate`, which only sometimes exists. - Always provide an entry for every transaction in `PackageMempoolAcceptResult::m_tx_results` when the error is `PCKG_TX`. ACKs for top commit: instagibbs: reACK https://github.com/bitcoin/bitcoin/pull/26646/commits/264f9ef17f650035882d24083fb419845942a3ac achow101: ACK 264f9ef17f650035882d24083fb419845942a3ac naumenkogs: reACK 264f9ef17f650035882d24083fb419845942a3ac Tree-SHA512: ce7fd9927a80030317cc6157822596e85a540feff5dbf5eea7c62da2eb50c917cdddc9da1e2ff62cc18b98b27d360151811546bd9d498859679a04bbee090837
Diffstat (limited to 'src/test')
-rw-r--r--src/test/txpackage_tests.cpp118
1 files changed, 72 insertions, 46 deletions
diff --git a/src/test/txpackage_tests.cpp b/src/test/txpackage_tests.cpp
index b290a664f9..e438867d15 100644
--- a/src/test/txpackage_tests.cpp
+++ b/src/test/txpackage_tests.cpp
@@ -90,17 +90,21 @@ BOOST_FIXTURE_TEST_CASE(package_validation_tests, TestChain100Setup)
const auto result_parent_child = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, {tx_parent, tx_child}, /*test_accept=*/true);
BOOST_CHECK_MESSAGE(result_parent_child.m_state.IsValid(),
"Package validation unexpectedly failed: " << result_parent_child.m_state.GetRejectReason());
+ BOOST_CHECK(result_parent_child.m_tx_results.size() == 2);
auto it_parent = result_parent_child.m_tx_results.find(tx_parent->GetWitnessHash());
auto it_child = result_parent_child.m_tx_results.find(tx_child->GetWitnessHash());
BOOST_CHECK(it_parent != result_parent_child.m_tx_results.end());
BOOST_CHECK_MESSAGE(it_parent->second.m_state.IsValid(),
"Package validation unexpectedly failed: " << it_parent->second.m_state.GetRejectReason());
+ BOOST_CHECK(it_parent->second.m_effective_feerate.value().GetFee(GetVirtualTransactionSize(*tx_parent)) == COIN);
+ BOOST_CHECK_EQUAL(it_parent->second.m_wtxids_fee_calculations.value().size(), 1);
+ BOOST_CHECK_EQUAL(it_parent->second.m_wtxids_fee_calculations.value().front(), tx_parent->GetWitnessHash());
BOOST_CHECK(it_child != result_parent_child.m_tx_results.end());
BOOST_CHECK_MESSAGE(it_child->second.m_state.IsValid(),
"Package validation unexpectedly failed: " << it_child->second.m_state.GetRejectReason());
- BOOST_CHECK(result_parent_child.m_package_feerate.has_value());
- BOOST_CHECK(result_parent_child.m_package_feerate.value() ==
- CFeeRate(2 * COIN, GetVirtualTransactionSize(*tx_parent) + GetVirtualTransactionSize(*tx_child)));
+ BOOST_CHECK(it_child->second.m_effective_feerate.value().GetFee(GetVirtualTransactionSize(*tx_child)) == COIN);
+ BOOST_CHECK_EQUAL(it_child->second.m_wtxids_fee_calculations.value().size(), 1);
+ BOOST_CHECK_EQUAL(it_child->second.m_wtxids_fee_calculations.value().front(), tx_child->GetWitnessHash());
// A single, giant transaction submitted through ProcessNewPackage fails on single tx policy.
CTransactionRef giant_ptx = create_placeholder_tx(999, 999);
@@ -109,10 +113,10 @@ BOOST_FIXTURE_TEST_CASE(package_validation_tests, TestChain100Setup)
BOOST_CHECK(result_single_large.m_state.IsInvalid());
BOOST_CHECK_EQUAL(result_single_large.m_state.GetResult(), PackageValidationResult::PCKG_TX);
BOOST_CHECK_EQUAL(result_single_large.m_state.GetRejectReason(), "transaction failed");
+ BOOST_CHECK(result_single_large.m_tx_results.size() == 1);
auto it_giant_tx = result_single_large.m_tx_results.find(giant_ptx->GetWitnessHash());
BOOST_CHECK(it_giant_tx != result_single_large.m_tx_results.end());
BOOST_CHECK_EQUAL(it_giant_tx->second.m_state.GetRejectReason(), "tx-size");
- BOOST_CHECK(result_single_large.m_package_feerate == std::nullopt);
// Check that mempool size hasn't changed.
BOOST_CHECK_EQUAL(m_node.mempool->size(), initialPoolSize);
@@ -233,7 +237,6 @@ BOOST_FIXTURE_TEST_CASE(package_submission_tests, TestChain100Setup)
BOOST_CHECK_EQUAL(result_unrelated_submit.m_state.GetResult(), PackageValidationResult::PCKG_POLICY);
BOOST_CHECK_EQUAL(result_unrelated_submit.m_state.GetRejectReason(), "package-not-child-with-parents");
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size);
- BOOST_CHECK(result_unrelated_submit.m_package_feerate == std::nullopt);
// Parent and Child (and Grandchild) Package
Package package_parent_child;
@@ -275,7 +278,30 @@ BOOST_FIXTURE_TEST_CASE(package_submission_tests, TestChain100Setup)
BOOST_CHECK_EQUAL(result_3gen_submit.m_state.GetResult(), PackageValidationResult::PCKG_POLICY);
BOOST_CHECK_EQUAL(result_3gen_submit.m_state.GetRejectReason(), "package-not-child-with-parents");
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size);
- BOOST_CHECK(result_3gen_submit.m_package_feerate == std::nullopt);
+ }
+
+ // Parent and child package where transactions are invalid for reasons other than fee and
+ // missing inputs, so the package validation isn't expected to happen.
+ {
+ CScriptWitness bad_witness;
+ bad_witness.stack.push_back(std::vector<unsigned char>(1));
+ CMutableTransaction mtx_parent_invalid{mtx_parent};
+ mtx_parent_invalid.vin[0].scriptWitness = bad_witness;
+ CTransactionRef tx_parent_invalid = MakeTransactionRef(mtx_parent_invalid);
+ auto result_quit_early = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
+ {tx_parent_invalid, tx_child}, /*test_accept=*/ false);
+ BOOST_CHECK(result_quit_early.m_state.IsInvalid());
+ BOOST_CHECK_EQUAL(result_quit_early.m_state.GetResult(), PackageValidationResult::PCKG_TX);
+ BOOST_CHECK(!result_quit_early.m_tx_results.empty());
+ BOOST_CHECK_EQUAL(result_quit_early.m_tx_results.size(), 2);
+ auto it_parent = result_quit_early.m_tx_results.find(tx_parent_invalid->GetWitnessHash());
+ auto it_child = result_quit_early.m_tx_results.find(tx_child->GetWitnessHash());
+ BOOST_CHECK(it_parent != result_quit_early.m_tx_results.end());
+ BOOST_CHECK(it_child != result_quit_early.m_tx_results.end());
+ BOOST_CHECK_EQUAL(it_parent->second.m_state.GetResult(), TxValidationResult::TX_WITNESS_MUTATED);
+ BOOST_CHECK_EQUAL(it_parent->second.m_state.GetRejectReason(), "bad-witness-nonstandard");
+ BOOST_CHECK_EQUAL(it_child->second.m_state.GetResult(), TxValidationResult::TX_MISSING_INPUTS);
+ BOOST_CHECK_EQUAL(it_child->second.m_state.GetRejectReason(), "bad-txns-inputs-missingorspent");
}
// Child with missing parent.
@@ -290,8 +316,6 @@ BOOST_FIXTURE_TEST_CASE(package_submission_tests, TestChain100Setup)
BOOST_CHECK_EQUAL(result_missing_parent.m_state.GetResult(), PackageValidationResult::PCKG_POLICY);
BOOST_CHECK_EQUAL(result_missing_parent.m_state.GetRejectReason(), "package-not-child-with-unconfirmed-parents");
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size);
-
- BOOST_CHECK(result_missing_parent.m_package_feerate == std::nullopt);
}
// Submit package with parent + child.
@@ -301,20 +325,23 @@ BOOST_FIXTURE_TEST_CASE(package_submission_tests, TestChain100Setup)
expected_pool_size += 2;
BOOST_CHECK_MESSAGE(submit_parent_child.m_state.IsValid(),
"Package validation unexpectedly failed: " << submit_parent_child.m_state.GetRejectReason());
+ BOOST_CHECK_EQUAL(submit_parent_child.m_tx_results.size(), package_parent_child.size());
auto it_parent = submit_parent_child.m_tx_results.find(tx_parent->GetWitnessHash());
auto it_child = submit_parent_child.m_tx_results.find(tx_child->GetWitnessHash());
BOOST_CHECK(it_parent != submit_parent_child.m_tx_results.end());
BOOST_CHECK(it_parent->second.m_state.IsValid());
+ BOOST_CHECK(it_parent->second.m_effective_feerate == CFeeRate(1 * COIN, GetVirtualTransactionSize(*tx_parent)));
+ BOOST_CHECK_EQUAL(it_parent->second.m_wtxids_fee_calculations.value().size(), 1);
+ BOOST_CHECK_EQUAL(it_parent->second.m_wtxids_fee_calculations.value().front(), tx_parent->GetWitnessHash());
BOOST_CHECK(it_child != submit_parent_child.m_tx_results.end());
BOOST_CHECK(it_child->second.m_state.IsValid());
+ BOOST_CHECK(it_child->second.m_effective_feerate == CFeeRate(1 * COIN, GetVirtualTransactionSize(*tx_child)));
+ BOOST_CHECK_EQUAL(it_child->second.m_wtxids_fee_calculations.value().size(), 1);
+ BOOST_CHECK_EQUAL(it_child->second.m_wtxids_fee_calculations.value().front(), tx_child->GetWitnessHash());
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size);
BOOST_CHECK(m_node.mempool->exists(GenTxid::Txid(tx_parent->GetHash())));
BOOST_CHECK(m_node.mempool->exists(GenTxid::Txid(tx_child->GetHash())));
-
- // Since both transactions have high feerates, they each passed validation individually.
- // Package validation was unnecessary, so there is no package feerate.
- BOOST_CHECK(submit_parent_child.m_package_feerate == std::nullopt);
}
// Already-in-mempool transactions should be detected and de-duplicated.
@@ -323,6 +350,7 @@ BOOST_FIXTURE_TEST_CASE(package_submission_tests, TestChain100Setup)
package_parent_child, /*test_accept=*/false);
BOOST_CHECK_MESSAGE(submit_deduped.m_state.IsValid(),
"Package validation unexpectedly failed: " << submit_deduped.m_state.GetRejectReason());
+ BOOST_CHECK_EQUAL(submit_deduped.m_tx_results.size(), package_parent_child.size());
auto it_parent_deduped = submit_deduped.m_tx_results.find(tx_parent->GetWitnessHash());
auto it_child_deduped = submit_deduped.m_tx_results.find(tx_child->GetWitnessHash());
BOOST_CHECK(it_parent_deduped != submit_deduped.m_tx_results.end());
@@ -335,8 +363,6 @@ BOOST_FIXTURE_TEST_CASE(package_submission_tests, TestChain100Setup)
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size);
BOOST_CHECK(m_node.mempool->exists(GenTxid::Txid(tx_parent->GetHash())));
BOOST_CHECK(m_node.mempool->exists(GenTxid::Txid(tx_child->GetHash())));
-
- BOOST_CHECK(submit_deduped.m_package_feerate == std::nullopt);
}
}
@@ -399,6 +425,7 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup)
{ptx_parent, ptx_child1}, /*test_accept=*/false);
BOOST_CHECK_MESSAGE(submit_witness1.m_state.IsValid(),
"Package validation unexpectedly failed: " << submit_witness1.m_state.GetRejectReason());
+ BOOST_CHECK_EQUAL(submit_witness1.m_tx_results.size(), 2);
auto it_parent1 = submit_witness1.m_tx_results.find(ptx_parent->GetWitnessHash());
auto it_child1 = submit_witness1.m_tx_results.find(ptx_child1->GetWitnessHash());
BOOST_CHECK(it_parent1 != submit_witness1.m_tx_results.end());
@@ -412,13 +439,11 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup)
BOOST_CHECK(m_node.mempool->exists(GenTxid::Txid(ptx_child1->GetHash())));
// Child2 would have been validated individually.
- BOOST_CHECK(submit_witness1.m_package_feerate == std::nullopt);
-
const auto submit_witness2 = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
{ptx_parent, ptx_child2}, /*test_accept=*/false);
- BOOST_CHECK(submit_witness2.m_package_feerate == std::nullopt);
BOOST_CHECK_MESSAGE(submit_witness2.m_state.IsValid(),
"Package validation unexpectedly failed: " << submit_witness2.m_state.GetRejectReason());
+ BOOST_CHECK_EQUAL(submit_witness2.m_tx_results.size(), 2);
auto it_parent2_deduped = submit_witness2.m_tx_results.find(ptx_parent->GetWitnessHash());
auto it_child2 = submit_witness2.m_tx_results.find(ptx_child2->GetWitnessHash());
BOOST_CHECK(it_parent2_deduped != submit_witness2.m_tx_results.end());
@@ -436,11 +461,11 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup)
{ptx_parent, ptx_child1}, /*test_accept=*/false);
BOOST_CHECK_MESSAGE(submit_segwit_dedup.m_state.IsValid(),
"Package validation unexpectedly failed: " << submit_segwit_dedup.m_state.GetRejectReason());
+ BOOST_CHECK_EQUAL(submit_segwit_dedup.m_tx_results.size(), 2);
auto it_parent_dup = submit_segwit_dedup.m_tx_results.find(ptx_parent->GetWitnessHash());
auto it_child_dup = submit_segwit_dedup.m_tx_results.find(ptx_child1->GetWitnessHash());
BOOST_CHECK(it_parent_dup->second.m_result_type == MempoolAcceptResult::ResultType::MEMPOOL_ENTRY);
BOOST_CHECK(it_child_dup->second.m_result_type == MempoolAcceptResult::ResultType::MEMPOOL_ENTRY);
- BOOST_CHECK(submit_witness2.m_package_feerate == std::nullopt);
}
// Try submitting Package1{child2, grandchild} where child2 is same-txid-different-witness as
@@ -465,6 +490,7 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup)
{ptx_child2, ptx_grandchild}, /*test_accept=*/false);
BOOST_CHECK_MESSAGE(submit_spend_ignored.m_state.IsValid(),
"Package validation unexpectedly failed: " << submit_spend_ignored.m_state.GetRejectReason());
+ BOOST_CHECK_EQUAL(submit_spend_ignored.m_tx_results.size(), 2);
auto it_child2_ignored = submit_spend_ignored.m_tx_results.find(ptx_child2->GetWitnessHash());
auto it_grandchild = submit_spend_ignored.m_tx_results.find(ptx_grandchild->GetWitnessHash());
BOOST_CHECK(it_child2_ignored != submit_spend_ignored.m_tx_results.end());
@@ -475,9 +501,6 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup)
BOOST_CHECK(m_node.mempool->exists(GenTxid::Txid(ptx_child2->GetHash())));
BOOST_CHECK(!m_node.mempool->exists(GenTxid::Wtxid(ptx_child2->GetWitnessHash())));
BOOST_CHECK(m_node.mempool->exists(GenTxid::Wtxid(ptx_grandchild->GetWitnessHash())));
-
- // Since child2 is ignored, grandchild would be validated individually.
- BOOST_CHECK(submit_spend_ignored.m_package_feerate == std::nullopt);
}
// A package Package{parent1, parent2, parent3, child} where the parents are a mixture of
@@ -568,6 +591,7 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup)
{
const auto mixed_result = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package_mixed, false);
BOOST_CHECK_MESSAGE(mixed_result.m_state.IsValid(), mixed_result.m_state.GetRejectReason());
+ BOOST_CHECK_EQUAL(mixed_result.m_tx_results.size(), package_mixed.size());
auto it_parent1 = mixed_result.m_tx_results.find(ptx_parent1->GetWitnessHash());
auto it_parent2 = mixed_result.m_tx_results.find(ptx_parent2_v1->GetWitnessHash());
auto it_parent3 = mixed_result.m_tx_results.find(ptx_parent3->GetWitnessHash());
@@ -590,11 +614,12 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup)
BOOST_CHECK(m_node.mempool->exists(GenTxid::Txid(ptx_mixed_child->GetHash())));
// package feerate should include parent3 and child. It should not include parent1 or parent2_v1.
- BOOST_CHECK(mixed_result.m_package_feerate.has_value());
const CFeeRate expected_feerate(1 * COIN, GetVirtualTransactionSize(*ptx_parent3) + GetVirtualTransactionSize(*ptx_mixed_child));
- BOOST_CHECK_MESSAGE(mixed_result.m_package_feerate.value() == expected_feerate,
- strprintf("Expected package feerate %s, got %s", expected_feerate.ToString(),
- mixed_result.m_package_feerate.value().ToString()));
+ BOOST_CHECK(it_parent3->second.m_effective_feerate.value() == expected_feerate);
+ BOOST_CHECK(it_child->second.m_effective_feerate.value() == expected_feerate);
+ std::vector<uint256> expected_wtxids({ptx_parent3->GetWitnessHash(), ptx_mixed_child->GetWitnessHash()});
+ BOOST_CHECK(it_parent3->second.m_wtxids_fee_calculations.value() == expected_wtxids);
+ BOOST_CHECK(it_child->second.m_wtxids_fee_calculations.value() == expected_wtxids);
}
}
@@ -638,16 +663,12 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size);
const auto submit_cpfp_deprio = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
package_cpfp, /*test_accept=*/ false);
+ BOOST_CHECK_EQUAL(submit_cpfp_deprio.m_state.GetResult(), PackageValidationResult::PCKG_POLICY);
BOOST_CHECK_MESSAGE(submit_cpfp_deprio.m_state.IsInvalid(),
"Package validation unexpectedly succeeded: " << submit_cpfp_deprio.m_state.GetRejectReason());
BOOST_CHECK(submit_cpfp_deprio.m_tx_results.empty());
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size);
const CFeeRate expected_feerate(0, GetVirtualTransactionSize(*tx_parent) + GetVirtualTransactionSize(*tx_child));
- BOOST_CHECK(submit_cpfp_deprio.m_package_feerate.has_value());
- BOOST_CHECK(submit_cpfp_deprio.m_package_feerate.value() == CFeeRate{0});
- BOOST_CHECK_MESSAGE(submit_cpfp_deprio.m_package_feerate.value() == expected_feerate,
- strprintf("Expected package feerate %s, got %s", expected_feerate.ToString(),
- submit_cpfp_deprio.m_package_feerate.value().ToString()));
}
// Clear the prioritisation of the parent transaction.
@@ -662,6 +683,7 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
expected_pool_size += 2;
BOOST_CHECK_MESSAGE(submit_cpfp.m_state.IsValid(),
"Package validation unexpectedly failed: " << submit_cpfp.m_state.GetRejectReason());
+ BOOST_CHECK_EQUAL(submit_cpfp.m_tx_results.size(), package_cpfp.size());
auto it_parent = submit_cpfp.m_tx_results.find(tx_parent->GetWitnessHash());
auto it_child = submit_cpfp.m_tx_results.find(tx_child->GetWitnessHash());
BOOST_CHECK(it_parent != submit_cpfp.m_tx_results.end());
@@ -677,11 +699,12 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
const CFeeRate expected_feerate(coinbase_value - child_value,
GetVirtualTransactionSize(*tx_parent) + GetVirtualTransactionSize(*tx_child));
+ BOOST_CHECK(it_parent->second.m_effective_feerate.value() == expected_feerate);
+ BOOST_CHECK(it_child->second.m_effective_feerate.value() == expected_feerate);
+ std::vector<uint256> expected_wtxids({tx_parent->GetWitnessHash(), tx_child->GetWitnessHash()});
+ BOOST_CHECK(it_parent->second.m_wtxids_fee_calculations.value() == expected_wtxids);
+ BOOST_CHECK(it_child->second.m_wtxids_fee_calculations.value() == expected_wtxids);
BOOST_CHECK(expected_feerate.GetFeePerK() > 1000);
- BOOST_CHECK(submit_cpfp.m_package_feerate.has_value());
- BOOST_CHECK_MESSAGE(submit_cpfp.m_package_feerate.value() == expected_feerate,
- strprintf("Expected package feerate %s, got %s", expected_feerate.ToString(),
- submit_cpfp.m_package_feerate.value().ToString()));
}
// Just because we allow low-fee parents doesn't mean we allow low-feerate packages.
@@ -716,10 +739,6 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
const CFeeRate expected_feerate(200,
GetVirtualTransactionSize(*tx_parent_cheap) + GetVirtualTransactionSize(*tx_child_cheap));
BOOST_CHECK(expected_feerate.GetFeePerK() < 1000);
- BOOST_CHECK(submit_package_too_low.m_package_feerate.has_value());
- BOOST_CHECK_MESSAGE(submit_package_too_low.m_package_feerate.value() == expected_feerate,
- strprintf("Expected package feerate %s, got %s", expected_feerate.ToString(),
- submit_package_too_low.m_package_feerate.value().ToString()));
}
// Package feerate includes the modified fees of the transactions.
@@ -734,10 +753,20 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
"Package validation unexpectedly failed" << submit_prioritised_package.m_state.GetRejectReason());
const CFeeRate expected_feerate(1 * COIN + 200,
GetVirtualTransactionSize(*tx_parent_cheap) + GetVirtualTransactionSize(*tx_child_cheap));
- BOOST_CHECK(submit_prioritised_package.m_package_feerate.has_value());
- BOOST_CHECK_MESSAGE(submit_prioritised_package.m_package_feerate.value() == expected_feerate,
- strprintf("Expected package feerate %s, got %s", expected_feerate.ToString(),
- submit_prioritised_package.m_package_feerate.value().ToString()));
+ 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_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_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);
+ BOOST_CHECK(it_child->second.m_wtxids_fee_calculations.value() == expected_wtxids);
}
// Package feerate is calculated without topology in mind; it's just aggregating fees and sizes.
@@ -770,10 +799,6 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
BOOST_CHECK_MESSAGE(submit_rich_parent.m_state.IsInvalid(), "Package validation unexpectedly succeeded");
// The child would have been validated on its own and failed, then submitted as a "package" of 1.
- // The package feerate is just the child's feerate, which is 0sat/vb.
- BOOST_CHECK(submit_rich_parent.m_package_feerate.has_value());
- BOOST_CHECK_MESSAGE(submit_rich_parent.m_package_feerate.value() == CFeeRate(),
- "expected 0, got " << submit_rich_parent.m_package_feerate.value().ToString());
BOOST_CHECK_EQUAL(submit_rich_parent.m_state.GetResult(), PackageValidationResult::PCKG_POLICY);
BOOST_CHECK_EQUAL(submit_rich_parent.m_state.GetRejectReason(), "package-fee-too-low");
@@ -783,6 +808,7 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
BOOST_CHECK(it_parent->second.m_state.GetRejectReason() == "");
BOOST_CHECK_MESSAGE(it_parent->second.m_base_fees.value() == high_parent_fee,
strprintf("rich parent: expected fee %s, got %s", high_parent_fee, it_parent->second.m_base_fees.value()));
+ BOOST_CHECK(it_parent->second.m_effective_feerate == CFeeRate(high_parent_fee, GetVirtualTransactionSize(*tx_parent_rich)));
BOOST_CHECK_EQUAL(m_node.mempool->size(), expected_pool_size);
BOOST_CHECK(m_node.mempool->exists(GenTxid::Txid(tx_parent_rich->GetHash())));