aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/test/coinselector_tests.cpp
diff options
context:
space:
mode:
authorMurch <murch@murch.one>2022-11-02 15:20:16 -0400
committerMurch <murch@murch.one>2023-09-13 14:33:58 -0400
commit2e35e944dab09eff30952233f8dfc0b12c4553d5 (patch)
tree29e769b0ee96b8dc8ebd578876577c9bf1200578 /src/wallet/test/coinselector_tests.cpp
parent3e3e05241128f68cf12f73ee06ff997395643885 (diff)
downloadbitcoin-2e35e944dab09eff30952233f8dfc0b12c4553d5.tar.xz
Bump unconfirmed parent txs to target feerate
When a transaction uses an unconfirmed input, preceding this commit it would not consider the feerate of the parent transaction. Given a parent transaction with a lower ancestor feerate, this resulted in the new transaction's ancestor feerate undershooting the target feerate. This commit changes how we calculate the effective value of unconfirmed UTXOs. The effective value of unconfirmed UTXOs is decreased by the fee necessary to bump its ancestry to the target feerate. This also impacts the calculation of the waste metric: since the estimate for the current fee is increased by the bump fees, unconfirmed UTXOs current fees appear less favorable compared to their unchanged long term fees. This has one caveat: if multiple UTXOs have overlapping ancestries, each of their individual estimates will account for bumping all ancestors.
Diffstat (limited to 'src/wallet/test/coinselector_tests.cpp')
-rw-r--r--src/wallet/test/coinselector_tests.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp
index 3964e9adde..0f344b7c15 100644
--- a/src/wallet/test/coinselector_tests.cpp
+++ b/src/wallet/test/coinselector_tests.cpp
@@ -954,6 +954,53 @@ BOOST_AUTO_TEST_CASE(waste_test)
}
}
+
+BOOST_AUTO_TEST_CASE(bump_fee_test)
+{
+ const CAmount fee{100};
+ const CAmount min_viable_change{200};
+ const CAmount change_cost{125};
+ const CAmount change_fee{35};
+ const CAmount fee_diff{40};
+ const CAmount target{2 * COIN};
+
+ {
+ SelectionResult selection{target, SelectionAlgorithm::MANUAL};
+ add_coin(1 * COIN, 1, selection, /*fee=*/fee, /*long_term_fee=*/fee + fee_diff);
+ add_coin(2 * COIN, 2, selection, fee, fee + fee_diff);
+ const std::vector<std::shared_ptr<COutput>> inputs = selection.GetShuffledInputVector();
+
+ for (size_t i = 0; i < inputs.size(); ++i) {
+ inputs[i]->ApplyBumpFee(20*(i+1));
+ }
+
+ selection.ComputeAndSetWaste(min_viable_change, change_cost, change_fee);
+ CAmount expected_waste = fee_diff * -2 + change_cost + /*bump_fees=*/60;
+ BOOST_CHECK_EQUAL(expected_waste, selection.GetWaste());
+ }
+
+ {
+ // Test with changeless transaction
+ //
+ // Bump fees and excess both contribute fully to the waste score,
+ // therefore, a bump fee group discount will not change the waste
+ // score as long as we do not create change in both instances.
+ CAmount changeless_target = 3 * COIN - 2 * fee - 100;
+ SelectionResult selection{changeless_target, SelectionAlgorithm::MANUAL};
+ add_coin(1 * COIN, 1, selection, /*fee=*/fee, /*long_term_fee=*/fee + fee_diff);
+ add_coin(2 * COIN, 2, selection, fee, fee + fee_diff);
+ const std::vector<std::shared_ptr<COutput>> inputs = selection.GetShuffledInputVector();
+
+ for (size_t i = 0; i < inputs.size(); ++i) {
+ inputs[i]->ApplyBumpFee(20*(i+1));
+ }
+
+ selection.ComputeAndSetWaste(min_viable_change, change_cost, change_fee);
+ CAmount expected_waste = fee_diff * -2 + /*bump_fees=*/60 + /*excess = 100 - bump_fees*/40;
+ BOOST_CHECK_EQUAL(expected_waste, selection.GetWaste());
+ }
+}
+
BOOST_AUTO_TEST_CASE(effective_value_test)
{
const int input_bytes = 148;