Skip to content

Commit

Permalink
Address review comments.
Browse files Browse the repository at this point in the history
  • Loading branch information
robin-near committed Oct 17, 2024
1 parent 552b185 commit dfaf49c
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 51 deletions.
13 changes: 6 additions & 7 deletions chain/chain/src/store_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,12 @@ impl StoreValidator {
store: Store,
is_archival: bool,
) -> Self {
let epoch_sync_boundary = if let Ok(Some(epoch_sync_proof)) =
store.get_ser::<EpochSyncProof>(DBCol::EpochSyncProof, &[])
{
Some(epoch_sync_proof.current_epoch.first_block_header_in_epoch.height())
} else {
None
};
let epoch_sync_boundary = store
.get_ser::<EpochSyncProof>(DBCol::EpochSyncProof, &[])
.expect("Store IO error when getting EpochSyncProof")
.map(|epoch_sync_proof| {
epoch_sync_proof.current_epoch.first_block_header_in_epoch.height()
});
StoreValidator {
me,
config,
Expand Down
6 changes: 5 additions & 1 deletion nightly/pytest-sanity.txt
Original file line number Diff line number Diff line change
Expand Up @@ -197,4 +197,8 @@ pytest sanity/replay_chain_from_archive.py --features nightly

# Tests that offline block+chunk producers and chunk validators are kicked out.
pytest --timeout=120 sanity/kickout_offline_validators.py
pytest --timeout=120 sanity/kickout_offline_validators.py --features nightly
pytest --timeout=120 sanity/kickout_offline_validators.py --features nightly

# Epoch sync
pytest --timeout=240 sanity/epoch_sync.py
pytest --timeout=240 sanity/epoch_sync.py --features nightly
109 changes: 66 additions & 43 deletions pytest/tests/sanity/epoch_sync.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#!/usr/bin/env python3
# Spins up a node, then waits for 10 epochs.
# Spins up a node, then waits for 5 epochs.
# Spin up another node with epoch sync enabled, and make sure it catches up.

import sys, time
import sys
import pathlib
import unittest

sys.path.append(str(pathlib.Path(__file__).resolve().parents[2] / 'lib'))

Expand All @@ -24,45 +25,67 @@
# that the node is fine with GC too.
CATCHUP_BLOCK = 12 * EPOCH_LENGTH

config = load_config()

node_config = state_sync_lib.get_state_sync_config_combined()

node_config['epoch_sync'] = {
"enabled": True,
"epoch_sync_horizon": EPOCH_LENGTH * 3,
"epoch_sync_accept_proof_max_horizon": EPOCH_LENGTH * 3,
"timeout_for_epoch_sync": {
"secs": 5,
"nanos": 0
}
}

# Make sure that state sync targets an epoch *later* than the epoch sync target epoch.
node_config["consensus.block_fetch_horizon"] = 3
node_config["consensus.block_header_fetch_horizon"] = EPOCH_LENGTH

near_root, node_dirs = init_cluster(
2, 1, 1, config,
[["min_gas_price", 0], ["epoch_length", EPOCH_LENGTH]],
{x: node_config for x in range(3)})

node0 = spin_up_node(config, near_root, node_dirs[0], 0)
node1 = spin_up_node(config, near_root, node_dirs[1], 1, boot_node=node0)

ctx = utils.TxContext([0, 0], [node0, node1])

for height, block_hash in utils.poll_blocks(node0,
timeout=SYNC_FROM_BLOCK * 2,
poll_interval=0.1):
if height >= SYNC_FROM_BLOCK:
break
ctx.send_moar_txs(block_hash, 1, False)

node1 = spin_up_node(config, near_root, node_dirs[2], 2, boot_node=node0)
tracker = utils.LogTracker(node1)

utils.wait_for_blocks(node1, target=CATCHUP_BLOCK, timeout=(CATCHUP_BLOCK - SYNC_FROM_BLOCK) * 2)

# Verify that we did bootstrap using epoch sync (rather than header sync).
tracker.check('Bootstrapped from epoch sync')
class EpochSyncTest(unittest.TestCase):

def setUp(self):
self.config = load_config()
node_config = state_sync_lib.get_state_sync_config_combined()

node_config['epoch_sync'] = {
"enabled": True,
"epoch_sync_horizon": EPOCH_LENGTH * 3,
"epoch_sync_accept_proof_max_horizon": EPOCH_LENGTH * 3,
"timeout_for_epoch_sync": {
"secs": 5,
"nanos": 0
}
}

# Make sure that state sync targets an epoch *later* than the epoch sync target epoch.
node_config["consensus.block_fetch_horizon"] = 3
node_config["consensus.block_header_fetch_horizon"] = EPOCH_LENGTH

self.near_root, self.node_dirs = init_cluster(
num_nodes=2,
num_observers=1,
num_shards=1,
config=self.config,
genesis_config_changes=[["min_gas_price", 0],
["epoch_length", EPOCH_LENGTH]],
client_config_changes={x: node_config for x in range(3)})

def test(self):
node0 = spin_up_node(self.config, self.near_root, self.node_dirs[0], 0)
node1 = spin_up_node(self.config,
self.near_root,
self.node_dirs[1],
1,
boot_node=node0)

ctx = utils.TxContext([0, 0], [node0, node1])

for height, block_hash in utils.poll_blocks(node0,
timeout=SYNC_FROM_BLOCK * 2,
poll_interval=0.1):
if height >= SYNC_FROM_BLOCK:
break
ctx.send_moar_txs(block_hash, 1, False)

node2 = spin_up_node(self.config,
self.near_root,
self.node_dirs[2],
2,
boot_node=node0)
tracker = utils.LogTracker(node2)

utils.wait_for_blocks(node2,
target=CATCHUP_BLOCK,
timeout=(CATCHUP_BLOCK - SYNC_FROM_BLOCK) * 2)

# Verify that we did bootstrap using epoch sync (rather than header sync).
tracker.check('Bootstrapped from epoch sync')


if __name__ == '__main__':
unittest.main()

0 comments on commit dfaf49c

Please sign in to comment.