chia-blockchain/tests/full_node/test_full_sync.py

104 lines
3.4 KiB
Python

import asyncio
import time
import pytest
from src.types.peer_info import PeerInfo
from src.protocols import full_node_protocol
from src.util.ints import uint16
from tests.setup_nodes import setup_two_nodes, test_constants, bt
@pytest.fixture(scope="module")
def event_loop():
loop = asyncio.get_event_loop()
yield loop
class TestFullSync:
@pytest.fixture(scope="function")
async def two_nodes(self):
async for _ in setup_two_nodes():
yield _
@pytest.mark.asyncio
async def test_basic_sync(self, two_nodes):
num_blocks = 100
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10)
full_node_1, full_node_2, server_1, server_2 = two_nodes
for i in range(1, num_blocks):
async for _ in full_node_1.respond_block(
full_node_protocol.RespondBlock(blocks[i])
):
pass
await server_2.start_client(PeerInfo("localhost", uint16(server_1._port)), None)
await asyncio.sleep(2) # Allow connections to get made
start = time.time()
while time.time() - start < 60:
# The second node should eventually catch up to the first one, and have the
# same tip at height num_blocks - 1 (or at least num_blocks - 3, in case we sync to a
# worse tip)
if (
max([h.height for h in full_node_2.blockchain.get_current_tips()])
>= num_blocks - 3
):
print(f"Time taken to sync {num_blocks} is {time.time() - start}")
return
await asyncio.sleep(0.1)
raise Exception(
f"Took too long to process blocks, stopped at: {time.time() - start}"
)
@pytest.mark.asyncio
async def test_short_sync(self, two_nodes):
num_blocks = 10
num_blocks_2 = 4
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 10)
blocks_2 = bt.get_consecutive_blocks(
test_constants, num_blocks_2, [], 10, seed=b"123"
)
full_node_1, full_node_2, server_1, server_2 = two_nodes
# 10 blocks to node_1
for i in range(1, num_blocks):
async for _ in full_node_1.respond_block(
full_node_protocol.RespondBlock(blocks[i])
):
pass
# 4 different blocks to node_2
for i in range(1, num_blocks_2):
async for _ in full_node_2.respond_block(
full_node_protocol.RespondBlock(blocks_2[i])
):
pass
# 6th block from node_1 to node_2
async for _ in full_node_2.respond_block(
full_node_protocol.RespondBlock(blocks[5])
):
pass
await server_2.start_client(PeerInfo("localhost", uint16(server_1._port)), None)
await asyncio.sleep(2) # Allow connections to get made
start = time.time()
while time.time() - start < 30:
# The second node should eventually catch up to the first one, and have the
# same tip at height num_blocks - 1.
if (
max([h.height for h in full_node_2.blockchain.get_current_tips()])
== num_blocks - 1
):
print(f"Time taken to sync {num_blocks} is {time.time() - start}")
return
await asyncio.sleep(0.1)
raise Exception("Took too long to process blocks")