Browse Source

Started implementing namespace association.

views
Just Wonder 4 years ago
parent
commit
76c50bc850
  1. 30
      src/coins.cpp
  2. 5
      src/coins.h
  3. 71
      src/keva/common.cpp
  4. 32
      src/keva/common.h
  5. 2
      src/rpc/rpckeva_nonwallet.cpp
  6. 25
      src/txdb.cpp
  7. 1
      src/txdb.h

30
src/coins.cpp

@ -14,6 +14,7 @@ bool CCoinsView::GetNamespace(const valtype &nameSpace, CKevaData &data) const {
bool CCoinsView::GetName(const valtype &nameSpace, const valtype &key, CKevaData &data) const { return false; } bool CCoinsView::GetName(const valtype &nameSpace, const valtype &key, CKevaData &data) const { return false; }
bool CCoinsView::GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const { return false; } bool CCoinsView::GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const { return false; }
CKevaIterator* CCoinsView::IterateKeys(const valtype& nameSpace) const { assert (false); } CKevaIterator* CCoinsView::IterateKeys(const valtype& nameSpace) const { assert (false); }
CKevaIterator* CCoinsView::IterateAssociatedNamespaces(const valtype& nameSpace) const { assert (false); }
bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const CKevaCache &names) { return false; } bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const CKevaCache &names) { return false; }
CCoinsViewCursor *CCoinsView::Cursor() const { return nullptr; } CCoinsViewCursor *CCoinsView::Cursor() const { return nullptr; }
bool CCoinsView::ValidateKevaDB() const { bool CCoinsView::ValidateKevaDB() const {
@ -43,6 +44,7 @@ bool CCoinsViewBacked::GetNamesForHeight(unsigned nHeight, std::set<valtype>& na
return base->GetNamesForHeight(nHeight, names); return base->GetNamesForHeight(nHeight, names);
} }
CKevaIterator* CCoinsViewBacked::IterateKeys(const valtype& nameSpace) const { return base->IterateKeys(nameSpace); } CKevaIterator* CCoinsViewBacked::IterateKeys(const valtype& nameSpace) const { return base->IterateKeys(nameSpace); }
CKevaIterator* CCoinsViewBacked::IterateAssociatedNamespaces(const valtype& nameSpace) const { return base->IterateAssociatedNamespaces(nameSpace); }
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const CKevaCache &names) { bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const CKevaCache &names) {
return base->BatchWrite(mapCoins, hashBlock, names); return base->BatchWrite(mapCoins, hashBlock, names);
@ -198,6 +200,10 @@ CKevaIterator* CCoinsViewCache::IterateKeys(const valtype& nameSpace) const {
return cacheNames.iterateKeys(base->IterateKeys(nameSpace)); return cacheNames.iterateKeys(base->IterateKeys(nameSpace));
} }
CKevaIterator* CCoinsViewCache::IterateAssociatedNamespaces(const valtype& nameSpace) const {
return cacheNames.IterateAssociatedNamespaces(base->IterateAssociatedNamespaces(nameSpace));
}
/* undo is set if the change is due to disconnecting blocks / going back in /* undo is set if the change is due to disconnecting blocks / going back in
time. The ordinary case (!undo) means that we update the name normally, time. The ordinary case (!undo) means that we update the name normally,
going forward in time. This is important for keeping track of the going forward in time. This is important for keeping track of the
@ -210,6 +216,18 @@ void CCoinsViewCache::SetName(const valtype &nameSpace, const valtype &key, cons
cacheNames.setNamespace(nameSpace, namespaceData); cacheNames.setNamespace(nameSpace, namespaceData);
} }
cacheNames.set(nameSpace, key, data); cacheNames.set(nameSpace, key, data);
// Handle namespace association.
valtype associdateNamespace;
if (!cacheNames.getAssociateNamespaces(data.getValue(), associdateNamespace)) {
return;
}
CKevaData dummyData;
if (!GetNamespace(associdateNamespace, dummyData)) {
return;
}
cacheNames.associateNamespaces(nameSpace, associdateNamespace);
} }
void CCoinsViewCache::DeleteName(const valtype &nameSpace, const valtype &key) { void CCoinsViewCache::DeleteName(const valtype &nameSpace, const valtype &key) {
@ -218,6 +236,18 @@ void CCoinsViewCache::DeleteName(const valtype &nameSpace, const valtype &key) {
assert(false); assert(false);
} }
cacheNames.remove(nameSpace, key); cacheNames.remove(nameSpace, key);
// Handle namespace association.
valtype associdateNamespace;
if (!cacheNames.getAssociateNamespaces(oldData.getValue(), associdateNamespace)) {
return;
}
CKevaData dummyData;
if (!GetNamespace(associdateNamespace, dummyData)) {
return;
}
cacheNames.disassociateNamespaces(nameSpace, associdateNamespace);
} }
bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn, const CKevaCache &names) { bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn, const CKevaCache &names) {

5
src/coins.h

@ -176,6 +176,9 @@ public:
// Get a key iterator. // Get a key iterator.
virtual CKevaIterator* IterateKeys(const valtype& nameSpace) const; virtual CKevaIterator* IterateKeys(const valtype& nameSpace) const;
// Get the associated namespace iterator.
virtual CKevaIterator* IterateAssociatedNamespaces(const valtype& nameSpace) const;
//! Do a bulk modification (multiple Coin changes + BestBlock change). //! Do a bulk modification (multiple Coin changes + BestBlock change).
//! The passed mapCoins can be modified. //! The passed mapCoins can be modified.
virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const CKevaCache &names); virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const CKevaCache &names);
@ -210,6 +213,7 @@ public:
bool GetName(const valtype& nameSpace, const valtype& key, CKevaData& data) const override; bool GetName(const valtype& nameSpace, const valtype& key, CKevaData& data) const override;
bool GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const override; bool GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const override;
CKevaIterator* IterateKeys(const valtype& nameSpace) const override; CKevaIterator* IterateKeys(const valtype& nameSpace) const override;
virtual CKevaIterator* IterateAssociatedNamespaces(const valtype& nameSpace) const override;
void SetBackend(CCoinsView &viewIn); void SetBackend(CCoinsView &viewIn);
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const CKevaCache &names) override; bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const CKevaCache &names) override;
CCoinsViewCursor *Cursor() const override; CCoinsViewCursor *Cursor() const override;
@ -252,6 +256,7 @@ public:
bool GetName(const valtype &nameSpace, const valtype &key, CKevaData& data) const override; bool GetName(const valtype &nameSpace, const valtype &key, CKevaData& data) const override;
bool GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const override; bool GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const override;
CKevaIterator* IterateKeys(const valtype& nameSpace) const override; CKevaIterator* IterateKeys(const valtype& nameSpace) const override;
CKevaIterator* IterateAssociatedNamespaces(const valtype& nameSpace) const override;
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const CKevaCache &names) override; bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const CKevaCache &names) override;
CCoinsViewCursor* Cursor() const override { CCoinsViewCursor* Cursor() const override {
throw std::logic_error("CCoinsViewCache cursor iteration not supported."); throw std::logic_error("CCoinsViewCache cursor iteration not supported.");

71
src/keva/common.cpp

@ -7,7 +7,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <keva/common.h> #include <keva/common.h>
#include <base58.h>
#include <script/keva.h> #include <script/keva.h>
@ -55,6 +55,9 @@ private:
/** Base iterator to combine with the cache. */ /** Base iterator to combine with the cache. */
CKevaIterator* base; CKevaIterator* base;
/** Whether or not it is for namespace association. */
bool isAssociation;
/** Whether or not the base iterator has more entries. */ /** Whether or not the base iterator has more entries. */
bool baseHasMore; bool baseHasMore;
@ -79,7 +82,7 @@ public:
* @param c The cache object to use. * @param c The cache object to use.
* @param b The base iterator. * @param b The base iterator.
*/ */
CCacheKeyIterator(const CKevaCache& c, CKevaIterator* b); CCacheKeyIterator(const CKevaCache& c, CKevaIterator* b, bool association=false);
/* Destruct, this deletes also the base iterator. */ /* Destruct, this deletes also the base iterator. */
~CCacheKeyIterator(); ~CCacheKeyIterator();
@ -90,8 +93,8 @@ public:
}; };
CCacheKeyIterator::CCacheKeyIterator(const CKevaCache& c, CKevaIterator* b) CCacheKeyIterator::CCacheKeyIterator(const CKevaCache& c, CKevaIterator* b, bool association)
: CKevaIterator(b->getNamespace()), cache(c), base(b) : CKevaIterator(b->getNamespace()), cache(c), base(b), isAssociation(association)
{ {
/* Add a seek-to-start to ensure that everything is consistent. This call /* Add a seek-to-start to ensure that everything is consistent. This call
may be superfluous if we seek to another position afterwards anyway, may be superfluous if we seek to another position afterwards anyway,
@ -116,7 +119,8 @@ CCacheKeyIterator::advanceBaseIterator()
void void
CCacheKeyIterator::seek(const valtype& start) CCacheKeyIterator::seek(const valtype& start)
{ {
cacheIter = cache.entries.lower_bound(std::make_tuple(nameSpace, start)); auto &entries = isAssociation ? cache.associations : cache.entries;
cacheIter = entries.lower_bound(std::make_tuple(nameSpace, start));
base->seek(start); base->seek(start);
baseHasMore = true; baseHasMore = true;
@ -127,15 +131,15 @@ bool CCacheKeyIterator::next(valtype& key, CKevaData& data)
{ {
/* Exit early if no more data is available in either the cache /* Exit early if no more data is available in either the cache
nor the base iterator. */ nor the base iterator. */
auto &entries = isAssociation ? cache.associations : cache.entries;
bool endOfCacheNamespace = false; bool endOfCacheNamespace = false;
if (cacheIter != cache.entries.end()) { if (cacheIter != entries.end()) {
valtype curNameSpace = std::get<0>(cacheIter->first); valtype curNameSpace = std::get<0>(cacheIter->first);
if (curNameSpace != nameSpace) { if (curNameSpace != nameSpace) {
endOfCacheNamespace = true; endOfCacheNamespace = true;
} }
} }
bool noMoreCache = (cacheIter == cache.entries.end()) || endOfCacheNamespace; bool noMoreCache = (cacheIter == entries.end()) || endOfCacheNamespace;
if (!baseHasMore && noMoreCache) { if (!baseHasMore && noMoreCache) {
return false; return false;
} }
@ -144,7 +148,7 @@ bool CCacheKeyIterator::next(valtype& key, CKevaData& data)
bool useBase = false; bool useBase = false;
if (!baseHasMore) { if (!baseHasMore) {
useBase = false; useBase = false;
} else if (cacheIter == cache.entries.end()) { } else if (cacheIter == entries.end()) {
useBase = true; useBase = true;
} else { } else {
if (baseKey == std::get<1>(cacheIter->first)) { if (baseKey == std::get<1>(cacheIter->first)) {
@ -182,6 +186,8 @@ bool CCacheKeyIterator::next(valtype& key, CKevaData& data)
/* ************************************************************************** */ /* ************************************************************************** */
/* CKevaCache. */ /* CKevaCache. */
const std::string CKevaCache::associatePrefix = "_A_";
bool bool
CKevaCache::get(const valtype& nameSpace, const valtype& key, CKevaData& data) const CKevaCache::get(const valtype& nameSpace, const valtype& key, CKevaData& data) const
{ {
@ -233,12 +239,55 @@ CKevaCache::remove(const valtype& nameSpace, const valtype& key)
deleted.insert(name); deleted.insert(name);
} }
/* If the value is an associated namespace (_A_N...), return the namespace */
bool
CKevaCache::getAssociateNamespaces(const valtype& value, valtype& nameSpace)
{
std::string valueStr = ValtypeToString(value);
if (valueStr.rfind(associatePrefix, 0) != 0) {
return false;
}
valueStr.erase(0, associatePrefix.length());
if (!DecodeKevaNamespace(valueStr, Params(), nameSpace)) {
return false;
}
return true;
}
void
CKevaCache::associateNamespaces(const valtype& nameSpace, const valtype& nameSpaceOther)
{
auto name = std::make_tuple(nameSpaceOther, nameSpace);
const NamespaceMap::iterator ei = associations.find(name);
CKevaData data;
if (ei != entries.end())
ei->second = data;
else
associations.insert(std::make_pair(name, data));
}
void
CKevaCache::disassociateNamespaces(const valtype& nameSpace, const valtype& nameSpaceOther)
{
auto name = std::make_tuple(nameSpaceOther, nameSpace);
const NamespaceMap::iterator ei = entries.find(name);
if (ei != entries.end()) {
associations.erase(ei);
}
}
CKevaIterator* CKevaIterator*
CKevaCache::iterateKeys(CKevaIterator* base) const CKevaCache::iterateKeys(CKevaIterator* base) const
{ {
return new CCacheKeyIterator(*this, base); return new CCacheKeyIterator(*this, base);
} }
CKevaIterator*
CKevaCache::IterateAssociatedNamespaces(CKevaIterator* base) const
{
return new CCacheKeyIterator(*this, base, true);
}
void void
CKevaCache::updateNamesForHeight (unsigned nHeight, CKevaCache::updateNamesForHeight (unsigned nHeight,
std::set<valtype>& names) const std::set<valtype>& names) const
@ -253,6 +302,10 @@ void CKevaCache::apply(const CKevaCache& cache)
set(std::get<0>(i->first), std::get<1>(i->first), i->second); set(std::get<0>(i->first), std::get<1>(i->first), i->second);
} }
for (NamespaceMap::const_iterator i = associations.begin(); i != associations.end(); ++i) {
set(std::get<0>(i->first), std::get<1>(i->first), i->second);
}
for (std::set<NamespaceKeyType>::const_iterator i = cache.deleted.begin(); i != cache.deleted.end(); ++i) { for (std::set<NamespaceKeyType>::const_iterator i = cache.deleted.begin(); i != cache.deleted.end(); ++i) {
remove(std::get<0>(*i), std::get<1>(*i)); remove(std::get<0>(*i), std::get<1>(*i));
} }

32
src/keva/common.h

@ -2,7 +2,7 @@
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Copyright (c) 2018 // Copyright (c) 2018-2020 The Kevacoin Core Developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -298,6 +298,8 @@ class CKevaCache
private: private:
const static std::string associatePrefix;
/** /**
* Special comparator class for names that compares by length first. * Special comparator class for names that compares by length first.
* This is used to sort the cache entry map in the same way as the * This is used to sort the cache entry map in the same way as the
@ -336,6 +338,8 @@ public:
typedef std::tuple<valtype, valtype> NamespaceKeyType; typedef std::tuple<valtype, valtype> NamespaceKeyType;
typedef std::map<std::tuple<valtype, valtype>, CKevaData, KeyComparator> NamespaceMap;
private: private:
/** New or updated names. */ /** New or updated names. */
@ -344,15 +348,19 @@ private:
/** Deleted names. */ /** Deleted names. */
std::set<NamespaceKeyType> deleted; std::set<NamespaceKeyType> deleted;
/** Namespace association. */
NamespaceMap associations;
friend class CCacheKeyIterator; friend class CCacheKeyIterator;
public: public:
inline void inline void
clear () clear()
{ {
entries.clear (); entries.clear();
deleted.clear (); deleted.clear();
associations.clear();
} }
/** /**
@ -362,9 +370,9 @@ public:
* @return True iff no changes are cached. * @return True iff no changes are cached.
*/ */
inline bool inline bool
empty () const empty() const
{ {
if (entries.empty() && deleted.empty()) { if (entries.empty() && deleted.empty() && associations.empty()) {
return true; return true;
} }
@ -394,11 +402,23 @@ public:
/* Delete a name. If it is in the "entries" set also, remove it there. */ /* Delete a name. If it is in the "entries" set also, remove it there. */
void remove(const valtype& nameSpace, const valtype& key); void remove(const valtype& nameSpace, const valtype& key);
/* If the value is an associated namespace (_A_N...), return the namespace */
bool getAssociateNamespaces(const valtype& value, valtype& nameSpace);
/* Associate nameSpace with nameSpaceOther */
void associateNamespaces(const valtype& nameSpace, const valtype& nameSpaceOther);
/* Disassociate nameSpace with nameSpaceOther */
void disassociateNamespaces(const valtype& nameSpace, const valtype& nameSpaceOther);
/* Return a name iterator that combines a "base" iterator with the changes /* Return a name iterator that combines a "base" iterator with the changes
made to it according to the cache. The base iterator is taken made to it according to the cache. The base iterator is taken
ownership of. */ ownership of. */
CKevaIterator* iterateKeys(CKevaIterator* base) const; CKevaIterator* iterateKeys(CKevaIterator* base) const;
// Get the associated namespace iterator.
CKevaIterator* IterateAssociatedNamespaces(CKevaIterator* base) const;
/* Query the cached changes to the expire index. In particular, /* Query the cached changes to the expire index. In particular,
for a given height and a given set of names that were indexed to for a given height and a given set of names that were indexed to
this update height, apply possible changes to the set that this update height, apply possible changes to the set that

2
src/rpc/rpckeva_nonwallet.cpp

@ -2,7 +2,7 @@
// Distributed under the MIT/X11 software license, see the accompanying // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Copyright (c) 2018 the Kevacoin Core Developers // Copyright (c) 2018-2020 the Kevacoin Core Developers
// Distributed under the MIT/X11 software license, see the accompanying // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.

25
src/txdb.cpp

@ -26,6 +26,7 @@ static const char DB_TXINDEX = 't';
static const char DB_BLOCK_INDEX = 'b'; static const char DB_BLOCK_INDEX = 'b';
static const char DB_NAME = 'n'; static const char DB_NAME = 'n';
static const char DB_NS_ASSOC = 'a';
static const char DB_BEST_BLOCK = 'B'; static const char DB_BEST_BLOCK = 'B';
static const char DB_HEAD_BLOCKS = 'H'; static const char DB_HEAD_BLOCKS = 'H';
@ -92,6 +93,9 @@ private:
/* The backing LevelDB iterator. */ /* The backing LevelDB iterator. */
CDBIterator* iter; CDBIterator* iter;
/* This iterator is for namespace association search. */
bool isAssociation;
public: public:
~CDbKeyIterator(); ~CDbKeyIterator();
@ -100,7 +104,7 @@ public:
* Construct a new name iterator for the database. * Construct a new name iterator for the database.
* @param db The database to create the iterator for. * @param db The database to create the iterator for.
*/ */
CDbKeyIterator(const CDBWrapper& db, const valtype& nameSpace); CDbKeyIterator(const CDBWrapper& db, const valtype& nameSpace, bool association=false);
/* Implement iterator methods. */ /* Implement iterator methods. */
void seek(const valtype& start); void seek(const valtype& start);
@ -112,22 +116,24 @@ CDbKeyIterator::~CDbKeyIterator() {
delete iter; delete iter;
} }
CDbKeyIterator::CDbKeyIterator(const CDBWrapper& db, const valtype& ns) CDbKeyIterator::CDbKeyIterator(const CDBWrapper& db, const valtype& ns, bool association)
: CKevaIterator(ns), iter(const_cast<CDBWrapper*>(&db)->NewIterator()) : CKevaIterator(ns), iter(const_cast<CDBWrapper*>(&db)->NewIterator()), isAssociation(association)
{ {
seek(valtype()); seek(valtype());
} }
void CDbKeyIterator::seek(const valtype& start) { void CDbKeyIterator::seek(const valtype& start) {
iter->Seek(std::make_pair(DB_NAME, std::make_pair(nameSpace, start))); auto &prefix = isAssociation ? DB_NS_ASSOC : DB_NAME;
iter->Seek(std::make_pair(prefix, std::make_pair(nameSpace, start)));
} }
bool CDbKeyIterator::next(valtype& key, CKevaData& data) { bool CDbKeyIterator::next(valtype& key, CKevaData& data) {
if (!iter->Valid()) if (!iter->Valid())
return false; return false;
auto &prefix = isAssociation ? DB_NS_ASSOC : DB_NAME;
std::pair<char, std::pair<valtype, valtype>> curKey; std::pair<char, std::pair<valtype, valtype>> curKey;
if (!iter->GetKey(curKey) || curKey.first != DB_NAME) if (!iter->GetKey(curKey) || curKey.first != prefix)
return false; return false;
valtype curNameSpace = std::get<0>(curKey.second); valtype curNameSpace = std::get<0>(curKey.second);
@ -148,6 +154,10 @@ CKevaIterator* CCoinsViewDB::IterateKeys(const valtype& nameSpace) const {
return new CDbKeyIterator(db, nameSpace); return new CDbKeyIterator(db, nameSpace);
} }
CKevaIterator* CCoinsViewDB::IterateAssociatedNamespaces(const valtype& nameSpace) const {
return new CDbKeyIterator(db, nameSpace, true);
}
bool CCoinsViewDB::GetNamespace(const valtype &nameSpace, CKevaData &data) const { bool CCoinsViewDB::GetNamespace(const valtype &nameSpace, CKevaData &data) const {
return db.Read(std::make_pair(DB_NAME, std::make_pair(nameSpace, CKevaScript::KEVA_DISPLAY_NAME_KEY)), data); return db.Read(std::make_pair(DB_NAME, std::make_pair(nameSpace, CKevaScript::KEVA_DISPLAY_NAME_KEY)), data);
} }
@ -324,6 +334,11 @@ void CKevaCache::writeBatch (CDBBatch& batch) const
batch.Write(std::make_pair(DB_NAME, name), i->second); batch.Write(std::make_pair(DB_NAME, name), i->second);
} }
for (NamespaceMap::const_iterator i = associations.begin(); i != associations.end(); ++i) {
std::pair<valtype, valtype> name = std::make_pair(std::get<0>(i->first), std::get<1>(i->first));
batch.Write(std::make_pair(DB_NS_ASSOC, name), i->second);
}
for (std::set<NamespaceKeyType>::const_iterator i = deleted.begin(); i != deleted.end(); ++i) { for (std::set<NamespaceKeyType>::const_iterator i = deleted.begin(); i != deleted.end(); ++i) {
std::pair<valtype, valtype> name = std::make_pair(std::get<0>(*i), std::get<1>(*i)); std::pair<valtype, valtype> name = std::make_pair(std::get<0>(*i), std::get<1>(*i));
batch.Erase(std::make_pair(DB_NAME, name)); batch.Erase(std::make_pair(DB_NAME, name));

1
src/txdb.h

@ -80,6 +80,7 @@ public:
bool GetName(const valtype &nameSpace, const valtype &key, CKevaData &data) const override; bool GetName(const valtype &nameSpace, const valtype &key, CKevaData &data) const override;
bool GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const override; bool GetNamesForHeight(unsigned nHeight, std::set<valtype>& names) const override;
CKevaIterator* IterateKeys(const valtype& nameSpace) const override; CKevaIterator* IterateKeys(const valtype& nameSpace) const override;
CKevaIterator* IterateAssociatedNamespaces(const valtype& nameSpace) const override;
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const CKevaCache &names) override; bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const CKevaCache &names) override;
CCoinsViewCursor *Cursor() const override; CCoinsViewCursor *Cursor() const override;

Loading…
Cancel
Save