Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
Already on GitHub? Sign in to your account
[rpc] getblockchaininfo: add size_on_disk, prune_target_size #11367
Conversation
fanquake
added
the
RPC/REST/ZMQ
label
Sep 19, 2017
|
If #11359 gets in it might be nice to have the prune hwm in there too, but I didn't want to add the dependency. |
jnewbery
reviewed
Sep 19, 2017
concept ACK. One nit inline.
Consider adding an explicit test for the getblockchaininfo RPC method to test/functional/blockchain.py.
| @@ -1137,6 +1137,8 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) | ||
| " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n" | ||
| " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n" | ||
| " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n" | ||
| + " \"disk_size\": xxxxxx, (numeric) the estimated size of the block and undo files on disk\n" |
jnewbery
Sep 19, 2017
Member
nit: perhaps disk_usage or size_on_disk?
Also consider placing this above pruned so all of the pruning-related fields are grouped.
promag
Sep 19, 2017
Contributor
IMO we should test the response result. In this case, at least, check that the key exists and value is a number. cc @jnewbery
| @@ -1180,6 +1182,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) | ||
| obj.push_back(Pair("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip()))); | ||
| obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); | ||
| obj.push_back(Pair("pruned", fPruneMode)); | ||
| + obj.push_back(Pair("disk_size", CalculateCurrentUsage())); |
|
Test for |
esotericnonsense
referenced this pull request
Sep 20, 2017
Closed
[rpc] Fix pruneheight help description in getblockchaininfo #11366
esotericnonsense
changed the title from
RPC: getblockchaininfo: Add disk_size, prune_target_size
to
[rpc] getblockchaininfo: add size_on_disk, prune_target_size
Sep 20, 2017
esotericnonsense
referenced this pull request
Sep 20, 2017
Merged
[test] Add getblockchaininfo functional test #11370
| @@ -1135,8 +1135,10 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) | ||
| " \"mediantime\": xxxxxx, (numeric) median time for the current best block\n" | ||
| " \"verificationprogress\": xxxx, (numeric) estimate of 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" |
jnewbery
Sep 20, 2017
Member
The help text for pruneheight should also include "(only present if pruning is enabled)"
| @@ -156,6 +156,7 @@ struct BlockHasher | ||
| extern CScript COINBASE_FLAGS; | ||
| extern CCriticalSection cs_main; | ||
| +extern CCriticalSection cs_LastBlockFile; |
sipa
Sep 21, 2017
Owner
I'd rather not expose more variables that are private to validation to the outside world.
Perhaps you can instead create a wrapper around CalculateCurrentUsage, which just grabs cs_LastBlockFile and calls the internal one, and expose that? That way the RPC code wouldn't need to know about the existence of that lock eve.
promag
Sep 21, 2017
Contributor
Why not just lock cs_LastBlockFile in CalculateCurrentUsage? It's a recursive mutex and IMO should be locked where it's needed (BTW the same for remaining locks...).
| obj.push_back(Pair("pruned", fPruneMode)); | ||
| + if (fPruneMode) { | ||
| + CBlockIndex *block = chainActive.Tip(); |
| @@ -156,6 +156,7 @@ struct BlockHasher | ||
| extern CScript COINBASE_FLAGS; | ||
| extern CCriticalSection cs_main; | ||
| +extern CCriticalSection cs_LastBlockFile; |
promag
Sep 21, 2017
Contributor
Why not just lock cs_LastBlockFile in CalculateCurrentUsage? It's a recursive mutex and IMO should be locked where it's needed (BTW the same for remaining locks...).
| @@ -1168,7 +1170,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) | ||
| + HelpExampleRpc("getblockchaininfo", "") | ||
| ); | ||
| - LOCK(cs_main); | ||
| + LOCK2(cs_main, cs_LastBlockFile); // cs_LastBlockFile for CalculateCurrentUsage() |
jonasschnelli
Sep 22, 2017
Member
As @sipa already commented, CalculateCurrentUsage() should be responsible for concurrency locking (not the calling code part).
| " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n" | ||
| - " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n" | ||
| + " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored (only present if pruning is enabled)\n" | ||
| + " \"prune_target_size\": xxxxxx, (numeric) the target size used by pruning (only present if pruning is enabled)\n" |
esotericnonsense
Sep 22, 2017
Contributor
I followed the example of 'verificationprogress'; can indent the others further if you think that makes sense.
|
Concept ACK |
|
Rebased on master, moved the lock into CalculateCurrentUsage, Travis failed on one platform (iirc linux64) on a timeout in p2p-segwit last time. Not sure why. We'll see how it goes. edit: looks good. |
|
utACK 071879a |
|
I've just tested this with
That's because of this section in
Returning the max int for |
|
Hmmm. Yes, that isn't desirable behaviour. Options I can see: b) fixes the RPC without having to touch pruning code but otherwise seems a bit messy to me. |
|
Or instead of b) just see if gArgs.GetArg("-prune", 0) is 1? |
|
I think just testing the value of |
|
|
Please rebase with #11370. |
|
Rebased on master and added tests for the relevant fields in test/functional/blockchain.py. My box:
|
| + | ||
| + obj.push_back(Pair("pruneheight", block->nHeight)); | ||
| + | ||
| + bool fPruneAuto = (gArgs.GetArg("-prune", 0) > 1); |
jnewbery
Sep 26, 2017
Member
current code style is snake_case for variables (https://github.com/bitcoin/bitcoin/blob/master/doc/developer-notes.md#developer-notes). prune_auto or auto_prune should be fine.
jnewbery
Sep 26, 2017
Member
nit: Since 1 is a magic number meaning manual pruning, I think it's clearer to use equality like in init.cpp, rather than greater-than:
bool fPruneAuto = (gArgs.GetArg("-prune", 0) != 1);
esotericnonsense
Sep 26, 2017
•
Contributor
I was torn there, because that actually gives True in the case prune=0, but that case can never happen because execution would skip over the if (fPruneMode) block. I'll change it.
| + obj.push_back(Pair("pruneheight", block->nHeight)); | ||
| + | ||
| + bool fPruneAuto = (gArgs.GetArg("-prune", 0) > 1); | ||
| + obj.push_back(Pair("pruneauto", fPruneAuto)); |
jnewbery
Sep 26, 2017
Member
Please also use snake_case for RPC fields. I think automatic_pruning is appropriate here.
jnewbery
reviewed
Sep 26, 2017
Implementation looks good. I've slightly tested and it works well.
A few style nits inline.
| + | ||
| + obj.push_back(Pair("pruneheight", block->nHeight)); | ||
| + | ||
| + bool fPruneAuto = (gArgs.GetArg("-prune", 0) > 1); |
jnewbery
Sep 26, 2017
Member
nit: Since 1 is a magic number meaning manual pruning, I think it's clearer to use equality like in init.cpp, rather than greater-than:
bool fPruneAuto = (gArgs.GetArg("-prune", 0) != 1);
| + assert_equal(sorted(res.keys()), sorted(['pruneheight', 'pruneauto'] + keys)) | ||
| + | ||
| + # size_on_disk should be >= 0 | ||
| + assert res['size_on_disk'] >= 0 |
jnewbery
Sep 26, 2017
Member
assert_greater_than_or_equal() is better here (since it will print out the value of res['size_on_disk'] if the assert fails)
esotericnonsense
Sep 26, 2017
Contributor
As below I've dropped the 'equal to' because I don't see why it should ever be 0 unless there's some caching going on.
| # pruneheight should be greater or equal to 0 | ||
| assert res['pruneheight'] >= 0 | ||
| + # check other pruning fields given that prune=1 | ||
| + assert_equal(res['pruned'], True) |
jnewbery
Sep 26, 2017
Member
No need for assert_equal when comparing a value to True or False. The following is fine:
assert res['pruned']
assert not res['pruneauto']| + assert_equal(res['pruneheight'], 0) | ||
| + assert_equal(res['pruneauto'], True) | ||
| + assert_equal(res['prune_target_size'], 576716800) | ||
| + assert_equal(res['size_on_disk'], 55550) |
jnewbery
Sep 26, 2017
Member
suggest that you change this to assert that size_on_disk is greater than zero. This test would fail unnecessarily if a change in the implementation changed the size on disk.
|
Changes made and rebased on master (second push, first was a mistake). |
|
Tested ACK 2b73ece |
| { | ||
| + LOCK(cs_LastBlockFile); |
TheBlueMatt
Sep 27, 2017
Contributor
While you're at it can you add this lock to PruneOneBlockFile and GetBlockFileInfo (both of which are only called without lock during testing, so its not an actual issue, just annoying).
|
Needs rebase™ |
|
®ebased |
|
utA©K b7dfc6c |
|
re-utACK b7dfc6c. In the future, can you avoid rebasing when squashing unless you need to? Avoiding rebasing onto latest master makes it easier for reviewers to identify what changed between reviews. |
|
Yes, I can do that in the future. I hadn't considered that. |
|
It is fine to just amend the existing commits with fix-ups, as reviewers
have the original commits fetched locally. So it is easy to compare the two
versions.
However, with a rebase on master in between, the reviewer needs to
painfully repeat the same rebase in some way.
|
esotericnonsense commentedSep 19, 2017
No description provided.