Ejemplo n.º 1
0
async def test_full_header_sync_and_reorg(request, event_loop,
                                          chaindb_mainnet_100):
    # Here we create our server with a populated chaindb, so upon startup it will announce its
    # chain head and the client will fetch all headers
    light_chain, client, server = await get_lightchain_with_peers(
        request, event_loop, chaindb_mainnet_100)

    # ... and our client should then fetch all headers.
    head = server.chaindb.get_canonical_head()
    await wait_for_head(light_chain.chaindb, head)
    assert_canonical_chains_are_equal(light_chain.chaindb, server.chaindb,
                                      head.block_number)

    head_parent = server.chaindb.get_block_header_by_hash(head.parent_hash)
    difficulty = head.difficulty + 1
    new_head = BlockHeader.from_parent(head_parent,
                                       head_parent.gas_limit,
                                       difficulty=difficulty,
                                       timestamp=head.timestamp,
                                       coinbase=head.coinbase)
    server.chaindb.persist_header_to_db(new_head)
    assert server.chaindb.get_canonical_head() == new_head
    server.send_announce(head_number=head.block_number, reorg_depth=1)

    await wait_for_head(light_chain.chaindb, new_head)
    assert_canonical_chains_are_equal(light_chain.chaindb, server.chaindb,
                                      new_head.block_number)
Ejemplo n.º 2
0
async def test_header_sync_with_multi_peers(request, event_loop, chaindb_mainnet_100):
    # In this test we start with one of our peers announcing block #100, and we sync all
    # headers up to that...
    light_chain, server, client = await get_lightchain_with_peers(
        request, event_loop, chaindb_mainnet_100)

    head = server.chaindb.get_canonical_head()
    await wait_for_head(light_chain.chaindb, head)
    assert_canonical_chains_are_equal(light_chain.chaindb, server.chaindb, head.block_number)

    # Now a second peer comes along and announces block #100 as well, but it's different
    # from the one we already have, so we need to fetch that too. And since it has a higher total
    # difficulty than the current head, it will become our new chain head.
    server2_chaindb = server.chaindb
    head_parent = server2_chaindb.get_block_header_by_hash(head.parent_hash)
    difficulty = head.difficulty + 1
    new_head = BlockHeader.from_parent(
        head_parent, head_parent.gas_limit, difficulty=difficulty,
        timestamp=head.timestamp, coinbase=head.coinbase)
    server2_chaindb.persist_header_to_db(new_head)
    assert server2_chaindb.get_canonical_head() == new_head
    server2, client2 = await get_linked_and_running_peers(
        request, event_loop,
        chaindb1=server2_chaindb,
        chaindb2=light_chain.chaindb, received_msg_callback2=light_chain.msg_handler)

    await wait_for_head(light_chain.chaindb, new_head)
    assert_canonical_chains_are_equal(light_chain.chaindb, server2.chaindb, new_head.block_number)
Ejemplo n.º 3
0
async def test_header_sync_with_multi_peers(request, event_loop, chaindb_mainnet_100):
    # In this test we start with one of our peers announcing block #100, and we sync all
    # headers up to that...
    light_chain, _, server = await get_lightchain_with_peers(
        request, event_loop, chaindb_mainnet_100)

    head = server.chaindb.get_canonical_head()
    await wait_for_head(light_chain.chaindb, head)
    assert_canonical_chains_are_equal(light_chain.chaindb, server.chaindb, head.block_number)

    # Now a second peer comes along and announces block #100 as well, but it's different
    # from the one we already have, so we need to fetch that too. And since it has a higher total
    # difficulty than the current head, it will become our new chain head.
    server2_chaindb = server.chaindb
    head_parent = server2_chaindb.get_block_header_by_hash(head.parent_hash)
    difficulty = head.difficulty + 1
    new_head = BlockHeader.from_parent(
        head_parent, head_parent.gas_limit, difficulty=difficulty,
        timestamp=head.timestamp, coinbase=head.coinbase)
    server2_chaindb.persist_header_to_db(new_head)
    assert server2_chaindb.get_canonical_head() == new_head
    client2, server2 = await get_client_and_server_peer_pair(
        request,
        event_loop,
        client_chaindb=light_chain.chaindb,
        server_chaindb=server2_chaindb)

    light_chain.register_peer(client2)
    await wait_for_head(light_chain.chaindb, new_head)
    assert_canonical_chains_are_equal(light_chain.chaindb, server2.chaindb, new_head.block_number)
Ejemplo n.º 4
0
def mk_header_chain(base_header, length):
    previous_header = base_header
    for _ in range(length):
        next_header = BlockHeader.from_parent(
            parent=previous_header,
            timestamp=previous_header.timestamp + 1,
            gas_limit=previous_header.gas_limit,
            difficulty=previous_header.difficulty,
            extra_data=keccak(random.randint(0, 1e18)),
        )
        yield next_header
        previous_header = next_header
Ejemplo n.º 5
0
def create_frontier_header_from_parent(parent_header, **header_params):
    if 'difficulty' not in header_params:
        timestamp = header_params.get('timestamp', parent_header.timestamp + 1)
        header_params['difficulty'] = compute_frontier_difficulty(
            parent_header,
            timestamp,
        )
    if 'gas_limit' not in header_params:
        header_params['gas_limit'] = compute_gas_limit(
            parent_header,
            gas_limit_floor=GENESIS_GAS_LIMIT,
        )

    header = BlockHeader.from_parent(parent=parent_header, **header_params)

    return header
Ejemplo n.º 6
0
def create_frontier_header_from_parent(parent_header, **header_params):
    if 'difficulty' not in header_params:
        # Use setdefault to ensure the new header has the same timestamp we use to calculate its
        # difficulty.
        header_params.setdefault('timestamp', parent_header.timestamp + 1)
        header_params['difficulty'] = compute_frontier_difficulty(
            parent_header,
            header_params['timestamp'],
        )
    if 'gas_limit' not in header_params:
        header_params['gas_limit'] = compute_gas_limit(
            parent_header,
            gas_limit_floor=GENESIS_GAS_LIMIT,
        )

    header = BlockHeader.from_parent(parent=parent_header, **header_params)

    return header
Ejemplo n.º 7
0
def create_frontier_header_from_parent(parent_header, **header_params):
    if 'difficulty' not in header_params:
        # Use setdefault to ensure the new header has the same timestamp we use to calculate its
        # difficulty.
        header_params.setdefault('timestamp', parent_header.timestamp + 1)
        header_params['difficulty'] = compute_frontier_difficulty(
            parent_header,
            header_params['timestamp'],
        )
    if 'gas_limit' not in header_params:
        header_params['gas_limit'] = compute_gas_limit(
            parent_header,
            gas_limit_floor=GENESIS_GAS_LIMIT,
        )

    header = BlockHeader.from_parent(parent=parent_header, **header_params)

    return header
Ejemplo n.º 8
0
async def test_full_header_sync_and_reorg(request, event_loop, chaindb_mainnet_100):
    # Here we create our server with a populated chaindb, so upon startup it will announce its
    # chain head and the client will fetch all headers
    light_chain, _, server = await get_lightchain_with_peers(
        request, event_loop, chaindb_mainnet_100)

    # ... and our client should then fetch all headers.
    head = server.chaindb.get_canonical_head()
    await wait_for_head(light_chain.chaindb, head)
    assert_canonical_chains_are_equal(light_chain.chaindb, server.chaindb, head.block_number)

    head_parent = server.chaindb.get_block_header_by_hash(head.parent_hash)
    difficulty = head.difficulty + 1
    new_head = BlockHeader.from_parent(
        head_parent, head_parent.gas_limit, difficulty=difficulty,
        timestamp=head.timestamp, coinbase=head.coinbase)
    server.chaindb.persist_header_to_db(new_head)
    assert server.chaindb.get_canonical_head() == new_head
    server.send_announce(head_number=head.block_number, reorg_depth=1)

    await wait_for_head(light_chain.chaindb, new_head)
    assert_canonical_chains_are_equal(light_chain.chaindb, server.chaindb, new_head.block_number)