Skip to content

Commit

Permalink
[Test] Add feature_blockhashcache.py
Browse files Browse the repository at this point in the history
to check the validity of the contents of the mnmanager block-hashes
rolling cache
  • Loading branch information
random-zebra committed Oct 19, 2020
1 parent 4031fd2 commit dd67066
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 0 deletions.
107 changes: 107 additions & 0 deletions test/functional/feature_blockhashcache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/usr/bin/env python3
# Copyright (c) 2019-2020 The PIVX developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

from test_framework.test_framework import PivxTestFramework
from test_framework.util import (
assert_equal,
)
import random
from time import sleep

class BlockHashCacheTest(PivxTestFramework):

def set_test_params(self):
self.num_nodes = 1
self.setup_clean_chain = True

def log_title(self):
title = "*** Starting %s ***" % self.__class__.__name__
underline = "-" * len(title)
description = "Tests the block-hashes rolling cache."
self.log.info("\n\n%s\n%s\n%s\n", title, underline, description)

def run_test(self):
self.log_title()
self.node = self.nodes[0]
CACHE_SIZE = 200
# Start with the genesis block
vBlocks = [self.node.getbestblockhash()]

# Mine blocks and save the hashes
self.log.info("Mining %d blocks..." % (CACHE_SIZE - 1))
for i in range(CACHE_SIZE-1):
vBlocks.append(self.node.generate(1)[0])

# Check the cache
cache = self.node.getcachedblockhashes()
assert_equal(vBlocks, cache)
self.log.info("First %d blocks check out" % (CACHE_SIZE - 1))

# Mine a block and check the cache
self.log.info("Mining another block...")
vBlocks.append(self.node.generate(1)[0])
height = self.node.getblockcount()
assert_equal(height, CACHE_SIZE)
assert_equal(len(vBlocks), height + 1) # genesis included
cache = self.node.getcachedblockhashes()
assert_equal(vBlocks[CACHE_SIZE], cache[0])
self.log.info("Block %d correctly cached (overwriting genesis hash)" % CACHE_SIZE)

# Mine a random number of blocks between 1 and CACHE_SIZE-1
x = random.randint(1, CACHE_SIZE)
self.log.info("Mining %d more blocks..." % x)
for i in range(x):
vBlocks.append(self.node.generate(1)[0])

# Check that the cache is (partially) overwritten
cache = self.node.getcachedblockhashes()
for i in range(1, x+1):
assert_equal(vBlocks[CACHE_SIZE + i], cache[i])
# ...but not completely
for i in range(x+1, CACHE_SIZE):
assert_equal(vBlocks[i], cache[i])
self.log.info("Cached correctly")

# Disconnect one block
self.log.info("Disconnecting one block...")
height = self.node.getblockcount()
old_hash = self.node.getbestblockhash()
self.node.invalidateblock(old_hash)
assert_equal(self.node.getblockcount(), height - 1)
vBlocks.pop()
assert_equal(len(vBlocks), height) # genesis included

# Check that the cache cycles back
cache = self.node.getcachedblockhashes()
assert_equal(vBlocks[height - CACHE_SIZE], cache[height % CACHE_SIZE])
self.log.info("Disconnecting %d, block at height %d cycles back in" % (
height, height - CACHE_SIZE))

# Reconsider the block, mine another on top, and check the cache again
self.log.info("Reconsidering and mining one more block...")
self.node.reconsiderblock(old_hash)
assert_equal(self.node.getblockcount(), height)
vBlocks.append(old_hash)
vBlocks.append(self.node.generate(1)[0])
assert_equal(self.node.getblockcount(), height + 1)
assert_equal(len(vBlocks), height + 2) # genesis included
assert_equal(vBlocks[height], old_hash)
cache = self.node.getcachedblockhashes()
assert_equal(vBlocks[height], cache[height % CACHE_SIZE])
assert_equal(vBlocks[height + 1], cache[(height + 1) % CACHE_SIZE])
self.log.info("Cached correctly")

# Restart the node and check that the cache is correctly initialized
self.log.info("Restarting the node...")
self.stop_nodes()
sleep(5)
self.start_nodes()
assert_equal(self.node.getcachedblockhashes(), cache)
self.log.info("All good.")



if __name__ == '__main__':
BlockHashCacheTest().main()
1 change: 1 addition & 0 deletions test/functional/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
'mining_pos_fakestake.py', # ~ 113 sec
'feature_reindex.py', # ~ 110 sec
'interface_http.py', # ~ 105 sec
'feature_blockhashcache.py', # ~ 100 sec
'wallet_listtransactions.py', # ~ 97 sec
'mempool_reorg.py', # ~ 92 sec
'sapling_wallet_persistence.py', # ~ 90 sec
Expand Down

0 comments on commit dd67066

Please sign in to comment.