refactor: prepare DBWrapper for obfuscation key change

Since `FastRandomContext` delegates to `GetRandBytes` anyway, we can simplify new key generation to a Write/Read combo, unifying the flow of enabling obfuscation via `Read`.

The comments were also adjusted to clarify that the `m_obfuscation` field affects the behavior of `Read` and `Write` methods.

These changes are meant to simplify the diffs for the riskier optimization commits later.
This commit is contained in:
Lőrinc
2025-04-05 18:25:20 +02:00
parent 0b8bec8aa6
commit 6bbf2d9311
2 changed files with 9 additions and 37 deletions

View File

@@ -249,24 +249,15 @@ CDBWrapper::CDBWrapper(const DBParams& params)
LogPrintf("Finished database compaction of %s\n", fs::PathToString(params.path));
}
// The base-case obfuscation key, which is a noop.
m_obfuscation = std::vector<unsigned char>(Obfuscation::KEY_SIZE, '\000');
bool key_exists = Read(OBFUSCATION_KEY_KEY, m_obfuscation);
if (!key_exists && params.obfuscate && IsEmpty()) {
// Initialize non-degenerate obfuscation if it won't upset
// existing, non-obfuscated data.
std::vector<unsigned char> new_key = CreateObfuscation();
// Write `new_key` so we don't obfuscate the key with itself
Write(OBFUSCATION_KEY_KEY, new_key);
m_obfuscation = new_key;
LogPrintf("Wrote new obfuscation key for %s: %s\n", fs::PathToString(params.path), HexStr(m_obfuscation));
m_obfuscation = std::vector<uint8_t>(Obfuscation::KEY_SIZE, '\000'); // Needed for unobfuscated Read()/Write() below
if (!Read(OBFUSCATION_KEY_KEY, m_obfuscation) && params.obfuscate && IsEmpty()) {
// Generate, write and read back the new obfuscation key, making sure we don't obfuscate the key itself
Write(OBFUSCATION_KEY_KEY, FastRandomContext{}.randbytes(Obfuscation::KEY_SIZE));
Read(OBFUSCATION_KEY_KEY, m_obfuscation);
LogInfo("Wrote new obfuscation key for %s: %s", fs::PathToString(params.path), HexStr(m_obfuscation));
}
LogInfo("Using obfuscation key for %s: %s", fs::PathToString(params.path), HexStr(m_obfuscation));
LogPrintf("Using obfuscation key for %s: %s\n", fs::PathToString(params.path), HexStr(m_obfuscation));
}
CDBWrapper::~CDBWrapper()
@@ -311,23 +302,6 @@ size_t CDBWrapper::DynamicMemoryUsage() const
return parsed.value();
}
// Prefixed with null character to avoid collisions with other keys
//
// We must use a string constructor which specifies length so that we copy
// past the null-terminator.
const std::string CDBWrapper::OBFUSCATION_KEY_KEY("\000obfuscate_key", 14);
/**
* Returns a string (consisting of 8 random bytes) suitable for use as an
* obfuscating XOR key.
*/
std::vector<unsigned char> CDBWrapper::CreateObfuscation() const
{
std::vector<uint8_t> ret(Obfuscation::KEY_SIZE);
GetRandBytes(ret);
return ret;
}
std::optional<std::string> CDBWrapper::ReadImpl(std::span<const std::byte> key) const
{
leveldb::Slice slKey(CharCast(key.data()), key.size());

View File

@@ -190,10 +190,8 @@ private:
//! a key used for optional XOR-obfuscation of the database
std::vector<unsigned char> m_obfuscation;
//! the key under which the obfuscation key is stored
static const std::string OBFUSCATION_KEY_KEY;
std::vector<unsigned char> CreateObfuscation() const;
//! obfuscation key storage key, null-prefixed to avoid collisions
inline static const std::string OBFUSCATION_KEY_KEY{"\000obfuscate_key", 14}; // explicit size to avoid truncation at leading \0
//! path to filesystem storage
const fs::path m_path;