#4044·dogecoin

[feature] Wallet-level minimum input value for automatic coin selection

Author: AxonOS-BCICreated Aug 8, 2026Updated Aug 10, 2026

Problem

Dogecoin Core has two independent dust mechanisms today, and both of them govern outputs, not inputs:

  1. Relay / mempool policy -- -dustlimit and -harddustlimit (src/policy/policy.cpp:212-213, defaults in src/policy/policy.h:70,81). These control what the node accepts and relays.
  2. Wallet output policy -- -discardthreshold (src/wallet/wallet.cpp:65-69, default DEFAULT_DISCARD_THRESHOLD = COIN / 100). The comment in the source is explicit: outputs smaller than this get rejected, change smaller than this gets discarded to fee.

There is no equivalent policy on the input side. CWallet::CreateTransaction gathers spendable coins with:

cpp
// src/wallet/wallet.cpp:2484
AvailableCoins(vAvailableCoins, true, coinControl);

CWallet::AvailableCoins (src/wallet/wallet.cpp:1996) already accepts an nMinimumAmount parameter and filters on it at line 2063:

cpp
if (pcoin->tx->vout[i].nValue < nMinimumAmount || pcoin->tx->vout[i].nValue > nMaximumAmount)
    continue;

but the CreateTransaction call site passes no value, so the default of 1 koinu applies and every dust UTXO in the wallet is eligible for automatic selection.

The practical consequence: a wallet configured to never create outputs below 0.01 DOGE will still silently consume arbitrarily small received outputs, merging them with the user's other coins. For users targeted by dust-based address-linking (see #3544 for the network-side discussion of large-scale dust on Dogecoin), the only current defence is manual Coin Control, which is impractical for non-technical users and offers no protection against accidental consolidation.

Proposed solution

An opt-in wallet-level minimum input value, applied only to automatic coin selection.

Expected behaviour

  • New startup option, e.g. -mininputvalue=<amt>, default 0 (disabled, exactly today's behaviour).
  • When set, UTXOs below the threshold are excluded from automatic selection.
  • The filter must be applied at the CreateTransaction call site (wallet.cpp:2484), not inside AvailableCoins and not by changing its default parameter. WalletModel::listCoins (src/qt/walletmodel.cpp:585) and the Coin Control dialog use the same function; filtering inside AvailableCoins would hide the coins from the Coin Control UI and make them unspendable through the documented escape hatch.
  • Manual selection via Coin Control and CCoinControl::Select remains unaffected: preset inputs are added in CWallet::SelectCoins before the automatic passes.
  • No consensus, mempool, or relay behaviour changes.
  • No balance change: CWallet::GetBalance (wallet.cpp:1906) iterates mapWallet and does not go through AvailableCoins, so filtered coins remain fully counted.

Why not reuse an existing parameter

  • -dustlimit / -harddustlimit are network policy. A node operator may legitimately want to relay dust while not spending it, and vice versa.
  • -discardthreshold is wallet output policy and is validated to be at least the dust limit (wallet.cpp:3977-3980) specifically to avoid creating stuck transactions. Overloading it with input-selection semantics would couple two unrelated decisions, and raising it to protect inputs would also change change- discard behaviour and fee outcomes.

Scope of the change

Small, because the filtering primitive already exists:

  • src/wallet/wallet.cpp -- parse and validate the new option next to the existing -discardthreshold handling (~3971), pass it as nMinimumAmount at the CreateTransaction call site (2484).
  • src/wallet/wallet.h -- static member and default constant alongside DEFAULT_DISCARD_THRESHOLD.
  • Optionally CCoinControl -- a per-call override, so RPCs such as sendtoaddress and fundrawtransaction can opt out.

No RPC surface change is required for inspection: listunspent already exposes query_options.minimumAmount (src/wallet/rpcwallet.cpp:2680), which is sufficient for users to enumerate the outputs the filter would skip.

Testing

Functional tests to add:

  • default (0) reproduces current selection results byte for byte;
  • with a threshold set, sub-threshold UTXOs are not selected automatically;
  • the same UTXOs are still spendable when passed explicitly via Coin Control;
  • getbalance is unchanged with the filter active;
  • a wallet whose entire balance is below the threshold fails with a clear insufficient-funds error rather than an opaque one.

Alternatives considered

  • Manual Coin Control only (status quo): requires per-transaction attention and does not prevent accidental consolidation.
  • Raising -discardthreshold: wrong axis; it governs outputs, and raising it increases change discarded to fee.
  • Filtering inside AvailableCoins: breaks Coin Control and listCoins, as described above.

Notes

Filed as a design proposal, not a bug. Happy to open a PR against the current development branch if maintainers agree with the direction and the option name.