Initial Vexta Core v0.1.0 release
This commit is contained in:
commit
25c454329d
2481 changed files with 689289 additions and 0 deletions
233
src/wallet/bdb.h
Normal file
233
src/wallet/bdb.h
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef DIGIBYTE_WALLET_BDB_H
|
||||
#define DIGIBYTE_WALLET_BDB_H
|
||||
|
||||
#include <clientversion.h>
|
||||
#include <fs.h>
|
||||
#include <serialize.h>
|
||||
#include <streams.h>
|
||||
#include <util/system.h>
|
||||
#include <wallet/db.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsuggest-override"
|
||||
#endif
|
||||
#include <db_cxx.h>
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
struct bilingual_str;
|
||||
|
||||
static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100;
|
||||
static const bool DEFAULT_WALLET_PRIVDB = true;
|
||||
|
||||
struct WalletDatabaseFileId {
|
||||
u_int8_t value[DB_FILE_ID_LEN];
|
||||
bool operator==(const WalletDatabaseFileId& rhs) const;
|
||||
};
|
||||
|
||||
class BerkeleyDatabase;
|
||||
|
||||
class BerkeleyEnvironment
|
||||
{
|
||||
private:
|
||||
bool fDbEnvInit;
|
||||
bool fMockDb;
|
||||
// Don't change into fs::path, as that can result in
|
||||
// shutdown problems/crashes caused by a static initialized internal pointer.
|
||||
std::string strPath;
|
||||
|
||||
public:
|
||||
std::unique_ptr<DbEnv> dbenv;
|
||||
std::map<std::string, std::reference_wrapper<BerkeleyDatabase>> m_databases;
|
||||
std::unordered_map<std::string, WalletDatabaseFileId> m_fileids;
|
||||
std::condition_variable_any m_db_in_use;
|
||||
|
||||
explicit BerkeleyEnvironment(const fs::path& env_directory);
|
||||
BerkeleyEnvironment();
|
||||
~BerkeleyEnvironment();
|
||||
void Reset();
|
||||
|
||||
bool IsMock() const { return fMockDb; }
|
||||
bool IsInitialized() const { return fDbEnvInit; }
|
||||
fs::path Directory() const { return strPath; }
|
||||
|
||||
bool Open(bilingual_str& error);
|
||||
void Close();
|
||||
void Flush(bool fShutdown);
|
||||
void CheckpointLSN(const std::string& strFile);
|
||||
|
||||
void CloseDb(const std::string& strFile);
|
||||
void ReloadDbEnv();
|
||||
|
||||
DbTxn* TxnBegin(int flags = DB_TXN_WRITE_NOSYNC)
|
||||
{
|
||||
DbTxn* ptxn = nullptr;
|
||||
int ret = dbenv->txn_begin(nullptr, &ptxn, flags);
|
||||
if (!ptxn || ret != 0)
|
||||
return nullptr;
|
||||
return ptxn;
|
||||
}
|
||||
};
|
||||
|
||||
/** Get BerkeleyEnvironment given a directory path. */
|
||||
std::shared_ptr<BerkeleyEnvironment> GetBerkeleyEnv(const fs::path& env_directory);
|
||||
|
||||
class BerkeleyBatch;
|
||||
|
||||
/** An instance of this class represents one database.
|
||||
* For BerkeleyDB this is just a (env, strFile) tuple.
|
||||
**/
|
||||
class BerkeleyDatabase : public WalletDatabase
|
||||
{
|
||||
public:
|
||||
BerkeleyDatabase() = delete;
|
||||
|
||||
/** Create DB handle to real database */
|
||||
BerkeleyDatabase(std::shared_ptr<BerkeleyEnvironment> env, std::string filename) :
|
||||
WalletDatabase(), env(std::move(env)), strFile(std::move(filename))
|
||||
{
|
||||
auto inserted = this->env->m_databases.emplace(strFile, std::ref(*this));
|
||||
assert(inserted.second);
|
||||
}
|
||||
|
||||
~BerkeleyDatabase() override;
|
||||
|
||||
/** Open the database if it is not already opened. */
|
||||
void Open() override;
|
||||
|
||||
/** Rewrite the entire database on disk, with the exception of key pszSkip if non-zero
|
||||
*/
|
||||
bool Rewrite(const char* pszSkip=nullptr) override;
|
||||
|
||||
/** Indicate the a new database user has began using the database. */
|
||||
void AddRef() override;
|
||||
/** Indicate that database user has stopped using the database and that it could be flushed or closed. */
|
||||
void RemoveRef() override;
|
||||
|
||||
/** Back up the entire database to a file.
|
||||
*/
|
||||
bool Backup(const std::string& strDest) const override;
|
||||
|
||||
/** Make sure all changes are flushed to database file.
|
||||
*/
|
||||
void Flush() override;
|
||||
/** Flush to the database file and close the database.
|
||||
* Also close the environment if no other databases are open in it.
|
||||
*/
|
||||
void Close() override;
|
||||
/* flush the wallet passively (TRY_LOCK)
|
||||
ideal to be called periodically */
|
||||
bool PeriodicFlush() override;
|
||||
|
||||
void IncrementUpdateCounter() override;
|
||||
|
||||
void ReloadDbEnv() override;
|
||||
|
||||
/** Verifies the environment and database file */
|
||||
bool Verify(bilingual_str& error);
|
||||
|
||||
/** Return path to main database filename */
|
||||
std::string Filename() override { return (env->Directory() / strFile).string(); }
|
||||
|
||||
std::string Format() override { return "bdb"; }
|
||||
/**
|
||||
* Pointer to shared database environment.
|
||||
*
|
||||
* Normally there is only one BerkeleyDatabase object per
|
||||
* BerkeleyEnvivonment, but in the special, backwards compatible case where
|
||||
* multiple wallet BDB data files are loaded from the same directory, this
|
||||
* will point to a shared instance that gets freed when the last data file
|
||||
* is closed.
|
||||
*/
|
||||
std::shared_ptr<BerkeleyEnvironment> env;
|
||||
|
||||
/** Database pointer. This is initialized lazily and reset during flushes, so it can be null. */
|
||||
std::unique_ptr<Db> m_db;
|
||||
|
||||
std::string strFile;
|
||||
|
||||
/** Make a BerkeleyBatch connected to this database */
|
||||
std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override;
|
||||
};
|
||||
|
||||
/** RAII class that provides access to a Berkeley database */
|
||||
class BerkeleyBatch : public DatabaseBatch
|
||||
{
|
||||
/** RAII class that automatically cleanses its data on destruction */
|
||||
class SafeDbt final
|
||||
{
|
||||
Dbt m_dbt;
|
||||
|
||||
public:
|
||||
// construct Dbt with internally-managed data
|
||||
SafeDbt();
|
||||
// construct Dbt with provided data
|
||||
SafeDbt(void* data, size_t size);
|
||||
~SafeDbt();
|
||||
|
||||
// delegate to Dbt
|
||||
const void* get_data() const;
|
||||
u_int32_t get_size() const;
|
||||
|
||||
// conversion operator to access the underlying Dbt
|
||||
operator Dbt*();
|
||||
};
|
||||
|
||||
private:
|
||||
bool ReadKey(CDataStream&& key, CDataStream& value) override;
|
||||
bool WriteKey(CDataStream&& key, CDataStream&& value, bool overwrite = true) override;
|
||||
bool EraseKey(CDataStream&& key) override;
|
||||
bool HasKey(CDataStream&& key) override;
|
||||
|
||||
protected:
|
||||
Db* pdb;
|
||||
std::string strFile;
|
||||
DbTxn* activeTxn;
|
||||
Dbc* m_cursor;
|
||||
bool fReadOnly;
|
||||
bool fFlushOnClose;
|
||||
BerkeleyEnvironment *env;
|
||||
BerkeleyDatabase& m_database;
|
||||
|
||||
public:
|
||||
explicit BerkeleyBatch(BerkeleyDatabase& database, const bool fReadOnly, bool fFlushOnCloseIn=true);
|
||||
~BerkeleyBatch() override;
|
||||
|
||||
BerkeleyBatch(const BerkeleyBatch&) = delete;
|
||||
BerkeleyBatch& operator=(const BerkeleyBatch&) = delete;
|
||||
|
||||
void Flush() override;
|
||||
void Close() override;
|
||||
|
||||
bool StartCursor() override;
|
||||
bool ReadAtCursor(CDataStream& ssKey, CDataStream& ssValue, bool& complete) override;
|
||||
void CloseCursor() override;
|
||||
bool TxnBegin() override;
|
||||
bool TxnCommit() override;
|
||||
bool TxnAbort() override;
|
||||
};
|
||||
|
||||
std::string BerkeleyDatabaseVersion();
|
||||
|
||||
/** Perform sanity check of runtime BDB version versus linked BDB version.
|
||||
*/
|
||||
bool BerkeleyDatabaseSanityCheck();
|
||||
|
||||
//! Return object giving access to Berkeley database at specified path.
|
||||
std::unique_ptr<BerkeleyDatabase> MakeBerkeleyDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
|
||||
|
||||
#endif // DIGIBYTE_WALLET_BDB_H
|
||||
Loading…
Reference in a new issue