Skip to content

Conversation

yancyribbens
Copy link
Collaborator

@yancyribbens yancyribbens commented Dec 14, 2024

Add Coin Grinder, A Rust DFS-based selection algorithm which optimizes for transaction
weight and creates a change output.

This is a Rust implementation of the C++ version bitcoin/bitcoin#27877

I plan to follow up and add fuzz tests, property tests and benchmarks before a release. While i've made a best attempt to guard against possible overflows by using checked arithmetic, I suspect more will be uncovered once fuzz tests are added. Every instance of checked arithmetic slows the performance, therefore I've left places unchecked for now that are not obvious.

@yancyribbens yancyribbens force-pushed the coin-grinder branch 7 times, most recently from 27ddcd2 to 635b0c8 Compare December 14, 2024 23:37
@yancyribbens yancyribbens force-pushed the coin-grinder branch 2 times, most recently from c72d8a0 to f714814 Compare January 7, 2025 01:11
@yancyribbens yancyribbens force-pushed the coin-grinder branch 11 times, most recently from 291fe91 to 70c6aa5 Compare March 6, 2025 01:40
@yancyribbens yancyribbens force-pushed the coin-grinder branch 2 times, most recently from bda2072 to a4a5aad Compare March 6, 2025 02:13
@yancyribbens yancyribbens changed the title draft: add coin-grinder Add coin-grinder Mar 6, 2025
@yancyribbens yancyribbens force-pushed the coin-grinder branch 2 times, most recently from 1a474ca to d1726c2 Compare March 6, 2025 23:18
This is a preparatory step.  Preferably, the effective_value function
from rust-bitcoin would be used, however in an upcoming commit, the library
transitions to use weight instead of satisfaction_weight.  Therefore,
while the rust-bitcoin upstream effective_value uses
satisfaction_weight, a local version of effective_value using weight is
added.
Simplify by using a trait method which requires only argument instead of
three.
Core uses just weight in coin-grinder, and it's complicated to maintain
using both satisfaction_weight and weight.  Therefore, switch to just
weight units for all algorithms.

As a consequence, two tests in SRD needed to be revised.  Now that
Weight is used instead, if no Weight is defined in the test, the default
Weight is zero since 160 is no longer added as the base_weight.  This
means that the default weight for all UTXOs in the tests is now zero
where in previously the default was 160 if not otherwise defined.
Simplify code base by using an upstream method instead of creating a
local method that does the same thing.
@yancyribbens yancyribbens force-pushed the coin-grinder branch 2 times, most recently from 5fc6455 to 041957d Compare March 7, 2025 15:19
yancyribbens and others added 4 commits March 7, 2025 09:29
Provide a DFS-based selection algorithm which optimizes for transaction
weight and creates a change output.
If the currently selected input does not contribute to a valid solution,
and the next input to be evaluated is of the same construction (same
value and weight), then skip (do not evaluate).  Therefore, this
optimization significantly improves performance when a candidate input
set contains many identical inputs.

See also:
bitcoin/bitcoin@451be19
It can be estimated that if we continue adding inputs that no better
solution than the current best solution will be forthcoming.

See also:
bitcoin/bitcoin@13161ec
A UTXO pool that contains multiple values that when added together
produce an overflow.  Instead of panic, return None in order to safely
handle such cases.
@yancyribbens
Copy link
Collaborator Author

There's a lot of scar tissue on this one, so re-opening since now I consider this a merge candidate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant