Skip to content

Commit

Permalink
Return height of last block pruned by pruneblockchain RPC
Browse files Browse the repository at this point in the history
Change suggested by Jonas Schnelli <[email protected]> in
bitcoin/bitcoin#7871 (comment)
  • Loading branch information
ryanofsky committed Jan 11, 2017
1 parent e2e624d commit 918d1fb
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 8 deletions.
27 changes: 22 additions & 5 deletions qa/rpc-tests/pruning.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import time
import os

MIN_BLOCKS_TO_KEEP = 288


def calc_usage(blockdir):
return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f)) / (1024. * 1024.)
Expand Down Expand Up @@ -241,6 +243,21 @@ def height(index):
else:
return index

def prune(index, expected_ret=None):
ret = node.pruneblockchain(height(index))
# Check the return value. When use_timestamp is True, just check
# that the return value is less than or equal to the expected
# value, because when more than one block is generated per second,
# a timestamp will not be granular enough to uniquely identify an
# individual block.
if expected_ret is None:
expected_ret = index
if use_timestamp:
assert_greater_than(ret, 0)
assert_greater_than(expected_ret + 1, ret)
else:
assert_equal(ret, expected_ret)

def has_block(index):
return os.path.isfile(self.options.tmpdir + "/node{}/regtest/blocks/blk{:05}.dat".format(node_number, index))

Expand All @@ -264,30 +281,30 @@ def has_block(index):
pass

# height=100 too low to prune first block file so this is a no-op
node.pruneblockchain(height(100))
prune(100)
if not has_block(0):
raise AssertionError("blk00000.dat is missing when should still be there")

# height=500 should prune first file
node.pruneblockchain(height(500))
prune(500)
if has_block(0):
raise AssertionError("blk00000.dat is still there, should be pruned by now")
if not has_block(1):
raise AssertionError("blk00001.dat is missing when should still be there")

# height=650 should prune second file
node.pruneblockchain(height(650))
prune(650)
if has_block(1):
raise AssertionError("blk00001.dat is still there, should be pruned by now")

# height=1000 should not prune anything more, because tip-288 is in blk00002.dat.
node.pruneblockchain(height(1000))
prune(1000, 1001 - MIN_BLOCKS_TO_KEEP)
if not has_block(2):
raise AssertionError("blk00002.dat is still there, should be pruned by now")

# advance the tip so blk00002.dat and blk00003.dat can be pruned (the last 288 blocks should now be in blk00004.dat)
node.generate(288)
node.pruneblockchain(height(1000))
prune(1000)
if has_block(2):
raise AssertionError("blk00002.dat is still there, should be pruned by now")
if has_block(3):
Expand Down
13 changes: 10 additions & 3 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,12 @@ UniValue pruneblockchain(const JSONRPCRequest& request)
throw runtime_error(
"pruneblockchain\n"
"\nArguments:\n"
"1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or to a unix timestamp to prune based on block time.\n");
"1. \"height\" (numeric, required) The block height to prune up to. May be set to a discrete height, or to a unix timestamp to prune based on block time.\n"
"\nResult:\n"
"n (numeric) Height of the last block pruned.\n"
"\nExamples:\n"
+ HelpExampleCli("pruneblockchain", "1000")
+ HelpExampleRpc("pruneblockchain", "1000"));

if (!fPruneMode)
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Cannot prune blocks because node is not in prune mode.");
Expand All @@ -847,11 +852,13 @@ UniValue pruneblockchain(const JSONRPCRequest& request)
throw JSONRPCError(RPC_INTERNAL_ERROR, "Blockchain is too short for pruning.");
else if (height > chainHeight)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Blockchain is shorter than the attempted prune height.");
else if (height > chainHeight - MIN_BLOCKS_TO_KEEP)
else if (height > chainHeight - MIN_BLOCKS_TO_KEEP) {
LogPrint("rpc", "Attempt to prune blocks close to the tip. Retaining the minimum number of blocks.");
height = chainHeight - MIN_BLOCKS_TO_KEEP;
}

PruneBlockFilesManual(height);
return NullUniValue;
return uint64_t(height);
}

UniValue gettxoutsetinfo(const JSONRPCRequest& request)
Expand Down

0 comments on commit 918d1fb

Please sign in to comment.