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);