Browse Source

Improve gettxoutsetinfo command

* Bugfix: output the correct best block hash (during IBD, it can
  differ from the actual current best block)
* Add height to output
* Add hash_serialized, which is a hash of the entire UTXO state.
  Can be useful to compare two nodes.
* Add total_amount, the sum of all UTXOs' values.
0.8
Pieter Wuille 12 years ago
parent
commit
e31aa7c9d7
  1. 5
      src/main.h
  2. 5
      src/rpcblockchain.cpp
  3. 22
      src/txdb.cpp

5
src/main.h

@ -2096,11 +2096,14 @@ extern CTxMemPool mempool;
struct CCoinsStats struct CCoinsStats
{ {
int nHeight; int nHeight;
uint256 hashBlock;
uint64 nTransactions; uint64 nTransactions;
uint64 nTransactionOutputs; uint64 nTransactionOutputs;
uint64 nSerializedSize; uint64 nSerializedSize;
uint256 hashSerialized;
int64 nTotalAmount;
CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0) {} CCoinsStats() : nHeight(0), hashBlock(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), hashSerialized(0), nTotalAmount(0) {}
}; };
/** Abstract view on the open txout dataset. */ /** Abstract view on the open txout dataset. */

5
src/rpcblockchain.cpp

@ -172,10 +172,13 @@ Value gettxoutsetinfo(const Array& params, bool fHelp)
CCoinsStats stats; CCoinsStats stats;
if (pcoinsTip->GetStats(stats)) { if (pcoinsTip->GetStats(stats)) {
ret.push_back(Pair("bestblock", pcoinsTip->GetBestBlock()->GetBlockHash().GetHex())); ret.push_back(Pair("height", (boost::int64_t)stats.nHeight));
ret.push_back(Pair("bestblock", stats.hashBlock.GetHex()));
ret.push_back(Pair("transactions", (boost::int64_t)stats.nTransactions)); ret.push_back(Pair("transactions", (boost::int64_t)stats.nTransactions));
ret.push_back(Pair("txouts", (boost::int64_t)stats.nTransactionOutputs)); ret.push_back(Pair("txouts", (boost::int64_t)stats.nTransactionOutputs));
ret.push_back(Pair("bytes_serialized", (boost::int64_t)stats.nSerializedSize)); ret.push_back(Pair("bytes_serialized", (boost::int64_t)stats.nSerializedSize));
ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
} }
return ret; return ret;
} }

22
src/txdb.cpp

@ -5,6 +5,7 @@
#include "txdb.h" #include "txdb.h"
#include "main.h" #include "main.h"
#include "hash.h"
using namespace std; using namespace std;
@ -114,6 +115,10 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) {
leveldb::Iterator *pcursor = db.NewIterator(); leveldb::Iterator *pcursor = db.NewIterator();
pcursor->SeekToFirst(); pcursor->SeekToFirst();
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
stats.hashBlock = GetBestBlock()->GetBlockHash();
ss << stats.hashBlock;
int64 nTotalAmount = 0;
while (pcursor->Valid()) { while (pcursor->Valid()) {
boost::this_thread::interruption_point(); boost::this_thread::interruption_point();
try { try {
@ -128,13 +133,22 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) {
ssValue >> coins; ssValue >> coins;
uint256 txhash; uint256 txhash;
ssKey >> txhash; ssKey >> txhash;
ss << txhash;
ss << VARINT(coins.nVersion);
ss << (coins.fCoinBase ? 'c' : 'n');
ss << VARINT(coins.nHeight);
stats.nTransactions++; stats.nTransactions++;
BOOST_FOREACH(const CTxOut &out, coins.vout) { for (unsigned int i=0; i<coins.vout.size(); i++) {
if (!out.IsNull()) const CTxOut &out = coins.vout[i];
if (!out.IsNull()) {
stats.nTransactionOutputs++; stats.nTransactionOutputs++;
ss << VARINT(i+1);
ss << out;
nTotalAmount += out.nValue;
}
} }
stats.nSerializedSize += 32 + slValue.size(); stats.nSerializedSize += 32 + slValue.size();
ss << VARINT(0);
} }
pcursor->Next(); pcursor->Next();
} catch (std::exception &e) { } catch (std::exception &e) {
@ -143,6 +157,8 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) {
} }
delete pcursor; delete pcursor;
stats.nHeight = GetBestBlock()->nHeight; stats.nHeight = GetBestBlock()->nHeight;
stats.hashSerialized = ss.GetHash();
stats.nTotalAmount = nTotalAmount;
return true; return true;
} }

Loading…
Cancel
Save