From adcf111f07dae50b6ae424ab5534f43ed931a524 Mon Sep 17 00:00:00 2001 From: Jianping Wu Date: Wed, 21 Nov 2018 12:48:33 -0800 Subject: [PATCH] Implemented keva_pending. --- src/keva/main.cpp | 26 ++++++++++---- src/keva/main.h | 5 ++- src/txmempool.cpp | 8 +++-- src/txmempool.h | 8 +++-- src/validation.cpp | 2 +- src/wallet/rpckeva.cpp | 77 +++++++++++++++++++++++++++++++++++++--- src/wallet/rpcwallet.cpp | 4 ++- 7 files changed, 111 insertions(+), 19 deletions(-) diff --git a/src/keva/main.cpp b/src/keva/main.cpp index 50a328009..deb2cce39 100644 --- a/src/keva/main.cpp +++ b/src/keva/main.cpp @@ -74,16 +74,30 @@ CKevaMemPool::getUnconfirmedKeyValue(const valtype& nameSpace, const valtype& ke return found; } -bool -CKevaMemPool::getUnconfirmedNamespaces(std::vector>& nameSpaces) const { - bool found = false; +void +CKevaMemPool::getUnconfirmedKeyValueList(std::vector>& keyValueList, const valtype& nameSpace) { + bool matchNamespace = nameSpace.size() > 0; + for (auto entry : listUnconfirmedKeyValues) { + auto txid = std::get<0>(entry); + auto n = std::get<1>(entry); + auto k = std::get<2>(entry); + auto v = std::get<3>(entry); + if (!matchNamespace) { + keyValueList.push_back(std::make_tuple(n, k, v, txid)); + } else if (n == nameSpace) { + keyValueList.push_back(std::make_tuple(n, k, v, txid)); + } + } +} + +void +CKevaMemPool::getUnconfirmedNamespaceList(std::vector>& nameSpaces) const { for (auto entry : listUnconfirmedNamespaces) { + auto txid = std::get<0>(entry); auto ns = std::get<1>(entry); auto displayName = std::get<2>(entry); - nameSpaces.push_back(std::make_tuple(ns, displayName)); - found = true; + nameSpaces.push_back(std::make_tuple(ns, displayName, txid)); } - return found; } void CKevaMemPool::remove(const CTxMemPoolEntry& entry) diff --git a/src/keva/main.h b/src/keva/main.h index 87f2d3c43..fbb42aa57 100644 --- a/src/keva/main.h +++ b/src/keva/main.h @@ -177,11 +177,14 @@ public: bool checkTx (const CTransaction& tx) const; /** Keva get unconfirmed namespaces. */ - bool getUnconfirmedNamespaces(std::vector>& nameSpaces) const; + void getUnconfirmedNamespaceList(std::vector>& nameSpaces) const; /** Keva get unconfirmed key value. */ bool getUnconfirmedKeyValue(const valtype& nameSpace, const valtype& key, valtype& value) const; + /** Keva get list of unconfirmed key value list. */ + void getUnconfirmedKeyValueList(std::vector>& keyValueList, const valtype& nameSpace); + }; /* ************************************************************************** */ diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 5ecddd129..0dbde7ec7 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1087,8 +1087,12 @@ bool CTxMemPool::getUnconfirmedKeyValue(const valtype& nameSpace, const valtype& return kevaMemPool.getUnconfirmedKeyValue(nameSpace, key, value); } -bool CTxMemPool::getUnconfirmedNamespaces(std::vector>& nameSpaces) const { - return kevaMemPool.getUnconfirmedNamespaces(nameSpaces); +void CTxMemPool::getUnconfirmedNamespaceList(std::vector>& nameSpaces) const { + return kevaMemPool.getUnconfirmedNamespaceList(nameSpaces); +} + +void CTxMemPool::getUnconfirmedKeyValueList(std::vector>& keyValueList, const valtype& nameSpace) { + kevaMemPool.getUnconfirmedKeyValueList(keyValueList, nameSpace); } SaltedTxidHasher::SaltedTxidHasher() : k0(GetRand(std::numeric_limits::max())), k1(GetRand(std::numeric_limits::max())) {} diff --git a/src/txmempool.h b/src/txmempool.h index 1805b96b7..96777057d 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -682,8 +682,7 @@ public: * @param tx The tx that should be added. * @return True if it doesn't conflict. */ - inline bool - checkNameOps (const CTransaction& tx) const + inline bool checkKevaOps(const CTransaction& tx) const { AssertLockHeld(cs); return kevaMemPool.checkTx(tx); @@ -693,7 +692,10 @@ public: bool getUnconfirmedKeyValue(const valtype& nameSpace, const valtype& key, valtype& value) const; /** Keva get unconfirmed namespaces. */ - bool getUnconfirmedNamespaces(std::vector>& nameSpaces) const; + void getUnconfirmedNamespaceList(std::vector>& nameSpaces) const; + + /** Keva get list of unconfirmed key value list. */ + void getUnconfirmedKeyValueList(std::vector>& keyValueList, const valtype& nameSpace); CTransactionRef get(const uint256& hash) const; TxMempoolInfo info(const uint256& hash) const; diff --git a/src/validation.cpp b/src/validation.cpp index 9b36ca52e..6d15b4707 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -637,7 +637,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool } } - if (!pool.checkNameOps(tx)) { + if (!pool.checkKevaOps(tx)) { return false; } diff --git a/src/wallet/rpckeva.cpp b/src/wallet/rpckeva.cpp index ae8ab2136..3754d968e 100644 --- a/src/wallet/rpckeva.cpp +++ b/src/wallet/rpckeva.cpp @@ -185,11 +185,10 @@ UniValue keva_list_namespaces(const JSONRPCRequest& request) { LOCK (mempool.cs); // Also get the unconfirmed ones from mempool. - std::vector> unconfirmedNamespaces; - if (mempool.getUnconfirmedNamespaces(unconfirmedNamespaces)) { - for (auto entry : unconfirmedNamespaces) { - res.push_back(EncodeBase58(std::get<0>(entry)) + " : " + ValtypeToString(std::get<1>(entry))); - } + std::vector> unconfirmedNamespaces; + mempool.getUnconfirmedNamespaceList(unconfirmedNamespaces); + for (auto entry : unconfirmedNamespaces) { + res.push_back(EncodeBase58(std::get<0>(entry)) + " : " + ValtypeToString(std::get<1>(entry))); } } @@ -340,3 +339,71 @@ UniValue keva_get(const JSONRPCRequest& request) return ValtypeToString(value); } + +UniValue keva_pending(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size () > 1) + throw std::runtime_error ( + "keva_pending (\"namespace\")\n" + "\nList unconfirmed keva operations in the mempool.\n" + "\nIf a namespace is given, only check for operations on this namespace.\n" + "\nArguments:\n" + "1. \"namespace\" (string, optional) only look for this namespace\n" + "\nResult:\n" + "[\n" + " {\n" + " \"op\": xxxx (string) the operation being performed\n" + " \"name\": xxxx (string) the namespace operated on\n" + " \"value\": xxxx (string) the namespace's new value\n" + " \"txid\": xxxx (string) the txid corresponding to the operation\n" + " \"ismine\": xxxx (boolean) whether the name is owned by the wallet\n" + " },\n" + " ...\n" + "]\n" + + HelpExampleCli ("keva_pending", "") + + HelpExampleCli ("keva_pending", "\"NJdZVkeerpgxqFM2oAzitVU8xsdj7\"") + + HelpExampleRpc ("keva_pending", "") + ); + + ObserveSafeMode (); + + std::string namespaceStr; + valtype nameSpace; + + if (request.params.size() == 1) { + RPCTypeCheckArgument(request.params[0], UniValue::VSTR); + namespaceStr = request.params[0].get_str(); + if (!DecodeBase58(namespaceStr, nameSpace)) { + throw JSONRPCError (RPC_INVALID_PARAMETER, "failed to decode namespace"); + } + } + + LOCK (mempool.cs); + + std::vector> unconfirmedNamespaces; + mempool.getUnconfirmedNamespaceList(unconfirmedNamespaces); + + std::vector> unconfirmedKeyValueList; + mempool.getUnconfirmedKeyValueList(unconfirmedKeyValueList, nameSpace); + + UniValue arr(UniValue::VARR); + + for (auto entry: unconfirmedNamespaces) { + UniValue obj(UniValue::VOBJ); + obj.pushKV("namespace", EncodeBase58(std::get<0>(entry))); + obj.pushKV("display name", ValtypeToString(std::get<1>(entry))); + obj.pushKV("txid", std::get<2>(entry).ToString()); + arr.push_back(obj); + } + + for (auto entry: unconfirmedKeyValueList) { + UniValue obj(UniValue::VOBJ); + obj.pushKV("namespace", EncodeBase58(std::get<0>(entry))); + obj.pushKV("key", ValtypeToString(std::get<1>(entry))); + obj.pushKV("value", ValtypeToString(std::get<2>(entry))); + obj.pushKV("txid", std::get<3>(entry).ToString()); + arr.push_back(obj); + } + + return arr; +} diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 82abc9720..3aa412f02 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3595,6 +3595,7 @@ extern UniValue keva_namespace(const JSONRPCRequest& request); extern UniValue keva_put(const JSONRPCRequest& request); extern UniValue keva_get(const JSONRPCRequest& request); extern UniValue keva_list_namespaces(const JSONRPCRequest& request); +extern UniValue keva_pending(const JSONRPCRequest& request); static const CRPCCommand commands[] = { // category name actor (function) argNames @@ -3657,7 +3658,8 @@ static const CRPCCommand commands[] = { "kevacoin", "keva_namespace", &keva_namespace, {"display_name"} }, { "kevacoin", "keva_list_namespaces", &keva_list_namespaces, {} }, { "kevacoin", "keva_put", &keva_put, {"namespace", "key", "value"} }, - { "kevacoin", "keva_get", &keva_get, {"namespace", "key"} } + { "kevacoin", "keva_get", &keva_get, {"namespace", "key"} }, + { "kevacoin", "keva_pending", &keva_pending, {"namespace"} } }; void RegisterWalletRPCCommands(CRPCTable &t)