Skip to content

Commit c3aa0c1

Browse files
committed
Report on-disk size in gettxoutsetinfo
1 parent d342424 commit c3aa0c1

File tree

7 files changed

+35
-1
lines changed

7 files changed

+35
-1
lines changed

src/coins.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ uint256 CCoinsViewBacked::GetBestBlock() const { return base->GetBestBlock(); }
5555
void CCoinsViewBacked::SetBackend(CCoinsView &viewIn) { base = &viewIn; }
5656
bool CCoinsViewBacked::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) { return base->BatchWrite(mapCoins, hashBlock); }
5757
CCoinsViewCursor *CCoinsViewBacked::Cursor() const { return base->Cursor(); }
58+
size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); }
5859

5960
SaltedTxidHasher::SaltedTxidHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {}
6061

src/coins.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,9 @@ class CCoinsView
319319

320320
//! As we use CCoinsViews polymorphically, have a virtual destructor
321321
virtual ~CCoinsView() {}
322+
323+
//! Estimate database size (0 if not implemented)
324+
virtual size_t EstimateSize() const { return 0; }
322325
};
323326

324327

@@ -336,6 +339,7 @@ class CCoinsViewBacked : public CCoinsView
336339
void SetBackend(CCoinsView &viewIn);
337340
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
338341
CCoinsViewCursor *Cursor() const;
342+
size_t EstimateSize() const override;
339343
};
340344

341345

src/dbwrapper.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,22 @@ class CDBWrapper
305305
* Return true if the database managed by this class contains no entries.
306306
*/
307307
bool IsEmpty();
308+
309+
template<typename K>
310+
size_t EstimateSize(const K& key_begin, const K& key_end) const
311+
{
312+
CDataStream ssKey1(SER_DISK, CLIENT_VERSION), ssKey2(SER_DISK, CLIENT_VERSION);
313+
ssKey1.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
314+
ssKey2.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
315+
ssKey1 << key_begin;
316+
ssKey2 << key_end;
317+
leveldb::Slice slKey1(ssKey1.data(), ssKey1.size());
318+
leveldb::Slice slKey2(ssKey2.data(), ssKey2.size());
319+
uint64_t size = 0;
320+
leveldb::Range range(slKey1, slKey2);
321+
pdb->GetApproximateSizes(&range, 1, &size);
322+
return size;
323+
}
308324
};
309325

310326
#endif // BITCOIN_DBWRAPPER_H
311-

src/rpc/blockchain.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,7 @@ struct CCoinsStats
782782
uint64_t nTransactions;
783783
uint64_t nTransactionOutputs;
784784
uint256 hashSerialized;
785+
uint64_t nDiskSize;
785786
CAmount nTotalAmount;
786787

787788
CCoinsStats() : nHeight(0), nTransactions(0), nTransactionOutputs(0), nTotalAmount(0) {}
@@ -826,6 +827,7 @@ static bool GetUTXOStats(CCoinsView *view, CCoinsStats &stats)
826827
}
827828
stats.hashSerialized = ss.GetHash();
828829
stats.nTotalAmount = nTotalAmount;
830+
stats.nDiskSize = view->EstimateSize();
829831
return true;
830832
}
831833

@@ -892,6 +894,7 @@ UniValue gettxoutsetinfo(const JSONRPCRequest& request)
892894
" \"transactions\": n, (numeric) The number of transactions\n"
893895
" \"txouts\": n, (numeric) The number of output transactions\n"
894896
" \"hash_serialized\": \"hash\", (string) The serialized hash\n"
897+
" \"disk_size\": n, (numeric) The estimated size of the chainstate on disk\n"
895898
" \"total_amount\": x.xxx (numeric) The total amount\n"
896899
"}\n"
897900
"\nExamples:\n"
@@ -909,6 +912,7 @@ UniValue gettxoutsetinfo(const JSONRPCRequest& request)
909912
ret.push_back(Pair("transactions", (int64_t)stats.nTransactions));
910913
ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs));
911914
ret.push_back(Pair("hash_serialized_2", stats.hashSerialized.GetHex()));
915+
ret.push_back(Pair("disk_size", stats.nDiskSize));
912916
ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
913917
} else {
914918
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");

src/txdb.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
6767
return db.WriteBatch(batch);
6868
}
6969

70+
size_t CCoinsViewDB::EstimateSize() const
71+
{
72+
return db.EstimateSize(DB_COINS, (char)(DB_COINS+1));
73+
}
74+
7075
CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) {
7176
}
7277

src/txdb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class CCoinsViewDB : public CCoinsView
7878
uint256 GetBestBlock() const;
7979
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
8080
CCoinsViewCursor *Cursor() const;
81+
82+
size_t EstimateSize() const override;
8183
};
8284

8385
/** Specialization of CCoinsViewCursor to iterate over a CCoinsViewDB */

test/functional/blockchain.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ def _test_gettxoutsetinfo(self):
5050
assert_equal(res['height'], 200)
5151
assert_equal(res['txouts'], 200)
5252
assert_equal(res['bestblock'], node.getblockhash(200))
53+
size = res['disk_size']
54+
assert size > 6400
55+
assert size < 64000
5356
assert_equal(len(res['bestblock']), 64)
5457
assert_equal(len(res['hash_serialized_2']), 64)
5558

0 commit comments

Comments
 (0)