Skip to content

Commit 6ace3e9

Browse files
committed
bdb: Be able to make byteswapped databases
Byteswapped databases make it easier to test opening and deserializing other endian databases.
1 parent d987890 commit 6ace3e9

File tree

4 files changed

+21
-1
lines changed

4 files changed

+21
-1
lines changed

src/wallet/bdb.cpp

+15-1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ RecursiveMutex cs_db;
6565
std::map<std::string, std::weak_ptr<BerkeleyEnvironment>> g_dbenvs GUARDED_BY(cs_db); //!< Map from directory name to db environment.
6666
} // namespace
6767

68+
static constexpr auto REVERSE_BYTE_ORDER{std::endian::native == std::endian::little ? 4321 : 1234};
69+
6870
bool WalletDatabaseFileId::operator==(const WalletDatabaseFileId& rhs) const
6971
{
7072
return memcmp(value, &rhs.value, sizeof(value)) == 0;
@@ -300,7 +302,11 @@ static Span<const std::byte> SpanFromDbt(const SafeDbt& dbt)
300302
}
301303

302304
BerkeleyDatabase::BerkeleyDatabase(std::shared_ptr<BerkeleyEnvironment> env, fs::path filename, const DatabaseOptions& options) :
303-
WalletDatabase(), env(std::move(env)), m_filename(std::move(filename)), m_max_log_mb(options.max_log_mb)
305+
WalletDatabase(),
306+
env(std::move(env)),
307+
m_byteswap(options.require_format == DatabaseFormat::BERKELEY_SWAP),
308+
m_filename(std::move(filename)),
309+
m_max_log_mb(options.max_log_mb)
304310
{
305311
auto inserted = this->env->m_databases.emplace(m_filename, std::ref(*this));
306312
assert(inserted.second);
@@ -389,6 +395,10 @@ void BerkeleyDatabase::Open()
389395
}
390396
}
391397

398+
if (m_byteswap) {
399+
pdb_temp->set_lorder(REVERSE_BYTE_ORDER);
400+
}
401+
392402
ret = pdb_temp->open(nullptr, // Txn pointer
393403
fMockDb ? nullptr : strFile.c_str(), // Filename
394404
fMockDb ? strFile.c_str() : "main", // Logical db name
@@ -521,6 +531,10 @@ bool BerkeleyDatabase::Rewrite(const char* pszSkip)
521531
BerkeleyBatch db(*this, true);
522532
std::unique_ptr<Db> pdbCopy = std::make_unique<Db>(env->dbenv.get(), 0);
523533

534+
if (m_byteswap) {
535+
pdbCopy->set_lorder(REVERSE_BYTE_ORDER);
536+
}
537+
524538
int ret = pdbCopy->open(nullptr, // Txn pointer
525539
strFileRes.c_str(), // Filename
526540
"main", // Logical db name

src/wallet/bdb.h

+3
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ class BerkeleyDatabase : public WalletDatabase
147147
/** Database pointer. This is initialized lazily and reset during flushes, so it can be null. */
148148
std::unique_ptr<Db> m_db;
149149

150+
// Whether to byteswap
151+
bool m_byteswap;
152+
150153
fs::path m_filename;
151154
int64_t m_max_log_mb;
152155

src/wallet/db.h

+1
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ enum class DatabaseFormat {
184184
BERKELEY,
185185
SQLITE,
186186
BERKELEY_RO,
187+
BERKELEY_SWAP,
187188
};
188189

189190
struct DatabaseOptions {

src/wallet/dump.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ bool CreateFromDump(const ArgsManager& args, const std::string& name, const fs::
186186
data_format = DatabaseFormat::BERKELEY;
187187
} else if (file_format == "sqlite") {
188188
data_format = DatabaseFormat::SQLITE;
189+
} else if (file_format == "bdb_swap") {
190+
data_format = DatabaseFormat::BERKELEY_SWAP;
189191
} else {
190192
error = strprintf(_("Unknown wallet file format \"%s\" provided. Please provide one of \"bdb\" or \"sqlite\"."), file_format);
191193
return false;

0 commit comments

Comments
 (0)