#35716 wallet: Replace mapWallet and wtxOrdered with a boost::multi_index
| Reviewability | Reviews | Agreement | Size | ||||
|---|---|---|---|---|---|---|---|
| #35716 wallet: Replace mapWallet and wtxOrdered with a boost::multi_index | Needs rebase | 0 (+1) | Strong | 331 + 36 tests | |||
|
|
|
|
| |||
Reviewability: ReadyStalePaused Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs. Size: lines added or modified outside tests, then in tests; greener = smaller. | |||||||
Goal
Replace the wallet's separate `mapWallet` and `wtxOrdered` containers with a single `boost::multi_index_container` indexed by txid and insertion order. Update wallet internals, RPC handlers, and tests to access transactions through helper functions or explicit index views rather than direct map manipulation. Mark `CWalletTx::MarkDirty` const so it can be called on elements stored in the multi-index container.
Problem: The wallet tracks transactions both by txid and by insertion order, which previously required maintaining two separate containers where `wtxOrdered` stored raw pointers to `CWalletTx` objects inside `mapWallet`. Keeping two containers in sync and holding raw pointers to container elements is fragile and introduces lifetime risks.
Evidence of importance:
- Author description: 'These are replaced by a new boost multi index which indexes on txid and insertion order, allowing us to get rid of the 2 separate containers, and holding raw pointers to CWalletTx.'
Scope: Mechanically updates call sites across the wallet and wallet tests to use `GetWalletTx()` or index iterators instead of directly manipulating `mapWallet`. Also links `Boost::headers` to `bitcoin-wallet` in CMake.
Reviewability
Ready · Needs rebase
Conflicts with master; review the logic now, the rebase is mechanical.
Agreement
Strong
substantive support, no open objection (theuni, pablomartin4btc, rkrux, pablomartin4btc)
Thread notes: Initial assessment of the PR. theuni's requests to use explicit index tags and extract/insert semantics instead of modify are recorded as non-blocking claims and were resolved in a subsequent push.
Objections, suggestions, and questions:
| Reviewer | Type | Harm, request, or question | Status | Must be | Author replied | Quote |
|---|---|---|---|---|---|---|
| theuni (member) | objection, approach | modify has complex re-insertion failure semantics and is incompatible with standard container APIs | fixed · fix pushed · v1, not yet re-checked | answered | yes | 2026-07-14: 'please use `extract`/`insert` rather than `modify`. The former is compatible with the std container apis and has familiar (and much simpler) semantics wrt re-insertion failure.' Status from: 2026-07-20: achow101: 'I've changed all of the `modify` to `extract` then `insert`' |
Support:
- theuni (member) (Concept ACK, 2026-07-14): multi_index seems like the right thing to use here. Since this doesn't leak into consensus/node, I don't see the harm in spreading the dependency to wallet.
- pablomartin4btc (member) (Concept ACK, 2026-08-10): Replace two containers — mapWallet and wtxOrdered — with a single boost::multi_index_container that owns the CWalletTx objects and provides both lookups natively. Most importantly, eliminates the raw pointer indirection and the synchronisation burden of keeping two containers in sync.
- rkrux (member) (Concept ACK, 2026-08-26): This also scratches the itch of renaming/removing the variable name mapWallet - it was not an intuitive name and didn't represent what the object contained within it.
- pablomartin4btc (member) (ACK, 2026-08-26): incidentally fixes a real bug on master: ReorderTransactions() mutates each CWalletTx::nOrderPos in place but never touches wtxOrdered... This PR's multi_index refactor makes that bug structurally impossible, since nOrderPos is the sort key of the ordered index itself — any mutation has to go throug
Participants:
- theuni (member, support, 1 statements 2026-07-14 to 2026-07-14): Concept ACK; requested explicit index tags and extract/insert semantics
- pablomartin4btc (member, support, 8 statements 2026-08-09 to 2026-08-26): ACK; verified fix for a latent ordering bug in ReorderTransactions
- rkrux (member, support, 1 statements 2026-08-26 to 2026-08-26): Concept ACK
Files
76 lines under test/bench/ci.
- src/wallet/wallet.cpp +208/-180
- src/wallet/wallet.h +54/-13
- src/wallet/interfaces.cpp +22/-22
- src/wallet/test/wallet_tests.cpp +20/-21
- src/wallet/rpc/transactions.cpp +10/-16
- src/wallet/feebumper.cpp +6/-6
- src/wallet/test/group_outputs_tests.cpp +5/-7
- src/wallet/test/coinselector_tests.cpp +5/-6
- src/wallet/spend.cpp +5/-5
- src/wallet/transaction.h +5/-5
- src/wallet/walletdb.cpp +7/-2
- src/wallet/receive.cpp +4/-4
- src/wallet/rpc/coins.cpp +4/-4
- src/wallet/export.cpp +3/-3
- src/wallet/test/fuzz/spend.cpp +2/-4
- src/wallet/test/psbt_wallet_tests.cpp +4/-2
- src/wallet/rpc/wallet.cpp +1/-1
- src/wallet/wallettool.cpp +1/-1
- src/CMakeLists.txt +1/-0
Card
The short text the ranking pass compares across PRs.
This PR replaces the wallet's `mapWallet` and `wtxOrdered` containers with a single `boost::multi_index_container` indexed by txid and order position. Today, the wallet maintains two separate data structures to look up transactions by id and insertion order, requiring raw pointers to `CWalletTx` across containers and manual synchronization. The change simplifies transaction storage and removes pointer management between containers. It is an internal refactor with no stated external dependencies.
Data
thread read through 2026-08-26 (18 statements), head f31dfaeedf
Discussion read under schema 1 rules: suggestions and questions may be missing, and an objection may combine several harms (schema history).
labels: Wallet, Needs rebase
Categories
Wallet
P3 · cleanup (ranking pass: Moved down: structural fragility reduction with no user-visible payoff, ranked with the other internal refactors.)
Replaces two synchronized containers and raw pointer references with a unified boost::multi_index container, eliminating lifetime risks and container desynchronization bugs. As noted in review, this refactor removes raw pointer indirection and structurally fixes a bug where 'ReorderTransactions() mutates each CWalletTx::nOrderPos in place but never touches wtxOrdered'.
Membership: Matches the 'Wallet' area label and modifies core wallet transaction storage across src/wallet/.
Factors: security/stability 1, bug 1, performance 0, user value 0, leverage 1