diff options
| author | bitflash <dev@bitflash.network> | 2026-08-18 14:23:38 -0300 |
|---|---|---|
| committer | bitflash <dev@bitflash.network> | 2026-08-18 14:23:38 -0300 |
| commit | e58c4022e0ddd137b93cdb3464753bef5df1d456 (patch) | |
| tree | 8adc9ec855d19e5a7308eb2a1b2be8139db47188 /src/walletcmd.cpp | |
| parent | beb5c1435a0d85b7b24d4d371933758ebed90907 (diff) | |
wallet: encrypt atomically under the SQLite backend
EncryptWallet() had only a Berkeley DB path: it rebuilt a wallet.dat temp
file and swapped it in. Under -walletbackend=sqlite that was wrong -- it
would leave the live wallet.sqlite unencrypted and write a divergent
wallet.dat instead. Add a SQLite persistence branch that rebuilds a fresh
wallet.sqlite in one transaction (public records copied from the live
store, encrypted key material serialized byte-for-byte the way the BDB
path writes it), checkpoints it, and swaps it in with a .before-encrypt
backup, mirroring the BDB rename dance. A fresh file rather than an
in-place rewrite keeps the change atomic and leaves no plaintext key in a
freed page.
CmdEncryptWallet skips PurgeDbEnvironmentLogs under SQLite (no Berkeley DB
environment behind the wallet) and reports the backend it used.
New wallet-sqlite-encrypt self-test drives the real command path in child
processes: export a wallet to SQLite, encrypt it through
-walletbackend=sqlite, and prove it comes out encrypted, unlockable with
the right passphrase, refusing the wrong one, with its recovery phrase
intact and the original wallet.dat left untouched.
Diffstat (limited to 'src/walletcmd.cpp')
| -rw-r--r-- | src/walletcmd.cpp | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/walletcmd.cpp b/src/walletcmd.cpp index 4dda8dd..374b2cc 100644 --- a/src/walletcmd.cpp +++ b/src/walletcmd.cpp | |||
| @@ -1365,6 +1365,11 @@ int CmdEncryptWallet(const std::string& strPassphrase) | |||
| 1365 | { | 1365 | { |
| 1366 | AttachTerminal(); | 1366 | AttachTerminal(); |
| 1367 | 1367 | ||
| 1368 | // Capture the backend now: under SQLite, EncryptWallet() closes the runtime | ||
| 1369 | // store to swap the file, so WalletSQLiteRuntimeActive() reads false by the | ||
| 1370 | // time we would decide whether to purge Berkeley DB logs below. | ||
| 1371 | bool fSQLiteBackend = WalletSQLiteRuntimeActive(); | ||
| 1372 | |||
| 1368 | string strBackup; | 1373 | string strBackup; |
| 1369 | string strError; | 1374 | string strError; |
| 1370 | if (!EncryptWallet(strPassphrase, strBackup, strError)) | 1375 | if (!EncryptWallet(strPassphrase, strBackup, strError)) |
| @@ -1375,6 +1380,8 @@ int CmdEncryptWallet(const std::string& strPassphrase) | |||
| 1375 | } | 1380 | } |
| 1376 | 1381 | ||
| 1377 | printf("Wallet encrypted.\n"); | 1382 | printf("Wallet encrypted.\n"); |
| 1383 | if (fSQLiteBackend) | ||
| 1384 | printf("Wallet backend: SQLite (wallet.sqlite).\n"); | ||
| 1378 | printf("The old unencrypted wallet was moved to:\n"); | 1385 | printf("The old unencrypted wallet was moved to:\n"); |
| 1379 | printf(" %s\n", strBackup.c_str()); | 1386 | printf(" %s\n", strBackup.c_str()); |
| 1380 | printf("That backup still contains private keys in plain text. Move it offline or\n"); | 1387 | printf("That backup still contains private keys in plain text. Move it offline or\n"); |
| @@ -1387,7 +1394,13 @@ int CmdEncryptWallet(const std::string& strPassphrase) | |||
| 1387 | // them. Closing the environment and dropping the logs is the last step of | 1394 | // them. Closing the environment and dropping the logs is the last step of |
| 1388 | // encrypting, not an optimisation -- our own backup advice is to copy the | 1395 | // encrypting, not an optimisation -- our own backup advice is to copy the |
| 1389 | // whole directory, and following it otherwise carries the keys along. | 1396 | // whole directory, and following it otherwise carries the keys along. |
| 1390 | PurgeDbEnvironmentLogs(); | 1397 | // |
| 1398 | // The SQLite backend has no Berkeley DB environment behind the wallet, and | ||
| 1399 | // EncryptWallet() already closed and swapped the SQLite store; there is | ||
| 1400 | // nothing to purge, and calling into the environment here would only open | ||
| 1401 | // one needlessly. | ||
| 1402 | if (!fSQLiteBackend) | ||
| 1403 | PurgeDbEnvironmentLogs(); | ||
| 1391 | return 0; | 1404 | return 0; |
| 1392 | } | 1405 | } |
| 1393 | 1406 | ||