3566eed9e1
Move CWalletDB off the Berkeley CDB base class and onto the typed batch
seam introduced by walletdb-batch.h / walletdb-{factory,sqlite}.{h,cpp}.
Build seam
----------
* CWalletDB now derives from CWalletBatchTyped. The typed Read/Write/
Erase/Exists templates come from the seam; their bodies (WriteTx,
WriteKey, WriteMasterKey, ReadPool, WriteSetting, ...) are unchanged
because only the base class swapped — the call signatures resolve to
the same templates.
* CWalletBatchTyped takes ownership of the WalletDatabase so the
underlying connection outlives any batch issued by it (SQLiteBatch
holds a reference, not a value). The two-phase Open() pattern lets
CWalletDB hand the freshly opened database to the base class after
MakeWalletDatabase() returns.
* MakeWalletDatabase (walletdb-factory.cpp) routes -walletdb=sqlite to
SQLiteDatabase, returning nullptr with a clear error for the
unfinished Berkeley branch. The CWalletDB constructor surfaces that
error string on failure.
Cursor sites (the only Berkeley-specific call sites)
---------------------------------------------------
Three sites used GetCursor()/ReadAtCursor() directly:
* LoadWallet — full scan, now uses StartCursor()/NextRecord()
* ListAccountCreditDebit — used DB_SET_RANGE + DB_NEXT loop; replaced
with full keyspace scan + filter-in-loop (SQLite cursor does not
support keyed range seeks). Behaviour matches Berkeley: terminates
when strType changes or, in single-account mode, when
acentry.strAccount differs.
* ZapWalletTx — moved to BerkeleyZapWalletTx (see below) because it
operates on raw Berkeley Db/Dbc/Dbt now that CWalletDB is on the
seam.
The 3 unused public methods on the old CWalletDB (GetAtCursor /
GetTxnCursor / GetAtActiveTxn) had no callers outside walletdb.{h,cpp}
(verified by grep) and were removed.
Berkeley-only escape hatches
----------------------------
Recover(CDBEnv&,...) and ZapWalletTx(...) became BerkeleyRecoverWallet
and BerkeleyZapWalletTx in a new walletdb-recover.{h,cpp} pair. They
operate directly on DbEnv/Db/Dbc/Dbt because CDB's members are
protected (free functions cannot use the wrapper). The recovery logic
duplicates a BDB-only ReadKeyValue variant locally to avoid pulling
the typed batch seam into a Berkeley-only file.
Init.cpp uses these via:
* -salvagewallet -> BerkeleyRecoverWallet(bitdb, ..., fOnlyKeys=true)
* -zapwallettxes -> BerkeleyZapWalletTx(...)
* bitdb.Verify -> BerkeleyRecoverWallet as the recover callback
Wallet migration hook
---------------------
After the Berkeley verify/salvage/zap steps and before CWalletDB is
opened for the live wallet, init.cpp now calls:
if (ResolveWalletDbKind() == SQLite &&
!IsSQLiteFile(walletPath))
MaybeMigrateBerkeleyWalletToSQLite(walletPath, err)
The migration code (walletmigrate.{h,cpp}) is unchanged — it opens a
private Berkeley environment over the wallet directory, copies every
record verbatim (raw key/value bytes) into a fresh SQLite file,
verifies the row count, then atomically renames the BDB original to
"<name>.bdb.bak" and the SQLite file into place. On any failure the
BDB original is left exactly as it was. Errors surface through
InitError so the daemon refuses to start with a corrupt wallet rather
than silently falling back to Berkeley.
No working Berkeley fallback
----------------------------
MakeWalletDatabase returns nullptr for the Berkeley branch, so
-walletdb=bdb no longer opens a working wallet through the seam. This
is intentional for this release — the migration hook handles existing
BDB wallets at first startup, after which the on-disk file is SQLite
and the BDB code path becomes pure recovery glue.
Header fallout
--------------
walletdb.h no longer pulls in db.h (which would drag <db_cxx.h> into
every TU that includes the wallet API). Forward decls added for
CWalletTx, CBlockLocator, CWallet, CPubKey, CScript, CMasterKey,
uint160, uint256. nWalletDBUpdated is now extern-declared in
walletdb.h and defined in db.cpp (was previously declared in db.h).
Validation
----------
Build: GREEN with USE_TOR_EMBEDDED=ON USE_I2P_EMBEDDED=ON. 6 binaries:
trianglesd, triangles-cli, test_triangles, test_chaindb_runtime,
test_chaindb_equivalence, test_snapshotnet.
Tests: 107/107 + 10/10 + 5/5 = byte-identical to the 5d9da84
baseline. wallet_tests and accounting_tests inside test_triangles now
exercise the SQLite path for the first time — their pass is the
de-facto wallet-migration validation at the test-suite level.
41 lines
1.8 KiB
C++
41 lines
1.8 KiB
C++
// Copyright (c) 2026 The Triangles developers.
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
//
|
|
// Berkeley-only wallet recovery helpers — moved out of CWalletDB so the
|
|
// mainline wallet code path (SQLite via the typed batch seam) does not have
|
|
// to include <db_cxx.h>.
|
|
//
|
|
// These functions operate directly on bitdb / CDB and are used only:
|
|
// * during startup, before the wallet migration hook (on a possible BDB
|
|
// wallet.dat), and
|
|
// * on the .bdb.bak copy that migration leaves behind, for diagnostic /
|
|
// manual recovery if migration ever needs investigation.
|
|
//
|
|
// They are intentionally NOT methods of CWalletDB — that class is on the
|
|
// SQLite seam now and has no Berkeley state.
|
|
|
|
#ifndef TRIANGLES_WALLETDB_RECOVER_H
|
|
#define TRIANGLES_WALLETDB_RECOVER_H
|
|
|
|
#include "db.h"
|
|
#include <string>
|
|
|
|
// Aggressive salvage of a Berkeley wallet.dat file. Moves the file aside to
|
|
// wallet.<timestamp>.bak, then walks the salvaged records and re-writes them
|
|
// into a fresh Berkeley database at the original path.
|
|
//
|
|
// If fOnlyKeys is true, only key-type records are kept (used for recovery
|
|
// when transaction history is corrupt). Returns true on success.
|
|
bool BerkeleyRecoverWallet(CDBEnv& dbenv, std::string filename, bool fOnlyKeys);
|
|
inline bool BerkeleyRecoverWallet(CDBEnv& dbenv, std::string filename)
|
|
{
|
|
return BerkeleyRecoverWallet(dbenv, filename, false);
|
|
}
|
|
|
|
// Strip every "tx" record from a Berkeley wallet.dat, leaving keys and other
|
|
// metadata intact. A rescan rebuilds the transaction list from the chain.
|
|
// Used for `-zapwallettxes` on legacy (pre-migration) wallets.
|
|
bool BerkeleyZapWalletTx(const std::string& strWalletFile);
|
|
|
|
#endif // TRIANGLES_WALLETDB_RECOVER_H
|