Fix for compile issue with rocksdb v11 or greater

The rocksdb team removed the long-standing "raw pointer"
rocksdb::DB::Open() API in favor of the unique_ptr version.

The reason we were using the raw pointer version is because it was more
compatible with older versions, including the one that ships with
Fulcrum.

As a result we were forced to create a "Compat" later in Storage/ for
rocksdb::DB::Open that smoothes over the differences. This commit just
makes all calls to rocksdb::DB::Open() in the codebase go through
Compat::DBOpen.
This commit is contained in:
Calin Culianu 2026-04-24 18:29:28 -05:00
parent ea21678240
commit 183076ea4f
No known key found for this signature in database
GPG key ID: 21810A542031C02C
6 changed files with 111 additions and 11 deletions

View file

@ -376,6 +376,7 @@ SOURCES += \
Servers.cpp \
SrvMgr.cpp \
Storage.cpp \
Storage/Compat.cpp \
Storage/ConcatOperator.cpp \
Storage/DBRecordArray.cpp \
Storage/RecordFile.cpp \
@ -428,6 +429,7 @@ HEADERS += \
Span.h \
SrvMgr.h \
Storage.h \
Storage/Compat.h \
Storage/ConcatOperator.h \
Storage/DBRecordArray.h \
Storage/RecordFile.h \

View file

@ -26,6 +26,7 @@
#include "Rpa.h"
#include "Span.h"
#include "Storage.h"
#include "Storage/Compat.h"
#include "Storage/ConcatOperator.h"
#include "Storage/DBRecordArray.h"
#include "Storage/RecordFile.h"
@ -1661,10 +1662,8 @@ void Storage::openOrCreateDB(bool bulkLoad)
}
}
rocksdb::DB *db = nullptr;
s = rocksdb::DB::Open(opts, path.toStdString(), colFamDescs, &p->db.columnFamilies, &db);
p->db.db.reset(db);
if (!s.ok() || !db)
s = Compat::DBOpen(opts, path.toStdString(), colFamDescs, &p->db.columnFamilies, &p->db.db);
if (!s.ok() || !p->db.db)
throw DatabaseError(QString("Error opening %1 database: %2 (path: %3)")
.arg(kDBName, StatusString(s), path));
}
@ -1913,11 +1912,11 @@ bool Storage::checkFulc1xUpgradeDB()
if (info.options.merge_operator) dbopts.merge_operator = info.options.merge_operator;
dbopts.comparator = info.options.comparator; // should always be default BytewiseComparator, but defensively we ensure that is the case
rocksdb::DB *dbin_raw{};
if (auto st = rocksdb::DB::Open(dbopts, fname.toStdString(), &dbin_raw); !st.ok()) {
std::unique_ptr<rocksdb::DB> dbin;
if (auto st = Compat::DBOpen(dbopts, fname.toStdString(), &dbin); !st.ok()) {
throw DatabaseError("rocksdb::DB::Open returned error for " + name + ": " + StatusString(st));
}
std::unique_ptr<rocksdb::DB> dbin(dbin_raw);
const bool isMetaTable = info.handle == p->db.meta;
std::optional<QByteArray> convertedDbMetaSerialization; // upgraded/converted 'kMeta' row (class: Meta)

View file

@ -50,8 +50,8 @@
// fwd decls used by Storage private(s)
namespace rocksdb {
class DB;
class ColumnFamilyHandle;
class DB;
class WriteBatch;
}

60
src/Storage/Compat.cpp Normal file
View file

@ -0,0 +1,60 @@
//
// Fulcrum - A fast & nimble SPV Server for Bitcoin Cash
// Copyright (C) 2019-2026 Calin A. Culianu <calin.culianu@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program (see LICENSE.txt). If not, see
// <https://www.gnu.org/licenses/>.
//
#include "Storage/Compat.h"
#include <rocksdb/version.h>
#if ROCKSDB_MAJOR >= 11
/* RocksDB v11.0.0 or greater may not have the "raw pointer" versions of DB::Open() (which we still must support for
* compatibility with older rocksdb). See: https://github.com/facebook/rocksdb/releases/tag/v11.0.4
*/
#define USE_RAW_PTR_ROCKSDB_OPEN_FUNC 0
#else
#define USE_RAW_PTR_ROCKSDB_OPEN_FUNC 1
#endif
namespace Compat {
rocksdb::Status DBOpen(const rocksdb::Options &options, const std::string &name, std::unique_ptr<rocksdb::DB> *dbptr)
{
#if USE_RAW_PTR_ROCKSDB_OPEN_FUNC
rocksdb::DB *raw = nullptr;
rocksdb::Status st = rocksdb::DB::Open(options, name, &raw);
dbptr->reset(raw); // Give the raw DB ptr to the unique ptr
return st;
#else
return rocksdb::DB::Open(options, name, dbptr);
#endif
}
rocksdb::Status DBOpen(const rocksdb::DBOptions &db_options, const std::string &name,
const std::vector<rocksdb::ColumnFamilyDescriptor> &column_families,
std::vector<rocksdb::ColumnFamilyHandle*> *handles,
std::unique_ptr<rocksdb::DB> *dbptr)
{
#if USE_RAW_PTR_ROCKSDB_OPEN_FUNC
rocksdb::DB *raw = nullptr;
rocksdb::Status st = rocksdb::DB::Open(db_options, name, column_families, handles, &raw);
dbptr->reset(raw); // Give the raw DB ptr to the unique ptr
return st;
#else
return rocksdb::DB::Open(db_options, name, column_families, handles, dbptr);
#endif
}
} // namespace Compat

38
src/Storage/Compat.h Normal file
View file

@ -0,0 +1,38 @@
//
// Fulcrum - A fast & nimble SPV Server for Bitcoin Cash
// Copyright (C) 2019-2026 Calin A. Culianu <calin.culianu@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program (see LICENSE.txt). If not, see
// <https://www.gnu.org/licenses/>.
//
#pragma once
#include <rocksdb/db.h>
#include <rocksdb/options.h>
#include <rocksdb/status.h>
#include <string>
#include <memory>
#include <vector>
/// A namespace for encapsulating a "compatibility" layer to smoothe over API differences between various
/// rocksdb versions
namespace Compat {
// rocksdb::DB::Open changed after version v11.0.0 of rocksdb so we smoothe it over with a unified API
rocksdb::Status DBOpen(const rocksdb::Options &options, const std::string &name, std::unique_ptr<rocksdb::DB> *dbptr);
rocksdb::Status DBOpen(const rocksdb::DBOptions &db_options, const std::string &name,
const std::vector<rocksdb::ColumnFamilyDescriptor> &column_families,
std::vector<rocksdb::ColumnFamilyHandle*> *handles,
std::unique_ptr<rocksdb::DB> *dbptr);
} // namespace Compat

View file

@ -20,6 +20,7 @@
#include "ByteView.h"
#include "ConcatOperator.h"
#include "Storage/Compat.h"
#include "Util.h"
#include "bitcoin/serialize.h"
@ -509,13 +510,13 @@ TEST_CASE(gen_hashes) {
TEST_CASE(open_db) {
TEST_CHECK(tmpDir.isValid());
rocksdb::DB *dbptr{};
rocksdb::Options opts;
opts.create_if_missing = true;
opts.merge_operator.reset(new StorageDetail::ConcatOperator);
auto st = rocksdb::DB::Open(opts, tmpDir.path().toStdString(), &dbptr);
std::unique_ptr<rocksdb::DB> simple_uptr;
auto st = Compat::DBOpen(opts, tmpDir.path().toStdString(), &simple_uptr);
TEST_CHECK_MESSAGE(st.ok(), st.ToString());
db.reset(dbptr);
db.reset(simple_uptr.release());
TEST_CHECK(db != nullptr);
if (!db) throw Exception("DB pointer is null! Cannot proceed!");
cf = db->DefaultColumnFamily();