From 40c941c34cfa0b0db5ee6b72b5f9827be30250eb Mon Sep 17 00:00:00 2001 From: levonpetrosyan93 Date: Mon, 18 Nov 2024 02:44:31 +0400 Subject: [PATCH 1/3] Implemented an rpc to get the number of addresses with positive balance --- src/rpc/client.cpp | 1 + src/rpc/misc.cpp | 14 ++++++++++++++ src/rpc/server.cpp | 2 ++ src/rpc/server.h | 2 ++ src/txdb.cpp | 25 +++++++++++++++++++++++++ src/txdb.h | 1 + 6 files changed, 45 insertions(+) diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 629dde9a14..9fdf6e2eb3 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -140,6 +140,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getspentinfo", 0}, { "getaddresstxids", 0}, { "getaddressbalance", 0}, + { "getAddressNumWBalance", 0}, { "getaddressdeltas", 0}, { "getaddressutxos", 0}, { "getaddressmempool", 0}, diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 8f73698fa0..712fede06a 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1011,6 +1011,20 @@ UniValue getaddressbalance(const JSONRPCRequest& request) } +UniValue getAddressNumWBalance(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() > 0) + throw std::runtime_error( + "getAddressNumWBalance\n" + "Gives the number of addresses which has positive balance." + ); + if (!GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX)) + throw std::runtime_error( + "You have to reindex with -addressindex flag to get an accurate result."); + + return uint64_t(pblocktree->findAddressNumWBalance()); +} + UniValue getanonymityset(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 2) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 0f07787f1b..5e333672be 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -331,6 +331,8 @@ static const CRPCCommand vRPCCommands[] = { "addressindex", "getaddressdeltas", &getaddressdeltas, false }, { "addressindex", "getaddresstxids", &getaddresstxids, false }, { "addressindex", "getaddressbalance", &getaddressbalance, false }, + { "addressindex", "getAddressNumWBalance", &getAddressNumWBalance, false }, + /* Mobile related */ { "mobile", "getanonymityset", &getanonymityset, false }, { "mobile", "getmintmetadata", &getmintmetadata, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index dbf98839b9..5fdd565dad 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -206,6 +206,8 @@ extern UniValue getaddressutxos(const JSONRPCRequest &request); extern UniValue getaddressdeltas(const JSONRPCRequest &request); extern UniValue getaddresstxids(const JSONRPCRequest &request); extern UniValue getaddressbalance(const JSONRPCRequest &request); +extern UniValue getAddressNumWBalance(const JSONRPCRequest &request); + extern UniValue getanonymityset(const JSONRPCRequest& params); extern UniValue getmintmetadata(const JSONRPCRequest& params); diff --git a/src/txdb.cpp b/src/txdb.cpp index 2ba448dffa..eec85cd5e9 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -313,6 +313,31 @@ bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, AddressType type, return true; } +size_t CBlockTreeDB::findAddressNumWBalance() { + boost::scoped_ptr pcursor(NewIterator()); + pcursor->SeekToFirst(); + std::unordered_map addrMap; + while (pcursor->Valid()) { + boost::this_thread::interruption_point(); + std::pair key; + if (pcursor->GetKey(key) && key.first == DB_ADDRESSINDEX && (key.second.type == AddressType::payToPubKeyHash || key.second.type == AddressType::payToExchangeAddress)) { + CAmount nValue; + if (pcursor->GetValue(nValue)) { + auto it = addrMap.find(key.second.hashBytes); + if (it != addrMap.end()) { + it->second += nValue; + if (it->second <= 0) + addrMap.erase(it); + } else { + if (nValue != 0) + addrMap[key.second.hashBytes] = nValue; + } + } + } + pcursor->Next(); + } + return addrMap.size(); +} bool CBlockTreeDB::WriteTimestampIndex(const CTimestampIndexKey ×tampIndex) { CDBBatch batch(*this); diff --git a/src/txdb.h b/src/txdb.h index fb35aa4c9f..15e44fcfe0 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -142,6 +142,7 @@ class CBlockTreeDB : public CDBWrapper bool ReadAddressIndex(uint160 addressHash, AddressType type, std::vector > &addressIndex, int start = 0, int end = 0); + size_t findAddressNumWBalance(); bool WriteTimestampIndex(const CTimestampIndexKey ×tampIndex); bool ReadTimestampIndex(const unsigned int &high, const unsigned int &low, std::vector &vect); From 3bfe8acfc70af3a48aad0e09b7a11227f255ce41 Mon Sep 17 00:00:00 2001 From: levonpetrosyan93 Date: Mon, 25 Nov 2024 03:39:31 +0400 Subject: [PATCH 2/3] Review comment applied --- src/txdb.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index eec85cd5e9..1c5bc6fb42 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -323,20 +323,24 @@ size_t CBlockTreeDB::findAddressNumWBalance() { if (pcursor->GetKey(key) && key.first == DB_ADDRESSINDEX && (key.second.type == AddressType::payToPubKeyHash || key.second.type == AddressType::payToExchangeAddress)) { CAmount nValue; if (pcursor->GetValue(nValue)) { - auto it = addrMap.find(key.second.hashBytes); - if (it != addrMap.end()) { - it->second += nValue; - if (it->second <= 0) - addrMap.erase(it); - } else { - if (nValue != 0) - addrMap[key.second.hashBytes] = nValue; + CAmount nValue; + // Retrieve the associated value + if (pcursor->GetValue(nValue) && nValue != 0) { // Only process non-zero values + addrMap[key.second.hashBytes] += nValue; // Accumulate balance for the address } } } pcursor->Next(); } - return addrMap.size(); + + size_t counter = 0; + for (auto& itr : addrMap) { + if (itr.second > 0) { + ++counter; + } + } + + return counter; } bool CBlockTreeDB::WriteTimestampIndex(const CTimestampIndexKey ×tampIndex) { From 88597524735ce4ae5b66920db7105d4f86213e9e Mon Sep 17 00:00:00 2001 From: levonpetrosyan93 Date: Fri, 29 Nov 2024 23:28:23 +0400 Subject: [PATCH 3/3] Typo fixed --- src/txdb.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/txdb.cpp b/src/txdb.cpp index 1c5bc6fb42..ff5e450d07 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -322,12 +322,9 @@ size_t CBlockTreeDB::findAddressNumWBalance() { std::pair key; if (pcursor->GetKey(key) && key.first == DB_ADDRESSINDEX && (key.second.type == AddressType::payToPubKeyHash || key.second.type == AddressType::payToExchangeAddress)) { CAmount nValue; - if (pcursor->GetValue(nValue)) { - CAmount nValue; - // Retrieve the associated value - if (pcursor->GetValue(nValue) && nValue != 0) { // Only process non-zero values - addrMap[key.second.hashBytes] += nValue; // Accumulate balance for the address - } + // Retrieve the associated value + if (pcursor->GetValue(nValue) && nValue != 0) { // Only process non-zero values + addrMap[key.second.hashBytes] += nValue; // Accumulate balance for the address } } pcursor->Next();