From 49c7c3ef252281533f8a3f4357aad75a8ab6d50c Mon Sep 17 00:00:00 2001 From: Jimmy Kiselak Date: Fri, 10 Apr 2015 16:50:50 -0400 Subject: [PATCH] fix bug due to unitialized var in CTxInUndo, and create rpc calls for getting some statistics about the ncc trie --- src/ncctrie.cpp | 62 +++++++++++++++++++++++++++++++++ src/ncctrie.h | 6 ++++ src/rpcclient.cpp | 1 + src/rpcncctrie.cpp | 75 ++++++++++++++++++++++++++++++++++++++++ src/rpcserver.cpp | 3 ++ src/rpcserver.h | 3 ++ src/undo.h | 2 +- src/wallet/rpcwallet.cpp | 8 +++++ 8 files changed, 159 insertions(+), 1 deletion(-) diff --git a/src/ncctrie.cpp b/src/ncctrie.cpp index d407522db..cf42bfa28 100644 --- a/src/ncctrie.cpp +++ b/src/ncctrie.cpp @@ -153,6 +153,68 @@ bool CNCCTrie::haveClaim(const std::string& name, const uint256& txhash, uint32_ return current->haveValue(txhash, nOut); } +unsigned int CNCCTrie::getTotalNamesInTrie() const +{ + if (empty()) + return 0; + const CNCCTrieNode* current = &root; + return getTotalNamesRecursive(current); +} + +unsigned int CNCCTrie::getTotalNamesRecursive(const CNCCTrieNode* current) const +{ + unsigned int names_in_subtrie = 0; + if (!(current->values.empty())) + names_in_subtrie += 1; + for (nodeMapType::const_iterator it = current->children.begin(); it != current->children.end(); ++it) + { + names_in_subtrie += getTotalNamesRecursive(it->second); + } + return names_in_subtrie; +} + +unsigned int CNCCTrie::getTotalClaimsInTrie() const +{ + if (empty()) + return 0; + const CNCCTrieNode* current = &root; + return getTotalClaimsRecursive(current); +} + +unsigned int CNCCTrie::getTotalClaimsRecursive(const CNCCTrieNode* current) const +{ + unsigned int claims_in_subtrie = current->values.size(); + for (nodeMapType::const_iterator it = current->children.begin(); it != current->children.end(); ++it) + { + claims_in_subtrie += getTotalClaimsRecursive(it->second); + } + return claims_in_subtrie; +} + +CAmount CNCCTrie::getTotalValueOfClaimsInTrie(bool fControllingOnly) const +{ + if (empty()) + return 0; + const CNCCTrieNode* current = &root; + return getTotalValueOfClaimsRecursive(current, fControllingOnly); +} + +CAmount CNCCTrie::getTotalValueOfClaimsRecursive(const CNCCTrieNode* current, bool fControllingOnly) const +{ + CAmount value_in_subtrie = 0; + for (std::vector::const_iterator itval = current->values.begin(); itval != current->values.end(); ++itval) + { + value_in_subtrie += itval->nAmount; + if (fControllingOnly) + break; + } + for (nodeMapType::const_iterator itchild = current->children.begin(); itchild != current->children.end(); ++itchild) + { + value_in_subtrie += getTotalValueOfClaimsRecursive(itchild->second, fControllingOnly); + } + return value_in_subtrie; +} + bool CNCCTrie::recursiveDumpToJSON(const std::string& name, const CNCCTrieNode* current, json_spirit::Array& ret) const { using namespace json_spirit; diff --git a/src/ncctrie.h b/src/ncctrie.h index 936d22d75..41c82ebc8 100644 --- a/src/ncctrie.h +++ b/src/ncctrie.h @@ -160,6 +160,9 @@ public: int nCurrentHeight; bool queueEmpty() const; bool haveClaim(const std::string& name, const uint256& txhash, uint32_t nOut) const; + unsigned int getTotalNamesInTrie() const; + unsigned int getTotalClaimsInTrie() const; + CAmount getTotalValueOfClaimsInTrie(bool fControllingOnly) const; friend class CNCCTrieCache; private: void clear(CNCCTrieNode* current); @@ -169,6 +172,9 @@ private: bool recursiveNullify(CNCCTrieNode* node, std::string& name); bool recursiveCheckConsistency(CNCCTrieNode* node); bool InsertFromDisk(const std::string& name, CNCCTrieNode* node); + unsigned int getTotalNamesRecursive(const CNCCTrieNode* current) const; + unsigned int getTotalClaimsRecursive(const CNCCTrieNode* current) const; + CAmount getTotalValueOfClaimsRecursive(const CNCCTrieNode* current, bool fControllingOnly) const; bool recursiveDumpToJSON(const std::string& name, const CNCCTrieNode* current, json_spirit::Array& ret) const; CNCCTrieNode root; uint256 hashBlock; diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 975ba39e2..8f48c410b 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -95,6 +95,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "abandonname", 2}, { "listnameclaims", 0}, { "listnameclaims", 1}, + { "gettotalvalueofclaims", 0}, }; class CRPCConvertTable diff --git a/src/rpcncctrie.cpp b/src/rpcncctrie.cpp index a8fa1083f..947be9f36 100644 --- a/src/rpcncctrie.cpp +++ b/src/rpcncctrie.cpp @@ -105,3 +105,78 @@ Value getvalueforname(const Array& params, bool fHelp) return ret; } +Value gettotalclaimednames(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw std::runtime_error( + "gettotalclaimednames\n" + "Return the total number of names that have been\n" + "successfully claimed, and therefore exist in the trie\n" + "Arguments:\n" + "Result:\n" + "\"total names\" (numeric) the total number of\n" + " names in the trie\n" + ); + LOCK(cs_main); + Object ret; + if (!pnccTrie) + { + ret.push_back(Pair("total names", -1)); + return ret; + } + unsigned int num_names = pnccTrie->getTotalNamesInTrie(); + ret.push_back(Pair("total names", (int)num_names)); + return ret; +} + +Value gettotalclaims(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw std::runtime_error( + "gettotalclaims\n" + "Return the total number of active claims in the trie\n" + "Arguments:\n" + "Result:\n" + "\"total claims\" (numeric) the total number\n" + " of active claims\n" + ); + LOCK(cs_main); + Object ret; + if (!pnccTrie) + { + ret.push_back(Pair("total claims", -1)); + return ret; + } + unsigned int num_claims = pnccTrie->getTotalClaimsInTrie(); + ret.push_back(Pair("total claims", (int)num_claims)); + return ret; +} + +Value gettotalvalueofclaims(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw std::runtime_error( + "gettotalvalueofclaims\n" + "Return the total value of the claims in the trie\n" + "Arguments:\n" + "1. \"controlling_only\" (boolean) only include the value\n" + " of controlling claims\n" + "Result:\n" + "\"total value\" (numeric) the total value of the\n" + " claims in the trie\n" + ); + LOCK(cs_main); + Object ret; + if (!pnccTrie) + { + ret.push_back(Pair("total value", -1)); + return ret; + } + bool controlling_only = false; + if (params.size() == 1) + controlling_only = params[0].get_bool(); + CAmount total_amount = pnccTrie->getTotalValueOfClaimsInTrie(controlling_only); + ret.push_back(Pair("total value", total_amount)); + return ret; +} + diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index d6b092e9d..72e243aff 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -388,6 +388,9 @@ static const CRPCCommand vRPCCommands[] = { "ncctrie", "getncctrie", &getncctrie, true, false}, { "ncctrie", "gettxinfoforname", &gettxinfoforname, true, false}, { "ncctrie", "getvalueforname", &getvalueforname, true, false}, + { "ncctrie", "gettotalclaimednames", &gettotalclaimednames, true, false}, + { "ncctrie", "gettotalclaims", &gettotalclaims, true, false}, + { "ncctrie", "gettotalvalueofclaims", &gettotalvalueofclaims, true, false}, }; CRPCTable::CRPCTable() diff --git a/src/rpcserver.h b/src/rpcserver.h index 8aacf8568..c012e63cd 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -241,6 +241,9 @@ extern json_spirit::Value reconsiderblock(const json_spirit::Array& params, bool extern json_spirit::Value getncctrie(const json_spirit::Array& params, bool fHelp); // in rpcncctrie.cpp extern json_spirit::Value gettxinfoforname(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getvalueforname(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value gettotalclaimednames(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value gettotalclaims(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value gettotalvalueofclaims(const json_spirit::Array& params, bool fHelp); // in rest.cpp extern bool HTTPReq_REST(AcceptedConnection *conn, diff --git a/src/undo.h b/src/undo.h index 18d620f68..c8324537d 100644 --- a/src/undo.h +++ b/src/undo.h @@ -28,7 +28,7 @@ public: unsigned int nNCCValidHeight; // If the outpoint was an NCC claim, the height at which the claim should be inserted into the trie CTxInUndo() : txout(), fLastUnspent(false), fCoinBase(false), nHeight(0), nVersion(0), nNCCValidHeight(0) {} - CTxInUndo(const CTxOut &txoutIn, bool fCoinBaseIn = false, unsigned int nHeightIn = 0, int nVersionIn = 0, unsigned int nNCCValidHeight = 0) : txout(txoutIn), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), nVersion(nVersionIn), nNCCValidHeight(nNCCValidHeight) { } + CTxInUndo(const CTxOut &txoutIn, bool fLastUnspent = false, bool fCoinBaseIn = false, unsigned int nHeightIn = 0, int nVersionIn = 0, unsigned int nNCCValidHeight = 0) : txout(txoutIn), fLastUnspent(fLastUnspent), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), nVersion(nVersionIn), nNCCValidHeight(nNCCValidHeight) { } unsigned int GetSerializeSize(int nType, int nVersion) const { return ::GetSerializeSize(VARINT(nHeight*4+(fCoinBase ? 2 : 0)+(fLastUnspent ? 1: 0)), nType, nVersion) + diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f5ef34107..c6221e818 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -630,6 +630,13 @@ void ListNameClaims(const CWalletTx& wtx, const string& strAccount, int nMinDept entry.push_back(Pair("amount", ValueFromAmount(s.amount))); entry.push_back(Pair("vout", s.vout)); entry.push_back(Pair("fee", ValueFromAmount(nFee))); + BlockMap::iterator it = mapBlockIndex.find(wtx.hashBlock); + if (it != mapBlockIndex.end()) + { + CBlockIndex* pindex = it->second; + if (pindex) + entry.push_back(Pair("height", pindex->nHeight)); + } entry.push_back(Pair("confirmations", wtx.GetDepthInMainChain())); entry.push_back(Pair("is spent", pwalletMain->IsSpent(wtx.GetHash(), s.vout))); entry.push_back(Pair("is in ncc trie", pnccTrie->haveClaim(sName, wtx.GetHash(), s.vout))); @@ -662,6 +669,7 @@ Value listnameclaims(const Array& params, bool fHelp) " \"amount\": x.xxx, (numeric) The amount in btc.\n" " \"vout\": n, (numeric) The vout value\n" " \"fee\": x.xxx, (numeric) The amount of the fee in btc.\n" + " \"height\": n (numeric) The height of the block in which this transaction was included.\n" " \"confirmations\": n, (numeric) The number of confirmations for the transaction\n" " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction.\n" " \"blockindex\": n, (numeric) The block index containing the transaction.\n"