/
state_sync.py
executable file
·118 lines (93 loc) · 3.95 KB
/
state_sync.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env python3
# Spins up a node, then waits for couple epochs
# and spins up another node
# Makes sure that eventually the second node catches up
# Three modes:
# - notx: no transactions are sent, just checks that
# the second node starts and catches up
# - onetx: sends one series of txs at the beginning,
# makes sure the second node balances reflect them
# - manytx: constantly issues txs throughout the test
# makes sure the balances are correct at the end
import sys, time
import pathlib
sys.path.append(str(pathlib.Path(__file__).resolve().parents[2] / 'lib'))
if len(sys.argv) < 3:
logger.info("python state_sync.py [notx, onetx, manytx] <launch_at_block>")
exit(1)
mode = sys.argv[1]
assert mode in ['notx', 'onetx', 'manytx']
from cluster import init_cluster, spin_up_node, load_config
from configured_logger import logger
import state_sync_lib
import utils
START_AT_BLOCK = int(sys.argv[2])
TIMEOUT = 150 + START_AT_BLOCK * 10
config = load_config()
node_config = state_sync_lib.get_state_sync_config_combined()
near_root, node_dirs = init_cluster(
2, 1, 1, config,
[["min_gas_price", 0], ["max_inflation_rate", [0, 1]], ["epoch_length", 10],
["block_producer_kickout_threshold", 80]],
{x: node_config for x in range(3)})
started = time.time()
boot_node = spin_up_node(config, near_root, node_dirs[0], 0)
node1 = spin_up_node(config, near_root, node_dirs[1], 1, boot_node=boot_node)
ctx = utils.TxContext([0, 0], [boot_node, node1])
sent_txs = False
observed_height = 0
for height, block_hash in utils.poll_blocks(boot_node,
timeout=TIMEOUT,
poll_interval=0.1):
observed_height = height
if height >= START_AT_BLOCK:
break
if mode == 'onetx' and not sent_txs:
ctx.send_moar_txs(block_hash, 3, False)
sent_txs = True
elif mode == 'manytx':
if ctx.get_balances() == ctx.expected_balances:
ctx.send_moar_txs(block_hash, 3, False)
logger.info(f'Sending moar txs at height {height}')
if mode == 'onetx':
assert ctx.get_balances() == ctx.expected_balances
node2 = spin_up_node(config, near_root, node_dirs[2], 2, boot_node=boot_node)
tracker = utils.LogTracker(node2)
time.sleep(3)
catch_up_height = 0
for height, block_hash in utils.poll_blocks(boot_node,
timeout=TIMEOUT,
poll_interval=0.1):
catch_up_height = height
if height >= observed_height:
break
if mode == 'manytx' and ctx.get_balances() == ctx.expected_balances:
boot_height = boot_node.get_latest_block().height
ctx.send_moar_txs(block_hash, 3, False)
logger.info(f'Sending moar txs at height {boot_height}')
boot_heights = boot_node.get_all_heights()
assert catch_up_height in boot_heights, "%s not in %s" % (catch_up_height,
boot_heights)
tracker.reset(
) # the transition might have happened before we initialized the tracker
if catch_up_height >= 100:
assert tracker.check("transition to State Sync")
elif catch_up_height <= 30:
assert not tracker.check("transition to State Sync")
if mode == 'manytx':
while ctx.get_balances() != ctx.expected_balances:
assert time.time() - started < TIMEOUT
logger.info(
"Waiting for the old node to catch up. Current balances: %s; Expected balances: %s"
% (ctx.get_balances(), ctx.expected_balances))
time.sleep(1)
# requery the balances from the newly started node
ctx.nodes.append(node2)
ctx.act_to_val = [2, 2, 2]
while ctx.get_balances() != ctx.expected_balances:
assert time.time() - started < TIMEOUT
logger.info(
"Waiting for the new node to catch up. Current balances: %s; Expected balances: %s"
% (ctx.get_balances(), ctx.expected_balances))
time.sleep(1)
logger.info('EPIC')