Report on-disk size in gettxoutsetinfo
This commit is contained in:
parent
d342424301
commit
c3aa0c1194
7 changed files with 35 additions and 1 deletions
|
@ -55,6 +55,7 @@ uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); }
|
||||||
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
|
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
|
||||||
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
|
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
|
||||||
CCoinsViewCursor *CCoinsViewBacked::Cursor() const { return base->Cursor(); }
|
CCoinsViewCursor *CCoinsViewBacked::Cursor() const { return base->Cursor(); }
|
||||||
|
size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); }
|
||||||
|
|
||||||
SaltedTxidHasher::SaltedTxidHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {}
|
SaltedTxidHasher::SaltedTxidHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {}
|
||||||
|
|
||||||
|
|
|
@ -319,6 +319,9 @@ public:
|
||||||
|
|
||||||
//! As we use CCoinsViews polymorphically, have a virtual destructor
|
//! As we use CCoinsViews polymorphically, have a virtual destructor
|
||||||
virtual ~CCoinsView() {}
|
virtual ~CCoinsView() {}
|
||||||
|
|
||||||
|
//! Estimate database size (0 if not implemented)
|
||||||
|
virtual size_t EstimateSize() const { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -336,6 +339,7 @@ public:
|
||||||
void SetBackend(CCoinsView &viewIn);
|
void SetBackend(CCoinsView &viewIn);
|
||||||
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
|
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
|
||||||
CCoinsViewCursor *Cursor() const;
|
CCoinsViewCursor *Cursor() const;
|
||||||
|
size_t EstimateSize() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -305,7 +305,22 @@ public:
|
||||||
* Return true if the database managed by this class contains no entries.
|
* Return true if the database managed by this class contains no entries.
|
||||||
*/
|
*/
|
||||||
bool IsEmpty();
|
bool IsEmpty();
|
||||||
|
|
||||||
|
template<typename K>
|
||||||
|
size_t EstimateSize(const K& key_begin, const K& key_end) const
|
||||||
|
{
|
||||||
|
CDataStream ssKey1(SER_DISK, CLIENT_VERSION), ssKey2(SER_DISK, CLIENT_VERSION);
|
||||||
|
ssKey1.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
|
||||||
|
ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
|
||||||
|
ssKey1 << key_begin;
|
||||||
|
ssKey2 << key_end;
|
||||||
|
leveldb::Slice slKey1(ssKey1.data(), ssKey1.size());
|
||||||
|
leveldb::Slice slKey2(ssKey2.data(), ssKey2.size());
|
||||||
|
uint64_t size = 0;
|
||||||
|
leveldb::Range range(slKey1, slKey2);
|
||||||
|
pdb->GetApproximateSizes(&range, 1, &size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BITCOIN_DBWRAPPER_H
|
#endif // BITCOIN_DBWRAPPER_H
|
||||||
|
|
||||||
|
|
|
@ -782,6 +782,7 @@ struct CCoinsStats
|
||||||
uint64_t nTransactions;
|
uint64_t nTransactions;
|
||||||
uint64_t nTransactionOutputs;
|
uint64_t nTransactionOutputs;
|
||||||
uint256 hashSerialized;
|
uint256 hashSerialized;
|
||||||
|
uint64_t nDiskSize;
|
||||||
CAmount nTotalAmount;
|
CAmount nTotalAmount;
|
||||||
|
|
||||||
CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nTotalAmount(0) {}
|
CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nTotalAmount(0) {}
|
||||||
|
@ -826,6 +827,7 @@ static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
|
||||||
}
|
}
|
||||||
stats.hashSerialized = ss.GetHash();
|
stats.hashSerialized = ss.GetHash();
|
||||||
stats.nTotalAmount = nTotalAmount;
|
stats.nTotalAmount = nTotalAmount;
|
||||||
|
stats.nDiskSize = view->EstimateSize();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -892,6 +894,7 @@ UniValue gettxoutsetinfo(const JSONRPCRequest& request)
|
||||||
" \"transactions\": n, (numeric) The number of transactions\n"
|
" \"transactions\": n, (numeric) The number of transactions\n"
|
||||||
" \"txouts\": n, (numeric) The number of output transactions\n"
|
" \"txouts\": n, (numeric) The number of output transactions\n"
|
||||||
" \"hash_serialized\": \"hash\", (string) The serialized hash\n"
|
" \"hash_serialized\": \"hash\", (string) The serialized hash\n"
|
||||||
|
" \"disk_size\": n, (numeric) The estimated size of the chainstate on disk\n"
|
||||||
" \"total_amount\": x.xxx (numeric) The total amount\n"
|
" \"total_amount\": x.xxx (numeric) The total amount\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"\nExamples:\n"
|
"\nExamples:\n"
|
||||||
|
@ -909,6 +912,7 @@ UniValue gettxoutsetinfo(const JSONRPCRequest& request)
|
||||||
ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
|
ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
|
||||||
ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
|
ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
|
||||||
ret.push_back(Pair("hash_serialized_2", stats.hashSerialized.GetHex()));
|
ret.push_back(Pair("hash_serialized_2", stats.hashSerialized.GetHex()));
|
||||||
|
ret.push_back(Pair("disk_size", stats.nDiskSize));
|
||||||
ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
|
ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
|
||||||
} else {
|
} else {
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
|
||||||
|
|
|
@ -67,6 +67,11 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
|
||||||
return db.WriteBatch(batch);
|
return db.WriteBatch(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t CCoinsViewDB::EstimateSize() const
|
||||||
|
{
|
||||||
|
return db.EstimateSize(DB_COINS, (char)(DB_COINS+1));
|
||||||
|
}
|
||||||
|
|
||||||
CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) {
|
CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,8 @@ public:
|
||||||
uint256 GetBestBlock() const;
|
uint256 GetBestBlock() const;
|
||||||
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
|
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
|
||||||
CCoinsViewCursor *Cursor() const;
|
CCoinsViewCursor *Cursor() const;
|
||||||
|
|
||||||
|
size_t EstimateSize() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Specialization of CCoinsViewCursor to iterate over a CCoinsViewDB */
|
/** Specialization of CCoinsViewCursor to iterate over a CCoinsViewDB */
|
||||||
|
|
|
@ -50,6 +50,9 @@ class BlockchainTest(BitcoinTestFramework):
|
||||||
assert_equal(res['height'], 200)
|
assert_equal(res['height'], 200)
|
||||||
assert_equal(res['txouts'], 200)
|
assert_equal(res['txouts'], 200)
|
||||||
assert_equal(res['bestblock'], node.getblockhash(200))
|
assert_equal(res['bestblock'], node.getblockhash(200))
|
||||||
|
size = res['disk_size']
|
||||||
|
assert size > 6400
|
||||||
|
assert size < 64000
|
||||||
assert_equal(len(res['bestblock']), 64)
|
assert_equal(len(res['bestblock']), 64)
|
||||||
assert_equal(len(res['hash_serialized_2']), 64)
|
assert_equal(len(res['hash_serialized_2']), 64)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue