Skip to content

Commit

Permalink
bdb: Be able to make byteswapped databases
Browse files Browse the repository at this point in the history
Byteswapped databases make it easier to test opening and deserializing
other endian databases.
  • Loading branch information
achow101 committed May 16, 2024
1 parent d987890 commit 6ace3e9
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 1 deletion.
16 changes: 15 additions & 1 deletion src/wallet/bdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ RecursiveMutex cs_db;
std::map<std::string, std::weak_ptr<BerkeleyEnvironment>> g_dbenvs GUARDED_BY(cs_db); //!< Map from directory name to db environment.
} // namespace

static constexpr auto REVERSE_BYTE_ORDER{std::endian::native == std::endian::little ? 4321 : 1234};

bool WalletDatabaseFileId::operator==(const WalletDatabaseFileId& rhs) const
{
return memcmp(value, &rhs.value, sizeof(value)) == 0;
Expand Down Expand Up @@ -300,7 +302,11 @@ static Span<const std::byte> SpanFromDbt(const SafeDbt& dbt)
}

BerkeleyDatabase::BerkeleyDatabase(std::shared_ptr<BerkeleyEnvironment> env, fs::path filename, const DatabaseOptions& options) :
WalletDatabase(), env(std::move(env)), m_filename(std::move(filename)), m_max_log_mb(options.max_log_mb)
WalletDatabase(),
env(std::move(env)),
m_byteswap(options.require_format == DatabaseFormat::BERKELEY_SWAP),
m_filename(std::move(filename)),
m_max_log_mb(options.max_log_mb)
{
auto inserted = this->env->m_databases.emplace(m_filename, std::ref(*this));
assert(inserted.second);
Expand Down Expand Up @@ -389,6 +395,10 @@ void BerkeleyDatabase::Open()
}
}

if (m_byteswap) {
pdb_temp->set_lorder(REVERSE_BYTE_ORDER);
}

ret = pdb_temp->open(nullptr, // Txn pointer
fMockDb ? nullptr : strFile.c_str(), // Filename
fMockDb ? strFile.c_str() : "main", // Logical db name
Expand Down Expand Up @@ -521,6 +531,10 @@ bool BerkeleyDatabase::Rewrite(const char* pszSkip)
BerkeleyBatch db(*this, true);
std::unique_ptr<Db> pdbCopy = std::make_unique<Db>(env->dbenv.get(), 0);

if (m_byteswap) {
pdbCopy->set_lorder(REVERSE_BYTE_ORDER);
}

int ret = pdbCopy->open(nullptr, // Txn pointer
strFileRes.c_str(), // Filename
"main", // Logical db name
Expand Down
3 changes: 3 additions & 0 deletions src/wallet/bdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ class BerkeleyDatabase : public WalletDatabase
/** Database pointer. This is initialized lazily and reset during flushes, so it can be null. */
std::unique_ptr<Db> m_db;

// Whether to byteswap
bool m_byteswap;

fs::path m_filename;
int64_t m_max_log_mb;

Expand Down
1 change: 1 addition & 0 deletions src/wallet/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ enum class DatabaseFormat {
BERKELEY,
SQLITE,
BERKELEY_RO,
BERKELEY_SWAP,
};

struct DatabaseOptions {
Expand Down
2 changes: 2 additions & 0 deletions src/wallet/dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ bool CreateFromDump(const ArgsManager& args, const std::string& name, const fs::
data_format = DatabaseFormat::BERKELEY;
} else if (file_format == "sqlite") {
data_format = DatabaseFormat::SQLITE;
} else if (file_format == "bdb_swap") {
data_format = DatabaseFormat::BERKELEY_SWAP;
} else {
error = strprintf(_("Unknown wallet file format \"%s\" provided. Please provide one of \"bdb\" or \"sqlite\"."), file_format);
return false;
Expand Down

0 comments on commit 6ace3e9

Please sign in to comment.