|
12 | 12 |
|
13 | 13 | from test_framework.blocktools import create_block, create_coinbase
|
14 | 14 | from test_framework.messages import msg_block
|
15 |
| -from test_framework.mininode import P2PInterface, network_thread_start |
| 15 | +from test_framework.mininode import P2PInterface, network_thread_start, mininode_lock |
16 | 16 | from test_framework.test_framework import BitcoinTestFramework
|
| 17 | +from test_framework.util import wait_until |
17 | 18 |
|
18 | 19 | VB_PERIOD = 144 # versionbits period length for regtest
|
19 | 20 | VB_THRESHOLD = 108 # versionbits activation threshold for regtest
|
|
23 | 24 |
|
24 | 25 | WARN_UNKNOWN_RULES_MINED = "Unknown block versions being mined! It's possible unknown rules are in effect"
|
25 | 26 | WARN_UNKNOWN_RULES_ACTIVE = "unknown new rules activated (versionbit {})".format(VB_UNKNOWN_BIT)
|
26 |
| -VB_PATTERN = re.compile("^Warning.*versionbit") |
27 |
| - |
28 |
| -class TestNode(P2PInterface): |
29 |
| - def on_inv(self, message): |
30 |
| - pass |
| 27 | +VB_PATTERN = re.compile("Warning: unknown new rules activated.*versionbit") |
31 | 28 |
|
32 | 29 | class VersionBitsWarningTest(BitcoinTestFramework):
|
33 | 30 | def set_test_params(self):
|
@@ -59,61 +56,57 @@ def send_blocks_with_version(self, peer, numblocks, version):
|
59 | 56 | tip = block.sha256
|
60 | 57 | peer.sync_with_ping()
|
61 | 58 |
|
62 |
| - def test_versionbits_in_alert_file(self): |
63 |
| - """Test that the versionbits warning has been written to the alert file. |
64 |
| -
|
65 |
| - Note that this is only called after the node is shutdown, so doesn't need |
66 |
| - a wait_until wrapper.""" |
67 |
| - with open(self.alert_filename, 'r', encoding='utf8') as f: |
68 |
| - alert_text = f.read() |
69 |
| - assert(VB_PATTERN.match(alert_text)) |
| 59 | + def versionbits_in_alert_file(self): |
| 60 | + """Test that the versionbits warning has been written to the alert file.""" |
| 61 | + alert_text = open(self.alert_filename, 'r', encoding='utf8').read() |
| 62 | + return VB_PATTERN.search(alert_text) is not None |
70 | 63 |
|
71 | 64 | def run_test(self):
|
72 |
| - self.nodes[0].add_p2p_connection(TestNode()) |
| 65 | + # Handy alias |
| 66 | + node = self.nodes[0] |
| 67 | + node.add_p2p_connection(P2PInterface()) |
73 | 68 | network_thread_start()
|
74 |
| - self.nodes[0].p2p.wait_for_verack() |
| 69 | + node.p2p.wait_for_verack() |
75 | 70 |
|
76 | 71 | # Mine one period worth of blocks
|
77 |
| - self.nodes[0].generate(VB_PERIOD) |
| 72 | + node.generate(VB_PERIOD) |
78 | 73 |
|
79 | 74 | self.log.info("Check that there is no warning if previous VB_BLOCKS have <VB_THRESHOLD blocks with unknown versionbits version.")
|
80 | 75 | # Build one period of blocks with < VB_THRESHOLD blocks signaling some unknown bit
|
81 |
| - self.send_blocks_with_version(self.nodes[0].p2p, VB_THRESHOLD - 1, VB_UNKNOWN_VERSION) |
82 |
| - self.nodes[0].generate(VB_PERIOD - VB_THRESHOLD + 1) |
| 76 | + self.send_blocks_with_version(node.p2p, VB_THRESHOLD - 1, VB_UNKNOWN_VERSION) |
| 77 | + node.generate(VB_PERIOD - VB_THRESHOLD + 1) |
83 | 78 |
|
84 | 79 | # Check that we're not getting any versionbit-related errors in get*info()
|
85 |
| - assert(not VB_PATTERN.match(self.nodes[0].getmininginfo()["warnings"])) |
86 |
| - assert(not VB_PATTERN.match(self.nodes[0].getnetworkinfo()["warnings"])) |
| 80 | + assert(not VB_PATTERN.match(node.getmininginfo()["warnings"])) |
| 81 | + assert(not VB_PATTERN.match(node.getnetworkinfo()["warnings"])) |
87 | 82 |
|
| 83 | + self.log.info("Check that there is a warning if >50 blocks in the last 100 were an unknown version") |
88 | 84 | # Build one period of blocks with VB_THRESHOLD blocks signaling some unknown bit
|
89 |
| - self.send_blocks_with_version(self.nodes[0].p2p, VB_THRESHOLD, VB_UNKNOWN_VERSION) |
90 |
| - self.nodes[0].generate(VB_PERIOD - VB_THRESHOLD) |
| 85 | + self.send_blocks_with_version(node.p2p, VB_THRESHOLD, VB_UNKNOWN_VERSION) |
| 86 | + node.generate(VB_PERIOD - VB_THRESHOLD) |
91 | 87 |
|
92 |
| - self.log.info("Check that there is a warning if <50 blocks in the last 100 were an unknown version") |
93 | 88 | # Check that get*info() shows the 51/100 unknown block version error.
|
94 |
| - assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getmininginfo()["warnings"]) |
95 |
| - assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getnetworkinfo()["warnings"]) |
96 |
| - |
97 |
| - # Mine a period worth of expected blocks so the generic block-version warning |
98 |
| - # is cleared, and restart the node. This will move the versionbit state |
99 |
| - # to ACTIVE. |
100 |
| - self.nodes[0].generate(VB_PERIOD) |
101 |
| - self.stop_nodes() |
102 |
| - # Empty out the alert file |
103 |
| - with open(self.alert_filename, 'w', encoding='utf8'): |
104 |
| - pass |
105 |
| - self.start_nodes() |
| 89 | + assert(WARN_UNKNOWN_RULES_MINED in node.getmininginfo()["warnings"]) |
| 90 | + assert(WARN_UNKNOWN_RULES_MINED in node.getnetworkinfo()["warnings"]) |
106 | 91 |
|
107 | 92 | self.log.info("Check that there is a warning if previous VB_BLOCKS have >=VB_THRESHOLD blocks with unknown versionbits version.")
|
108 |
| - # Connecting one block should be enough to generate an error. |
109 |
| - self.nodes[0].generate(1) |
110 |
| - assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getmininginfo()["warnings"]) |
111 |
| - assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getnetworkinfo()["warnings"]) |
112 |
| - self.stop_nodes() |
113 |
| - self.test_versionbits_in_alert_file() |
114 |
| - |
115 |
| - # Test framework expects the node to still be running... |
116 |
| - self.start_nodes() |
| 93 | + # Mine a period worth of expected blocks so the generic block-version warning |
| 94 | + # is cleared. This will move the versionbit state to ACTIVE. |
| 95 | + node.generate(VB_PERIOD) |
| 96 | + |
| 97 | + # Stop-start the node. This is required because bitcoind will only warn once about unknown versions or unknown rules activating. |
| 98 | + self.restart_node(0) |
| 99 | + |
| 100 | + # Generating one block guarantees that we'll get out of IBD |
| 101 | + node.generate(1) |
| 102 | + wait_until(lambda: not node.getblockchaininfo()['initialblockdownload'], timeout=10, lock=mininode_lock) |
| 103 | + # Generating one more block will be enough to generate an error. |
| 104 | + node.generate(1) |
| 105 | + # Check that get*info() shows the versionbits unknown rules warning |
| 106 | + assert(WARN_UNKNOWN_RULES_ACTIVE in node.getmininginfo()["warnings"]) |
| 107 | + assert(WARN_UNKNOWN_RULES_ACTIVE in node.getnetworkinfo()["warnings"]) |
| 108 | + # Check that the alert file shows the versionbits unknown rules warning |
| 109 | + wait_until(lambda: self.versionbits_in_alert_file(), timeout=60) |
117 | 110 |
|
118 | 111 | if __name__ == '__main__':
|
119 | 112 | VersionBitsWarningTest().main()
|
0 commit comments