31 Commits

Author SHA1 Message Date
ismaelsadeeq
734076c6de [wallet, rpc]: add max_tx_weight to tx funding options
This allows a transaction's weight to be bound under a certain
weight if possible and desired. This can be beneficial for future
RBF attempts, or whenever a more restricted spend topology is
desired.

Co-authored-by: Greg Sanders <gsanders87@gmail.com>
2024-06-27 15:31:21 +01:00
ismaelsadeeq
7f61d31a5c [refactor]: update coin selection algorithms input parameter max_weight name
- This commit renames the coin selection algorithms input parameter `max_weight`
  to `max_selection_weight` for clarity.

  The parameter represent the maximum weight of the UTXOs the coin selection algorithm
  should select, not the transaction maximum weight.

- The commit updates the parameter docstring to provide correct description.

- Also updates coin selection unit and fuzzing test variables to match the new name.
2024-06-27 12:37:33 +01:00
Ava Chow
701b0cf2f3
Merge bitcoin/bitcoin#28366: Fix waste calculation in SelectionResult
bd34dd85e7b8b4cc26d2173d84bbeda2e9c27624 Use `exact_target` shorthand in coinselector_tests (Murch)
7aa7e30441fe77bf8e8092916e36b004bbbfe2a7 Fold GetSelectionWaste() into ComputeAndSetWaste() (Murch)

Pull request description:

  PR #26152 moved waste calculation into SelectionResult to be able to correct the waste score on basis of the bump_fee_group_discount for overlapping ancestries. This left two functions with largely overlapping purpose, where one was simply a wrapper of the other. This PR cleans up the overlap, and fixes the double-meaning of `change_cost` where the `GetChange()` function assumed that no change was created when `change_cost` was set to 0. This behavior was exploited in a bunch of tests, but is problematic, because a `change_cost` of 0 is permitted with custom settings for feerate and discard_feerate (i.e. when they’re both 0).

ACKs for top commit:
  achow101:
    ACK bd34dd85e7b8b4cc26d2173d84bbeda2e9c27624
  furszy:
    Code ACK bd34dd85e7b8b4cc26d2173d84bbeda2e9c27624
  ismaelsadeeq:
    Code Review ACK bd34dd85e7b8b4cc26d2173d84bbeda2e9c27624

Tree-SHA512: 83a2688d45d719dc61a64b5180fe136107faccf401a59df65245c05d701748a03e85ed56fde8c9b7ef39a3ab54374dd3718c559bda5b3f55dafedfd7fed25161
2024-06-04 18:37:18 -04:00
Murch
7aa7e30441 Fold GetSelectionWaste() into ComputeAndSetWaste()
Both `GetSelectionWaste()` and `ComputeAndSetWaste()` now are part of
`SelectionResult`. Instead of `ComputeAndSetWaste()` being a wrapper for
`GetSelectionWaste()`, we combine them to a new function
`RecalculateWaste()`.

As I was combining the logic of the two functions, I noticed that
`GetSelectionWaste()` was making the odd assumption that the
`change_cost` being set to zero means that no change is created.
However, if we build transactions at a feerate of zero with the
`discard_feerate` also set to zero, we'd organically have a
`change_cost` of zero, even when we create change on a transaction.

This commit cleans up this duplicate meaning of `change_cost` and relies
on `GetChange()` to figure out whether there is change on basis of the
`min_viable_change` and whatever is left after deducting fees.

Since this broke a bunch of tests that relied on the double-meaning of
`change_cost` a bunch of tests had to be fixed.
2024-05-24 14:53:54 -04:00
Ryan Ofsky
6a8b2befea refactor: Avoid copying util::Result values
Copying util::Result values is less efficient than moving them because they
allocate memory and contain strings. Also this is needed to avoid compile
errors in https://github.com/bitcoin/bitcoin/pull/25722 which adds a
std::unique_ptr member to util::Result which implicity disables copying.
2024-04-25 16:08:24 -04:00
Murch
9dae3b970a [fuzz] Avoid partial negative result 2024-02-21 15:49:05 -05:00
Murch
d68bc74fb2 fuzz: Test optimality of CoinGrinder
Co-authored-by: Pieter Wuille <pieter@wuille.net>
2024-02-09 10:50:10 +01:00
Murch
67df6c629a fuzz: Add CoinGrinder fuzz target 2024-02-09 10:50:10 +01:00
brunoerg
cd810075ed fuzz: coinselection, improve min_viable_change/change_output_size
Change it to use same approach from
`CreateTransactionInternal`.
2023-12-15 06:28:42 -03:00
furszy
576bee88fd
fuzz: disable BnB when SFFO is enabled 2023-12-11 23:40:21 -03:00
brunoerg
bf26f978ff fuzz: coinselection, fix m_cost_of_change
`m_cost_of_change` must not be generated randomly
independent from m_change_fee. This commit changes
it to set it up according to `wallet/spend`.
2023-08-23 14:48:27 -03:00
brunoerg
6d9b26d56a fuzz: coinselection, BnB should never produce change 2023-08-23 14:48:27 -03:00
brunoerg
b2eb558407 fuzz: coinselection, compare GetSelectedValue with target
The valid results should have a target below the sum of
the selected inputs amounts. Also, it increases the
minimum value for target to make it more realistic.
2023-08-23 14:48:27 -03:00
brunoerg
0df0438c60 fuzz: coinselection, improve ComputeAndSetWaste
Instead of using `cost_of_change` for `min_viable_change`
and `change_cost`, and 0 for `change_fee`, use values from
`coin_params`. The previous values don't generate any effects
that is relevant for that context.
2023-08-23 14:48:27 -03:00
brunoerg
1e351e5db1 fuzz: coinselection, add coverage for Merge 2023-08-23 14:48:27 -03:00
brunoerg
f0244a8614 fuzz: coinselection, add coverage for GetShuffledInputVector/GetInputSet 2023-08-23 14:48:04 -03:00
brunoerg
808618b8a2 fuzz: coinselection, add coverage for AddInputs 2023-08-23 14:47:11 -03:00
brunoerg
90c4e6a241 fuzz: coinselection, add coverage for EligibleForSpending 2023-08-22 14:41:57 -03:00
brunoerg
2a031cb2c2 fuzz: coinselection, add CreateCoins
Move coins creation for a specific function. It
allows us to use it in other parts of the code.
2023-08-22 14:41:57 -03:00
Murch
1771daa815
[fuzz] Show that SRD budgets for non-dust change
Adding this assert to the fuzz test without increasing the change target
by the change_fee resulted in a crash within a few seconds.
2023-06-21 16:19:26 -04:00
Murch
941b8c6539
[bug] Increase SRD target by change_fee
I discovered via fuzzing of another coin selection approach that at
extremely high feerates SRD may find input sets that lead to
transactions without change outputs. This is an unintended outcome since
SRD is meant to always produce a transaction with a change output—we use
other algorithms to specifically search for changeless solutions.

The issue occures when the flat allowance of 50,000 ṩ for change is
insufficient to pay for the creation of a change output with a non-dust
amount, at and above 1,613 ṩ/vB. Increasing the change budget by
change_fees makes SRD behave as expected at any feerates.
2023-06-21 16:19:19 -04:00
furszy
2d112584e3
coin selection: BnB, don't return selection if exceeds max allowed tx weight 2023-04-05 09:32:39 -03:00
furszy
9d9689e5a6
coin selection: heap-ify SRD, don't return selection if exceeds max tx weight
Uses a min-effective-value heap, so we can remove the least valuable input/s
while the selected weight exceeds the maximum allowed weight.

Co-authored-by: Murch <murch@murch.one>
2023-04-05 09:32:39 -03:00
furszy
6107ec2229
coin selection: knapsack, select closest UTXO above target if result exceeds max tx size
The simplest scenario where this is useful is on the 'check_max_weight' unit test
already:

We create 1515 UTXOs with 0.033 BTC each, and 1 UTXO with 50 BTC. Then perform
Coin Selection.

As the selection of the 1515 small UTXOs exceeds the max allowed tx size, the
expectation here is to receive a selection result that only contain the big
UTXO (which is not happening for the reasons stated below).

As knapsack returns a result that exceeds the max allowed transaction size, we
fallback to SRD, which selects coins randomly up until the target is met. So
we end up with a selection result with lot more coins than what is needed.
2023-04-05 09:32:39 -03:00
furszy
461f0821a2
refactor: make OutputGroup::m_outputs field a vector of shared_ptr
Initial steps towards sharing COutput instances across all possible
OutputGroups (instead of copying them time after time).
2023-03-06 09:45:40 -03:00
furszy
06ec8f9928
wallet: make OutputGroup "positive_only" filter explicit
And not hide it inside the `OutputGroup::Insert` method.
This method does not return anything if insertion fails.

We can know before calling `Insert` whether the coin
will be accepted or not.
2023-03-03 18:18:03 -03:00
Jon Atack
b6a65568df Fix issues identified by codespell 2.2.1 and update ignored words
and also fix spelling in test/lint/lint-locale-dependence.py not caught by the
spelling linter and fix up a paragraph we are touching here in test/README.md.
2022-09-15 13:03:40 +02:00
S3RK
4fef534428 wallet: use GetChange() when computing waste 2022-08-15 09:35:20 +02:00
S3RK
c8cf08ea74 wallet: ensure m_min_change_target always covers change fee 2022-08-15 09:34:26 +02:00
furszy
c97e961d46
fuzz: coinselection, add missing fee rate.
Otherwise, 'GroupOutputs' will crash at group insertion time (output.GetEffectiveValue() asserts that the value exists).
2022-05-25 14:07:33 -03:00
Martin Zumsande
21520b9551 fuzz: add target for coinselection
This creates random OutputGroups and runs the
existing coinselection algorithms for them.
2022-03-30 17:17:37 +02:00