forked from Conflux-Chain/conflux-rust
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinvalid_block_sync_test.py
executable file
·103 lines (88 loc) · 4.35 KB
/
invalid_block_sync_test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env python3
from rlp.sedes import Binary, BigEndianInt
from conflux import utils, trie
from conflux.rpc import RpcClient
from conflux.trie import compute_transaction_root_for_single_transaction
from conflux.utils import encode_hex, bytes_to_int, int_to_hex, str_to_bytes
from test_framework.blocktools import create_block, create_transaction, create_chain_of_blocks
from test_framework.test_framework import ConfluxTestFramework
from test_framework.mininode import *
from test_framework.util import *
CHAIN_LEN = 400
class InvalidBodyNode(DefaultNode):
def __init__(self, genesis):
super().__init__(genesis)
correct_chain = create_chain_of_blocks(parent_hash=self.genesis, parent_height=0, count=CHAIN_LEN)
invalid_tx = create_transaction(chain_id=0)
invalid_body_block = create_block(parent_hash=self.genesis, height=1, transactions=[invalid_tx],
transaction_root=compute_transaction_root_for_single_transaction(invalid_tx.hash))
invalid_chain_suffix = create_chain_of_blocks(parent_hash=invalid_body_block.hash, parent_height=1,
count=CHAIN_LEN)
last_block = create_block(parent_hash=invalid_chain_suffix[-1].hash, height=CHAIN_LEN + 2,
referee_hashes=[correct_chain[-1].hash])
invalid_chain = [invalid_body_block] + invalid_chain_suffix + [last_block]
self.block_map = {self.genesis: self.genesis}
self.epoch_map = {0: self.genesis}
for i in range(1, CHAIN_LEN + 3):
b = invalid_chain[i-1]
self.block_map[b.hash] = b
self.epoch_map[i] = {b.hash}
for b in correct_chain:
self.block_map[b.hash] = b
self.epoch_map[CHAIN_LEN + 2].add(b.hash)
self.invalid_block = invalid_body_block.hash
self.set_callback(GET_BLOCK_HEADERS, self.__class__.on_get_block_headers)
self.best_block_hash = last_block.hash
def on_get_block_hashes_by_epoch(self, msg: GetBlockHashesByEpoch):
hashes = []
for epoch in msg.epochs:
hashes.extend(self.epoch_map[epoch])
resp = BlockHashes(reqid=msg.reqid, hashes=hashes)
self.send_protocol_msg(resp)
def on_get_blocks(self, msg: GetBlocks):
blocks = []
for h in msg.hashes:
blocks.append(self.block_map[h])
resp = Blocks(reqid=msg.reqid, blocks=blocks)
self.send_protocol_msg(resp)
def on_get_block_headers(self, msg: GetBlockHeaders):
blocks = []
for h in msg.hashes:
blocks.append(self.block_map[h].block_header)
resp = BlockHeaders(reqid=msg.reqid, headers=blocks)
self.send_protocol_msg(resp)
def send_status(self):
status = Status(
ChainIdParams(self.chain_id),
self.genesis, CHAIN_LEN + 2, 0, [self.best_block_hash])
self.send_protocol_msg(status)
class InvalidBodySyncTest(ConfluxTestFramework):
def set_test_params(self):
self.num_nodes = 2
self.conf_parameters["dev_allow_phase_change_without_peer"] = "false"
# Disable 1559 because the client submit old format data
self.conf_parameters["cip1559_transition_height"] = str(99999999)
def setup_network(self):
self.add_nodes(self.num_nodes)
for i in range(self.num_nodes):
self.nodes[i].start(extra_args=["--full"])
self.nodes[i].wait_for_rpc_connection()
self.nodes[i].wait_for_nodeid()
def run_test(self):
genesis = self.nodes[0].cfx_getBlockByEpochNumber("0x0", False)["hash"]
conn0 = InvalidBodyNode(genesis)
conn1 = DefaultNode(genesis)
self.nodes[1].add_p2p_connection(conn1)
network_thread_start()
conn1.wait_for_status()
for (h, b) in conn0.block_map.items():
if h != conn0.invalid_block and h != decode_hex(genesis):
conn1.send_protocol_msg(NewBlock(block=b))
wait_for_block_count(self.nodes[1], CHAIN_LEN + 1)
self.nodes[0].add_p2p_connection(conn0)
conn0.wait_for_status()
connect_nodes(self.nodes, 0, 1)
self.nodes[0].wait_for_phase(["NormalSyncPhase"], wait_time=120)
wait_until(lambda: int(self.nodes[0].cfx_getStatus()["epochNumber"], 0) == CHAIN_LEN)
if __name__ == "__main__":
InvalidBodySyncTest().main()