Brings in uncommitted work from SAMI-PC E:\repos\triangles
cpp20-modernization branch:
- RocksDB default chain DB + auto-migrate from txleveldb
- SQLite default wallet + non-destructive migration from Berkeley
- Boost.Asio removed from RPC (rpc_httpsocket.h)
- Boost removed from all daemon + GUI code
- New: walletdb-base.h, walletdb-batch.h, walletdb-sqlite.{h,cpp},
walletdb-factory.{h,cpp}, walletmigrate.{h,cpp}
- New tests: chaindb_runtime_tests, chaindb_equivalence_tests,
snapshotnet_tests
- Docs: BOOST-REMOVAL.md, ROCKSDB-DEFAULT-MIGRATION.md,
WALLET-SQLITE-MIGRATION.md
Does not yet build — needs CWalletDB->CWalletBatchTyped rebase in
walletdb.cpp/wallet.cpp/db.cpp and merge with origin/master for
v6 source files (checkpointpublisher, tor/, snapshot/, utxosnapshot,
bootstrap.cpp).
Build flags: -DBUILD_QT=OFF -DUSE_I2P_EMBEDDED=OFF
5.9 KiB
RocksDB as the default chain database backend
This change finishes the RocksDB chain-database backend, makes it the default, and provides a transparent migration path off LevelDB. No consensus rules change — only how the block index / tx index / UTXO set / address index are stored on disk. On-disk key bytes remain identical across both backends, which is what the migration and the dual-backend equivalence tests rely on.
What changed
1. Fixed the column-family iteration bug (the real "unfinished" blocker)
The RocksDB backend routed keys into per-prefix column families
(blockindex, txindex, utxo, addrindex) on write, but the read path —
both CRocksTxDB::NewIterator() and CRocksTxDB::LoadBlockIndex() — only ever
iterated the default column family. With column families enabled:
LoadBlockIndex()loaded zero blocks (block-index records were in a non-default CF the loader never scanned),- UTXO snapshot dumps and address-index range scans saw nothing, and
- the migration verifier
CollectStats()reported a record-count mismatch.
This is why -chaindb=rocksdb "compiled clean but was never runtime-valid."
Fix: column-family partitioning is disabled. GetCF() now always returns
the default CF, so writes, point reads, Exists, Erase, and full-keyspace
iteration are mutually consistent — and byte-identical to the single-keyspace
LevelDB backend. New databases are created single-CF; pre-existing experimental
multi-CF databases are still opened (for compatibility) but should be
re-migrated or reindexed. RocksDB still delivers its performance win from
parallel compaction, bloom filters, large write buffer, and block cache — the
CF split was a premature optimization, not the source of the speedup.
Re-introducing column families is a tracked follow-up that first requires
CF-aware iterators (a multiplexed merge across CFs) in NewIterator() /
LoadBlockIndex().
2. Automatic LevelDB -> RocksDB migration on startup
init.cpp now runs the migration automatically when RocksDB is the active
backend and the only chain DB present is a legacy txleveldb/ (no rocksdb/
yet). MaybeMigrateLevelDbToRocksDb() is a no-op when there is nothing to
migrate, so it is safe on every launch. The LevelDB source is never modified;
it remains a fallback.
3. RocksDB is now the default backend
-chaindb defaults to rocksdb (was leveldb). LevelDB stays selectable with
-chaindb=leveldb and is retained as migration source + fallback. Full removal
of LevelDB is deferred to a later phase, after live-chain validation.
4. Fixed NeedsBootstrap() to recognize the RocksDB directory
Bootstrap::NeedsBootstrap() checked for txleveldb/ but not rocksdb/. With
RocksDB as default, a fully-synced rocksdb-only node would have been treated as
"fresh" and could have triggered a bootstrap download over a healthy chain on
every restart. It now treats a rocksdb/ directory as an existing chain DB.
Files changed
src/txdb-rocksdb.cpp— disable CF routing; single-CF open; remove dead CF tablessrc/txdb-rocksdb.h— update CF member docssrc/txdb-factory.cpp— default backendleveldb->rocksdbsrc/txdb.h— update factory doc commentsrc/init.cpp— auto-migrate on startup when RocksDB active + legacy LevelDB presentsrc/bootstrap.cpp—NeedsBootstrap()recognizesrocksdb/src/test/chaindb_runtime_tests.cpp— update default-backend expectationsREADME.md— document RocksDB default + migration
Build
cmake -B build -G Ninja -DBUILD_QT=ON -DBUILD_TESTS=ON
cmake --build build
RocksDB is required (librocksdb-dev >= 7.4 on Debian/Ubuntu,
mingw-w64-x86_64-rocksdb on MSYS2, rocksdb on Homebrew).
Tests
# RocksDB wrapper runtime smoke tests (the class the daemon uses at runtime)
./build/bin/test_chaindb_runtime
# LevelDB/RocksDB byte-for-byte migration equivalence
./build/bin/test_chaindb_equivalence
# Full unit suite
./build/bin/test_triangles
Expected after this change:
get_chain_data_dir_default_is_rocksdbpasses (default resolves to rocksdb).iterator_walks_every_key_in_sorted_orderpasses (the"banana"key, which previously routed to a non-default CF the iterator never read, now lives in the default CF and is iterated).- Migration verification (
CollectStats/StatsMatch) passes end-to-end.
Live-chain validation checklist (V6 task T010)
This is the step that cannot be done without real chain data and must be run on a node before release:
- Migrate a real chain. On a node with an existing
txleveldb/, launch the new binary (default backend). Confirm the log showsChainDB: RocksDB backend active with a legacy LevelDB present; migrating automatically.followed byChainDB migration: verified N records ... best=<hash>. - Verify block index loads. Confirm
LoadBlockIndex()reports the correctheight=andhashBestChain=(matching the prior LevelDB tip), not 0. - Compare RPC output.
getinfo,getblockcount,getbestblockhash, and a spot-check ofgettxout/ address-index queries must match a LevelDB run of the same datadir (-chaindb=leveldb). - Restart twice. Confirm no spurious bootstrap download fires and the tip is stable across restarts.
- Sync new blocks. Let the node accept and stake new blocks; confirm UTXO set and money supply stay consistent.
- Benchmark. Use
contrib/bench/bench-chaindb.sh --backends=rocksdbvsleveldbto confirm the speedup on this hardware.
Rollback
Set -chaindb=leveldb in triangles.conf (or on the command line). The
original txleveldb/ is untouched by migration, so reverting is immediate.
Remaining follow-ups
- CF-aware iteration, then re-enable column-family partitioning for independent compaction/caching.
- Retire LevelDB entirely (remove
txdb-leveldb.*, drop the-chaindb=leveldboption and the bundled LevelDB dependency) once RocksDB is validated in production for at least one release cycle.