@ -18,11 +18,14 @@
# include "txmempool.h"
# include "txmempool.h"
# include "util.h"
# include "util.h"
# include "utilstrencodings.h"
# include "utilstrencodings.h"
# include "hash.h"
# include <stdint.h>
# include <stdint.h>
# include <univalue.h>
# include <univalue.h>
# include <boost/thread/thread.hpp> // boost::thread::interrupt
using namespace std ;
using namespace std ;
extern void TxToJSON ( const CTransaction & tx , const uint256 hashBlock , UniValue & entry ) ;
extern void TxToJSON ( const CTransaction & tx , const uint256 hashBlock , UniValue & entry ) ;
@ -432,6 +435,59 @@ UniValue getblock(const UniValue& params, bool fHelp)
return blockToJSON ( block , pblockindex ) ;
return blockToJSON ( block , pblockindex ) ;
}
}
struct CCoinsStats
{
int nHeight ;
uint256 hashBlock ;
uint64_t nTransactions ;
uint64_t nTransactionOutputs ;
uint64_t nSerializedSize ;
uint256 hashSerialized ;
CAmount nTotalAmount ;
CCoinsStats ( ) : nHeight ( 0 ) , nTransactions ( 0 ) , nTransactionOutputs ( 0 ) , nSerializedSize ( 0 ) , nTotalAmount ( 0 ) { }
} ;
//! Calculate statistics about the unspent transaction output set
static bool GetUTXOStats ( CCoinsView * view , CCoinsStats & stats )
{
boost : : scoped_ptr < CCoinsViewCursor > pcursor ( view - > Cursor ( ) ) ;
CHashWriter ss ( SER_GETHASH , PROTOCOL_VERSION ) ;
stats . hashBlock = pcursor - > GetBestBlock ( ) ;
{
LOCK ( cs_main ) ;
stats . nHeight = mapBlockIndex . find ( stats . hashBlock ) - > second - > nHeight ;
}
ss < < stats . hashBlock ;
CAmount nTotalAmount = 0 ;
while ( pcursor - > Valid ( ) ) {
boost : : this_thread : : interruption_point ( ) ;
uint256 key ;
CCoins coins ;
if ( pcursor - > GetKey ( key ) & & pcursor - > GetValue ( coins ) ) {
stats . nTransactions + + ;
for ( unsigned int i = 0 ; i < coins . vout . size ( ) ; i + + ) {
const CTxOut & out = coins . vout [ i ] ;
if ( ! out . IsNull ( ) ) {
stats . nTransactionOutputs + + ;
ss < < VARINT ( i + 1 ) ;
ss < < out ;
nTotalAmount + = out . nValue ;
}
}
stats . nSerializedSize + = 32 + pcursor - > GetValueSize ( ) ;
ss < < VARINT ( 0 ) ;
} else {
return error ( " %s: unable to read value " , __func__ ) ;
}
pcursor - > Next ( ) ;
}
stats . hashSerialized = ss . GetHash ( ) ;
stats . nTotalAmount = nTotalAmount ;
return true ;
}
UniValue gettxoutsetinfo ( const UniValue & params , bool fHelp )
UniValue gettxoutsetinfo ( const UniValue & params , bool fHelp )
{
{
if ( fHelp | | params . size ( ) ! = 0 )
if ( fHelp | | params . size ( ) ! = 0 )
@ -458,7 +514,7 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp)
CCoinsStats stats ;
CCoinsStats stats ;
FlushStateToDisk ( ) ;
FlushStateToDisk ( ) ;
if ( pcoinsTip - > GetStats ( stats ) ) {
if ( GetUTXOStats ( pcoinsTip , stats ) ) {
ret . push_back ( Pair ( " height " , ( int64_t ) stats . nHeight ) ) ;
ret . push_back ( Pair ( " height " , ( int64_t ) stats . nHeight ) ) ;
ret . push_back ( Pair ( " bestblock " , stats . hashBlock . GetHex ( ) ) ) ;
ret . push_back ( Pair ( " bestblock " , stats . hashBlock . GetHex ( ) ) ) ;
ret . push_back ( Pair ( " transactions " , ( int64_t ) stats . nTransactions ) ) ;
ret . push_back ( Pair ( " transactions " , ( int64_t ) stats . nTransactions ) ) ;