Implement roll-back limit for reorganisation

Closes #713.
This commit is contained in:
Jack Grigg
2017-06-21 23:53:01 +12:00
parent e6850571dd
commit 57e6ecda5a
6 changed files with 120 additions and 2 deletions

View File

@@ -44,6 +44,7 @@ testScripts=(
'zcjoinsplit.py'
'zcjoinsplitdoublespend.py'
'zkey_import_export.py'
'reorg_limit.py'
'getblocktemplate.py'
'bip65-cltv-p2p.py'
'bipdersig-p2p.py'

86
qa/rpc-tests/reorg_limit.py Executable file
View File

@@ -0,0 +1,86 @@
#!/usr/bin/env python2
# Copyright (c) 2017 The Zcash developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
# Test reorg limit
#
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
check_node,
connect_nodes_bi,
initialize_chain_clean,
start_node,
sync_blocks,
)
from time import sleep
def check_stopped(i, timeout=10):
stopped = False
for x in xrange(1, timeout):
ret = check_node(i)
if ret is None:
sleep(1)
else:
stopped = True
break
return stopped
class ReorgLimitTest(BitcoinTestFramework):
def run_test(self):
assert(self.nodes[0].getblockcount() == 200)
assert(self.nodes[2].getblockcount() == 200)
self.split_network()
print "Test the maximum-allowed reorg:"
print "Mine 99 blocks on Node 0"
self.nodes[0].generate(99)
assert(self.nodes[0].getblockcount() == 299)
assert(self.nodes[2].getblockcount() == 200)
print "Mine competing 100 blocks on Node 2"
self.nodes[2].generate(100)
assert(self.nodes[0].getblockcount() == 299)
assert(self.nodes[2].getblockcount() == 300)
print "Connect nodes to force a reorg"
connect_nodes_bi(self.nodes, 0, 2)
self.is_network_split = False
sync_blocks(self.nodes)
print "Check Node 0 is still running and on the correct chain"
assert(self.nodes[0].getblockcount() == 300)
self.split_network()
print "Test the minimum-rejected reorg:"
print "Mine 100 blocks on Node 0"
self.nodes[0].generate(100)
assert(self.nodes[0].getblockcount() == 400)
assert(self.nodes[2].getblockcount() == 300)
print "Mine competing 101 blocks on Node 2"
self.nodes[2].generate(101)
assert(self.nodes[0].getblockcount() == 400)
assert(self.nodes[2].getblockcount() == 401)
print "Sync nodes to force a reorg"
connect_nodes_bi(self.nodes, 0, 2)
self.is_network_split = False
# sync_blocks uses RPC calls to wait for nodes to be synced, so don't
# call it here, because it will have a non-specific connection error
# when Node 0 stops. Instead, we explicitly check for the process itself
# to stop.
print "Check Node 0 is no longer running"
assert(check_stopped(0))
# Dummy stop to enable the test to tear down
self.nodes[0].stop = lambda: True
if __name__ == '__main__':
ReorgLimitTest().main()

View File

@@ -213,6 +213,10 @@ def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None):
def log_filename(dirname, n_node, logname):
return os.path.join(dirname, "node"+str(n_node), "regtest", logname)
def check_node(i):
bitcoind_processes[i].poll()
return bitcoind_processes[i].returncode
def stop_node(node, i):
node.stop()
bitcoind_processes[i].wait()