From c1c83ddc1b52be3b0a8c785ea1467094e35610c1 Mon Sep 17 00:00:00 2001 From: Jimmy Kiselak Date: Tue, 27 Oct 2015 16:37:09 -0400 Subject: [PATCH] create an rpc command for getting claims out of a transaction id --- src/ncctrie.cpp | 39 +++++++++++++++- src/ncctrie.h | 4 +- src/rpcncctrie.cpp | 109 +++++++++++++++++++++++++++++++++++++++++++++ src/rpcserver.cpp | 1 + src/rpcserver.h | 1 + 5 files changed, 151 insertions(+), 3 deletions(-) diff --git a/src/ncctrie.cpp b/src/ncctrie.cpp index 1e214ba4a..065c303fc 100644 --- a/src/ncctrie.cpp +++ b/src/ncctrie.cpp @@ -217,6 +217,41 @@ bool CNCCTrie::haveClaim(const std::string& name, const uint256& txhash, uint32_ return current->haveValue(txhash, nOut); } +bool CNCCTrie::haveClaimInQueueRow(const std::string& name, const uint256& txhash, uint32_t nOut, int nHeight, const std::vector& row) const +{ + for (std::vector::const_iterator itRow = row.begin(); itRow != row.end(); ++itRow) + { + if (itRow->name == name && itRow->val.txhash == txhash && itRow->val.nOut == nOut && itRow->val.nHeight == nHeight) + { + return true; + } + } + return false; +} + +bool CNCCTrie::haveClaimInQueue(const std::string& name, const uint256& txhash, uint32_t nOut, int nHeight, int& nValidAtHeight) const +{ + std::vector row; + if (getQueueRow(nHeight, row)) + { + if (haveClaimInQueueRow(name, txhash, nOut, nHeight, row)) + { + nValidAtHeight = nHeight; + return true; + } + } + row.clear(); + if (getQueueRow(nHeight + DEFAULT_DELAY, row)) + { + if (haveClaimInQueueRow(name, txhash, nOut, nHeight, row)) + { + nValidAtHeight = nHeight + DEFAULT_DELAY; + return true; + } + } + return false; +} + unsigned int CNCCTrie::getTotalNamesInTrie() const { if (empty()) @@ -353,9 +388,9 @@ bool CNCCTrie::recursiveCheckConsistency(CNCCTrieNode* node) return calculatedHash == node->hash; } -bool CNCCTrie::getQueueRow(int nHeight, std::vector& row) +bool CNCCTrie::getQueueRow(int nHeight, std::vector& row) const { - valueQueueType::iterator itQueueRow = dirtyQueueRows.find(nHeight); + valueQueueType::const_iterator itQueueRow = dirtyQueueRows.find(nHeight); if (itQueueRow != dirtyQueueRows.end()) { row = itQueueRow->second; diff --git a/src/ncctrie.h b/src/ncctrie.h index 96becc0df..b7f8ab468 100644 --- a/src/ncctrie.h +++ b/src/ncctrie.h @@ -162,9 +162,11 @@ public: bool queueEmpty() const; bool expirationQueueEmpty() const; void setExpirationTime(int t); - bool getQueueRow(int nHeight, std::vector& row); + bool getQueueRow(int nHeight, std::vector& row) const; bool getExpirationQueueRow(int nHeight, std::vector& row); bool haveClaim(const std::string& name, const uint256& txhash, uint32_t nOut) const; + bool haveClaimInQueue(const std::string& name, const uint256& txhash, uint32_t nOut, int nHeight, int& nValidAtHeight) const; + bool haveClaimInQueueRow(const std::string& name, const uint256& txhash, uint32_t nOut, int nHeight, const std::vector& row) const; unsigned int getTotalNamesInTrie() const; unsigned int getTotalClaimsInTrie() const; CAmount getTotalValueOfClaimsInTrie(bool fControllingOnly) const; diff --git a/src/rpcncctrie.cpp b/src/rpcncctrie.cpp index aca63dccd..06bc40b3c 100644 --- a/src/rpcncctrie.cpp +++ b/src/rpcncctrie.cpp @@ -160,3 +160,112 @@ UniValue gettotalvalueofclaims(const UniValue& params, bool fHelp) return ValueFromAmount(total_amount); } +UniValue getclaimsfortx(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw std::runtime_error( + "getclaimsfortx\n" + "Return any claims or supports found in a transaction\n" + "Arguments:\n" + "1. \"txid\" (string) the txid of the transaction to check for unspent claims\n" + "Result:\n" + "[\n" + " {\n" + " \"nOut\" (numeric) the index of the claim in the transaction's list out outputs\n" + " \"name\" (string) the name claimed\n" + " \"value\" (string) the value of the claim\n" + " \"depth\" (numeric) the depth of the transaction in the main chain\n" + " \"in claim trie\" (boolean) whether the claim has made it into the trie\n" + " \"is controlling\" (boolean) whether the claim is the current controlling claim for the name\n" + " \"in queue\" (boolean) whether the claim is in a queue waiting to be inserted into the trie\n" + " \"blocks to valid\" (numeric) if in a queue, the number of blocks until it's inserted into the trie\n" + " }\n" + "]\n" + ); + + LOCK(cs_main); + + uint256 hash; + hash.SetHex(params[0].get_str()); + + UniValue ret(UniValue::VARR); + + int op; + std::vector > vvchParams; + + CCoinsViewCache view(pcoinsTip); + const CCoins* coin = view.AccessCoins(hash); + std::vector txouts; + int nHeight = 0; + if (!coin) + { + CTransaction tx; + if (!mempool.lookup(hash, tx)) + { + return NullUniValue; + } + else + { + txouts = tx.vout; + } + } + else + { + txouts = coin->vout; + nHeight = coin->nHeight; + } + + for (unsigned int i = 0; i < txouts.size(); ++i) + { + if (!txouts[i].IsNull()) + { + vvchParams.clear(); + const CTxOut& txout = txouts[i]; + UniValue o(UniValue::VOBJ); + if (DecodeNCCScript(txout.scriptPubKey, op, vvchParams)) + { + o.push_back(Pair("nOut", (int64_t)i)); + std::string sName(vvchParams[0].begin(), vvchParams[0].end()); + o.push_back(Pair("name", sName)); + std::string sValue(vvchParams[1].begin(), vvchParams[1].end()); + o.push_back(Pair("value", sValue)); + if (nHeight > 0) + { + o.push_back(Pair("depth", chainActive.Height() - nHeight)); + bool inClaimTrie = pnccTrie->haveClaim(sName, hash, i); + o.push_back(Pair("in claim trie", inClaimTrie)); + if (inClaimTrie) + { + CNodeValue val; + if (!pnccTrie->getInfoForName(sName, val)) + { + LogPrintf("HaveClaim was true but getInfoForName returned false."); + } + o.push_back(Pair("is controlling", (val.txhash == hash && val.nOut == i))); + } + else + { + int nValidAtHeight; + if (pnccTrie->haveClaimInQueue(sName, hash, i, coin->nHeight, nValidAtHeight)) + { + o.push_back(Pair("in queue", true)); + o.push_back(Pair("blocks to valid", nValidAtHeight - chainActive.Height())); + } + else + { + o.push_back(Pair("in queue", false)); + } + } + } + else + { + o.push_back(Pair("depth", 0)); + o.push_back(Pair("in claim trie", false)); + o.push_back(Pair("in queue", false)); + } + ret.push_back(o); + } + } + } + return ret; +} diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index b427adfae..1d68c2898 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -385,6 +385,7 @@ static const CRPCCommand vRPCCommands[] = { "nametrie", "gettotalclaimednames", &gettotalclaimednames, true }, { "nametrie", "gettotalclaims", &gettotalclaims, true }, { "nametrie", "gettotalvalueofclaims", &gettotalvalueofclaims, true }, + { "nametrie", "getclaimsfortx", &getclaimsfortx, true }, }; CRPCTable::CRPCTable() diff --git a/src/rpcserver.h b/src/rpcserver.h index 9fd6c550f..bfd366f55 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -246,6 +246,7 @@ extern UniValue getvalueforname(const UniValue& params, bool fHelp); extern UniValue gettotalclaimednames(const UniValue& params, bool fHelp); extern UniValue gettotalclaims(const UniValue& params, bool fHelp); extern UniValue gettotalvalueofclaims(const UniValue& params, bool fHelp); +extern UniValue getclaimsfortx(const UniValue& params, bool fHelp); // in rest.cpp extern bool HTTPReq_REST(AcceptedConnection *conn,