From 155b6818b8dd354310589c6fc556f308a11d2f31 Mon Sep 17 00:00:00 2001
From: Anthony Fieroni <bvbfan@abv.bg>
Date: Thu, 8 Aug 2019 16:39:57 +0300
Subject: [PATCH] Unify claimtrie rpc methods

Signed-off-by: Anthony Fieroni <bvbfan@abv.bg>
---
 src/claimtrie.cpp                     |  53 ++--
 src/claimtrie.h                       |  90 +++++--
 src/claimtrieforks.cpp                |  11 +-
 src/rpc/claimtrie.cpp                 | 359 +++++++++++++-------------
 src/test/claimtriebranching_tests.cpp | 142 +++++-----
 src/test/claimtriecache_tests.cpp     |  18 +-
 6 files changed, 348 insertions(+), 325 deletions(-)

diff --git a/src/claimtrie.cpp b/src/claimtrie.cpp
index 4c977e7ba..9963b3731 100644
--- a/src/claimtrie.cpp
+++ b/src/claimtrie.cpp
@@ -391,7 +391,7 @@ bool CClaimTrieCacheBase::getInfoForName(const std::string& name, CClaimValue& c
     return base->find(name, claims) && claims.getBestClaim(claim);
 }
 
-CClaimsForNameType CClaimTrieCacheBase::getClaimsForName(const std::string& name) const
+CClaimSupportToName CClaimTrieCacheBase::getClaimsForName(const std::string& name) const
 {
     claimEntryType claims;
     int nLastTakeoverHeight = 0;
@@ -406,30 +406,24 @@ CClaimsForNameType CClaimTrieCacheBase::getClaimsForName(const std::string& name
         claims = data.claims;
         nLastTakeoverHeight = data.nHeightOfLastTakeover;
     }
-    return {std::move(claims), std::move(supports), nLastTakeoverHeight, name};
-}
-
-CAmount CClaimTrieCacheBase::getEffectiveAmountForClaim(const std::string& name, const uint160& claimId, std::vector<CSupportValue>* supports) const
-{
-    return getEffectiveAmountForClaim(getClaimsForName(name), claimId, supports);
-}
-
-CAmount CClaimTrieCacheBase::getEffectiveAmountForClaim(const CClaimsForNameType& claims, const uint160& claimId, std::vector<CSupportValue>* supports) const
-{
-    CAmount effectiveAmount = 0;
-    for (const auto& claim : claims.claims) {
-        if (claim.claimId == claimId && claim.nValidAtHeight < nNextHeight) {
-            effectiveAmount += claim.nAmount;
-            for (const auto& support : claims.supports) {
-                if (support.supportedClaimId == claimId && support.nValidAtHeight < nNextHeight) {
-                    effectiveAmount += support.nAmount;
-                    if (supports) supports->push_back(support);
-                }
-            }
-            break;
+    auto find = [&supports](decltype(supports)::iterator& it, const CClaimValue& claim) {
+        it = std::find_if(it, supports.end(), [&claim](const CSupportValue& support) {
+            return claim.claimId == support.supportedClaimId;
+        });
+        return it != supports.end();
+    };
+    // match support to claim
+    std::vector<CClaimNsupports> claimsNsupports;
+    for (const auto& claim : claims) {
+        CAmount nAmount = claim.nValidAtHeight < nNextHeight ? claim.nAmount : 0;
+        auto ic = claimsNsupports.emplace(claimsNsupports.end(), claim, nAmount);
+        for (auto it = supports.begin(); find(it, claim); it = supports.erase(it)) {
+            if (it->nValidAtHeight < nNextHeight)
+                ic->effectiveAmount += it->nAmount;
+            ic->supports.emplace_back(std::move(*it));
         }
     }
-    return effectiveAmount;
+    return {name, nLastTakeoverHeight, std::move(claimsNsupports), std::move(supports)};
 }
 
 void completeHash(uint256& partialHash, const std::string& key, std::size_t to)
@@ -532,19 +526,6 @@ bool CClaimTrie::find(const std::string& key, CClaimTrieData &data) const {
     return db->Read(std::make_pair(TRIE_NODE_CLAIMS, key), data);
 }
 
-bool CClaimTrieCacheBase::getClaimById(const uint160& claimId, std::string& name, CClaimValue& claim) const
-{
-    CClaimIndexElement element;
-    if (!base->db->Read(std::make_pair(CLAIM_BY_ID, claimId), element))
-        return false;
-    if (element.claim.claimId == claimId) {
-        name = element.name;
-        claim = element.claim;
-        return true;
-    }
-    return false;
-}
-
 template <typename K, typename T>
 void BatchWrite(CDBBatch& batch, uint8_t dbkey, const K& key, const std::vector<T>& value)
 {
diff --git a/src/claimtrie.h b/src/claimtrie.h
index 6e360fc64..532582cd5 100644
--- a/src/claimtrie.h
+++ b/src/claimtrie.h
@@ -36,10 +36,10 @@ struct CClaimValue
 {
     COutPoint outPoint;
     uint160 claimId;
-    CAmount nAmount;
-    CAmount nEffectiveAmount;
-    int nHeight;
-    int nValidAtHeight;
+    CAmount nAmount = 0;
+    CAmount nEffectiveAmount = 0;
+    int nHeight = 0;
+    int nValidAtHeight = 0;
 
     CClaimValue() = default;
 
@@ -94,9 +94,9 @@ struct CSupportValue
 {
     COutPoint outPoint;
     uint160 supportedClaimId;
-    CAmount nAmount;
-    int nHeight;
-    int nValidAtHeight;
+    CAmount nAmount = 0;
+    int nHeight = 0;
+    int nValidAtHeight = 0;
 
     CSupportValue() = default;
 
@@ -213,7 +213,7 @@ struct CClaimTrieDataNode {
 struct COutPointHeightType
 {
     COutPoint outPoint;
-    int nHeight;
+    int nHeight = 0;
 
     COutPointHeightType() = default;
 
@@ -236,7 +236,7 @@ struct CNameOutPointHeightType
 {
     std::string name;
     COutPoint outPoint;
-    int nHeight;
+    int nHeight = 0;
 
     CNameOutPointHeightType() = default;
 
@@ -305,22 +305,59 @@ struct CClaimIndexElement
     CClaimValue claim;
 };
 
-struct CClaimsForNameType
+struct CClaimNsupports
 {
-    claimEntryType claims;
-    supportEntryType supports;
-    int nLastTakeoverHeight;
-    std::string name;
+    CClaimNsupports() = default;
+    CClaimNsupports(CClaimNsupports&&) = default;
+    CClaimNsupports(const CClaimNsupports&) = default;
 
-    CClaimsForNameType(claimEntryType claims, supportEntryType supports, int nLastTakeoverHeight, std::string name)
-        : claims(std::move(claims)), supports(std::move(supports)), nLastTakeoverHeight(nLastTakeoverHeight), name(std::move(name))
+    CClaimNsupports& operator=(CClaimNsupports&&) = default;
+    CClaimNsupports& operator=(const CClaimNsupports&) = default;
+
+    CClaimNsupports(const CClaimValue& claim, CAmount effectiveAmount, const std::vector<CSupportValue>& supports = {})
+        : claim(claim), effectiveAmount(effectiveAmount), supports(supports)
     {
     }
 
-    CClaimsForNameType(CClaimsForNameType&&) = default;
-    CClaimsForNameType(const CClaimsForNameType&) = default;
-    CClaimsForNameType& operator=(CClaimsForNameType&&) = default;
-    CClaimsForNameType& operator=(const CClaimsForNameType&) = default;
+    bool IsNull() const
+    {
+        return claim.claimId.IsNull();
+    }
+
+    CClaimValue claim;
+    CAmount effectiveAmount = 0;
+    std::vector<CSupportValue> supports;
+};
+
+static const CClaimNsupports invalid;
+
+struct CClaimSupportToName
+{
+    CClaimSupportToName(const std::string& name, int nLastTakeoverHeight, std::vector<CClaimNsupports> claimsNsupports, std::vector<CSupportValue> unmatchedSupports)
+        : name(name), nLastTakeoverHeight(nLastTakeoverHeight), claimsNsupports(std::move(claimsNsupports)), unmatchedSupports(std::move(unmatchedSupports))
+    {
+    }
+
+    const CClaimNsupports& find(const uint160& claimId) const
+    {
+        auto it = std::find_if(claimsNsupports.begin(), claimsNsupports.end(), [&claimId](const CClaimNsupports& value) {
+            return claimId == value.claim.claimId;
+        });
+        return it != claimsNsupports.end() ? *it : invalid;
+    }
+
+    const CClaimNsupports& find(const std::string& partialId) const
+    {
+        auto it = std::find_if(claimsNsupports.begin(), claimsNsupports.end(), [&partialId](const CClaimNsupports& value) {
+            return value.claim.claimId.GetHex().find(partialId) == 0;
+        });
+        return it != claimsNsupports.end() ? *it : invalid;
+    }
+
+    const std::string name;
+    const int nLastTakeoverHeight;
+    const std::vector<CClaimNsupports> claimsNsupports;
+    const std::vector<CSupportValue> unmatchedSupports;
 };
 
 class CClaimTrie
@@ -341,6 +378,8 @@ public:
     friend struct ClaimTrieChainFixture;
     friend class CClaimTrieCacheExpirationFork;
     friend class CClaimTrieCacheNormalizationFork;
+    friend bool getClaimById(const uint160&, std::string&, CClaimValue*);
+    friend bool getClaimById(const std::string&, std::string&, CClaimValue*);
 
     std::size_t getTotalNamesInTrie() const;
     std::size_t getTotalClaimsInTrie() const;
@@ -475,8 +514,6 @@ public:
 
     uint256 getMerkleHash();
 
-    bool getClaimById(const uint160& claimId, std::string& name, CClaimValue& claim) const;
-
     bool flush();
     bool empty() const;
     bool ReadFromDisk(const CBlockIndex* tip);
@@ -517,10 +554,7 @@ public:
 
     virtual bool finalizeDecrement(std::vector<std::pair<std::string, int>>& takeoverHeightUndo);
 
-    virtual CClaimsForNameType getClaimsForName(const std::string& name) const;
-
-    CAmount getEffectiveAmountForClaim(const std::string& name, const uint160& claimId, std::vector<CSupportValue>* supports = nullptr) const;
-    CAmount getEffectiveAmountForClaim(const CClaimsForNameType& claims, const uint160& claimId, std::vector<CSupportValue>* supports = nullptr) const;
+    virtual CClaimSupportToName getClaimsForName(const std::string& name) const;
 
     CClaimPrefixTrie::const_iterator begin() const;
     CClaimPrefixTrie::const_iterator end() const;
@@ -704,7 +738,7 @@ public:
 
     bool getProofForName(const std::string& name, CClaimTrieProof& proof) override;
     bool getInfoForName(const std::string& name, CClaimValue& claim) const override;
-    CClaimsForNameType getClaimsForName(const std::string& name) const override;
+    CClaimSupportToName getClaimsForName(const std::string& name) const override;
     std::string adjustNameForValidHeight(const std::string& name, int validHeight) const override;
 
 protected:
@@ -733,7 +767,7 @@ public:
     explicit CClaimTrieCacheHashFork(CClaimTrie* base);
 
     bool getProofForName(const std::string& name, CClaimTrieProof& proof) override;
-    bool getProofForName(const std::string& name, CClaimTrieProof& proof, const uint160& claimId);
+    bool getProofForName(const std::string& name, CClaimTrieProof& proof, const std::function<bool(const CClaimValue&)>& comp);
     void initializeIncrement() override;
     bool finalizeDecrement(std::vector<std::pair<std::string, int>>& takeoverHeightUndo) override;
 
diff --git a/src/claimtrieforks.cpp b/src/claimtrieforks.cpp
index 4c79a885a..def94092f 100644
--- a/src/claimtrieforks.cpp
+++ b/src/claimtrieforks.cpp
@@ -246,7 +246,7 @@ bool CClaimTrieCacheNormalizationFork::getInfoForName(const std::string& name, C
     return CClaimTrieCacheExpirationFork::getInfoForName(normalizeClaimName(name), claim);
 }
 
-CClaimsForNameType CClaimTrieCacheNormalizationFork::getClaimsForName(const std::string& name) const
+CClaimSupportToName CClaimTrieCacheNormalizationFork::getClaimsForName(const std::string& name) const
 {
     return CClaimTrieCacheExpirationFork::getClaimsForName(normalizeClaimName(name));
 }
@@ -408,10 +408,10 @@ std::vector<uint256> ComputeMerklePath(const std::vector<uint256>& hashes, uint3
 
 bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, CClaimTrieProof& proof)
 {
-    return getProofForName(name, proof, uint160());
+    return getProofForName(name, proof, nullptr);
 }
 
-bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, CClaimTrieProof& proof, const uint160& claimId)
+bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, CClaimTrieProof& proof, const std::function<bool(const CClaimValue&)>& comp)
 {
     if (nNextHeight < Params().GetConsensus().nAllClaimsInMerkleForkHeight)
         return CClaimTrieCacheNormalizationFork::getProofForName(name, proof);
@@ -445,10 +445,7 @@ bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, CClaimTri
         if (it.key() == name) {
             uint32_t nClaimIndex = 0;
             auto& claims = it->claims;
-            auto itClaim = claimId.IsNull() ? claims.begin() :
-                std::find_if(claims.begin(), claims.end(), [&claimId](const CClaimValue& claim) {
-                    return claim.claimId == claimId;
-                });
+            auto itClaim = !comp ? claims.begin() : std::find_if(claims.begin(), claims.end(), comp);
             if (itClaim != claims.end()) {
                 proof.hasValue = true;
                 proof.outPoint = itClaim->outPoint;
diff --git a/src/rpc/claimtrie.cpp b/src/rpc/claimtrie.cpp
index defb31bb9..479c192ae 100644
--- a/src/rpc/claimtrie.cpp
+++ b/src/rpc/claimtrie.cpp
@@ -15,21 +15,19 @@
 #include <boost/thread.hpp>
 #include <cmath>
 
-uint160 ParseClaimtrieId(const UniValue& v, const std::string& strName)
+void ParseClaimtrieId(const UniValue& v, std::string& partialId, uint160& claimId, const std::string& strName)
 {
     static constexpr size_t claimIdHexLength = 40;
 
     std::string strHex;
     if (v.isStr())
         strHex = v.get_str();
-    if (!IsHex(strHex)) // Note: IsHex("") is false
-        throw JSONRPCError(RPC_INVALID_PARAMETER, strName + " must be a 20-character hexadecimal string (not '" + strHex + "')");
-    if (strHex.length() != claimIdHexLength)
-        throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d)", strName, claimIdHexLength, strHex.length()));
-
-    uint160 result;
-    result.SetHex(strHex);
-    return result;
+    if (!IsHex(strHex))
+        throw JSONRPCError(RPC_INVALID_PARAMETER, strName + " must be a hexadecimal string");
+    if (strHex.length() == claimIdHexLength)
+        claimId.SetHex(strHex);
+    else
+        partialId = strHex;
 }
 
 static CBlockIndex* BlockHashIndex(const uint256& blockHash)
@@ -107,29 +105,128 @@ static bool getValueForOutPoint(const CCoinsViewCache& coinsCache, const COutPoi
 {
     const Coin& coin = coinsCache.AccessCoin(out);
     if (coin.IsSpent())
-    {
         return false;
-    }
 
     int op;
     std::vector<std::vector<unsigned char> > vvchParams;
     if (!DecodeClaimScript(coin.out.scriptPubKey, op, vvchParams))
-    {
         return false;
-    }
+
     if (op == OP_CLAIM_NAME)
-    {
         sValue = HexStr(vvchParams[1].begin(), vvchParams[1].end());
-        return true;
-    }
-    if (vvchParams.size() > 2) // both UPDATE and SUPPORT
-    {
+    else if (vvchParams.size() > 2) // both UPDATE and SUPPORT
         sValue = HexStr(vvchParams[2].begin(), vvchParams[2].end());
+    else
+        return false;
+    return true;
+}
+
+bool getClaimById(const uint160& claimId, std::string& name, CClaimValue* claim = nullptr)
+{
+    if (claimId.IsNull())
+        return false;
+
+    CClaimIndexElement element;
+    if (!pclaimTrie->db->Read(std::make_pair(CLAIM_BY_ID, claimId), element))
+        return false;
+    if (element.claim.claimId == claimId) {
+        name = element.name;
+        if (claim)
+            *claim = element.claim;
         return true;
     }
     return false;
 }
 
+// name can be setted explicitly
+bool getClaimById(const std::string& partialId, std::string& name, CClaimValue* claim = nullptr)
+{
+    if (partialId.empty())
+        return false;
+
+    std::unique_ptr<CDBIterator> pcursor(pclaimTrie->db->NewIterator());
+
+    for (pcursor->SeekToFirst(); pcursor->Valid(); pcursor->Next()) {
+        std::pair<uint8_t, uint160> key;
+        if (!pcursor->GetKey(key) || key.first != CLAIM_BY_ID)
+            continue;
+
+        if (key.second.GetHex().find(partialId) != 0)
+            continue;
+
+        CClaimIndexElement element;
+        if (pcursor->GetValue(element)) {
+            if (!name.empty() && name != element.name)
+                continue;
+            name = element.name;
+            if (claim)
+                *claim = element.claim;
+            return true;
+        }
+    }
+    return false;
+}
+
+UniValue claimToJSON(const CCoinsViewCache& coinsCache, const CClaimValue& claim)
+{
+    UniValue result(UniValue::VOBJ);
+
+    std::string targetName;
+    if (getClaimById(claim.claimId, targetName))
+        result.pushKV("name", escapeNonUtf8(targetName));
+
+    std::string sValue;
+    if (getValueForOutPoint(coinsCache, claim.outPoint, sValue))
+        result.pushKV("value", sValue);
+
+    result.pushKV("claimId", claim.claimId.GetHex());
+    result.pushKV("txId", claim.outPoint.hash.GetHex());
+    result.pushKV("n", (int)claim.outPoint.n);
+    result.pushKV("height", claim.nHeight);
+    result.pushKV("validAtHeight", claim.nValidAtHeight);
+    result.pushKV("amount", claim.nAmount);
+
+    return result;
+}
+
+UniValue supportToJSON(const CCoinsViewCache& coinsCache, const CSupportValue& support)
+{
+    UniValue ret(UniValue::VOBJ);
+
+    std::string value;
+    if (getValueForOutPoint(coinsCache, support.outPoint, value))
+        ret.pushKV("value", value);
+
+    ret.pushKV("txId", support.outPoint.hash.GetHex());
+    ret.pushKV("n", (int)support.outPoint.n);
+    ret.pushKV("height", support.nHeight);
+    ret.pushKV("validAtHeight", support.nValidAtHeight);
+    ret.pushKV("amount", support.nAmount);
+
+    return ret;
+}
+
+UniValue claimAndSupportsToJSON(const CCoinsViewCache& coinsCache, const CClaimNsupports& claimNsupports)
+{
+    auto& claim = claimNsupports.claim;
+    auto& supports = claimNsupports.supports;
+
+    auto result = claimToJSON(coinsCache, claim);
+    result.pushKV("effectiveAmount", claimNsupports.effectiveAmount);
+
+    if (claim.nEffectiveAmount > claimNsupports.effectiveAmount)
+        result.pushKV("pendingEffectiveAmount", claim.nEffectiveAmount);
+
+    UniValue supportObjs(UniValue::VARR);
+    for (auto& support : supports)
+        supportObjs.push_back(supportToJSON(coinsCache, support));
+
+    if (!supportObjs.empty())
+        result.pushKV("supports", supportObjs);
+
+    return result;
+}
+
 bool validParams(const UniValue& params, uint8_t required, uint8_t optional)
 {
     auto count = params.size();
@@ -186,7 +283,7 @@ static UniValue getclaimsintrie(const JSONRPCRequest& request)
         RollBackTo(blockIndex, coinsCache, trieCache);
     }
 
-    trieCache.recurseNodes("", [&ret, &trieCache, &coinsCache] (const std::string& name, const CClaimTrieData& data) {
+    trieCache.recurseNodes({}, [&ret, &trieCache, &coinsCache] (const std::string& name, const CClaimTrieData& data) {
         if (ShutdownRequested())
             throw JSONRPCError(RPC_INTERNAL_ERROR, "Shutdown requested");
 
@@ -196,34 +293,8 @@ static UniValue getclaimsintrie(const JSONRPCRequest& request)
             return;
 
         UniValue claims(UniValue::VARR);
-        for (auto itClaims = data.claims.cbegin(); itClaims != data.claims.cend(); ++itClaims) {
-            UniValue claim(UniValue::VOBJ);
-            claim.pushKV("claimId", itClaims->claimId.GetHex());
-            claim.pushKV("txid", itClaims->outPoint.hash.GetHex());
-            claim.pushKV("n", (int) itClaims->outPoint.n);
-            claim.pushKV("amount", ValueFromAmount(itClaims->nAmount));
-            claim.pushKV("height", itClaims->nHeight);
-            const Coin &coin = coinsCache.AccessCoin(itClaims->outPoint);
-            if (coin.IsSpent()) {
-                LogPrintf("%s: the specified txout of %s appears to have been spent\n", __func__,
-                          itClaims->outPoint.hash.GetHex());
-                claim.pushKV("error", "Txout spent");
-            } else {
-                int op;
-                std::vector<std::vector<unsigned char> > vvchParams;
-                if (!DecodeClaimScript(coin.out.scriptPubKey, op, vvchParams)) {
-                    LogPrintf("%s: the specified txout of %s does not have an claim command\n", __func__,
-                              itClaims->outPoint.hash.GetHex());
-                }
-                claim.pushKV("value", HexStr(vvchParams[1].begin(), vvchParams[1].end()));
-            }
-            std::string targetName;
-            CClaimValue targetClaim;
-            if (trieCache.getClaimById(itClaims->claimId, targetName, targetClaim))
-                claim.push_back(Pair("name", escapeNonUtf8(targetName)));
-
-            claims.push_back(claim);
-        }
+        for (auto& claim : data.claims)
+            claims.push_back(claimToJSON(coinsCache, claim));
 
         UniValue nodeObj(UniValue::VOBJ);
         nodeObj.pushKV("normalized_name", escapeNonUtf8(name));
@@ -266,7 +337,7 @@ static UniValue getnamesintrie(const JSONRPCRequest& request)
     }
     UniValue ret(UniValue::VARR);
 
-    trieCache.recurseNodes("", [&ret](const std::string &name, const CClaimTrieData &data) {
+    trieCache.recurseNodes({}, [&ret](const std::string &name, const CClaimTrieData &data) {
         if (!data.empty())
             ret.push_back(escapeNonUtf8(name));
         if (ShutdownRequested())
@@ -280,10 +351,10 @@ static UniValue getnamesintrie(const JSONRPCRequest& request)
 
 static UniValue getvalueforname(const JSONRPCRequest& request)
 {
-    if (request.fHelp || !validParams(request.params, 1, 1))
+    if (request.fHelp || !validParams(request.params, 1, 2))
         throw std::runtime_error(
             "getvalueforname \"name\"\n"
-            "Return the winning value associated with a name, if one exists\n"
+            "Return the winning or specified by claimId value associated with a name\n"
             "Arguments:\n"
             "1. \"name\"          (string) the name to look up\n"
             "2. \"blockhash\"     (string, optional) get the value\n"
@@ -293,6 +364,7 @@ static UniValue getvalueforname(const JSONRPCRequest& request)
             "                                        If none is given,\n"
             "                                        the latest active\n"
             "                                        block will be used.\n"
+            "3. \"claimId\"       (string, optional) can be partial one\n"
             "Result: \n"
             "\"value\"            (string) the value of the name, if it exists\n"
             "\"claimId\"          (string) the claimId for this name claim\n"
@@ -313,82 +385,32 @@ static UniValue getvalueforname(const JSONRPCRequest& request)
         RollBackTo(blockIndex, coinsCache, trieCache);
     }
 
-    const auto& name = request.params[0].get_str();
+    uint160 claimId;
+    std::string partialId;
+    if (request.params.size() > 2)
+        ParseClaimtrieId(request.params[2], partialId, claimId, "claimId (optional parameter 3)");
+
+    const auto name = request.params[0].get_str();
     UniValue ret(UniValue::VOBJ);
 
-    CClaimValue claim;
-    if (!trieCache.getInfoForName(name, claim))
-        return ret; // they may have asked for a name that doesn't exist (which is not an error)
-
-    std::string sValue;
-    if (!getValueForOutPoint(coinsCache, claim.outPoint, sValue))
+    auto res = trieCache.getClaimsForName(name);
+    if (res.claimsNsupports.empty())
         return ret;
 
-    const auto nEffectiveAmount = trieCache.getEffectiveAmountForClaim(name, claim.claimId);
+    auto& claimNsupports =
+        !claimId.IsNull() ? res.find(claimId) :
+        !partialId.empty() ? res.find(partialId) : res.claimsNsupports[0];
 
-    ret.pushKV("value", sValue);
-    ret.pushKV("claimId", claim.claimId.GetHex());
-    ret.pushKV("txid", claim.outPoint.hash.GetHex());
-    ret.pushKV("n", (int)claim.outPoint.n);
-    ret.pushKV("amount", claim.nAmount);
-    ret.pushKV("effective amount", nEffectiveAmount);
-    ret.pushKV("height", claim.nHeight);
+    if (claimNsupports.IsNull())
+        return ret;
 
-    std::string targetName;
-    CClaimValue targetClaim;
-    if (trieCache.getClaimById(claim.claimId, targetName, targetClaim))
-        ret.pushKV("name", escapeNonUtf8(targetName));
+    ret.pushKV("normalizedName", escapeNonUtf8(res.name));
+    ret.pushKVs(claimAndSupportsToJSON(coinsCache, claimNsupports));
+    ret.pushKV("lastTakeoverHeight", res.nLastTakeoverHeight);
 
     return ret;
 }
 
-typedef std::pair<CClaimValue, std::vector<CSupportValue> > claimAndSupportsType;
-typedef std::map<uint160, claimAndSupportsType> claimSupportMapType;
-
-UniValue supportToJSON(const CCoinsViewCache& coinsCache, const CSupportValue& support)
-{
-    UniValue ret(UniValue::VOBJ);
-    ret.pushKV("txid", support.outPoint.hash.GetHex());
-    ret.pushKV("n", (int)support.outPoint.n);
-    ret.pushKV("nHeight", support.nHeight);
-    ret.pushKV("nValidAtHeight", support.nValidAtHeight);
-    ret.pushKV("nAmount", support.nAmount);
-    std::string value;
-    if (getValueForOutPoint(coinsCache, support.outPoint, value))
-        ret.pushKV("value", value);
-    return ret;
-}
-
-UniValue claimAndSupportsToJSON(const CClaimTrieCache& trieCache, const CCoinsViewCache& coinsCache, CAmount nEffectiveAmount, claimSupportMapType::const_iterator itClaimsAndSupports)
-{
-    const CClaimValue& claim = itClaimsAndSupports->second.first;
-    const std::vector<CSupportValue>& supports = itClaimsAndSupports->second.second;
-
-    UniValue supportObjs(UniValue::VARR);
-    for (const auto& support: supports)
-        supportObjs.push_back(supportToJSON(coinsCache, support));
-
-    UniValue result(UniValue::VOBJ);
-    result.pushKV("claimId", itClaimsAndSupports->first.GetHex());
-    result.pushKV("txid", claim.outPoint.hash.GetHex());
-    result.pushKV("n", (int)claim.outPoint.n);
-    result.pushKV("nHeight", claim.nHeight);
-    result.pushKV("nValidAtHeight", claim.nValidAtHeight);
-    result.pushKV("nAmount", claim.nAmount);
-    std::string sValue;
-    if (getValueForOutPoint(coinsCache, claim.outPoint, sValue))
-        result.pushKV("value", sValue);
-    result.pushKV("nEffectiveAmount", nEffectiveAmount);
-    result.pushKV("supports", supportObjs);
-
-    std::string targetName;
-    CClaimValue targetClaim;
-    if (trieCache.getClaimById(claim.claimId, targetName, targetClaim))
-        result.pushKV("name", escapeNonUtf8(targetName));
-
-    return result;
-}
-
 UniValue getclaimsforname(const JSONRPCRequest& request)
 {
     if (request.fHelp || !validParams(request.params, 1, 1))
@@ -452,39 +474,20 @@ UniValue getclaimsforname(const JSONRPCRequest& request)
     std::string name = request.params[0].get_str();
     auto claimsForName = trieCache.getClaimsForName(name);
 
-    UniValue claimObjs(UniValue::VARR);
-    claimSupportMapType claimSupportMap;
-    UniValue unmatchedSupports(UniValue::VARR);
-
-    for (auto itClaims = claimsForName.claims.begin(); itClaims != claimsForName.claims.end(); ++itClaims)
-    {
-        claimAndSupportsType claimAndSupports = std::make_pair(*itClaims, std::vector<CSupportValue>());
-        claimSupportMap.emplace(itClaims->claimId, claimAndSupports);
-    }
-
-    for (auto itSupports = claimsForName.supports.begin(); itSupports != claimsForName.supports.end(); ++itSupports)
-    {
-        auto itClaimAndSupports = claimSupportMap.find(itSupports->supportedClaimId);
-        if (itClaimAndSupports == claimSupportMap.end())
-            unmatchedSupports.push_back(supportToJSON(coinsCache, *itSupports));
-        else
-            itClaimAndSupports->second.second.push_back(*itSupports);
-    }
-
     UniValue result(UniValue::VOBJ);
-    result.pushKV("nLastTakeoverHeight", claimsForName.nLastTakeoverHeight);
     result.pushKV("normalized_name", escapeNonUtf8(claimsForName.name));
 
-    for (auto itClaims = claimsForName.claims.begin(); itClaims != claimsForName.claims.end(); ++itClaims)
-    {
-        auto itClaimsAndSupports = claimSupportMap.find(itClaims->claimId);
-        const auto nEffectiveAmount = trieCache.getEffectiveAmountForClaim(claimsForName, itClaimsAndSupports->first);
-        UniValue claimObj = claimAndSupportsToJSON(trieCache, coinsCache, nEffectiveAmount, itClaimsAndSupports);
-        claimObjs.push_back(claimObj);
-    }
+    UniValue claimObjs(UniValue::VARR);
+    for (auto& claim : claimsForName.claimsNsupports)
+        claimObjs.push_back(claimAndSupportsToJSON(coinsCache, claim));
+
+    UniValue unmatchedSupports(UniValue::VARR);
+    for (auto& support : claimsForName.unmatchedSupports)
+        unmatchedSupports.push_back(supportToJSON(coinsCache, support));
 
     result.pushKV("claims", claimObjs);
-    result.pushKV("supports without claims", unmatchedSupports);
+    result.pushKV("lastTakeoverHeight", claimsForName.nLastTakeoverHeight);
+    result.pushKV("supportsWithoutClaims", unmatchedSupports);
     return result;
 }
 
@@ -495,7 +498,7 @@ UniValue getclaimbyid(const JSONRPCRequest& request)
             "getclaimbyid\n"
             "Get a claim by claim id\n"
             "Arguments: \n"
-            "1.  \"claimId\"           (string) the claimId of this claim\n"
+            "1.  \"claimId\"           (string) the claimId of this claim or patial id (at least 3 chars)\n"
             "Result:\n"
             "{\n"
             "  \"name\"                (string) the original name of the claim (before normalization)\n"
@@ -521,43 +524,26 @@ UniValue getclaimbyid(const JSONRPCRequest& request)
 
     LOCK(cs_main);
     CClaimTrieCache trieCache(pclaimTrie);
-    uint160 claimId = ParseClaimtrieId(request.params[0], "Claim-id (parameter 1)");
+    CCoinsViewCache coinsCache(pcoinsTip.get());
+
+    uint160 claimId;
+    std::string partialId;
+    ParseClaimtrieId(request.params[0], partialId, claimId, "Claim-id (parameter 1)");
+
+    if (claimId.IsNull() && partialId.length() < 3)
+        throw JSONRPCError(RPC_INVALID_PARAMETER, "Claim-id (parameter 1) should be at least 3 chars");
+
     UniValue claim(UniValue::VOBJ);
     std::string name;
     CClaimValue claimValue;
-    trieCache.getClaimById(claimId, name, claimValue);
-    if (claimValue.claimId == claimId)
-    {
-        std::vector<CSupportValue> supports;
-        CAmount effectiveAmount = trieCache.getEffectiveAmountForClaim(name, claimValue.claimId, &supports);
-
-        std::string sValue;
-        claim.pushKV("name", escapeNonUtf8(name));
-        if (trieCache.shouldNormalize())
-            claim.pushKV("normalized_name", escapeNonUtf8(trieCache.normalizeClaimName(name, true)));
-        CCoinsViewCache coinsCache(pcoinsTip.get());
-        if (getValueForOutPoint(coinsCache, claimValue.outPoint, sValue))
-            claim.pushKV("value", sValue);
-        claim.pushKV("claimId", claimValue.claimId.GetHex());
-        claim.pushKV("txid", claimValue.outPoint.hash.GetHex());
-        claim.pushKV("n", (int) claimValue.outPoint.n);
-        claim.pushKV("amount", claimValue.nAmount);
-        claim.pushKV("effective amount", effectiveAmount);
-        UniValue supportList(UniValue::VARR);
-        for(const CSupportValue& support: supports) {
-            UniValue supportEntry(UniValue::VOBJ);
-            supportEntry.pushKV("txid", support.outPoint.hash.GetHex());
-            supportEntry.pushKV("n", (int)support.outPoint.n);
-            supportEntry.pushKV("height", support.nHeight);
-            supportEntry.pushKV("valid at height", support.nValidAtHeight);
-            supportEntry.pushKV("amount", support.nAmount);
-            if (getValueForOutPoint(coinsCache, support.outPoint, sValue))
-                claim.pushKV("value", sValue);
-            supportList.pushKVs(supportEntry);
+    if (getClaimById(claimId, name, &claimValue) || getClaimById(partialId, name, &claimValue)) {
+        auto res = trieCache.getClaimsForName(name);
+        auto& claimNsupports = !claimId.IsNull() ? res.find(claimId) : res.find(partialId);
+        if (!claimNsupports.IsNull()) {
+            claim.pushKV("normalizedName", escapeNonUtf8(res.name));
+            claim.pushKVs(claimAndSupportsToJSON(coinsCache, claimNsupports));
+            claim.pushKV("lastTakeoverHeight", res.nLastTakeoverHeight);
         }
-        claim.pushKV("supports", supportList);
-        claim.pushKV("height", claimValue.nHeight);
-        claim.pushKV("valid at height", claimValue.nValidAtHeight);
     }
     return claim;
 }
@@ -882,12 +868,23 @@ UniValue getnameproof(const JSONRPCRequest& request)
     }
 
     uint160 claimId;
+    std::string partialId;
     if (request.params.size() > 2)
-        claimId = ParseClaimtrieId(request.params[2], "claimId (optional parameter 3)");
+        ParseClaimtrieId(request.params[2], partialId, claimId, "claimId (optional parameter 3)");
+
+    std::function<bool(const CClaimValue&)> comp;
+    if (!claimId.IsNull())
+        comp = [&claimId](const CClaimValue& claim) {
+            return claim.claimId == claimId;
+        };
+    else
+        comp = [&partialId](const CClaimValue& claim) {
+            return claim.claimId.GetHex().find(partialId) == 0;
+        };
 
     CClaimTrieProof proof;
     std::string name = request.params[0].get_str();
-    if (!trieCache.getProofForName(name, proof, claimId))
+    if (!trieCache.getProofForName(name, proof, comp))
         throw JSONRPCError(RPC_INTERNAL_ERROR, "Failed to generate proof");
 
     return proofToJSON(proof);
@@ -917,7 +914,7 @@ static const CRPCCommand commands[] =
     { "Claimtrie",          "getclaimsintrie",              &getclaimsintrie,           { "blockhash" } },
     { "Claimtrie",          "getnamesintrie",               &getnamesintrie,            { "blockhash" } },
     { "hidden",             "getclaimtrie",                 &getclaimtrie,              { } },
-    { "Claimtrie",          "getvalueforname",              &getvalueforname,           { "name","blockhash" } },
+    { "Claimtrie",          "getvalueforname",              &getvalueforname,           { "name","blockhash","claimId" } },
     { "Claimtrie",          "getclaimsforname",             &getclaimsforname,          { "name","blockhash" } },
     { "Claimtrie",          "gettotalclaimednames",         &gettotalclaimednames,      { "" } },
     { "Claimtrie",          "gettotalclaims",               &gettotalclaims,            { "" } },
diff --git a/src/test/claimtriebranching_tests.cpp b/src/test/claimtriebranching_tests.cpp
index 385ce52f3..cb22e554e 100644
--- a/src/test/claimtriebranching_tests.cpp
+++ b/src/test/claimtriebranching_tests.cpp
@@ -25,6 +25,7 @@
 extern ::CChainState g_chainstate;
 extern ::ArgsManager gArgs;
 extern std::vector<std::string> random_strings(std::size_t count);
+extern bool getClaimById(const uint160&, std::string&, CClaimValue*);
 
 using namespace std;
 
@@ -434,7 +435,7 @@ struct ClaimTrieChainFixture: public CClaimTrieCache
             res.message() << "No claim found";
             return res;
         } else {
-            CAmount effective_amount = getEffectiveAmountForClaim(name, val.claimId);
+            CAmount effective_amount = getClaimsForName(name).find(val.claimId).effectiveAmount;
             if (effective_amount != amount) {
                 boost::test_tools::predicate_result res(false);
                 res.message() << amount << " != " << effective_amount;
@@ -566,12 +567,12 @@ BOOST_AUTO_TEST_CASE(claim_test)
     CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",2);
     fixture.IncrementBlocks(1);
     BOOST_CHECK(fixture.is_best_claim("test",tx3));
-    BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claims.size());
+    BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claimsNsupports.size());
 
     fixture.DecrementBlocks(1);
     BOOST_CHECK(!fixture.is_best_claim("test",tx2));
     BOOST_CHECK(!fixture.is_best_claim("test",tx3));
-    BOOST_CHECK_EQUAL(0U, fixture.getClaimsForName("test").claims.size());
+    BOOST_CHECK_EQUAL(0U, fixture.getClaimsForName("test").claimsNsupports.size());
 
     // make two claims , one older
     CMutableTransaction tx4 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",1);
@@ -583,7 +584,7 @@ BOOST_AUTO_TEST_CASE(claim_test)
     BOOST_CHECK(fixture.is_best_claim("test", tx4));
     fixture.IncrementBlocks(1);
     BOOST_CHECK(fixture.is_best_claim("test",tx4));
-    BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claims.size());
+    BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claimsNsupports.size());
 
     fixture.DecrementBlocks(1);
     BOOST_CHECK(fixture.is_best_claim("test", tx4));
@@ -603,7 +604,7 @@ BOOST_AUTO_TEST_CASE(claim_test)
     BOOST_CHECK(fixture.is_best_claim("test", tx6));
     fixture.IncrementBlocks(10);
     BOOST_CHECK(fixture.is_best_claim("test",tx7));
-    BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claims.size());
+    BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claimsNsupports.size());
 
     fixture.DecrementBlocks(10);
     BOOST_CHECK(fixture.is_claim_in_queue("test",tx7));
@@ -873,7 +874,7 @@ BOOST_AUTO_TEST_CASE(support_spend_test)
     CMutableTransaction s2 = fixture.MakeSupport(fixture.GetCoinbase(),tx5,"test",2);
     fixture.IncrementBlocks(1);
     BOOST_CHECK(fixture.is_best_claim("test",tx5));
-    BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claims.size());
+    BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claimsNsupports.size());
 
     // build the spend where s2 is sppent on txin[1] and tx3 is  spent on txin[0]
     uint32_t prevout = 0;
@@ -938,7 +939,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_update_test)
     CMutableTransaction u3 = fixture.MakeUpdate(tx3, "test", "one", ClaimIdHash(tx3.GetHash(), 0), 2);
     fixture.IncrementBlocks(1);
     BOOST_CHECK(fixture.is_best_claim("test",u3));
-    BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claims.size());
+    BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claimsNsupports.size());
     fixture.DecrementBlocks(11);
 
     // losing update on winning claim happens without delay
@@ -946,7 +947,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_update_test)
     CMutableTransaction tx6 = fixture.MakeClaim(fixture.GetCoinbase(), "test", "one", 2);
     fixture.IncrementBlocks(10);
     BOOST_CHECK(fixture.is_best_claim("test", tx5));
-    BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claims.size());
+    BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claimsNsupports.size());
     CMutableTransaction u4 = fixture.MakeUpdate(tx5, "test", "one", ClaimIdHash(tx5.GetHash(), 0), 1);
     fixture.IncrementBlocks(1);
     BOOST_CHECK(fixture.is_best_claim("test",tx6));
@@ -1054,7 +1055,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_expire_test)
     BOOST_CHECK(fixture.is_best_claim("test", tx6));
 }
 /*
- * tests for CClaimPrefixTrie::getEffectiveAmountForClaim
+ * tests for effectiveAmount
  */
 BOOST_AUTO_TEST_CASE(claimtriebranching_get_effective_amount_for_claim)
 {
@@ -1064,42 +1065,42 @@ BOOST_AUTO_TEST_CASE(claimtriebranching_get_effective_amount_for_claim)
     uint160 claimId = ClaimIdHash(claimtx.GetHash(), 0);
     fixture.IncrementBlocks(1);
 
-    BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId), 2);
-    BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("inexistent", claimId), 0); //not found returns 0
+    BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId).effectiveAmount, 2);
+    BOOST_CHECK_EQUAL(fixture.getClaimsForName("inexistent").find(claimId).effectiveAmount, 0); //not found returns 0
 
     // one claim, one support
     fixture.MakeSupport(fixture.GetCoinbase(), claimtx, "test", 40);
     fixture.IncrementBlocks(1);
 
-    BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId), 42);
+    BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId).effectiveAmount, 42);
 
     // Two claims, first one with supports
     CMutableTransaction claimtx2 = fixture.MakeClaim(fixture.GetCoinbase(), "test", "two", 1);
     uint160 claimId2 = ClaimIdHash(claimtx2.GetHash(), 0);
     fixture.IncrementBlocks(10);
 
-    BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId), 42);
-    BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId2), 1);
-    BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("inexistent", claimId), 0);
-    BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("inexistent", claimId2), 0);
+    BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId).effectiveAmount, 42);
+    BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId2).effectiveAmount, 1);
+    BOOST_CHECK_EQUAL(fixture.getClaimsForName("inexistent").find(claimId).effectiveAmount, 0);
+    BOOST_CHECK_EQUAL(fixture.getClaimsForName("inexistent").find(claimId2).effectiveAmount, 0);
 
     // Two claims, both with supports, second claim effective amount being less than first claim
     fixture.MakeSupport(fixture.GetCoinbase(), claimtx2, "test", 6);
     fixture.IncrementBlocks(13); //delay
 
-    BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId), 42);
-    BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId2), 7);
+    BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId).effectiveAmount, 42);
+    BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId2).effectiveAmount, 7);
 
     // Two claims, both with supports, second one taking over
     fixture.MakeSupport(fixture.GetCoinbase(), claimtx2, "test", 1330);
     fixture.IncrementBlocks(26); //delay
 
-    BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId), 42);
-    BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId2), 1337);
+    BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId).effectiveAmount, 42);
+    BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId2).effectiveAmount, 1337);
 }
 
 /*
- * tests for CClaimPrefixTrie::getClaimById basic consistency checks
+ * tests for getClaimById basic consistency checks
  */
 BOOST_AUTO_TEST_CASE(get_claim_by_id_test)
 {
@@ -1111,7 +1112,7 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test)
 
     CClaimValue claimValue;
     std::string claimName;
-    fixture.getClaimById(claimId, claimName, claimValue);
+    BOOST_CHECK(getClaimById(claimId, claimName, &claimValue));
     BOOST_CHECK_EQUAL(claimName, name);
     BOOST_CHECK_EQUAL(claimValue.claimId, claimId);
 
@@ -1122,14 +1123,14 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test)
     uint160 claimId2 = ClaimIdHash(tx2.GetHash(), 0);
     fixture.IncrementBlocks(1);
 
-    fixture.getClaimById(claimId2, claimName, claimValue);
+    BOOST_CHECK(getClaimById(claimId2, claimName, &claimValue));
     BOOST_CHECK_EQUAL(claimName, name);
     BOOST_CHECK_EQUAL(claimValue.claimId, claimId2);
 
 
     CMutableTransaction u1 = fixture.MakeUpdate(tx1, name, "updated one", claimId, 1);
     fixture.IncrementBlocks(1);
-    fixture.getClaimById(claimId, claimName, claimValue);
+    BOOST_CHECK(getClaimById(claimId, claimName, &claimValue));
     BOOST_CHECK_EQUAL(claimName, name);
     BOOST_CHECK_EQUAL(claimValue.claimId, claimId);
     BOOST_CHECK_EQUAL(claimValue.nAmount, 1);
@@ -1137,24 +1138,24 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test)
 
     fixture.Spend(u1);
     fixture.IncrementBlocks(1);
-    BOOST_CHECK(!fixture.getClaimById(claimId, claimName, claimValue));
+    BOOST_CHECK(!getClaimById(claimId, claimName, &claimValue));
 
     fixture.DecrementBlocks(3);
 
     CClaimValue claimValue2;
     claimName = "";
-    fixture.getClaimById(claimId2, claimName, claimValue2);
+    BOOST_CHECK(!getClaimById(claimId2, claimName, &claimValue2));
     BOOST_CHECK(claimName != name);
     BOOST_CHECK(claimValue2.claimId != claimId2);
 
-    fixture.getClaimById(claimId, claimName, claimValue);
+    BOOST_CHECK(getClaimById(claimId, claimName, &claimValue));
     BOOST_CHECK_EQUAL(claimName, name);
     BOOST_CHECK_EQUAL(claimValue.claimId, claimId);
 
     fixture.DecrementBlocks(2);
 
     claimName = "";
-    fixture.getClaimById(claimId, claimName, claimValue2);
+    BOOST_CHECK(!getClaimById(claimId, claimName, &claimValue2));
     BOOST_CHECK(claimName != name);
     BOOST_CHECK(claimValue2.claimId != claimId);
 }
@@ -1535,7 +1536,7 @@ BOOST_AUTO_TEST_CASE(claimtriecache_normalization)
 
     CClaimValue lookupClaim;
     std::string lookupName;
-    BOOST_CHECK(fixture.getClaimById(ClaimIdHash(tx2.GetHash(), 0), lookupName, lookupClaim));
+    BOOST_CHECK(getClaimById(ClaimIdHash(tx2.GetHash(), 0), lookupName, &lookupClaim));
     CClaimValue nval1;
     BOOST_CHECK(fixture.getInfoForName("amelie1", nval1));
     // ameĢlie is not found cause normalization still not appear
@@ -1614,13 +1615,13 @@ BOOST_AUTO_TEST_CASE(normalized_activations_fall_through)
     BOOST_CHECK(fixture.is_best_claim("AB", tx1));
     fixture.IncrementBlocks(3);
     BOOST_CHECK(fixture.is_best_claim("ab", tx2));
-    BOOST_CHECK(fixture.getClaimsForName("ab").claims.size() == 4U);
+    BOOST_CHECK(fixture.getClaimsForName("ab").claimsNsupports.size() == 4U);
     fixture.DecrementBlocks(3);
     fixture.Spend(tx1);
     fixture.Spend(tx2);
     fixture.IncrementBlocks(1);
     BOOST_CHECK(fixture.is_best_claim("ab", tx3));
-    BOOST_CHECK(fixture.getClaimsForName("ab").claims.size() == 2U);
+    BOOST_CHECK(fixture.getClaimsForName("ab").claimsNsupports.size() == 2U);
     fixture.DecrementBlocks(1);
     BOOST_CHECK(fixture.is_best_claim("AB", tx1));
     fixture.Spend(tx1);
@@ -1666,8 +1667,10 @@ BOOST_AUTO_TEST_CASE(normalization_removal_test)
     supportQueueRowType expireSupportUndo;
     std::vector<std::pair<std::string, int> > takeoverHeightUndo;
     BOOST_CHECK(cache.incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverHeightUndo));
-    BOOST_CHECK(cache.getClaimsForName("ab").claims.size() == 3U);
-    BOOST_CHECK(cache.getClaimsForName("ab").supports.size() == 2U);
+    BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports.size() == 3U);
+    BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[0].supports.size() == 1U);
+    BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[1].supports.size() == 0U);
+    BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[2].supports.size() == 1U);
     BOOST_CHECK(cache.decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo));
     BOOST_CHECK(cache.finalizeDecrement(takeoverHeightUndo));
     BOOST_CHECK(cache.undoAddSupport("AB", COutPoint(sx1.GetHash(), 0), height));
@@ -1675,7 +1678,7 @@ BOOST_AUTO_TEST_CASE(normalization_removal_test)
     BOOST_CHECK(cache.undoAddClaim("AB", COutPoint(tx1.GetHash(), 0), height));
     BOOST_CHECK(cache.undoAddClaim("Ab", COutPoint(tx2.GetHash(), 0), height));
     BOOST_CHECK(cache.undoAddClaim("aB", COutPoint(tx3.GetHash(), 0), height));
-    BOOST_CHECK(cache.getClaimsForName("ab").claims.size() == 0U);
+    BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports.size() == 0U);
 }
 
 BOOST_AUTO_TEST_CASE(normalization_does_not_kill_supports)
@@ -1745,7 +1748,7 @@ BOOST_AUTO_TEST_CASE(normalization_does_not_kill_sort_order)
     fixture.IncrementBlocks(1);
     BOOST_CHECK(!fixture.is_best_claim("A", tx2));
     BOOST_CHECK(fixture.is_best_claim("a", tx3));
-    BOOST_CHECK(fixture.getClaimsForName("a").claims.size() == 3U);
+    BOOST_CHECK(fixture.getClaimsForName("a").claimsNsupports.size() == 3U);
 
     fixture.DecrementBlocks(1);
     BOOST_CHECK(fixture.is_best_claim("A", tx2));
@@ -3837,7 +3840,7 @@ BOOST_AUTO_TEST_CASE(bogus_claimtrie_hash_test)
 }
 
 /*
- * tests for CClaimPrefixTrie::getClaimById basic consistency checks
+ * tests for getClaimById basic consistency checks
  */
 BOOST_AUTO_TEST_CASE(get_claim_by_id_test_2)
 {
@@ -3852,7 +3855,7 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test_2)
 
     CClaimValue claimValue;
     std::string claimName;
-    fixture.getClaimById(claimId, claimName, claimValue);
+    BOOST_CHECK(getClaimById(claimId, claimName, &claimValue));
     BOOST_CHECK_EQUAL(claimName, name);
     BOOST_CHECK_EQUAL(claimValue.claimId, claimId);
 
@@ -3860,16 +3863,16 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test_2)
     CMutableTransaction txb = fixture.Spend(txx);
 
     fixture.IncrementBlocks(1);
-    BOOST_CHECK(!fixture.getClaimById(claimId, claimName, claimValue));
-    BOOST_CHECK(!fixture.getClaimById(claimIdx, claimName, claimValue));
+    BOOST_CHECK(!getClaimById(claimId, claimName, &claimValue));
+    BOOST_CHECK(!getClaimById(claimIdx, claimName, &claimValue));
 
     fixture.DecrementBlocks(1);
-    fixture.getClaimById(claimId, claimName, claimValue);
+    BOOST_CHECK(getClaimById(claimId, claimName, &claimValue));
     BOOST_CHECK_EQUAL(claimName, name);
     BOOST_CHECK_EQUAL(claimValue.claimId, claimId);
 
     // this test fails
-    fixture.getClaimById(claimIdx, claimName, claimValue);
+    BOOST_CHECK(getClaimById(claimIdx, claimName, &claimValue));
     BOOST_CHECK_EQUAL(claimName, name);
     BOOST_CHECK_EQUAL(claimValue.claimId, claimIdx);
 }
@@ -3886,7 +3889,7 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test_3)
 
     CClaimValue claimValue;
     std::string claimName;
-    fixture.getClaimById(claimId, claimName, claimValue);
+    BOOST_CHECK(getClaimById(claimId, claimName, &claimValue));
     BOOST_CHECK_EQUAL(claimName, name);
     BOOST_CHECK_EQUAL(claimValue.claimId, claimId);
     // make second claim with activation delay 1
@@ -3896,14 +3899,14 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test_3)
     fixture.IncrementBlocks(1);
     // second claim is not activated yet, but can still access by claim id
     BOOST_CHECK(fixture.is_best_claim(name, tx1));
-    BOOST_CHECK(fixture.getClaimById(claimId2, claimName, claimValue));
+    BOOST_CHECK(getClaimById(claimId2, claimName, &claimValue));
     BOOST_CHECK_EQUAL(claimName, name);
     BOOST_CHECK_EQUAL(claimValue.claimId, claimId2);
 
     fixture.IncrementBlocks(1);
     // second claim has activated
     BOOST_CHECK(fixture.is_best_claim(name, tx2));
-    BOOST_CHECK(fixture.getClaimById(claimId2, claimName, claimValue));
+    BOOST_CHECK(getClaimById(claimId2, claimName, &claimValue));
     BOOST_CHECK_EQUAL(claimName, name);
     BOOST_CHECK_EQUAL(claimValue.claimId, claimId2);
 
@@ -3912,14 +3915,14 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test_3)
     // second claim has been deactivated via decrement
     // should still be accesible via claim id
     BOOST_CHECK(fixture.is_best_claim(name, tx1));
-    BOOST_CHECK(fixture.getClaimById(claimId2, claimName, claimValue));
+    BOOST_CHECK(getClaimById(claimId2, claimName, &claimValue));
     BOOST_CHECK_EQUAL(claimName, name);
     BOOST_CHECK_EQUAL(claimValue.claimId, claimId2);
 
     fixture.IncrementBlocks(1);
     // second claim should have been re activated via increment
     BOOST_CHECK(fixture.is_best_claim(name, tx2));
-    BOOST_CHECK(fixture.getClaimById(claimId2, claimName, claimValue));
+    BOOST_CHECK(getClaimById(claimId2, claimName, &claimValue));
     BOOST_CHECK_EQUAL(claimName, name);
     BOOST_CHECK_EQUAL(claimValue.claimId, claimId2);
 }
@@ -3970,13 +3973,13 @@ BOOST_AUTO_TEST_CASE(getvalueforname_test)
     UniValue results = getvalueforname(req);
     BOOST_CHECK_EQUAL(results["value"].get_str(), HexStr(sValue1));
     BOOST_CHECK_EQUAL(results["amount"].get_int(), 2);
-    BOOST_CHECK_EQUAL(results["effective amount"].get_int(), 5);
+    BOOST_CHECK_EQUAL(results["effectiveAmount"].get_int(), 5);
 
     req.params.push_back(blockHash.GetHex());
 
     results = getvalueforname(req);
     BOOST_CHECK_EQUAL(results["amount"].get_int(), 2);
-    BOOST_CHECK_EQUAL(results["effective amount"].get_int(), 2);
+    BOOST_CHECK_EQUAL(results["effectiveAmount"].get_int(), 2);
 }
 
 BOOST_AUTO_TEST_CASE(getclaimsforname_test)
@@ -4004,8 +4007,8 @@ BOOST_AUTO_TEST_CASE(getclaimsforname_test)
     UniValue results = getclaimsforname(req);
     UniValue claims = results["claims"];
     BOOST_CHECK_EQUAL(claims.size(), 1U);
-    BOOST_CHECK_EQUAL(results["nLastTakeoverHeight"].get_int(), height + 1);
-    BOOST_CHECK_EQUAL(claims[0]["nEffectiveAmount"].get_int(), 2);
+    BOOST_CHECK_EQUAL(results["lastTakeoverHeight"].get_int(), height + 1);
+    BOOST_CHECK_EQUAL(claims[0]["effectiveAmount"].get_int(), 2);
     BOOST_CHECK_EQUAL(claims[0]["supports"].size(), 0U);
 
     fixture.IncrementBlocks(1);
@@ -4013,9 +4016,9 @@ BOOST_AUTO_TEST_CASE(getclaimsforname_test)
     results = getclaimsforname(req);
     claims = results["claims"];
     BOOST_CHECK_EQUAL(claims.size(), 2U);
-    BOOST_CHECK_EQUAL(results["nLastTakeoverHeight"].get_int(), height + 3);
-    BOOST_CHECK_EQUAL(claims[0]["nEffectiveAmount"].get_int(), 3);
-    BOOST_CHECK_EQUAL(claims[1]["nEffectiveAmount"].get_int(), 2);
+    BOOST_CHECK_EQUAL(results["lastTakeoverHeight"].get_int(), height + 3);
+    BOOST_CHECK_EQUAL(claims[0]["effectiveAmount"].get_int(), 3);
+    BOOST_CHECK_EQUAL(claims[1]["effectiveAmount"].get_int(), 2);
     BOOST_CHECK_EQUAL(claims[0]["supports"].size(), 0U);
     BOOST_CHECK_EQUAL(claims[1]["supports"].size(), 0U);
 
@@ -4024,8 +4027,8 @@ BOOST_AUTO_TEST_CASE(getclaimsforname_test)
     results = getclaimsforname(req);
     claims = results["claims"];
     BOOST_CHECK_EQUAL(claims.size(), 1U);
-    BOOST_CHECK_EQUAL(results["nLastTakeoverHeight"].get_int(), height + 1);
-    BOOST_CHECK_EQUAL(claims[0]["nEffectiveAmount"].get_int(), 2);
+    BOOST_CHECK_EQUAL(results["lastTakeoverHeight"].get_int(), height + 1);
+    BOOST_CHECK_EQUAL(claims[0]["effectiveAmount"].get_int(), 2);
     BOOST_CHECK_EQUAL(claims[0]["supports"].size(), 0U);
 }
 
@@ -4056,7 +4059,7 @@ BOOST_AUTO_TEST_CASE(claim_rpcs_rollback2_test)
     req.params.push_back(blockHash.GetHex());
 
     UniValue claimsResults = getclaimsforname(req);
-    BOOST_CHECK_EQUAL(claimsResults["nLastTakeoverHeight"].get_int(), height + 5);
+    BOOST_CHECK_EQUAL(claimsResults["lastTakeoverHeight"].get_int(), height + 5);
     BOOST_CHECK_EQUAL(claimsResults["claims"][0]["supports"].size(), 0U);
     BOOST_CHECK_EQUAL(claimsResults["claims"][1]["supports"].size(), 0U);
 
@@ -4097,7 +4100,7 @@ BOOST_AUTO_TEST_CASE(claim_rpcs_rollback3_test)
     req.params.push_back(blockHash.GetHex());
 
     UniValue claimsResults = getclaimsforname(req);
-    BOOST_CHECK_EQUAL(claimsResults["nLastTakeoverHeight"].get_int(), height + 1);
+    BOOST_CHECK_EQUAL(claimsResults["lastTakeoverHeight"].get_int(), height + 1);
 
     UniValue valueResults = getvalueforname(req);
     BOOST_CHECK_EQUAL(valueResults["value"].get_str(), HexStr(sValue1));
@@ -4172,7 +4175,9 @@ BOOST_AUTO_TEST_CASE(hash_includes_all_claims_single_test)
     uint160 claimId = ClaimIdHash(tx1.GetHash(), 0);
 
     CClaimTrieProof proof;
-    BOOST_CHECK(fixture.getProofForName("test", proof, claimId));
+    BOOST_CHECK(fixture.getProofForName("test", proof, [&claimId](const CClaimValue& claim) {
+        return claim.claimId == claimId;
+    }));
     BOOST_CHECK(proof.hasValue);
     BOOST_CHECK_EQUAL(proof.outPoint, outPoint);
     auto claimHash = getValueHash(outPoint, proof.nHeightOfLastTakeover);
@@ -4197,9 +4202,12 @@ BOOST_AUTO_TEST_CASE(hash_includes_all_claims_triple_test)
     fixture.IncrementBlocks(1);
 
     for (const auto& name : names) {
-        for (auto& claim : fixture.getClaimsForName(name).claims) {
+        for (auto& claimSupports : fixture.getClaimsForName(name).claimsNsupports) {
             CClaimTrieProof proof;
-            BOOST_CHECK(fixture.getProofForName(name, proof, claim.claimId));
+            auto& claim = claimSupports.claim;
+            BOOST_CHECK(fixture.getProofForName(name, proof, [&claim](const CClaimValue& value) {
+                return claim.claimId == value.claimId;
+            }));
             BOOST_CHECK(proof.hasValue);
             BOOST_CHECK_EQUAL(proof.outPoint, claim.outPoint);
             uint256 claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
@@ -4225,9 +4233,12 @@ BOOST_AUTO_TEST_CASE(hash_includes_all_claims_branched_test)
     fixture.IncrementBlocks(1);
 
     for (const auto& name : names) {
-        for (auto& claim : fixture.getClaimsForName(name).claims) {
+        for (auto& claimSupports : fixture.getClaimsForName(name).claimsNsupports) {
             CClaimTrieProof proof;
-            BOOST_CHECK(fixture.getProofForName(name, proof, claim.claimId));
+            auto& claim = claimSupports.claim;
+            BOOST_CHECK(fixture.getProofForName(name, proof, [&claim](const CClaimValue& value) {
+                return claim.claimId == value.claimId;
+            }));
             BOOST_CHECK(proof.hasValue);
             BOOST_CHECK_EQUAL(proof.outPoint, claim.outPoint);
             uint256 claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
@@ -4257,9 +4268,12 @@ BOOST_AUTO_TEST_CASE(hash_claims_children_fuzzer_test)
     }
 
     for (const auto& name : names) {
-        for (auto& claim : fixture.getClaimsForName(name).claims) {
+        for (auto& claimSupports : fixture.getClaimsForName(name).claimsNsupports) {
             CClaimTrieProof proof;
-            BOOST_CHECK(fixture.getProofForName(name, proof, claim.claimId));
+            auto& claim = claimSupports.claim;
+            BOOST_CHECK(fixture.getProofForName(name, proof, [&claim](const CClaimValue& value) {
+                return claim.claimId == value.claimId;
+            }));
             BOOST_CHECK(proof.hasValue);
             BOOST_CHECK_EQUAL(proof.outPoint, claim.outPoint);
             uint256 claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
diff --git a/src/test/claimtriecache_tests.cpp b/src/test/claimtriecache_tests.cpp
index 38906a9b8..697b6e0af 100644
--- a/src/test/claimtriecache_tests.cpp
+++ b/src/test/claimtriecache_tests.cpp
@@ -210,13 +210,13 @@ BOOST_AUTO_TEST_CASE(basic_insertion_info_test)
     CClaimValue claimVal(claimOutPoint, claimId, amount, height, validHeight);
     ctc.insertClaimIntoTrie("test", claimVal, true);
 
-    // try getClaimsForName, getEffectiveAmountForClaim, getInfoForName
+    // try getClaimsForName, effectiveAmount, getInfoForName
     auto res = ctc.getClaimsForName("test");
-    BOOST_CHECK_EQUAL(res.claims.size(), 1);
-    BOOST_CHECK_EQUAL(res.claims[0], claimVal);
-    BOOST_CHECK_EQUAL(res.supports.size(), 0);
+    BOOST_CHECK_EQUAL(res.claimsNsupports.size(), 1);
+    BOOST_CHECK_EQUAL(res.claimsNsupports[0].claim, claimVal);
+    BOOST_CHECK_EQUAL(res.claimsNsupports[0].supports.size(), 0);
 
-    BOOST_CHECK_EQUAL(10, ctc.getEffectiveAmountForClaim("test", claimId));
+    BOOST_CHECK_EQUAL(10, res.claimsNsupports[0].effectiveAmount);
 
     CClaimValue claim;
     BOOST_CHECK(ctc.getInfoForName("test", claim));
@@ -231,12 +231,12 @@ BOOST_AUTO_TEST_CASE(basic_insertion_info_test)
     CSupportValue support(supportOutPoint, claimId, supportAmount, height, validHeight);
     ctc.insertSupportIntoMap("test", support, false);
 
-    res = ctc.getClaimsForName("test");
-    BOOST_CHECK_EQUAL(res.claims.size(), 1);
-    BOOST_CHECK_EQUAL(res.supports.size(), 1);
+    auto res1 = ctc.getClaimsForName("test");
+    BOOST_CHECK_EQUAL(res1.claimsNsupports.size(), 1);
+    BOOST_CHECK_EQUAL(res1.claimsNsupports[0].supports.size(), 1);
 
     // try getEffectiveAmount
-    BOOST_CHECK_EQUAL(20, ctc.getEffectiveAmountForClaim("test", claimId));
+    BOOST_CHECK_EQUAL(20, res1.claimsNsupports[0].effectiveAmount);
 }
 
 BOOST_AUTO_TEST_CASE(recursive_prune_test)