diff --git a/src/claimtrie.cpp b/src/claimtrie.cpp index 9963b3731..9435610a8 100644 --- a/src/claimtrie.cpp +++ b/src/claimtrie.cpp @@ -391,27 +391,44 @@ bool CClaimTrieCacheBase::getInfoForName(const std::string& name, CClaimValue& c return base->find(name, claims) && claims.getBestClaim(claim); } +template +void CClaimTrieCacheBase::insertRowsFromQueue(std::vector& result, const std::string& name) const +{ + supportedType(); + if (auto nameRows = getQueueCacheNameRow(name)) + for (auto& nameRow : *nameRows) + if (auto rows = getQueueCacheRow(nameRow.nHeight)) + for (auto& row : *rows) + if (row.first == name) + result.push_back(row.second); +} + CClaimSupportToName CClaimTrieCacheBase::getClaimsForName(const std::string& name) const { claimEntryType claims; int nLastTakeoverHeight = 0; auto supports = getSupportsForName(name); + insertRowsFromQueue(supports, name); - CClaimTrieData data; if (auto it = nodesToAddOrUpdate.find(name)) { claims = it->claims; nLastTakeoverHeight = it->nHeightOfLastTakeover; + } else if (!nodesToDelete.count(name)) { + CClaimTrieData data; + if (base->find(name, data)) { + claims = data.claims; + nLastTakeoverHeight = data.nHeightOfLastTakeover; + } } - else if (!nodesToDelete.count(name) && base->find(name, data)) { - claims = data.claims; - nLastTakeoverHeight = data.nHeightOfLastTakeover; - } + insertRowsFromQueue(claims, name); + 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 claimsNsupports; for (const auto& claim : claims) { diff --git a/src/claimtrie.h b/src/claimtrie.h index 532582cd5..81eadf76c 100644 --- a/src/claimtrie.h +++ b/src/claimtrie.h @@ -628,6 +628,9 @@ private: bool validateTrieConsistency(const CBlockIndex* tip); + template + void insertRowsFromQueue(std::vector& result, const std::string& name) const; + template std::vector>* getQueueCacheRow(int nHeight, bool createIfNotExists); diff --git a/src/rpc/claimrpchelp.h b/src/rpc/claimrpchelp.h index f7fd91f3a..2933d1ba1 100644 --- a/src/rpc/claimrpchelp.h +++ b/src/rpc/claimrpchelp.h @@ -45,6 +45,7 @@ #define T_CLAIMSREMOVED "claimsRemoved" #define T_SUPPORTSREMOVED "supportsRemoved" #define T_ADDRESS "address" +#define T_PENDINGAMOUNT "pendingAmount" enum { GETCLAIMSINTRIE = 0, @@ -89,6 +90,7 @@ S3(" ", T_HEIGHT, " (numeric) the height of the block in whic S3(" ", T_VALIDATHEIGHT, " (numeric) the height at which the support became/becomes valid") \ S3(" ", T_AMOUNT, " (numeric) the amount of the claim") \ S3(" ", T_EFFECTIVEAMOUNT, " (numeric) the amount plus amount from all supports associated with the claim") \ +S3(" ", T_PENDINGAMOUNT, " (numeric) expected amount when claim and its support got valid") \ S3(" ", T_SUPPORTS, ": [ (array of object) supports for this claim") \ S3(" ", T_VALUE, " (string) the metadata of the support if any") \ S3(" ", T_ADDRESS, " (string) the destination address of the support") \ @@ -184,6 +186,7 @@ S3(" ", T_HEIGHT, " (numeric) the height of the block in whic S3(" ", T_VALIDATHEIGHT, " (numeric) the height at which the claim became/becomes valid") S3(" ", T_AMOUNT, " (numeric) the amount of the claim") S3(" ", T_EFFECTIVEAMOUNT, " (numeric) the amount plus amount from all supports associated with the claim") +S3(" ", T_PENDINGAMOUNT, " (numeric) expected amount when claim and its support got valid") S3(" ", T_SUPPORTS, ": [ (array of object) supports for this claim") S3(" ", T_VALUE, " (string) the metadata of the support if any") S3(" ", T_ADDRESS, " (string) the destination address of the support") diff --git a/src/rpc/claimtrie.cpp b/src/rpc/claimtrie.cpp index af940a790..3a69591e9 100644 --- a/src/rpc/claimtrie.cpp +++ b/src/rpc/claimtrie.cpp @@ -245,6 +245,14 @@ UniValue supportToJSON(const CCoinsViewCache& coinsCache, const CSupportValue& s return ret; } +CAmount amountToClaim(const CClaimNsupports& claimNsupports) +{ + auto fullAmount = claimNsupports.claim.nAmount; + for (auto& support : claimNsupports.supports) + fullAmount += support.nAmount; + return fullAmount; +} + UniValue claimAndSupportsToJSON(const CCoinsViewCache& coinsCache, const CClaimNsupports& claimNsupports) { auto& claim = claimNsupports.claim; @@ -253,6 +261,10 @@ UniValue claimAndSupportsToJSON(const CCoinsViewCache& coinsCache, const CClaimN auto result = claimToJSON(coinsCache, claim); result.pushKV(T_EFFECTIVEAMOUNT, claimNsupports.effectiveAmount); + auto fullAmount = amountToClaim(claimNsupports); + if (fullAmount > claimNsupports.effectiveAmount) + result.pushKV(T_PENDINGAMOUNT, fullAmount); + UniValue supportObjs(UniValue::VARR); for (auto& support : supports) supportObjs.push_back(supportToJSON(coinsCache, support)); diff --git a/src/test/claimtriebranching_tests.cpp b/src/test/claimtriebranching_tests.cpp index 2d7f5d04c..569e0bf0d 100644 --- a/src/test/claimtriebranching_tests.cpp +++ b/src/test/claimtriebranching_tests.cpp @@ -4007,7 +4007,7 @@ BOOST_AUTO_TEST_CASE(getclaimsforname_test) UniValue results = getclaimsforname(req); UniValue claims = results[T_CLAIMS]; - BOOST_CHECK_EQUAL(claims.size(), 1U); + BOOST_CHECK_EQUAL(claims.size(), 2U); BOOST_CHECK_EQUAL(results[T_LASTTAKEOVERHEIGHT].get_int(), height + 1); BOOST_CHECK_EQUAL(claims[0][T_EFFECTIVEAMOUNT].get_int(), 2); BOOST_CHECK_EQUAL(claims[0][T_SUPPORTS].size(), 0U); @@ -4460,4 +4460,41 @@ BOOST_AUTO_TEST_CASE(hash_bid_seq_claim_changes_test) BOOST_CHECK_EQUAL(result[T_SUPPORTSREMOVED].size(), 0); } +BOOST_AUTO_TEST_CASE(claim_rpc_pending_amount_test) +{ + ClaimTrieChainFixture fixture; + std::string sName1("test"); + std::string sValue1("test1"); + std::string sValue2("test2"); + + rpcfn_type getclaimsforname = tableRPC["getclaimsforname"]->actor; + + JSONRPCRequest req; + req.params = UniValue(UniValue::VARR); + req.params.push_back(UniValue(sName1)); + + fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue1, 1); + fixture.IncrementBlocks(1); + + fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue2, 2); + fixture.IncrementBlocks(1); + + auto claims = getclaimsforname(req)[T_CLAIMS]; + BOOST_CHECK_EQUAL(claims.size(), 2U); + BOOST_CHECK_EQUAL(claims[0][T_EFFECTIVEAMOUNT].get_int(), 1); + BOOST_CHECK(!claims[0].exists(T_PENDINGAMOUNT)); + BOOST_CHECK_EQUAL(claims[1][T_EFFECTIVEAMOUNT].get_int(), 0); + BOOST_CHECK(claims[1].exists(T_PENDINGAMOUNT)); + BOOST_CHECK_EQUAL(claims[1][T_PENDINGAMOUNT].get_int(), 2); + + fixture.IncrementBlocks(1); + + claims = getclaimsforname(req)[T_CLAIMS]; + BOOST_CHECK_EQUAL(claims.size(), 2U); + BOOST_CHECK_EQUAL(claims[0][T_EFFECTIVEAMOUNT].get_int(), 2); + BOOST_CHECK(!claims[0].exists(T_PENDINGAMOUNT)); + BOOST_CHECK_EQUAL(claims[1][T_EFFECTIVEAMOUNT].get_int(), 1); + BOOST_CHECK(!claims[1].exists(T_PENDINGAMOUNT)); +} + BOOST_AUTO_TEST_SUITE_END()