diff --git a/doc/release-notes.md b/doc/release-notes.md --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -3,3 +3,6 @@ This release includes the following features and fixes: + - Added to `getblockchaininfo` `size_on_disk` and, when the prune option is + enabled, `prune_height`, `automatic_pruning`, and `prune_target_size`. + - The help message also reflects this. diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1251,10 +1251,16 @@ "verification progress [0..1]\n" " \"chainwork\": \"xxxx\" (string) total amount of work " "in active chain, in hexadecimal\n" + " \"size_on_disk\": xxxxxx, (numeric) the estimated size of " + "the block and undo files on disk\n" " \"pruned\": xx, (boolean) if the blocks are " "subject to pruning\n" " \"pruneheight\": xxxxxx, (numeric) lowest-height " - "complete block stored\n" + "complete block stored (only present if pruning is enabled)\n" + " \"automatic_pruning\": xx, (boolean) whether automatic " + "pruning is enabled (only present if pruning is enabled)\n" + " \"prune_target_size\": xxxxxx, (numeric) the target size " + "used by pruning (only present if automatic pruning is enabled)\n" " \"softforks\": [ (array) status of softforks in " "progress\n" " {\n" @@ -1288,8 +1294,26 @@ GuessVerificationProgress(config.GetChainParams().TxData(), chainActive.Tip())); obj.pushKV("chainwork", chainActive.Tip()->nChainWork.GetHex()); + obj.pushKV("size_on_disk", CalculateCurrentUsage()); obj.pushKV("pruned", fPruneMode); + if (fPruneMode) { + CBlockIndex *block = chainActive.Tip(); + assert(block); + while (block->pprev && (block->pprev->nStatus.hasData())) { + block = block->pprev; + } + + obj.pushKV("pruneheight", block->nHeight); + + // if 0, execution bypasses the whole if block. + bool automatic_pruning = (gArgs.GetArg("-prune", 0) != 1); + obj.pushKV("automatic_pruning", automatic_pruning); + if (automatic_pruning) { + obj.pushKV("prune_target_size", nPruneTarget); + } + } + const Consensus::Params &consensusParams = config.GetChainParams().GetConsensus(); CBlockIndex *tip = chainActive.Tip(); @@ -1300,14 +1324,6 @@ softforks.push_back(SoftForkDesc("csv", 5, tip, consensusParams)); obj.pushKV("softforks", softforks); - if (fPruneMode) { - CBlockIndex *block = chainActive.Tip(); - while (block && block->pprev && block->pprev->nStatus.hasData()) { - block = block->pprev; - } - - obj.pushKV("pruneheight", block->nHeight); - } obj.pushKV("warnings", GetWarnings("statusbar")); return obj; } diff --git a/src/validation.h b/src/validation.h --- a/src/validation.h +++ b/src/validation.h @@ -425,6 +425,11 @@ double GuessVerificationProgress(const ChainTxData &data, CBlockIndex *pindex); /** + * Calculate the amount of disk space the block & undo files currently use. + */ +uint64_t CalculateCurrentUsage(); + +/** * Mark one block file as pruned. */ void PruneOneBlockFile(const int fileNumber); diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -4088,7 +4088,9 @@ /** * Calculate the amount of disk space the block & undo files currently use. */ -static uint64_t CalculateCurrentUsage() { +uint64_t CalculateCurrentUsage() { + LOCK(cs_LastBlockFile); + uint64_t retval = 0; for (const CBlockFileInfo &file : vinfoBlockFile) { retval += file.nSize + file.nUndoSize; @@ -4101,6 +4103,8 @@ * Prune a block file (modify associated database entries) */ void PruneOneBlockFile(const int fileNumber) { + LOCK(cs_LastBlockFile); + for (const std::pair &it : mapBlockIndex) { CBlockIndex *pindex = it.second; if (pindex->nFile == fileNumber) { @@ -5411,6 +5415,8 @@ } CBlockFileInfo *GetBlockFileInfo(size_t n) { + LOCK(cs_LastBlockFile); + return &vinfoBlockFile.at(n); } diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -25,6 +25,8 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, + assert_greater_than, + assert_greater_than_or_equal, assert_raises, assert_raises_rpc_error, assert_is_hash_string, @@ -61,21 +63,46 @@ 'headers', 'mediantime', 'pruned', + 'size_on_disk', 'softforks', 'verificationprogress', 'warnings', ] res = self.nodes[0].getblockchaininfo() - # result should have pruneheight and default keys if pruning is enabled - assert_equal(sorted(res.keys()), sorted(['pruneheight'] + keys)) + + # result should have these additional pruning keys if manual pruning is + # enabled + assert_equal(sorted(res.keys()), sorted( + ['pruneheight', 'automatic_pruning'] + keys)) + + # size_on_disk should be > 0 + assert_greater_than(res['size_on_disk'], 0) + # pruneheight should be greater or equal to 0 - assert res['pruneheight'] >= 0 + assert_greater_than_or_equal(res['pruneheight'], 0) + + # check other pruning fields given that prune=1 + assert res['pruned'] + assert not res['automatic_pruning'] self.restart_node(0, ['-stopatheight=207']) res = self.nodes[0].getblockchaininfo() # should have exact keys assert_equal(sorted(res.keys()), keys) + self.restart_node(0, ['-stopatheight=207', '-prune=550']) + res = self.nodes[0].getblockchaininfo() + # result should have these additional pruning keys if prune=550 + assert_equal(sorted(res.keys()), sorted( + ['pruneheight', 'automatic_pruning', 'prune_target_size'] + keys)) + + # check related fields + assert res['pruned'] + assert_equal(res['pruneheight'], 0) + assert res['automatic_pruning'] + assert_equal(res['prune_target_size'], 576716800) + assert_greater_than(res['size_on_disk'], 0) + def _test_getchaintxstats(self): self.log.info("Test getchaintxstats")