AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Moderate 68 Bitcoin

Merge bitcoin/bitcoin#35752: wallet: make encryption state updates atomic

Public commit record

What the developer wrote

Authored by Ava Chow

91/100 · Strong
Merge bitcoin/bitcoin#35752: wallet: make encryption state updates atomic

6d2414542b86ff7d6eae0f4c873e47bc4e57a57c wallet: reuse unlock and passphrase change errors (Ava Chow)
593554622e2ced30eb5c2b2fbc642e31c66b2bb8 wallet: return passphrase errors with Expected (Ava Chow)
f949b3ba2ad78eed70540a31564032ab3efefda6 wallet: publish descriptor keys after writes (Lőrinc)
e3712b7d492fc72a763c9e5c73a5a174be59dd21 test: characterize descriptor insertion failure (Lőrinc)
bd558107784cf1170482700a13904cfa5b6816a8 wallet: abort failed descriptor key erases (Lőrinc)
537e79191585ca5ea46c527287d311c9abdcabd0 test: cover encrypted descriptor key insertion (Lőrinc)
d8a6f5e48d6b007207ba00e70167affbff2900f9 wallet: abort failed descriptor key writes (Lőrinc)
14ce3fdb493ac1cbb8e8fb583c9c2e99d9d9fb65 test: characterize descriptor key failures (Lőrinc)
5bc0be16fe4d910d363b5cd8eeb11a9b9629e0b9 wallet: reject failed passphrase changes (Lőrinc)
ee6d45a07e3ae06e490e30c9d4a3f01d9917c740 test: characterize passphrase write failure (Lőrinc)
2daa2f94f4a2930c2f315cf9e50ffd027d4bc101 wallet: restore lock state before re-encryption (Ava Chow)
8b23fa47737a8e1deb23953b5e3b438454e10e73 wallet: abort failed encryption transactions (Lőrinc)
e6c374d302018f352d0583c38c5c4211f9b59a2f test: characterize encryption transaction failures (Lőrinc)
70381010c0af96db8b23e2af02599798b063c92b refactor/test: add wallet failure injection (Lőrinc)

Pull request description:

**Problem:** Wallet encryption and passphrase changes can leave database records and live key state out of sync when a database operation fails.
Encryption can report success without persisting the master key, and a passphrase change can activate the new passphrase only in memory.
Descriptor key write failures can publish keys that were not persisted, while erase failures can leave plaintext keys on disk.
A failed encryption transaction commit aborts the node, and a re-encryption failure during a passphrase change can leave a previously locked wallet unlocked.
Boolean results also force callers to duplicate error messages or report database and encryption failures as incorrect passphrases.

**Fix:** Publish wallet encryption state only after the database transaction commits, and publish newly inserted descriptor keys only after their database writes succeed.
For passphrase changes, restore the original lock state after validating the old passphrase and replace the live master key only after persisting its re-encrypted value.
These changes preserve the affected keys on failure and allow retries.
Return structured errors from wallet unlock and passphrase changes so callers can share messages and report the specific failure.
Fresh descriptor setup after the encryption transaction remains unchanged.

ACKs for top commit:
achow101:
ACK 6d2414542b86ff7d6eae0f4c873e47bc4e57a57c
w0xlt:
reACK 6d2414542b86ff7d6eae0f4c873e47bc4e57a57c

Tree-SHA512: 2d7293d9482ef259732cd0c3dd31eb2c376fc39e23a76141032b6e308b0e71c5d86b3f03995ef3f923cabbc431a139a39a4be02853f352f7103a7f9f52a95299
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification✓ Links an issue, advisory, or supporting reference
The short version

What changed, and why it matters

This Bitcoin Core update fixes several wallet bugs where a failed database write could leave a wallet in an inconsistent state. For example, encrypting a wallet or changing its passphrase could appear to succeed in memory while the change was not actually saved to disk, or could leave unencrypted private keys behind. The patch makes these operations atomic: in-memory state is only updated after the database transaction commits, and failures now return clear, structured error messages instead of crashing the program or giving misleading 'wrong passphrase' errors.

Recommended action

Reviewers should verify that all database writes inside RunWithinTxn correctly return false on failure, that no in-memory state is updated before the commit listener fires, and that the new FaultInjectingDatabase tests cover the previously aborting/asserting paths. Users running wallets with private keys should upgrade to a release containing this fix once available.

Security signals we found

01

Atomicity fix for encryption state and descriptor key persistence

02

Failure to persist master key during encryption previously reported success in memory

03

Passphrase change could activate new passphrase only in memory

04

Descriptor key write failures could publish keys not persisted to disk

05

Descriptor key erase failures could leave plaintext keys on disk

06

Failed encryption transaction commit previously aborted the node via assert(false)

07

Re-encryption failure during passphrase change could leave a locked wallet unlocked

08

Structured error reporting replaces boolean errors and duplicated messages

Risk score

Why this scored 68/100

Our methodology →
Potential impact 22/30
Exploitability 12/25
Stealth signal 10/15
Affected reach 12/15
Confidence 8/10
Evidence quality 4/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.