#34698 wallet: handle MiniMiner bump fee calculation failures

full analysis

https://github.com/bitcoin/bitcoin/pull/34698 · shuv-amp · +147/-37 in 11 files, 1 commits · labels: Wallet

Goal

  • Prevent internal exceptions when spending unconfirmed coins tied to very large mempool clusters
  • Return clear error messages instead to wallet users creating transactions or running sendall

Handles MiniMiner bump fee calculation failures when unconfirmed outpoints exceed mempool cluster limits. It turns an empty bump-fee map into an explicit error and refactors AvailableCoins to return util::Result<CoinsResult>, propagating an informative error message up through wallet RPCs instead of throwing an out-of-bounds map exception.

Problem: When the mempool cluster size exceeds 500 transactions, MiniMiner's fee calculation gives up and returns an empty map; subsequent indexing via map::at leaks an internal exception to users creating transactions or running sendall.

Category: Wallet (#43 of 84)

P3 · bug fix

  • P3 because it prevents an unhandled internal exception exposed to users in rare mempool topologies
  • Only occurs when spending coins in clusters over 500 transactions and does not endanger funds

Fixes issue #29711 where an unhandled map::at exception was exposed to users attempting to spend unconfirmed coins associated with a mempool cluster exceeding the 500-tx limit. While the bug causes a confusing error message, it only occurs in rare high-depth mempool topologies and does not endanger funds.

Membership: Changes wallet fee calculation handling in src/wallet/spend.cpp and updates wallet RPC error handling.

Factors: security/stability 1, bug 1, performance 0, user value 1, leverage 0

Reviewability: Ready

  • Ready to review
  • Author incorporated all reviewer feedback and CI is passing

The author implemented reviewer suggestions from achow101, CI is clean, and there are no unresolved review requests.

Author status: active

Resolved concerns:

  • achow101 suggested avoiding std::optional in MiniMiner return types, which the author addressed by detecting emptiness in the wallet callers.
  • achow101 suggested using util::Result<CoinsResult> rather than an error out-parameter for AvailableCoins, which the author adopted in the latest push.

Agreement: Positive

  • Positive sentiment with reviewer feedback addressed
  • Guided error reporting patterns and return types, which the author implemented (achow101)

Positive; author adopted all suggested changes from achow101, awaiting re-review.

achow101 provided directional review on error reporting and return types, which the author implemented.

  • achow101 suggested checking !empty() instead of wrapping return in std::optional; author complied.
  • achow101 suggested returning util::Result<CoinsResult> from AvailableCoins; author implemented in latest rebase.

Review verdicts (DrahtBot): 0

Files

135 lines under test/bench/ci.

  • test/functional/wallet_spend_unconfirmed.py +70/-0
  • src/wallet/spend.cpp +22/-9
  • src/test/fuzz/mini_miner.cpp +15/-9
  • src/bench/wallet_create_tx.cpp +8/-6
  • src/wallet/test/wallet_tests.cpp +9/-5
  • src/test/miniminer_tests.cpp +11/-0
  • src/wallet/spend.h +4/-4
  • src/wallet/rpc/spend.cpp +5/-1
  • src/wallet/interfaces.cpp +1/-1
  • src/wallet/rpc/coins.cpp +1/-1
  • src/wallet/test/spend_tests.cpp +1/-1

Card

This PR fixes issue #29711 by handling MiniMiner bump fee calculation failures when an unconfirmed input belongs to an unconfirmed transaction cluster that exceeds the 500-tx limit. Instead of indexing into an empty map and throwing a map::at exception, the wallet detects calculation failure and AvailableCoins returns util::Result<CoinsResult> with a clear descriptive error. Reviewer achow101 suggested returning util::Result, which the author implemented; the PR is clean, passing CI, and ready for follow-up review.

Data

dossier JSON · extract JSON · model openrouter/google/gemini-3.8-flash, generated 2026-09-17T16:17, confidence high, input hash fafee9503517e9c0