Skip to content

feat: add CoinSelector::select_srd (Single Random Draw)#50

Open
evanlinjin wants to merge 1 commit into
bitcoindevkit:masterfrom
evanlinjin:feature/single-random-draw
Open

feat: add CoinSelector::select_srd (Single Random Draw)#50
evanlinjin wants to merge 1 commit into
bitcoindevkit:masterfrom
evanlinjin:feature/single-random-draw

Conversation

@evanlinjin

@evanlinjin evanlinjin commented Jul 2, 2026

Copy link
Copy Markdown
Member

Motivation

Adds Single Random Draw coin selection — a port of Bitcoin Core's SelectCoinsSRD. Unlike run_bnb with LowestFee (which minimizes fees), SRD deliberately aims for a healthy-sized, privacy-friendly change output, avoiding tiny "toxic" change. It's the natural complement to the fee-minimizing metric from #49.

What it does

CoinSelector::select_srd adds candidates in random order until the change reaches change_lower, then returns the Drain to attach (or InsufficientFunds).

pub fn select_srd(
    &mut self,
    target: Target,
    drain_weights: DrainWeights,
    change_lower: u64,
    rng: impl FnMut() -> u64,
) -> Result<Drain, InsufficientFunds>
  • Fixed lower bound, like Core. We stop as soon as the change reaches change_lower; the change amount comes out random on its own, because candidates are added in random order and the final change is wherever the last random input pushed it. Core uses the same fixed-threshold approach (and its comment notes SRD "will result in a random change amount anyway"), so there's no need to randomize the target.
  • The stop condition reuses excess(target, drain_weights), so there's no new fee math — it inherits the existing rate/absolute/replacement handling.
  • Zero new dependencies: RNG is a plain impl FnMut() -> u64 (the crate is deliberately dependency-free), used to shuffle the candidates.
  • CHANGE_LOWER (Core's 50k) is added as the sensible default for change_lower.
  • Already-selected candidates are kept and counted toward the target.

max_selection_weight handling (evicting the least-valuable inputs when over a weight cap) is left as a documented // TODO pending the max-weight PR.

Tests

tests/srd.rs covers: change ≥ change_lower and target met across 300 seeds; a custom change_lower is honored; insufficient funds; per-seed determinism; preselected inputs preserved. Full suite + no_std build + clippy are green.

🤖 Generated with Claude Code

@evanlinjin evanlinjin force-pushed the feature/single-random-draw branch from 932e9f0 to a28b8ff Compare July 2, 2026 13:10
@evanlinjin evanlinjin self-assigned this Jul 2, 2026
@evanlinjin evanlinjin force-pushed the feature/single-random-draw branch 2 times, most recently from c44425b to f07df30 Compare July 2, 2026 13:30
Comment thread src/coin_selector.rs Outdated
@evanlinjin evanlinjin force-pushed the feature/single-random-draw branch 4 times, most recently from 1381fd4 to 99af2c6 Compare July 2, 2026 15:20
Port of Bitcoin Core's `SelectCoinsSRD`: add candidates in random order
until the change reaches a fixed `change_lower`, yielding a healthy-sized
(privacy-friendly) change output rather than minimizing fees. Like Core, the
threshold is fixed and the change amount comes out random from the draw
itself. The stop condition reuses `excess(target, drain_weights)`, so no new
fee math. RNG is a dependency-free `impl FnMut() -> u64`.

Adds the `CHANGE_LOWER` constant (Core's 50k).

Maximum-selection-weight handling is left as a TODO pending the max-weight PR.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@evanlinjin evanlinjin force-pushed the feature/single-random-draw branch from 99af2c6 to 7ab6377 Compare July 2, 2026 15:24

@evanlinjin evanlinjin left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 7ab6377

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