#32895 wallet: Prepare for future upgrades by recording versions of last client to open and decrypt

full analysis

https://github.com/bitcoin/bitcoin/pull/32895 · achow101 · +123/-18 in 6 files, 4 commits · labels: Wallet

Goal

  • Track which client capabilities last opened and decrypted a wallet
  • Lets future versions safely detect downgrades and re-run upgrades without full wallet rescans

This PR decouples the wallet database version record from the node client version and introduces two new database records: `LAST_OPENED_FEATURES` and `LAST_DECRYPTED_FEATURES`. These feature bitflags record the capabilities of the client that last opened and decrypted the wallet, allowing future software versions to detect when a wallet has been used with an older release and re-run automatic upgrades if necessary.

Problem: When a wallet is opened in an older release after being upgraded and then returned to a newer release, it can accumulate mixed upgraded and un-upgraded data. Without tracking the capabilities of the client that last accessed or decrypted the wallet, future versions cannot reliably detect this condition without costly full-wallet rescans on every load.

Category: Wallet (#21 of 84)

P2 · migration

  • P2 because recording client capabilities must be deployed well before future releases can rely on them
  • Unblocks future automatic wallet upgrades without risking data inconsistency across release cycles

P2 because recording client capabilities must be deployed in an earlier release before subsequent releases can safely rely on them for automatic wallet upgrades. The author noted that 'in order for this to work, we need to have implemented writing such information into versions prior to the ones which introduce new automatic upgrades,' making early merge strategically important for wallet roadmap features.

Membership: Modifies core wallet database serialization, wallet loading, and decryption lifecycle in src/wallet/.

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

Reviewability: Ready

  • Ready to review
  • Code is clean, CI is passing, and all previous reviewer feedback has been addressed

The patch is clean, rebased, CI is green, and the latest review suggestion from w0xlt has already been integrated.

Author status: Active and responsive; quickly incorporated suggestions and pushed fixes.

Resolved concerns:

  • Decoupling wallet client version from the node CLIENT_VERSION to avoid false downgrade detection (raised by maflcko and ryanofsky, implemented via independent enum).
  • Handling bit allocation and room for more than 64 future features (raised by ajtowns, resolved by adjusting minimum version and clarifying extension strategy).
  • Thread safety locking annotations for last decrypted features (raised by ajtowns, resolved with AssertLockHeld).
  • Erasing stale LAST_DECRYPTED_FEATURES when loading under an older client version that does not support the record (suggested by w0xlt, adopted by author).

Agreement: Strong

  • Strong consensus across wallet contributors with all review threads addressed
  • Concept support for detecting un-upgraded data after downgrade cycles (ryanofsky)
  • Support after verifying versioning and locking semantics (ajtowns)
  • Verified by running test suites across multiple release versions (Eunovo, Bortlesboat)
  • Support after handling stale records on legacy wallet reloads (w0xlt)

Strong consensus among wallet contributors, with several ACKs and all review threads resolved.

Reviewers agreed on the concept of tracking client capability flags in the wallet db. All structural, architectural, and edge-case concerns raised by reviewers were resolved and followed by ACKs.

  • ryanofsky gave Concept ACK for adding metadata to detect un-upgraded material after downgrade-upgrade cycles.
  • ajtowns Concept ACKed and later ACKed the updated versioning and locking semantics.
  • Eunovo and Bortlesboat provided ACKs after validating range-diffs and running test suites across multiple releases.
  • w0xlt ACKed the latest push after their suggestion to erase stale decrypted features on legacy reload was adopted.

Review verdicts (DrahtBot): 1 (+3)

Dependencies

Enables:

  • Future PRs introducing backwards-compatible automatic wallet upgrades that need downgrade detection.

Files

4 lines under test/bench/ci.

  • src/wallet/walletdb.cpp +52/-5
  • src/wallet/wallet.cpp +32/-3
  • src/wallet/walletutil.h +22/-0
  • src/wallet/walletdb.h +9/-8
  • src/wallet/wallet.h +6/-0
  • test/functional/wallet_createwallet.py +2/-2

Card

This PR records the feature capabilities of the last client that opened and decrypted a wallet database, decoupling this tracking from the node client version. It prevents inconsistent wallet state when users switch between software versions (upgrade-downgrade-upgrade cycles) by enabling newer releases to reliably detect when automatic upgrades must be reapplied. Because this tracking must ship in releases before any new automatic upgrades can depend on it, delaying it holds up future wallet upgrade workflows. The PR is mature, has multiple ACKs from active wallet developers, and has addressed all feedback.

Data

dossier JSON · extract JSON · model openrouter/google/gemini-3.8-flash, generated 2026-09-17T15:49, confidence high, input hash 77108ef85bba2b24