This loop structure is repeated a bunch; might be clearer as:
0 def test_height(self, height, *status, mine=None):
1 if height > self.height:
2 assert mine is not None
3 self.log.info(f"Test status at height {height}...")
4 self.nodes[mine].generate(height - self.height)
5 self.sync_blocks()
6 elif height < self.height:
7 assert mine is None
8 self.log.info(f"Roll back to {height}...")
9 old_block = self.nodes[0].getblockhash(height + 1)
10 for node in self.nodes:
11 node.invalidateblock(old_block)
12 else:
13 assert height == 0 and self.height == 0
14 self.log.info(f"Test status at genesis...")
15
16 self.height = height
17
18 for (i, node), st in zip(enumerate(self.nodes), status):
19 self.log.debug('Node #{}...'.format(i))
20 info = node.getblockchaininfo()
21 assert_equal(info['blocks'], height)
22 assert_equal(info["softforks"]["testdummy"]["bip8"]["status"], st)
23
24 def run_test(self):
25 self.test_height(0, "defined", "defined", "defined")
26
27 # BIP 8 state transitions from "defined" to "started" or "failed" after
28 # the last block of the retargeting period has been mined. This means
29 # any new rules apply to transactions currently in the mempool, which
30 # might be mined in the next block.
31 #
32 # The next retargeting period starts at block 144, so nothing should
33 # happen at 142 and the state should change at 143.
34
35 self.test_height(144-2, "defined", "defined", "defined", mine=0)
36 self.test_height(144-1, "failed", "started", "started", mine=0)
37
38 self.log.info("Test status when not signalling...")
39 self.test_height(144*2-1, "failed", "started", "failed", mine=0)
40 self.test_height(144*3-1, "failed", "failed", "failed", mine=0)
41
42
43 self.log.info("Test status when signalling...")
44 # The new branch has unique block hashes, because of the signalling and
45 # because generate uses a deterministic address that depends on the node
46 # index.
47
48 self.test_height(144-1, "failed", "started", "started")
49 self.test_height(144*2-1, "failed", "locked_in", "locked_in", mine=2)
50 self.test_height(144*3-1, "failed", "active", "locked_in", mine=2)
51 self.test_height(144*4-1, "failed", "active", "active", mine=2)