123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- // ECOin - Copyright (c) - 2014/2022 - GPLv3 - epsylon@riseup.net (https://03c8.net)
- #ifndef ECOIN_LEVELDB_H
- #define ECOIN_LEVELDB_H
- #include "main.h"
- #include <map>
- #include <string>
- #include <vector>
- #include <leveldb/db.h>
- #include <leveldb/write_batch.h>
- class CTxDB
- {
- public:
- CTxDB(const char* pszMode="r+");
- ~CTxDB() {
- // Note that this is not the same as Close() because it deletes only
- // data scoped to this TxDB object.
- delete activeBatch;
- }
- // Destroys the underlying shared global state accessed by this TxDB.
- void Close();
- private:
- leveldb::DB *pdb; // Points to the global instance.
- // A batch stores up writes and deletes for atomic application. When this
- // field is non-NULL, writes/deletes go there instead of directly to disk.
- leveldb::WriteBatch *activeBatch;
- leveldb::Options options;
- bool fReadOnly;
- int nVersion;
- protected:
- // Returns true and sets (value,false) if activeBatch contains the given key
- // or leaves value alone and sets deleted = true if activeBatch contains a
- // delete for it.
- bool ScanBatch(const CDataStream &key, std::string *value, bool *deleted) const;
- template<typename K, typename T>
- bool Read(const K& key, T& value)
- {
- CDataStream ssKey(SER_DISK, CLIENT_VERSION);
- ssKey.reserve(1000);
- ssKey << key;
- std::string strValue;
- bool readFromDb = true;
- if (activeBatch) {
- // First we must search for it in the currently pending set of
- // changes to the db. If not found in the batch, go on to read disk.
- bool deleted = false;
- readFromDb = ScanBatch(ssKey, &strValue, &deleted) == false;
- if (deleted) {
- return false;
- }
- }
- if (readFromDb) {
- leveldb::Status status = pdb->Get(leveldb::ReadOptions(),
- ssKey.str(), &strValue);
- if (!status.ok()) {
- if (status.IsNotFound())
- return false;
- // Some unexpected error.
- printf("LevelDB read failure: %s\n", status.ToString().c_str());
- return false;
- }
- }
- // Unserialize value
- try {
- CDataStream ssValue(strValue.data(), strValue.data() + strValue.size(),
- SER_DISK, CLIENT_VERSION);
- ssValue >> value;
- }
- catch (std::exception &e) {
- return false;
- }
- return true;
- }
- template<typename K, typename T>
- bool Write(const K& key, const T& value)
- {
- if (fReadOnly)
- assert(!"Write called on database in read-only mode");
- CDataStream ssKey(SER_DISK, CLIENT_VERSION);
- ssKey.reserve(1000);
- ssKey << key;
- CDataStream ssValue(SER_DISK, CLIENT_VERSION);
- ssValue.reserve(10000);
- ssValue << value;
- if (activeBatch) {
- activeBatch->Put(ssKey.str(), ssValue.str());
- return true;
- }
- leveldb::Status status = pdb->Put(leveldb::WriteOptions(), ssKey.str(), ssValue.str());
- if (!status.ok()) {
- printf("LevelDB write failure: %s\n", status.ToString().c_str());
- return false;
- }
- return true;
- }
- template<typename K>
- bool Erase(const K& key)
- {
- if (!pdb)
- return false;
- if (fReadOnly)
- assert(!"Erase called on database in read-only mode");
- CDataStream ssKey(SER_DISK, CLIENT_VERSION);
- ssKey.reserve(1000);
- ssKey << key;
- if (activeBatch) {
- activeBatch->Delete(ssKey.str());
- return true;
- }
- leveldb::Status status = pdb->Delete(leveldb::WriteOptions(), ssKey.str());
- return (status.ok() || status.IsNotFound());
- }
- template<typename K>
- bool Exists(const K& key)
- {
- CDataStream ssKey(SER_DISK, CLIENT_VERSION);
- ssKey.reserve(1000);
- ssKey << key;
- std::string unused;
- if (activeBatch) {
- bool deleted;
- if (ScanBatch(ssKey, &unused, &deleted) && !deleted) {
- return true;
- }
- }
- leveldb::Status status = pdb->Get(leveldb::ReadOptions(), ssKey.str(), &unused);
- return status.IsNotFound() == false;
- }
- public:
- bool TxnBegin();
- bool TxnCommit();
- bool TxnAbort()
- {
- delete activeBatch;
- activeBatch = NULL;
- return true;
- }
- bool ReadVersion(int& nVersion)
- {
- nVersion = 0;
- return Read(std::string("version"), nVersion);
- }
- bool WriteVersion(int nVersion)
- {
- return Write(std::string("version"), nVersion);
- }
- bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
- bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
- bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
- bool EraseTxIndex(const CTransaction& tx);
- bool ContainsTx(uint256 hash);
- bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
- bool ReadDiskTx(uint256 hash, CTransaction& tx);
- bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
- bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
- bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
- bool ReadHashBestChain(uint256& hashBestChain);
- bool WriteHashBestChain(uint256 hashBestChain);
- bool ReadBestInvalidTrust(CBigNum& bnBestInvalidTrust);
- bool WriteBestInvalidTrust(CBigNum bnBestInvalidTrust);
- bool ReadSyncCheckpoint(uint256& hashCheckpoint);
- bool WriteSyncCheckpoint(uint256 hashCheckpoint);
- bool ReadCheckpointPubKey(std::string& strPubKey);
- bool WriteCheckpointPubKey(const std::string& strPubKey);
- bool LoadBlockIndex();
- private:
- bool LoadBlockIndexGuts();
- };
- #endif // ECOIN_DB_H
|