Skip to content

beta7: wallet perf — single AvailableCoins pass in SelectCoins + limit-aware listtransactions#129

Draft
RhettCreighton wants to merge 1 commit into
masterfrom
beta7/wallet-perf
Draft

beta7: wallet perf — single AvailableCoins pass in SelectCoins + limit-aware listtransactions#129
RhettCreighton wants to merge 1 commit into
masterfrom
beta7/wallet-perf

Conversation

@RhettCreighton

Copy link
Copy Markdown

What

Two safe, value-preserving wallet perf wins. Neither changes any returned value (balances, coin-selection results, RPC output) — they only avoid redundant work.

1. CWallet::SelectCoins — single AvailableCoins pass

SelectCoins previously called AvailableCoins twice per selection — once with fIncludeCoinBase=false and once with true — doing two full mapWallet scans. The only filter difference between the two calls is the coinbase-exclusion line, so the no-coinbase set is exactly the with-coinbase set minus coinbase-tx outputs.

We now do a single pass (fIncludeCoinBase=true) and partition in-memory via out.tx->IsCoinBase(). The non-coinbase outputs keep their original relative order, and all downstream consumers (fOnlyCoinbaseCoinsRet, the fProtectCoinbase set choice, the vCoinsWithCoinbase.size() > vCoinsNoCoinbase.size() check, the value-sum loops, the coin-control set insert, and SelectCoinsMinConf's random_shuffle) are order-independent or see identical contents. Selected-coin set is unchanged.

2. listtransactions / OrderedTxItems — limit-aware path

OrderedTxItems built the full ordered multimap of all wallet txs + accounting entries regardless of the requested count/from. Added an optional nLimit arg (default 0 = unchanged full behavior) that keeps only the newest nLimit items (largest nOrderPos) by trimming the smallest as it builds.

listtransactions requests nLimit = count + from and iterates newest-first as before. Because a single tx can expand to 0..N output rows, a trimmed window could in rare cases under-supply the requested rows; so when the window was actually capped and we still couldn't fill count+from rows, we fall back to the original unlimited pass. This guarantees byte-identical output ordering and contents for the returned slice, while saving the full-wallet multimap build in the common case (window smaller than wallet, txs yielding >= 1 row).

Files

  • src/wallet/wallet.cpp — single AvailableCoins pass in SelectCoins; limit-aware OrderedTxItems
  • src/wallet/wallet.hOrderedTxItems gains int nLimit = 0 (default preserves old behavior)
  • src/wallet/rpcwallet.cpplisttransactions limit-aware path + safe fallback

Consensus impact: none

No change to block/tx validation, PoW, script, serialization, chainparams, or activation heights. No amount math or balance-computation function touched.

Behavior preserved

Both changes are pure work-avoidance. Coin-selection results are identical; listtransactions output is identical (with a guaranteed fallback to the original code path if a trimmed window can't fill the requested rows).

DRAFT: pending maintainer build-verification.

…t-aware listtransactions

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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