From f1e1ea613397f369cc95cab636e1675aee66d992 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 23 Jul 2018 04:33:47 +0000 Subject: [PATCH] WIP add 'top N only' feature to gensnapshot rpc --- src/main.cpp | 4 ++-- src/rpcmisc.cpp | 43 +++++++++++++++++++++++++++++++++++++++---- src/txdb.cpp | 18 +++++++++++++++--- src/txdb.h | 2 +- 4 files changed, 57 insertions(+), 10 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index aa4435843..5ac78e38b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -588,7 +588,7 @@ CBlockTreeDB *pblocktree = NULL; #define KOMODO_ZCASH #include "komodo.h" -UniValue komodo_snapshot() +UniValue komodo_snapshot(int top) { LOCK(cs_main); int64_t total = -1; @@ -596,7 +596,7 @@ UniValue komodo_snapshot() if (fAddressIndex) { if ( pblocktree != 0 ) { - result = pblocktree->Snapshot(); + result = pblocktree->Snapshot(top); } else { fprintf(stderr,"null pblocktree start with -addressindex=true\n"); } diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 8eeff7877..657227173 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -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 result(UniValue::VOBJ); int64_t total; - if ( fHelp || params.size() > 0 ) + UniValue result(UniValue::VOBJ); int64_t total; int top = 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( "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 ) { result.push_back(Pair("end_time", time(NULL))); } else { diff --git a/src/txdb.cpp b/src/txdb.cpp index 6d0be5b61..7ca6175b0 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -399,7 +399,7 @@ bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, int type, 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; int64_t utxos = 0; int64_t ignoredAddresses; @@ -472,7 +472,7 @@ extern UniValue CBlockTreeDB::Snapshot() addressAmounts[address] += nValue; } //fprintf(stderr,"{\"%s\", %.8f},\n",address.c_str(),(double)nValue/COIN); - total += nValue; + // total += nValue; utxos++; } catch (const std::exception& e) { 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 addressesSorted(UniValue::VARR); + int topN = 0; for (std::vector>::iterator it = vaddr.begin(); it!=vaddr.end(); ++it) { UniValue obj(UniValue::VOBJ); obj.push_back( make_pair("addr", it->second.c_str() ) ); char amount[32]; sprintf(amount, "%.8f", (double) it->first / COIN); obj.push_back( make_pair("amount", amount) ); + total += it->first; 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) { + // Array of all addreses with balances 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 )); + // Average amount in each address of this snapshot 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)); // Total number of addresses in this snaphot result.push_back(make_pair("total_addresses", totalAddresses)); diff --git a/src/txdb.h b/src/txdb.h index 6c6b41917..4a5a367e7 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -95,7 +95,7 @@ public: bool ReadFlag(const std::string &name, bool &fValue); bool LoadBlockIndexGuts(); bool blockOnchainActive(const uint256 &hash); - UniValue Snapshot(); + UniValue Snapshot(int top); }; #endif // BITCOIN_TXDB_H