rocksdb: apply T010 review fixes (H1/H2/H3/M4) + CF routing disabled

H1: init.cpp now detects crashed migrations (MIGRATION_INCOMPLETE marker)
    and retries instead of opening a partial RocksDB. Refuses to start if
    the marker persists after migration attempt.
H2: LevelDB ExistsRaw now returns false for keys deleted in the active
    batch, matching ReadRaw and the RocksDB backend. Fixes latent
    cross-backend consensus split in intra-batch spend checks.
H3: All RocksDB close paths now go through close_rocksdb() which
    destroys CF handles before deleting the DB. Fixes RocksDB assertion
    / UB on shutdown and version-reset.
M4: Migration marker write is now flushed + verified (refuses to start
    migration if marker can't be written).

CF routing permanently disabled: GetCF() always returns nullptr (default
column family). The read path (NewIterator, LoadBlockIndex) only iterates
the default CF, so writes routed to per-prefix CFs were invisible to scans.
This is why -chaindb=rocksdb compiled clean but was never runtime-valid.
Existing CF-enabled DBs still open (handles retained for cleanup) but no
routing occurs. CF-aware iteration is a future follow-up.

txdb-factory: RocksDB is now the default backend (was still leveldb).
Tests updated for RocksDB-as-default expectations.

From Claude's ROCKSDB-T010-REVIEW-2026-07-01 audit on E:\repos\triangles.
This commit is contained in:
Krystie
2026-07-01 16:09:25 -07:00
parent a70019263d
commit fc7ad5bb69
6 changed files with 130 additions and 81 deletions
+15 -10
View File
@@ -141,16 +141,19 @@ BOOST_AUTO_TEST_SUITE(chaindb_backend_selection)
BOOST_AUTO_TEST_CASE(is_rocksdb_backend_flag_default_off)
{
// Default test build doesn't set -chaindb, so backend should NOT be rocksdb.
// The default test build doesn't set the -chaindb flag at all. (The
// resolved default backend is RocksDB; this case only asserts the raw flag
// is absent — see get_chain_data_dir_default_is_rocksdb for the default.)
BOOST_CHECK_EQUAL(GetBoolArg("-chaindb", false), false);
}
BOOST_AUTO_TEST_CASE(get_chain_data_dir_default_is_txleveldb)
BOOST_AUTO_TEST_CASE(get_chain_data_dir_default_is_rocksdb)
{
// No -chaindb flag set → GetChainDataDir() must return txleveldb path.
// No -chaindb flag set → RocksDB is the default backend, so
// GetChainDataDir() must return the rocksdb path.
mapArgs.erase("-chaindb");
BOOST_CHECK_EQUAL(IsRocksDbChainBackend(), false);
BOOST_CHECK_EQUAL(GetChainDataDir().filename().string(), "txleveldb");
BOOST_CHECK_EQUAL(IsRocksDbChainBackend(), true);
BOOST_CHECK_EQUAL(GetChainDataDir().filename().string(), "rocksdb");
}
BOOST_AUTO_TEST_CASE(get_chain_data_dir_rocksdb_when_flag_set)
@@ -451,12 +454,13 @@ BOOST_AUTO_TEST_CASE(wipe_removes_rocksdb_dir_when_flagged)
mapArgs.erase("-chaindb");
}
BOOST_AUTO_TEST_CASE(wipe_removes_txleveldb_dir_by_default)
BOOST_AUTO_TEST_CASE(wipe_removes_txleveldb_dir_when_leveldb_selected)
{
// No explicit write needed — MakeChainDB("cr+") opens the LevelDB
// handle which creates the txleveldb/ directory on disk. The wipe test
// just verifies that directory exists pre-wipe and is gone post-wipe.
mapArgs.erase("-chaindb");
// With -chaindb=leveldb, MakeChainDB("cr+") opens the LevelDB handle which
// creates the txleveldb/ directory on disk. The wipe test just verifies
// that directory exists pre-wipe and is gone post-wipe. (RocksDB is the
// default now, so LevelDB must be requested explicitly.)
mapArgs["-chaindb"] = "leveldb";
{
auto base = MakeChainDB("cr+");
BOOST_REQUIRE(base != nullptr);
@@ -467,6 +471,7 @@ BOOST_AUTO_TEST_CASE(wipe_removes_txleveldb_dir_by_default)
WipeChainDataDir();
BOOST_CHECK(!fs::exists(dir));
mapArgs.erase("-chaindb");
}
BOOST_AUTO_TEST_SUITE_END()