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..ff5e450d07 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -313,6 +313,32 @@ 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; + // 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(); + } + + size_t counter = 0; + for (auto& itr : addrMap) { + if (itr.second > 0) { + ++counter; + } + } + + return counter; +} 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);