From 97b35682e0e8b3a2cff9700b203d18e3e20809c7 Mon Sep 17 00:00:00 2001 From: Jianping Wu Date: Thu, 25 Oct 2018 13:55:01 -0700 Subject: [PATCH] WIP: main.cpp compiled. --- src/chainparams.cpp | 15 +++++++++ src/chainparams.h | 2 ++ src/coins.cpp | 4 ++- src/coins.h | 10 ++++-- src/keva/common.cpp | 28 +++++++++++------ src/keva/common.h | 8 ++++- src/keva/main.cpp | 68 +++++++++++++++++++++++++--------------- src/keva/main.h | 6 ++-- src/script/interpreter.h | 4 +++ src/txmempool.h | 3 +- src/undo.h | 1 + src/wallet/rpckeva.cpp | 2 +- 12 files changed, 108 insertions(+), 43 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 78bfec91e..6c2572bda 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -199,6 +199,11 @@ public: 0.06 // * estimated number of transactions per second after that timestamp }; } + + int DefaultCheckNameDB() const + { + return -1; + } }; /** @@ -304,6 +309,11 @@ public: }; } + + int DefaultCheckNameDB() const + { + return -1; + } }; /** @@ -396,6 +406,11 @@ public: bech32_hrp = "rltc"; } + + int DefaultCheckNameDB() const + { + return 0; + } }; static std::unique_ptr globalChainParams; diff --git a/src/chainparams.h b/src/chainparams.h index fce60bff6..a52343477 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -59,6 +59,8 @@ public: const CBlock& GenesisBlock() const { return genesis; } /** Default value for -checkmempool and -checkblockindex argument */ bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; } + /** Default value for -checknamedb argument */ + virtual int DefaultCheckNameDB() const = 0; /** Policy: Filter transactions that do not match well-defined patterns */ bool RequireStandard() const { return fRequireStandard; } uint64_t PruneAfterHeight() const { return nPruneAfterHeight; } diff --git a/src/coins.cpp b/src/coins.cpp index fba8e88ea..49b03be3e 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -14,6 +14,7 @@ bool CCoinsView::GetName(const valtype &nameSpace, const valtype &key, CKevaData bool CCoinsView::GetNamesForHeight(unsigned nHeight, std::set& names) const { return false; } bool CCoinsView::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return false; } CCoinsViewCursor *CCoinsView::Cursor() const { return nullptr; } +bool CCoinsView::ValidateNameDB() const { return false; } bool CCoinsView::HaveCoin(const COutPoint &outpoint) const { @@ -32,6 +33,7 @@ void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; } bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); } CCoinsViewCursor *CCoinsViewBacked::Cursor() const { return base->Cursor(); } size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); } +bool CCoinsViewBacked::ValidateNameDB() const { return base->ValidateNameDB(); } SaltedOutpointHasher::SaltedOutpointHasher() : k0(GetRand(std::numeric_limits::max())), k1(GetRand(std::numeric_limits::max())) {} @@ -217,7 +219,7 @@ void CCoinsViewCache::SetName(const valtype &nameSpace, const valtype &key, cons void CCoinsViewCache::DeleteName(const valtype &nameSpace, const valtype &key) { CKevaData oldData; if (GetName(nameSpace, key, oldData)) { -#if 0 +#if 0 cacheNames.removeExpireIndex(name, oldData.getHeight()); #endif } diff --git a/src/coins.h b/src/coins.h index 5dee9fe8c..439dad6a1 100644 --- a/src/coins.h +++ b/src/coins.h @@ -165,7 +165,7 @@ public: virtual std::vector GetHeadBlocks() const; // Get a name (if it exists) - virtual bool GetName(const valtype& nameSpace, const valtype& key, CKevaData& data) const; + virtual bool GetName(const valtype& nameSpace, const valtype& key, CKevaData& data) const; // Query for names that were updated at the given height virtual bool GetNamesForHeight(unsigned nHeight, std::set& names) const; @@ -177,6 +177,9 @@ public: //! Get a cursor to iterate over the whole state virtual CCoinsViewCursor *Cursor() const; + // Validate the name database. + virtual bool ValidateNameDB() const; + //! As we use CCoinsViews polymorphically, have a virtual destructor virtual ~CCoinsView() {} @@ -203,6 +206,7 @@ public: bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override; CCoinsViewCursor *Cursor() const override; size_t EstimateSize() const override; + bool ValidateNameDB() const; }; @@ -212,7 +216,7 @@ class CCoinsViewCache : public CCoinsViewBacked protected: /** * Make mutable so that we can "fill the cache" even from Get-methods - * declared as "const". + * declared as "const". */ mutable uint256 hashBlock; mutable CCoinsMap cacheCoins; @@ -298,7 +302,7 @@ public: //! Calculate the size of the cache (in bytes) size_t DynamicMemoryUsage() const; - /** + /** * Amount of bitcoins coming in to a transaction * Note that lightweight clients may not know anything besides the hash of previous transactions, * so may not be able to calculate this. diff --git a/src/keva/common.cpp b/src/keva/common.cpp index 2651c2ee2..95da255f6 100644 --- a/src/keva/common.cpp +++ b/src/keva/common.cpp @@ -40,6 +40,7 @@ CNameIterator::~CNameIterator () /* ************************************************************************** */ /* CKevaCacheNameIterator. */ +// JWU TODO: this doesn't work at all!!!! class CCacheNameIterator : public CNameIterator { @@ -104,7 +105,7 @@ CCacheNameIterator::advanceBaseIterator () assert (baseHasMore); do baseHasMore = base->next (baseName, baseData); - while (baseHasMore && cache.isDeleted (baseName)); + while (baseHasMore && cache.isDeleted(baseName, baseName)); } void @@ -175,7 +176,8 @@ CCacheNameIterator::next (valtype& name, CKevaData& data) bool CKevaCache::get (const valtype& nameSpace, const valtype& key, CKevaData& data) const { - valtype name = nameSpace + key; + valtype name = nameSpace; + name.insert( name.end(), key.begin(), key.end() ); const EntryMap::const_iterator i = entries.find (name); if (i == entries.end ()) return false; @@ -187,7 +189,8 @@ CKevaCache::get (const valtype& nameSpace, const valtype& key, CKevaData& data) void CKevaCache::set (const valtype& nameSpace, const valtype& key, const CKevaData& data) { - valtype name = nameSpace + key; + valtype name = nameSpace; + name.insert( name.end(), key.begin(), key.end() ); const std::set::iterator di = deleted.find (name); if (di != deleted.end ()) deleted.erase (di); @@ -202,7 +205,8 @@ CKevaCache::set (const valtype& nameSpace, const valtype& key, const CKevaData& void CKevaCache::remove (const valtype& nameSpace, const valtype& key) { - valtype name = nameSpace + key; + valtype name = nameSpace; + name.insert( name.end(), key.begin(), key.end() ); const EntryMap::iterator ei = entries.find (name); if (ei != entries.end ()) entries.erase (ei); @@ -250,6 +254,7 @@ CKevaCache::updateNamesForHeight (unsigned nHeight, /* Seek in the map of cached entries to the first one corresponding to our height. */ +#if 0 const ExpireEntry seekEntry(nHeight, valtype ()); std::map::const_iterator it; @@ -265,8 +270,10 @@ CKevaCache::updateNamesForHeight (unsigned nHeight, else names.erase (cur.name); } +#endif } +#if 0 void CKevaCache::addExpireIndex (const valtype& name, unsigned height) { @@ -280,17 +287,19 @@ CKevaCache::removeExpireIndex (const valtype& name, unsigned height) const ExpireEntry entry(height, name); expireIndex[entry] = false; } +#endif +#if 0 void -CKevaCache::apply (const CKevaCache& cache) +CKevaCache::apply(const CKevaCache& cache) { - for (EntryMap::const_iterator i = cache.entries.begin (); - i != cache.entries.end (); ++i) + for (EntryMap::const_iterator i = cache.entries.begin (); i != cache.entries.end (); ++i) { set (i->first, i->second); + } - for (std::set::const_iterator i = cache.deleted.begin (); - i != cache.deleted.end (); ++i) + for (std::set::const_iterator i = cache.deleted.begin (); i != cache.deleted.end (); ++i) { remove (*i); + } for (std::map::const_iterator i = cache.history.begin (); i != cache.history.end (); ++i) @@ -300,3 +309,4 @@ CKevaCache::apply (const CKevaCache& cache) = cache.expireIndex.begin (); i != cache.expireIndex.end (); ++i) expireIndex[i->first] = i->second; } +#endif diff --git a/src/keva/common.h b/src/keva/common.h index 3b90302df..83ad51c18 100644 --- a/src/keva/common.h +++ b/src/keva/common.h @@ -439,7 +439,11 @@ public: inline bool isDeleted (const valtype& nameSpace, const valtype& key) const { - return (deleted.count (name) > 0); +#if 0 + return (deleted.count(name) > 0); +#else + return false; +#endif } /* Try to get a name's associated data. This looks only @@ -490,7 +494,9 @@ public: #endif /* Apply all the changes in the passed-in record on top of this one. */ +#if 0 void apply (const CKevaCache& cache); +#endif /* Write all cached changes to a database batch update object. */ void writeBatch (CDBBatch& batch) const; diff --git a/src/keva/main.cpp b/src/keva/main.cpp index ce75153dc..79a6c064d 100644 --- a/src/keva/main.cpp +++ b/src/keva/main.cpp @@ -75,7 +75,7 @@ CKevaMemPool::addUnchecked (const uint256& hash, const CTxMemPoolEntry& entry) if (entry.isNamespaceRegistration()) { const valtype& nameSpace = entry.getNamespace(); assert(mapNamespaceRegs.count(nameSpace) == 0); - mapNamespaceRegs.insert(std::make_pair (nameSpace, hash)); + mapNamespaceRegs.insert(std::make_pair(nameSpace, hash)); } if (entry.isNamespaceKeyUpdate ()) { @@ -83,7 +83,7 @@ CKevaMemPool::addUnchecked (const uint256& hash, const CTxMemPoolEntry& entry) const valtype& key = entry.getKey(); NamespaceKeyTuple tuple(nameSpace, key); assert(mapNamespaceKeyUpdates.count(tuple) == 0); - mapNamespaceKeyUpdates.insert (std::make_pair (name, hash)); + mapNamespaceKeyUpdates.insert (std::make_pair(tuple, hash)); } } @@ -143,7 +143,7 @@ CKevaMemPool::check(const CCoinsView& coins) const nHeight = mapBlockIndex.find (blockHash)->second->nHeight; std::set nameRegs; - std::set nameUpdates; + std::set> namespaceKeyUpdates; for (const auto& entry : pool.mapTx) { const uint256 txHash = entry.GetTx ().GetHash (); if (entry.isNamespaceRegistration()) { @@ -155,43 +155,54 @@ CKevaMemPool::check(const CCoinsView& coins) const assert (nameRegs.count(nameSpace) == 0); nameRegs.insert(nameSpace); - +#if 0 /* The old name should be expired already. Note that we use nHeight+1 for the check, because that's the height at which the mempool tx will actually be mined. */ CKevaData data; if (coins.GetName(name, data)) assert (data.isExpired (nHeight + 1)); +#endif } if (entry.isNamespaceKeyUpdate()) { - const valtype& name = entry.getName (); - - const NameTxMap::const_iterator mit = mapNameUpdates.find (name); - assert (mit != mapNameUpdates.end ()); + const valtype& nameSpace = entry.getNamespace(); + const valtype& key = entry.getKey(); + std::tuple tuple(nameSpace, key); + const NamespaceKeyTxMap::const_iterator mit = mapNamespaceKeyUpdates.find(tuple); + assert (mit != mapNamespaceKeyUpdates.end ()); assert (mit->second == txHash); - assert (nameUpdates.count (name) == 0); - nameUpdates.insert(name); + assert (namespaceKeyUpdates.count(tuple) == 0); + namespaceKeyUpdates.insert(tuple); +#if 0 /* As above, use nHeight+1 for the expiration check. */ CKevaData data; - if (!coins.GetName(name, data)) + if (!coins.GetName(name, data)) { assert (false); + } assert (!data.isExpired (nHeight + 1)); +#endif } } - assert (nameRegs.size () == mapNameRegs.size ()); - assert (nameUpdates.size () == mapNameUpdates.size ()); + assert(nameRegs.size() == mapNamespaceRegs.size()); + assert(namespaceKeyUpdates.size() == mapNamespaceKeyUpdates.size()); /* Check that nameRegs and nameUpdates are disjoint. They must be since a name can only be in either category, depending on whether it exists at the moment or not. */ - for (const auto& name : nameRegs) - assert (nameUpdates.count (name) == 0); - for (const auto& name : nameUpdates) - assert (nameRegs.count (name) == 0); +#if 0 + // Is this neccesary? + for (const auto& nameSpace : nameRegs) { + assert(namespaceKeyUpdates.count(name) == 0); + } +#endif + + for (const auto& namespaceKey : namespaceKeyUpdates) { + assert(nameRegs.count(std::get<0>(namespaceKey)) == 0); + } } bool @@ -221,7 +232,7 @@ CKevaMemPool::checkTx (const CTransaction& tx) const if (mi != mapNamespaceRegs.end ()) return false; break; - } + } case OP_KEVA_PUT: { @@ -285,7 +296,7 @@ CheckNameTransaction (const CTransaction& tx, unsigned nHeight, { const std::string strTxid = tx.GetHash ().GetHex (); const char* txid = strTxid.c_str (); - const bool fMempool = (flags & SCRIPT_VERIFY_NAMES_MEMPOOL); + const bool fMempool = (flags & SCRIPT_VERIFY_KEVA_MEMPOOL); #if 0 /* Ignore historic bugs. */ @@ -354,9 +365,16 @@ CheckNameTransaction (const CTransaction& tx, unsigned nHeight, __func__, txid)); /* Reject "greedy names". */ +#if 0 const Consensus::Params& params = Params ().GetConsensus (); - if (tx.vout[nameOut].nValue < params.rules->MinNameCoinAmount(nHeight)) + if (tx.vout[nameOut].nValue < params.rules->MinNameCoinAmount(nHeight)) { + return state.Invalid (error ("%s: greedy name", __func__)); + } +#else + if (tx.vout[nameOut].nValue < KEVA_LOCKED_AMOUNT) { return state.Invalid (error ("%s: greedy name", __func__)); + } +#endif #if 0 /* Handle NAME_NEW now, since this is easy and different from the other @@ -392,7 +410,7 @@ CheckNameTransaction (const CTransaction& tx, unsigned nHeight, if (nameOpOut.getOpValue().size () > MAX_VALUE_LENGTH) { return state.Invalid (error ("CheckNameTransaction: value too long")); - } + } /* Process KEVA_PUT next. */ const valtype& nameSpace = nameOpOut.getOpNamespace(); @@ -400,12 +418,12 @@ CheckNameTransaction (const CTransaction& tx, unsigned nHeight, if (!nameOpIn.isAnyUpdate ()) { return state.Invalid(error("CheckNameTransaction: KEVA_PUT with" " prev input that is no update")); - } + } if (nameSpace != nameOpIn.getOpNamespace()) { return state.Invalid (error ("%s: KEVA_PUT namespace mismatch to prev tx" " found in %s", __func__, txid)); - } + } /* This is actually redundant, since expired names are removed from the UTXO set and thus not available to be spent anyway. @@ -656,7 +674,7 @@ void CheckNameDB (bool disconnect) { const int option - = gArgs.GetArg ("-checknamedb", Params ().DefaultCheckNameDB ()); + = gArgs.GetArg ("-checknamedb", Params().DefaultCheckNameDB ()); if (option == -1) return; @@ -669,7 +687,7 @@ CheckNameDB (bool disconnect) } pcoinsTip->Flush (); - const bool ok = pcoinsTip->ValidateNameDB (); + const bool ok = pcoinsTip->ValidateNameDB(); /* The DB is inconsistent (mismatch between UTXO set and names DB) between (roughly) blocks 139,000 and 180,000. This is caused by libcoin's diff --git a/src/keva/main.h b/src/keva/main.h index 9d5a350d0..2090fdb97 100644 --- a/src/keva/main.h +++ b/src/keva/main.h @@ -70,10 +70,12 @@ public: template inline void SerializationOp (Stream& s, Operation ser_action) { - READWRITE (name); + READWRITE (nameSpace); + READWRITE (key); READWRITE (isNew); - if (!isNew) + if (!isNew) { READWRITE (oldData); + } } /** diff --git a/src/script/interpreter.h b/src/script/interpreter.h index edb55cc45..f47814c6a 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -115,6 +115,10 @@ enum // Making OP_CODESEPARATOR and FindAndDelete fail any non-segwit scripts // SCRIPT_VERIFY_CONST_SCRIPTCODE = (1U << 16), + + // Perform namespace/key checks in "mempool" mode. This allows / disallows + // certain stuff. + SCRIPT_VERIFY_KEVA_MEMPOOL = (1U << 24), }; bool CheckSignatureEncoding(const std::vector &vchSig, unsigned int flags, ScriptError* serror); diff --git a/src/txmempool.h b/src/txmempool.h index 93a1635ac..7f25a7c99 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -20,6 +20,7 @@ #include #include #include +#include