WIP add 'top N only' feature to gensnapshot rpc

This commit is contained in:
Duke Leto
2018-07-23 04:33:47 +00:00
parent 1aa7af1794
commit f1e1ea6133
4 changed files with 57 additions and 10 deletions

View File

@@ -588,7 +588,7 @@ CBlockTreeDB *pblocktree = NULL;
#define KOMODO_ZCASH #define KOMODO_ZCASH
#include "komodo.h" #include "komodo.h"
UniValue komodo_snapshot() UniValue komodo_snapshot(int top)
{ {
LOCK(cs_main); LOCK(cs_main);
int64_t total = -1; int64_t total = -1;
@@ -596,7 +596,7 @@ UniValue komodo_snapshot()
if (fAddressIndex) { if (fAddressIndex) {
if ( pblocktree != 0 ) { if ( pblocktree != 0 ) {
result = pblocktree->Snapshot(); result = pblocktree->Snapshot(top);
} else { } else {
fprintf(stderr,"null pblocktree start with -addressindex=true\n"); fprintf(stderr,"null pblocktree start with -addressindex=true\n");
} }

View File

@@ -1015,18 +1015,53 @@ UniValue getaddressbalance(const UniValue& params, bool fHelp)
} }
UniValue komodo_snapshot(); UniValue komodo_snapshot(int top);
UniValue getsnapshot(const UniValue& params, bool fHelp) UniValue getsnapshot(const UniValue& params, bool fHelp)
{ {
UniValue result(UniValue::VOBJ); int64_t total; UniValue result(UniValue::VOBJ); int64_t total; int top = 0;
if ( fHelp || params.size() > 0 )
if (params.size() > 0 && !params[0].isNull()) {
top = params[0].get_str();
fprintf(stderr, "top=%s\n",top);
if (top <= 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, top must be a positive integer");
}
if ( fHelp || params.size() > 1)
{ {
throw runtime_error( throw runtime_error(
"getsnapshot\n" "getsnapshot\n"
"\nReturns a snapshot of (address,amount) pairs at current height (requires addressindex to be enabled).\n"
"\nArguments:\n"
" \"top\" (number, optional) Only return this many addresses, i.e. top N richlist\n"
"\nResult:\n"
"{\n"
" \"addresses\": [\n"
" {\n"
" \"addr\": \"RMEBhzvATA8mrfVK82E5TgPzzjtaggRGN3\",\n"
" \"amount\": \"100.0\"\n"
" },\n"
" {\n"
" \"addr\": \"RqEBhzvATAJmrfVL82E57gPzzjtaggR777\",\n"
" \"amount\": \"23.45\"\n"
" }\n"
" ],\n"
" \"total\": 123.45 (numeric) Total amount in snapshot\n"
" \"average\": 61.7, (numeric) Average amount in each address \n"
" \"utxos\": 14, (number) Total number of UTXOs in snapshot\n"
" \"total_addresses\": 2, (number) Total number of addresses in snapshot,\n"
" \"start_height\": 91, (number) Block height snapshot began\n"
" \"ending_height\": 91 (number) Block height snapsho finished,\n"
" \"start_time\": 1531982752, (number) Unix epoch time snapshot started\n"
" \"end_time\": 1531982752 (number) Unix epoch time snapshot finished\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("getsnapshot","")
+ HelpExampleRpc("getsnapshot", "1000")
); );
} }
result = komodo_snapshot(); result = komodo_snapshot(top);
if ( result.size() > 0 ) { if ( result.size() > 0 ) {
result.push_back(Pair("end_time", time(NULL))); result.push_back(Pair("end_time", time(NULL)));
} else { } else {

View File

@@ -399,7 +399,7 @@ bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, int type,
bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &address); bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &address);
extern UniValue CBlockTreeDB::Snapshot() extern UniValue CBlockTreeDB::Snapshot(int top)
{ {
char chType; int64_t total = 0; int64_t totalAddresses = 0; std::string address; char chType; int64_t total = 0; int64_t totalAddresses = 0; std::string address;
int64_t utxos = 0; int64_t ignoredAddresses; int64_t utxos = 0; int64_t ignoredAddresses;
@@ -472,7 +472,7 @@ extern UniValue CBlockTreeDB::Snapshot()
addressAmounts[address] += nValue; addressAmounts[address] += nValue;
} }
//fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN); //fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN);
total += nValue; // total += nValue;
utxos++; utxos++;
} catch (const std::exception& e) { } catch (const std::exception& e) {
fprintf(stderr, "DONE %s: LevelDB addressindex exception! - %s\n", __func__, e.what()); fprintf(stderr, "DONE %s: LevelDB addressindex exception! - %s\n", __func__, e.what());
@@ -495,21 +495,33 @@ extern UniValue CBlockTreeDB::Snapshot()
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
UniValue addressesSorted(UniValue::VARR); UniValue addressesSorted(UniValue::VARR);
int topN = 0;
for (std::vector<std::pair<CAmount, std::string>>::iterator it = vaddr.begin(); it!=vaddr.end(); ++it) { for (std::vector<std::pair<CAmount, std::string>>::iterator it = vaddr.begin(); it!=vaddr.end(); ++it) {
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
obj.push_back( make_pair("addr", it->second.c_str() ) ); obj.push_back( make_pair("addr", it->second.c_str() ) );
char amount[32]; char amount[32];
sprintf(amount, "%.8f", (double) it->first / COIN); sprintf(amount, "%.8f", (double) it->first / COIN);
obj.push_back( make_pair("amount", amount) ); obj.push_back( make_pair("amount", amount) );
total += it->first;
addressesSorted.push_back(obj); addressesSorted.push_back(obj);
topN++;
// If requested, only show top N addresses in output JSON
if (top == topN)
break;
} }
if (top)
totalAddresses = top;
if (totalAddresses > 0) { if (totalAddresses > 0) {
// Array of all addreses with balances
result.push_back(make_pair("addresses", addressesSorted)); result.push_back(make_pair("addresses", addressesSorted));
// Total amount in this snapshot, which is less than circulating supply if top parameter is used
result.push_back(make_pair("total", (double) total / COIN )); result.push_back(make_pair("total", (double) total / COIN ));
// Average amount in each address of this snapshot
result.push_back(make_pair("average",(double) (total/COIN) / totalAddresses )); result.push_back(make_pair("average",(double) (total/COIN) / totalAddresses ));
} }
// Total number of utxos in this snaphot // Total number of utxos processed in this snaphot
result.push_back(make_pair("utxos", utxos)); result.push_back(make_pair("utxos", utxos));
// Total number of addresses in this snaphot // Total number of addresses in this snaphot
result.push_back(make_pair("total_addresses", totalAddresses)); result.push_back(make_pair("total_addresses", totalAddresses));

View File

@@ -95,7 +95,7 @@ public:
bool ReadFlag(const std::string &name, bool &fValue); bool ReadFlag(const std::string &name, bool &fValue);
bool LoadBlockIndexGuts(); bool LoadBlockIndexGuts();
bool blockOnchainActive(const uint256 &hash); bool blockOnchainActive(const uint256 &hash);
UniValue Snapshot(); UniValue Snapshot(int top);
}; };
#endif // BITCOIN_TXDB_H #endif // BITCOIN_TXDB_H