Skip to content

Algo/coin grinder #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

yancyribbens
Copy link
Collaborator

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 algo/coin-grinder branch 4 times, most recently from f44b24b to 3971e4f Compare April 29, 2025 16:29
@yancyribbens yancyribbens force-pushed the algo/coin-grinder branch 13 times, most recently from 5c8d62f to 9f98371 Compare June 4, 2025 20:53
yancyribbens and others added 3 commits June 9, 2025 15:05
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.

The estimation is done as follows:
Calculate the number of inputs needed to reach the remaining target.
The input set is sorted by descending value, so we know that every following
input will be less than the current input.  Therefore, to determine the
number of inputs needed to reach the target, we use a lower bound by
estimating that every following input will be the same value as the current
input.  Then, multiply the lower bound input count by the best possible
weight (tail weight) and check if the result could be better than the known
best weight so far.

If the resulting estimation is higher (worse), then decide what fashion of
backtrack is next.  Check the value of the last selected value (tail).
If it's greater than any remaining values then move it to the
exclusion branch (shift) since a better combination is might be
possible.  Otherwise cut entire sub-tree since the tail was the best
possibility for this sub-tree.

See also:
bitcoin/bitcoin@13161ec
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