From 97be43ccc0833b9b724580eb19ddf32556db7188 Mon Sep 17 00:00:00 2001 From: Just Wonder Date: Mon, 22 Jun 2020 22:29:37 -0700 Subject: [PATCH] Handled namespace join even before confirmation. --- src/rpc/rpckeva_nonwallet.cpp | 37 +++++++++++++++++++++++++++++++++ test/functional/feature_keva.py | 32 +++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/rpc/rpckeva_nonwallet.cpp b/src/rpc/rpckeva_nonwallet.cpp index 522b4ac92..66ad434fb 100644 --- a/src/rpc/rpckeva_nonwallet.cpp +++ b/src/rpc/rpckeva_nonwallet.cpp @@ -168,6 +168,34 @@ void getNamespaceGroup(const valtype& nameSpace, std::set& namespaces, return; } + // 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; + } + if (nsList.find(targetNS) != nsList.end()) { + continue; + } + valtype val; + if (mempool.getUnconfirmedKeyValue(nameSpace, key, val) && val.size() > 0) { + namespaces.insert(targetNS); + nsList.insert(targetNS); + } + } + } + // Find the namespace connection initialized by us. std::unique_ptr iterKeys(pcoinsTip->IterateKeys(nameSpace)); valtype key; @@ -175,9 +203,18 @@ void getNamespaceGroup(const valtype& nameSpace, std::set& namespaces, valtype targetNS; // Find the value with the format _g:NamespaceId if (isNamespaceGroup(key, targetNS)) { + // 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; + } + } namespaces.insert(targetNS); } } + } UniValue keva_group_get(const JSONRPCRequest& request) diff --git a/test/functional/feature_keva.py b/test/functional/feature_keva.py index a33f14976..5cc4ddc1e 100755 --- a/test/functional/feature_keva.py +++ b/test/functional/feature_keva.py @@ -177,12 +177,42 @@ class KevaTest(BitcoinTestFramework): response = self.nodes[1].keva_namespace("Daisy") daisyNamespace = response['namespaceId'] + self.nodes[1].keva_put(daisyNamespace, "keyDaisy", "valueDaisy") self.sync_generate() self.nodes[0].keva_group_join(aliceNamespace, daisyNamespace) - self.sync_generate() + # Daisy namespace should show up even the joining is not confirmed. + response = self.nodes[0].keva_group_show(aliceNamespace) + assert(len(response) == 2) + # Key-value in Daisy's namespace should show up even the joining is not confirmed. + response = self.nodes[0].keva_group_filter(aliceNamespace) + assert(len(response) == 4) + found = False + for e in response: + if e.get("key") == "keyDaisy" and e.get("value") == "valueDaisy": + found = True + assert(found) + self.sync_generate() + # After confirmation, should have the same result as pre-confirmation. response = self.nodes[0].keva_group_show(aliceNamespace) assert(len(response) == 2) + response = self.nodes[0].keva_group_filter(aliceNamespace) + # After confirmation, the _g:N... is also in the result. So total is 5. + assert(len(response) == 5) + found = False + for e in response: + if e.get("key") == "keyDaisy" and e.get("value") == "valueDaisy": + found = True + assert(found) + + # Remove Diasy namespace. Its key-value pairs should not show up. + self.nodes[0].keva_group_leave(aliceNamespace, daisyNamespace) + response = self.nodes[0].keva_group_filter(aliceNamespace) + found = False + for e in response: + if e.get("key") == "keyDaisy" and e.get("value") == "valueDaisy": + found = True + assert(not found) tip = self.nodes[0].getbestblockhash() self.nodes[0].invalidateblock(tip)