Merge pull request #775 from letolabs/snapshot

Snapshot II
This commit is contained in:
jl777
2018-07-18 09:35:54 -11:00
committed by GitHub

View File

@@ -402,36 +402,36 @@ bool getAddressFromIndex(const int &type, const uint160 &hash, std::string &addr
extern UniValue CBlockTreeDB::Snapshot() extern UniValue CBlockTreeDB::Snapshot()
{ {
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;
boost::scoped_ptr<leveldb::Iterator> pcursor(NewIterator()); boost::scoped_ptr<leveldb::Iterator> iter(NewIterator());
std::map <std::string, CAmount> addressAmounts; std::map <std::string, CAmount> addressAmounts;
UniValue result(UniValue::VOBJ); UniValue result(UniValue::VOBJ);
result.push_back(Pair("start_time", time(NULL))); result.push_back(Pair("start_time", time(NULL)));
//pcursor->SeekToFirst();
pcursor->SeekToLast();
int64_t startingHeight = chainActive.Height(); int64_t startingHeight = chainActive.Height();
fprintf(stderr, "Starting snapshot at height %li\n", startingHeight);
while (pcursor->Valid()) for (iter->SeekToLast(); iter->Valid(); iter->Prev())
{ {
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
try try
{ {
leveldb::Slice slKey = pcursor->key(); leveldb::Slice slKey = iter->key();
CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION); CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION);
CAddressIndexIteratorKey indexKey; CAddressIndexIteratorKey indexKey;
ssKey >> chType;
ssKey >> indexKey;
if ( chType == DB_ADDRESSUNSPENTINDEX ) ssKey >> chType;
ssKey >> indexKey;
//fprintf(stderr, "chType=%d\n", chType);
if (chType == DB_ADDRESSUNSPENTINDEX)
{ {
try { try {
leveldb::Slice slValue = pcursor->value(); leveldb::Slice slValue = iter->value();
CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION); CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
CAmount nValue; CAmount nValue;
ssValue >> nValue; ssValue >> nValue;
getAddressFromIndex(indexKey.type, indexKey.hashBytes, address); getAddressFromIndex(indexKey.type, indexKey.hashBytes, address);
std::map <std::string, CAmount>::iterator pos = addressAmounts.find(address); std::map <std::string, CAmount>::iterator pos = addressAmounts.find(address);
if (pos == addressAmounts.end()) { if (pos == addressAmounts.end()) {
// insert new address + utxo amount // insert new address + utxo amount
@@ -440,20 +440,21 @@ extern UniValue CBlockTreeDB::Snapshot()
totalAddresses++; totalAddresses++;
} else { } else {
// update unspent tally for this address // update unspent tally for this address
//fprintf(stderr, "updating address %s with new utxo amount %li\n", address.c_str(), nValue);
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;
} catch (const std::exception& e) { } catch (const std::exception& e) {
return error("failed to get address index value"); fprintf(stderr, "DONE %s: LevelDB addressindex exception! - %s\n", __func__, e.what());
break;
} }
} else { break; } }
} catch (const std::exception& e) { } catch (const std::exception& e) {
fprintf(stderr, "%s: LevelDB exception! - %s\n", __func__, e.what()); fprintf(stderr, "DONE reading index entries\n");
break; break;
} }
pcursor->Prev();
} }
UniValue addresses(UniValue::VARR); UniValue addresses(UniValue::VARR);
@@ -477,9 +478,11 @@ extern UniValue CBlockTreeDB::Snapshot()
addressesSorted.push_back(obj); addressesSorted.push_back(obj);
} }
result.push_back(make_pair("addresses", addressesSorted)); if (totalAddresses > 0) {
result.push_back(make_pair("total", total / COIN )); result.push_back(make_pair("addresses", addressesSorted));
result.push_back(make_pair("average",(double) (total/COIN) / totalAddresses )); result.push_back(make_pair("total", total / COIN ));
result.push_back(make_pair("average",(double) (total/COIN) / totalAddresses ));
}
// 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));
// The snapshot began at this block height // The snapshot began at this block height