Auto merge of #3132 - str4d:2898-rewind-block-index, r=daira
When rewinding, remove insufficiently-validated blocks If a block is insufficiently-validated against a particular branch ID, then we cannot guarantee that even the block header will be valid under the actual consensus rules the node will want to apply. Instead require that the blocks are completely re-validated, by removing them from the block index (which is equivalent to reducing their validity to BLOCK_VALID_UNKNOWN). Closes #3100.
This commit is contained in:
85
qa/rpc-tests/rewind_index.py
Executable file
85
qa/rpc-tests/rewind_index.py
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2018 The Zcash 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 BitcoinTestFramework
|
||||
from test_framework.util import assert_equal, initialize_chain_clean, \
|
||||
start_nodes, start_node, connect_nodes_bi, bitcoind_processes
|
||||
|
||||
import time
|
||||
|
||||
|
||||
class RewindBlockIndexTest (BitcoinTestFramework):
|
||||
|
||||
def setup_chain(self):
|
||||
print("Initializing test directory "+self.options.tmpdir)
|
||||
initialize_chain_clean(self.options.tmpdir, 3)
|
||||
|
||||
def setup_network(self, split=False):
|
||||
# Node 0 - Overwinter, then Sprout, then Overwinter again
|
||||
# Node 1 - Sprout
|
||||
# Node 2 - Overwinter
|
||||
self.nodes = start_nodes(3, self.options.tmpdir, extra_args=[['-nuparams=5ba81b19:10'], [], ['-nuparams=5ba81b19:10']])
|
||||
connect_nodes_bi(self.nodes,0,1)
|
||||
connect_nodes_bi(self.nodes,1,2)
|
||||
connect_nodes_bi(self.nodes,0,2)
|
||||
self.is_network_split=False
|
||||
self.sync_all()
|
||||
|
||||
def run_test (self):
|
||||
# Bring all nodes to just before the activation block
|
||||
print("Mining blocks...")
|
||||
self.nodes[0].generate(8)
|
||||
block9 = self.nodes[0].generate(1)[0]
|
||||
self.sync_all()
|
||||
|
||||
assert_equal(self.nodes[0].getbestblockhash(), block9)
|
||||
assert_equal(self.nodes[1].getbestblockhash(), block9)
|
||||
|
||||
print("Mining diverging blocks")
|
||||
block10s = self.nodes[1].generate(1)[0]
|
||||
block10o = self.nodes[2].generate(1)[0]
|
||||
self.sync_all()
|
||||
|
||||
assert_equal(self.nodes[0].getbestblockhash(), block10o)
|
||||
assert_equal(self.nodes[1].getbestblockhash(), block10s)
|
||||
assert_equal(self.nodes[2].getbestblockhash(), block10o)
|
||||
|
||||
# Restart node 0 using Sprout instead of Overwinter
|
||||
print("Switching node 0 from Overwinter to Sprout")
|
||||
self.nodes[0].stop()
|
||||
bitcoind_processes[0].wait()
|
||||
self.nodes[0] = start_node(0,self.options.tmpdir)
|
||||
connect_nodes_bi(self.nodes,0,1)
|
||||
connect_nodes_bi(self.nodes,1,2)
|
||||
connect_nodes_bi(self.nodes,0,2)
|
||||
|
||||
# Assume node 1 will send block10s to node 0 quickly
|
||||
# (if we used self.sync_all() here and there was a bug, the test would hang)
|
||||
time.sleep(2)
|
||||
|
||||
# Node 0 has rewound and is now on the Sprout chain
|
||||
assert_equal(self.nodes[0].getblockcount(), 10)
|
||||
assert_equal(self.nodes[0].getbestblockhash(), block10s)
|
||||
|
||||
# Restart node 0 using Overwinter instead of Sprout
|
||||
print("Switching node 0 from Sprout to Overwinter")
|
||||
self.nodes[0].stop()
|
||||
bitcoind_processes[0].wait()
|
||||
self.nodes[0] = start_node(0,self.options.tmpdir, extra_args=['-nuparams=5ba81b19:10'])
|
||||
connect_nodes_bi(self.nodes,0,1)
|
||||
connect_nodes_bi(self.nodes,1,2)
|
||||
connect_nodes_bi(self.nodes,0,2)
|
||||
|
||||
# Assume node 2 will send block10o to node 0 quickly
|
||||
# (if we used self.sync_all() here and there was a bug, the test would hang)
|
||||
time.sleep(2)
|
||||
|
||||
# Node 0 has rewound and is now on the Overwinter chain again
|
||||
assert_equal(self.nodes[0].getblockcount(), 10)
|
||||
assert_equal(self.nodes[0].getbestblockhash(), block10o)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
RewindBlockIndexTest().main()
|
||||
Reference in New Issue
Block a user