From cc0512bbe3a9bacacd7c509d45206bf86f569c5e Mon Sep 17 00:00:00 2001 From: Just Wonder Date: Sat, 20 Jun 2020 15:12:23 -0700 Subject: [PATCH] Handled group join/leave in mempool. --- src/rpc/rpckeva_nonwallet.cpp | 80 +++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 17 deletions(-) diff --git a/src/rpc/rpckeva_nonwallet.cpp b/src/rpc/rpckeva_nonwallet.cpp index 35a7a4735..ad539b59a 100644 --- a/src/rpc/rpckeva_nonwallet.cpp +++ b/src/rpc/rpckeva_nonwallet.cpp @@ -147,6 +147,22 @@ enum InitiatorType : int INITIATOR_TYPE_OTHER }; + +// Check if the key has the format _g:NamespaceId. If yes, +// return the namespace. +bool isNamespaceGroup(const valtype& key, valtype& targetNS) +{ + std::string keyStr = ValtypeToString(key); + if (keyStr.rfind(CKevaData::ASSOCIATE_PREFIX, 0) != 0) { + return false; + } + keyStr.erase(0, CKevaData::ASSOCIATE_PREFIX.length()); + if (!DecodeKevaNamespace(keyStr, Params(), targetNS)) { + return false; + } + return true; +} + void getNamespaceGroup(const valtype& nameSpace, std::set& namespaces, const InitiatorType type) { CKevaData data; @@ -165,20 +181,13 @@ void getNamespaceGroup(const valtype& nameSpace, std::set& namespaces, // Find the namespace connection initialized by us. std::unique_ptr iterKeys(pcoinsTip->IterateKeys(nameSpace)); - valtype targetNS; valtype key; while (iterKeys->next(key, data)) { - + valtype targetNS; // Find the value with the format _g:NamespaceId - std::string keyStr = ValtypeToString(key); - if (keyStr.rfind(CKevaData::ASSOCIATE_PREFIX, 0) != 0) { - continue; - } - keyStr.erase(0, CKevaData::ASSOCIATE_PREFIX.length()); - if (!DecodeKevaNamespace(keyStr, Params(), targetNS)) { - continue; + if (isNamespaceGroup(key, targetNS)) { + namespaces.insert(targetNS); } - namespaces.insert(targetNS); } } @@ -763,20 +772,58 @@ UniValue keva_group_show(const JSONRPCRequest& request) } } - // Find the namespace connection initialized by us. + // Find the namespace connection initialized by us, and not confirmed yet. + { + LOCK (mempool.cs); + std::vector> unconfirmedKeyValueList; + mempool.getUnconfirmedKeyValueList(unconfirmedKeyValueList, nameSpace); + std::set nsList; + valtype targetNS; + for (auto entry: unconfirmedKeyValueList) { + const valtype ns = std::get<0>(entry); + if (ns != nameSpace) { + continue; + } + const valtype key = std::get<1>(entry); + // Find the value with the format _g:NamespaceId + if (!isNamespaceGroup(key, targetNS)) { + continue; + } + valtype val; + if (mempool.getUnconfirmedKeyValue(nameSpace, key, val) && val.size() > 0) { + CKevaData nsData; + valtype nsName; + if (pcoinsTip->GetName(targetNS, nsDisplayKey, nsData)) { + nsName = nsData.getValue(); + } + UniValue obj(UniValue::VOBJ); + obj.pushKV("namespaceId", EncodeBase58Check(targetNS)); + obj.pushKV("display_name", ValtypeToString(nsName)); + obj.pushKV("height", -1); + obj.pushKV("initiator", false); + namespaces.push_back(obj); + } + } + } + + // Find the namespace connection initialized by us and confirmed. std::unique_ptr iterKeys(pcoinsTip->IterateKeys(nameSpace)); valtype targetNS; valtype key; while (iterKeys->next(key, data)) { // Find the value with the format _g:NamespaceId - std::string keyStr = ValtypeToString(key); - if (keyStr.rfind(CKevaData::ASSOCIATE_PREFIX, 0) != 0) { + if (!isNamespaceGroup(key, targetNS)) { continue; } - keyStr.erase(0, CKevaData::ASSOCIATE_PREFIX.length()); - if (!DecodeKevaNamespace(keyStr, Params(), targetNS)) { - continue; + + // If it has been removed but not yet confirmed, skip it anyway. + { + LOCK (mempool.cs); + valtype val; + if (mempool.getUnconfirmedKeyValue(nameSpace, key, val) && val.size() == 0) { + continue; + } } const int age = chainActive.Height() - data.getHeight(); @@ -811,7 +858,6 @@ UniValue keva_group_show(const JSONRPCRequest& request) } } - if (stats) { UniValue res(UniValue::VOBJ); res.pushKV("blocks", chainActive.Height());