Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/bdb.cpp
Show First 20 Lines • Show All 887 Lines • ▼ Show 20 Lines | |||||
BerkeleyDatabase::MakeBatch(bool flush_on_close) { | BerkeleyDatabase::MakeBatch(bool flush_on_close) { | ||||
return std::make_unique<BerkeleyBatch>(*this, false, flush_on_close); | return std::make_unique<BerkeleyBatch>(*this, false, flush_on_close); | ||||
} | } | ||||
bool ExistsBerkeleyDatabase(const fs::path &path) { | bool ExistsBerkeleyDatabase(const fs::path &path) { | ||||
fs::path env_directory; | fs::path env_directory; | ||||
std::string data_filename; | std::string data_filename; | ||||
SplitWalletPath(path, env_directory, data_filename); | SplitWalletPath(path, env_directory, data_filename); | ||||
return IsBerkeleyBtree(env_directory / data_filename); | return IsBDBFile(env_directory / data_filename); | ||||
} | } | ||||
std::unique_ptr<BerkeleyDatabase> | std::unique_ptr<BerkeleyDatabase> | ||||
MakeBerkeleyDatabase(const fs::path &path, const DatabaseOptions &options, | MakeBerkeleyDatabase(const fs::path &path, const DatabaseOptions &options, | ||||
DatabaseStatus &status, bilingual_str &error) { | DatabaseStatus &status, bilingual_str &error) { | ||||
std::unique_ptr<BerkeleyDatabase> db; | std::unique_ptr<BerkeleyDatabase> db; | ||||
{ | { | ||||
// Lock env.m_databases until insert in BerkeleyDatabase constructor | // Lock env.m_databases until insert in BerkeleyDatabase constructor | ||||
Show All 15 Lines | MakeBerkeleyDatabase(const fs::path &path, const DatabaseOptions &options, | ||||
if (options.verify && !db->Verify(error)) { | if (options.verify && !db->Verify(error)) { | ||||
status = DatabaseStatus::FAILED_VERIFY; | status = DatabaseStatus::FAILED_VERIFY; | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
status = DatabaseStatus::SUCCESS; | status = DatabaseStatus::SUCCESS; | ||||
return db; | return db; | ||||
} | } | ||||
bool IsBDBFile(const fs::path &path) { | |||||
if (!fs::exists(path)) { | |||||
return false; | |||||
} | |||||
// A Berkeley DB Btree file has at least 4K. | |||||
// This check also prevents opening lock files. | |||||
boost::system::error_code ec; | |||||
auto size = fs::file_size(path, ec); | |||||
if (ec) { | |||||
LogPrintf("%s: %s %s\n", __func__, ec.message(), path.string()); | |||||
} | |||||
if (size < 4096) { | |||||
return false; | |||||
} | |||||
fsbridge::ifstream file(path, std::ios::binary); | |||||
if (!file.is_open()) { | |||||
return false; | |||||
} | |||||
file.seekg(12, std::ios::beg); // Magic bytes start at offset 12 | |||||
uint32_t data = 0; | |||||
file.read((char *)&data, | |||||
sizeof(data)); // Read 4 bytes of file to compare against magic | |||||
// Berkeley DB Btree magic bytes, from: | |||||
// https://github.com/file/file/blob/5824af38469ec1ca9ac3ffd251e7afe9dc11e227/magic/Magdir/database#L74-L75 | |||||
// - big endian systems - 00 05 31 62 | |||||
// - little endian systems - 62 31 05 00 | |||||
return data == 0x00053162 || data == 0x62310500; | |||||
} |