mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 03:47:29 -03:00
rpc: Make pruneheight also reflect undo data presence
This commit is contained in:
parent
96b4facc91
commit
4a1975008b
2 changed files with 33 additions and 7 deletions
|
@ -786,16 +786,24 @@ static RPCHelpMan getblock()
|
|||
std::optional<int> GetPruneHeight(const BlockManager& blockman, const CChain& chain) {
|
||||
AssertLockHeld(::cs_main);
|
||||
|
||||
// Search for the last block missing block data or undo data. Don't let the
|
||||
// search consider the genesis block, because the genesis block does not
|
||||
// have undo data, but should not be considered pruned.
|
||||
const CBlockIndex* first_block{chain[1]};
|
||||
const CBlockIndex* chain_tip{chain.Tip()};
|
||||
if (!(chain_tip->nStatus & BLOCK_HAVE_DATA)) return chain_tip->nHeight;
|
||||
|
||||
// Get first block with data, after the last block without data.
|
||||
// This is the start of the unpruned range of blocks.
|
||||
const auto& first_unpruned{*Assert(blockman.GetFirstBlock(*chain_tip, /*status_mask=*/BLOCK_HAVE_DATA))};
|
||||
if (!first_unpruned.pprev) {
|
||||
// No block before the first unpruned block means nothing is pruned.
|
||||
return std::nullopt;
|
||||
// If there are no blocks after the genesis block, or no blocks at all, nothing is pruned.
|
||||
if (!first_block || !chain_tip) return std::nullopt;
|
||||
|
||||
// If the chain tip is pruned, everything is pruned.
|
||||
if (!((chain_tip->nStatus & BLOCK_HAVE_MASK) == BLOCK_HAVE_MASK)) return chain_tip->nHeight;
|
||||
|
||||
const auto& first_unpruned{*Assert(blockman.GetFirstBlock(*chain_tip, /*status_mask=*/BLOCK_HAVE_MASK, first_block))};
|
||||
if (&first_unpruned == first_block) {
|
||||
// All blocks between first_block and chain_tip have data, so nothing is pruned.
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Block before the first unpruned block is the last pruned block.
|
||||
return Assert(first_unpruned.pprev)->nHeight;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ from test_framework.util import (
|
|||
assert_equal,
|
||||
assert_greater_than,
|
||||
assert_raises_rpc_error,
|
||||
try_rpc,
|
||||
)
|
||||
|
||||
# Rescans start at the earliest block up to 2 hours before a key timestamp, so
|
||||
|
@ -479,8 +480,12 @@ class PruneTest(BitcoinTestFramework):
|
|||
self.log.info("Test invalid pruning command line options")
|
||||
self.test_invalid_command_line_options()
|
||||
|
||||
self.log.info("Test scanblocks can not return pruned data")
|
||||
self.test_scanblocks_pruned()
|
||||
|
||||
self.log.info("Test pruneheight reflects the presence of block and undo data")
|
||||
self.test_pruneheight_undo_presence()
|
||||
|
||||
self.log.info("Done")
|
||||
|
||||
def test_scanblocks_pruned(self):
|
||||
|
@ -494,5 +499,18 @@ class PruneTest(BitcoinTestFramework):
|
|||
assert_raises_rpc_error(-1, "Block not available (pruned data)", node.scanblocks,
|
||||
"start", [{"desc": f"raw({false_positive_spk.hex()})"}], 0, 0, "basic", {"filter_false_positives": True})
|
||||
|
||||
def test_pruneheight_undo_presence(self):
|
||||
node = self.nodes[2]
|
||||
pruneheight = node.getblockchaininfo()["pruneheight"]
|
||||
fetch_block = node.getblockhash(pruneheight - 1)
|
||||
|
||||
self.connect_nodes(1, 2)
|
||||
peers = node.getpeerinfo()
|
||||
node.getblockfrompeer(fetch_block, peers[0]["id"])
|
||||
self.wait_until(lambda: not try_rpc(-1, "Block not available (pruned data)", node.getblock, fetch_block), timeout=5)
|
||||
|
||||
new_pruneheight = node.getblockchaininfo()["pruneheight"]
|
||||
assert_equal(pruneheight, new_pruneheight)
|
||||
|
||||
if __name__ == '__main__':
|
||||
PruneTest().main()
|
||||
|
|
Loading…
Reference in a new issue