12 #include <leveldb/cache.h> 13 #include <leveldb/env.h> 14 #include <leveldb/filter_policy.h> 28 for (
int iter = 0; iter < 2; iter++) {
32 bufsize =
sizeof(buffer);
37 base =
new char[bufsize];
40 char* limit = base + bufsize;
45 va_copy(backup_ap, ap);
47 p += vsnprintf(p, limit - p, format, backup_ap);
62 if (p == base || p[-1] !=
'\n') {
67 base[std::min(bufsize - 1, (
int)(p - base))] =
'\0';
77 static void SetMaxOpenFiles(leveldb::Options *options) {
92 int default_open_files = options->max_open_files;
94 if (
sizeof(
void*) < 8) {
95 options->max_open_files = 64;
99 options->max_open_files, default_open_files);
102 static leveldb::Options GetOptions(
size_t nCacheSize,
size_t maxFileSize)
104 leveldb::Options options;
105 options.block_cache = leveldb::NewLRUCache(nCacheSize / 2);
106 options.write_buffer_size = nCacheSize / 4;
107 options.filter_policy = leveldb::NewBloomFilterPolicy(10);
108 options.compression = leveldb::kNoCompression;
110 options.max_file_size = maxFileSize;
111 if (leveldb::kMajorVersion > 1 || (leveldb::kMajorVersion == 1 && leveldb::kMinorVersion >= 16)) {
114 options.paranoid_checks =
true;
116 SetMaxOpenFiles(&options);
120 CDBWrapper::CDBWrapper(
const fs::path& path,
size_t nCacheSize,
bool fMemory,
bool fWipe,
bool obfuscate,
size_t maxFileSize)
123 readoptions.verify_checksums =
true;
124 iteroptions.verify_checksums =
true;
125 iteroptions.fill_cache =
false;
126 syncoptions.sync =
true;
127 options = GetOptions(nCacheSize, maxFileSize);
128 options.create_if_missing =
true;
130 penv = leveldb::NewMemEnv(leveldb::Env::Default());
134 LogPrintf(
"Wiping LevelDB in %s\n", path.string());
135 leveldb::Status result = leveldb::DestroyDB(path.string(), options);
139 LogPrintf(
"Opening LevelDB in %s\n", path.string());
141 leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb);
143 LogPrintf(
"Opened LevelDB successfully\n");
146 LogPrintf(
"Starting database compaction of %s\n", path.string());
147 pdb->CompactRange(
nullptr,
nullptr);
148 LogPrintf(
"Finished database compaction of %s\n", path.string());
152 obfuscate_key = std::vector<unsigned char>(OBFUSCATE_KEY_NUM_BYTES,
'\000');
154 bool key_exists = Read(OBFUSCATE_KEY_KEY, obfuscate_key);
156 if (!key_exists && obfuscate && IsEmpty()) {
159 std::vector<unsigned char> new_key = CreateObfuscateKey();
162 Write(OBFUSCATE_KEY_KEY, new_key);
163 obfuscate_key = new_key;
165 LogPrintf(
"Wrote new obfuscate key for %s: %s\n", path.string(),
HexStr(obfuscate_key));
168 LogPrintf(
"Using obfuscation key for %s: %s\n", path.string(),
HexStr(obfuscate_key));
175 delete options.filter_policy;
176 options.filter_policy =
nullptr;
177 delete options.info_log;
178 options.info_log =
nullptr;
179 delete options.block_cache;
180 options.block_cache =
nullptr;
182 options.env =
nullptr;
187 leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.
batch);
206 unsigned char buff[OBFUSCATE_KEY_NUM_BYTES];
208 return std::vector<unsigned char>(&buff[0], &buff[OBFUSCATE_KEY_NUM_BYTES]);
214 std::unique_ptr<CDBIterator> it(NewIterator());
216 return !(it->Valid());
231 if (status.IsCorruption())
233 if (status.IsIOError())
235 if (status.IsNotFound())
These should be considered an implementation detail of the specific database.
Batch of changes queued to be written to a CDBWrapper.
void Logv(const char *format, va_list ap) override
CDBWrapper(const fs::path &path, size_t nCacheSize, bool fMemory=false, bool fWipe=false, bool obfuscate=false, size_t maxFileSize=2<< 20)
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
void HandleError(const leveldb::Status &status)
Handle database error by throwing dbwrapper_error exception.
leveldb::WriteBatch batch
std::vector< unsigned char > CreateObfuscateKey() const
Returns a string (consisting of 8 random bytes) suitable for use as an obfuscating XOR key...
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by Boost's create_directories if the requested directory exists...
bool IsEmpty()
Return true if the database managed by this class contains no entries.
const std::vector< unsigned char > & GetObfuscateKey(const CDBWrapper &w)
Work around circular dependency, as well as for testing in dbwrapper_tests.
#define LogPrint(category,...)
static const unsigned int OBFUSCATE_KEY_NUM_BYTES
the length of the obfuscate key in number of bytes
static const std::string OBFUSCATE_KEY_KEY
the key under which the obfuscation key is stored
void GetRandBytes(unsigned char *buf, int num)
Functions to gather random data via the OpenSSL PRNG.
bool WriteBatch(CDBBatch &batch, bool fSync=false)
std::vector< unsigned char > obfuscate_key
a key used for optional XOR-obfuscation of the database
int LogPrintStr(const std::string &str)
Send a string to the log output.