From 3c8efc7b84b6a009aa9d89a564247d8edbb37564 Mon Sep 17 00:00:00 2001 From: Jianping Wu Date: Tue, 20 Nov 2018 12:35:37 -0800 Subject: [PATCH] Started working on instant results. --- src/keva/main.cpp | 34 ++++++++++++++++++++++++++++++---- src/keva/main.h | 18 ++++++++++++++++++ src/txmempool.cpp | 8 ++++++++ src/txmempool.h | 16 ++++++++++++++++ src/wallet/rpckeva.cpp | 25 +++++++++++++++++++++++-- src/wallet/rpcwallet.cpp | 2 +- 6 files changed, 96 insertions(+), 7 deletions(-) diff --git a/src/keva/main.cpp b/src/keva/main.cpp index c32b66e10..aff918a92 100644 --- a/src/keva/main.cpp +++ b/src/keva/main.cpp @@ -49,25 +49,51 @@ void CKevaMemPool::addUnchecked (const uint256& hash, const CTxMemPoolEntry& entry) { AssertLockHeld (pool.cs); - if (entry.isNamespaceRegistration()) { const valtype& nameSpace = entry.getNamespace(); assert(mapNamespaceRegs.count(nameSpace) == 0); mapNamespaceRegs.insert(std::make_pair(nameSpace, hash)); + listUnconfirmedNamespaces.push_back(std::make_tuple(hash, nameSpace, entry.getDisplayName())); } if (entry.isNamespaceKeyUpdate ()) { const valtype& nameSpace = entry.getNamespace(); assert(mapNamespaceUpdates.count(nameSpace) == 0); + std::string(nameSpace.begin(), nameSpace.end()).c_str(), std::string(entry.getKey().begin(), entry.getKey().end()).c_str()); mapNamespaceUpdates.insert (std::make_pair(nameSpace, hash)); + listUnconfirmedKeyValues.push_back(std::make_tuple(hash, nameSpace, entry.getKey(), entry.getValue())); } } -void -CKevaMemPool::remove (const CTxMemPoolEntry& entry) +bool +CKevaMemPool::getUnconfirmedKeyValue(const valtype& nameSpace, const valtype& key, valtype& value) const { + bool found = false; + for (auto entry : listUnconfirmedKeyValues) { + auto ns = std::get<1>(entry); + auto k = std::get<2>(entry); + if (ns == nameSpace && key == k) { + value = std::get<3>(entry); + found = true; + } + } + return found; +} + +bool +CKevaMemPool::getUnconfirmedNamespaces(std::vector>& nameSpaces) const { + bool found = false; + for (auto entry : listUnconfirmedNamespaces) { + auto ns = std::get<1>(entry); + auto displayName = std::get<2>(entry); + nameSpaces.push_back(std::make_tuple(ns, displayName)); + found = true; + } + return found; +} + +void CKevaMemPool::remove(const CTxMemPoolEntry& entry) { AssertLockHeld (pool.cs); - if (entry.isNamespaceRegistration()) { const NamespaceTxMap::iterator mit = mapNamespaceRegs.find(entry.getNamespace()); assert (mit != mapNamespaceRegs.end()); diff --git a/src/keva/main.h b/src/keva/main.h index 3e13f6439..23796b596 100644 --- a/src/keva/main.h +++ b/src/keva/main.h @@ -136,6 +136,18 @@ private: */ NamespaceTxMap mapNamespaceUpdates; + /** + * Pending/unconfirmed namespaces. + * Tuple: txid, namespace, display name + */ + std::vector> listUnconfirmedNamespaces; + + /** + * Pending/unconfirmed key-values. + * Tuple: txid, namespace, key, value + */ + std::vector> listUnconfirmedKeyValues; + /** * Validate that the namespace is the hash of the first TxIn. */ @@ -232,6 +244,12 @@ public: */ bool checkTx (const CTransaction& tx) const; + /** Keva get unconfirmed namespaces. */ + bool getUnconfirmedNamespaces(std::vector>& nameSpaces) const; + + /** Keva get unconfirmed key value. */ + bool getUnconfirmedKeyValue(const valtype& nameSpace, const valtype& key, valtype& value) const; + }; /* ************************************************************************** */ diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 888574663..4e971abcb 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1083,4 +1083,12 @@ bool CTxMemPool::TransactionWithinChainLimit(const uint256& txid, size_t chainLi it->GetCountWithDescendants() < chainLimit); } +bool CTxMemPool::getUnconfirmedKeyValue(const valtype& nameSpace, const valtype& key, valtype& value) const { + return kevaMemPool.getUnconfirmedKeyValue(nameSpace, key, value); +} + +bool CTxMemPool::getUnconfirmedNamespaces(std::vector>& nameSpaces) const { + return kevaMemPool.getUnconfirmedNamespaces(nameSpaces); +} + 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 d52e671a7..2423b8e16 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -147,11 +147,21 @@ public: return kevaOp.getOpNamespace(); } + inline const valtype& getDisplayName() const + { + return kevaOp.getOpNamespaceDisplayName(); + } + inline const valtype& getKey() const { return kevaOp.getOpKey(); } + inline const valtype& getValue() const + { + return kevaOp.getOpValue(); + } + mutable size_t vTxHashesIdx; //!< Index in mempool's vTxHashes }; @@ -697,6 +707,12 @@ public: return kevaMemPool.checkTx(tx); } + /** Keva get unconfirmed key values. */ + bool getUnconfirmedKeyValue(const valtype& nameSpace, const valtype& key, valtype& value) const; + + /** Keva get unconfirmed namespaces. */ + bool getUnconfirmedNamespaces(std::vector>& nameSpaces) const; + CTransactionRef get(const uint256& hash) const; TxMempoolInfo info(const uint256& hash) const; std::vector infoAll() const; diff --git a/src/wallet/rpckeva.cpp b/src/wallet/rpckeva.cpp index c5d51b5f1..dc92a7f0e 100644 --- a/src/wallet/rpckeva.cpp +++ b/src/wallet/rpckeva.cpp @@ -182,6 +182,17 @@ UniValue keva_list_namespaces(const JSONRPCRequest& request) res.push_back(item.first + " : " + item.second); } + { + 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))); + } + } + } + return res; } @@ -330,9 +341,19 @@ UniValue keva_get(const JSONRPCRequest& request) { LOCK (cs_main); if (!pcoinsTip->GetName(nameSpace, key, data)) { - throw JSONRPCError (RPC_TRANSACTION_ERROR, "key not found"); + //throw JSONRPCError (RPC_TRANSACTION_ERROR, "key not found"); + } + } + + auto value = data.getValue(); + // Also get the unconfirmed ones. + { + LOCK (mempool.cs); + valtype val; + if (mempool.getUnconfirmedKeyValue(nameSpace, key, val)) { + value = val; } } - return ValtypeToString(data.getValue()); + return ValtypeToString(value); } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index d271efa52..82abc9720 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1203,7 +1203,7 @@ UniValue sendmany(const JSONRPCRequest& request) CAmount nFeeRequired = 0; int nChangePosRet = -1; std::string strFailReason; - std::vector empty; empty; + std::vector empty; bool fCreated = pwallet->CreateTransaction(vecSend, nullptr, empty, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason, coin_control); if (!fCreated) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);