Пример #1
0
async def test_request_beacon_blocks_by_root(monkeypatch):
    async with ConnectionPairFactory() as (alice, bob):

        blocks = SignedBeaconBlockFactory.create_branch(5)
        mock_root_to_block_db = {block.signing_root: block for block in blocks}

        def get_block_by_root(root):
            validate_word(root)
            if root in mock_root_to_block_db:
                return mock_root_to_block_db[root]
            else:
                raise BlockNotFound

        monkeypatch.setattr(bob.chain, "get_block_by_root", get_block_by_root)

        requesting_block_roots = [
            blocks[0].signing_root,
            b"\x12" * 32,  # Unknown block root
            blocks[1].signing_root,
            b"\x23" * 32,  # Unknown block root
            blocks[3].signing_root,
        ]
        requested_blocks = await alice.request_beacon_blocks_by_root(
            peer_id=bob.peer_id, block_roots=requesting_block_roots
        )

        expected_blocks = [blocks[0], blocks[1], blocks[3]]
        assert len(requested_blocks) == len(expected_blocks)
        assert set(requested_blocks) == set(expected_blocks)
Пример #2
0
async def test_handshake_failure_invalid_status_packet(monkeypatch, mock_timeout):
    async with ConnectionPairFactory(handshake=False) as (alice, bob):

        def status_with_wrong_fork_version(chain):
            return Status.create(
                head_fork_version=b"\x12\x34\x56\x78"  # version different from another node.
            )

        monkeypatch.setattr(node, "get_my_status", status_with_wrong_fork_version)
        with pytest.raises(HandshakeFailure):
            await alice.request_status(bob.peer_id)
        assert alice.peer_id not in bob.handshaked_peers
        assert bob.peer_id not in alice.handshaked_peers

        def status_with_wrong_checkpoint(chain):
            return Status.create(
                finalized_root=b"\x78"
                * 32  # finalized root different from another node.
            )

        monkeypatch.setattr(node, "get_my_status", status_with_wrong_checkpoint)
        with pytest.raises(HandshakeFailure):
            await alice.request_status(bob.peer_id)
        assert alice.peer_id not in bob.handshaked_peers
        assert bob.peer_id not in alice.handshaked_peers
Пример #3
0
async def test_hello_failure_invalid_hello_packet(monkeypatch, mock_timeout):
    async with ConnectionPairFactory(say_hello=False) as (alice, bob):

        def _make_hello_packet_with_wrong_fork_version():
            return HelloRequest(
                fork_version=b"\x12\x34\x56\x78"  # version different from another node.
            )

        monkeypatch.setattr(
            alice, "_make_hello_packet", _make_hello_packet_with_wrong_fork_version
        )
        # Test: Handshake fails when sending invalid hello packet.
        with pytest.raises(HandshakeFailure):
            await alice.say_hello(bob.peer_id)
        await asyncio.sleep(0.01)
        assert alice.peer_id not in bob.handshaked_peers
        assert bob.peer_id not in alice.handshaked_peers

        def _make_hello_packet_with_wrong_checkpoint():
            return HelloRequest(
                finalized_root=b"\x78"
                * 32  # finalized root different from another node.
            )

        monkeypatch.setattr(
            alice, "_make_hello_packet", _make_hello_packet_with_wrong_checkpoint
        )
        # Test: Handshake fails when sending invalid hello packet.
        with pytest.raises(HandshakeFailure):
            await alice.say_hello(bob.peer_id)
        await asyncio.sleep(0.01)
        assert alice.peer_id not in bob.handshaked_peers
        assert bob.peer_id not in alice.handshaked_peers
Пример #4
0
async def get_sync_setup(
    request,
    event_loop,
    event_bus,
    genesis_state,
    alice_branch,
    bob_branch,
    sync_timeout=6,
):
    alice_chaindb = AsyncBeaconChainDBFactory()
    bob_chaindb = AsyncBeaconChainDBFactory()
    peer_pair = ConnectionPairFactory(
        alice_chaindb=alice_chaindb,
        alice_branch=alice_branch,
        bob_chaindb=bob_chaindb,
        bob_branch=bob_branch,
        genesis_state=genesis_state,
    )

    async with peer_pair as (alice, bob):
        alice_syncer = BeaconChainSyncerFactory(
            chain_db__db=alice.chain.chaindb.db,
            peer_pool=alice.handshaked_peers)

        try:
            await asyncio.wait_for(alice_syncer.run(), timeout=sync_timeout)
        except asyncio.TimeoutError:
            # After sync is cancelled, return to let the caller do assertions about the state
            pass
        finally:
            yield alice, bob
Пример #5
0
async def test_handshake_failure_response():
    async with ConnectionPairFactory(handshake=False) as (alice, bob):

        async def fake_handle_status(stream):
            await read_req(stream, Status)
            # The overridden `resp_code` can be anything other than `ResponseCode.SUCCESS`
            await write_resp(stream, "error msg", ResponseCode.INVALID_REQUEST)

        # Mock the handler.
        bob.host.set_stream_handler(REQ_RESP_STATUS_SSZ, fake_handle_status)
        # Test: Handshake fails when the response is not success.
        with pytest.raises(HandshakeFailure):
            await alice.request_status(bob.peer_id)
        assert alice.peer_id not in bob.handshaked_peers
Пример #6
0
async def test_request_beacon_blocks_before_handshake():
    async with ConnectionPairFactory(handshake=False) as (alice, bob):
        # Test: Can not request beacon block before handshake
        with pytest.raises(RequestFailure):
            await alice.request_beacon_blocks_by_range(
                peer_id=bob.peer_id,
                head_block_root=ZERO_HASH32,
                start_slot=0,
                count=1,
                step=1,
            )

        # Test: Can not request beacon block by root before handshake
        with pytest.raises(RequestFailure):
            await alice.request_beacon_blocks_by_root(
                peer_id=bob.peer_id, block_roots=[b"\x12" * 32]
            )
Пример #7
0
async def get_sync_setup(request, event_loop, event_bus, alice_branch,
                         bob_branch):
    alice_chaindb = AsyncBeaconChainDBFactory(blocks=alice_branch)
    bob_chaindb = AsyncBeaconChainDBFactory(blocks=bob_branch)
    peer_pair = ConnectionPairFactory(alice_chaindb=alice_chaindb,
                                      bob_chaindb=bob_chaindb)
    async with peer_pair as (alice, bob):

        alice_syncer = BeaconChainSyncerFactory(
            chain_db__db=alice.chain.chaindb.db,
            peer_pool=alice.handshaked_peers)
        asyncio.ensure_future(alice_syncer.run())

        def finalizer():
            event_loop.run_until_complete(alice_syncer.cancel())

        request.addfinalizer(finalizer)
        await alice_syncer.events.finished.wait()
        yield alice, bob
Пример #8
0
async def test_request_beacon_blocks_by_range_on_nonexist_chain(monkeypatch):
    async with ConnectionPairFactory() as (alice, bob):

        request_head_block_root = b"\x56" * 32

        def get_block_by_root(root):
            raise BlockNotFound

        monkeypatch.setattr(bob.chain, "get_block_by_root", get_block_by_root)

        start_slot = 0
        count = 5
        step = 1
        requested_blocks = await alice.request_beacon_blocks_by_range(
            peer_id=bob.peer_id,
            head_block_root=request_head_block_root,
            start_slot=start_slot,
            count=count,
            step=step,
        )

        assert len(requested_blocks) == 0
Пример #9
0
async def get_sync_setup(
    request,
    event_loop,
    event_bus,
    genesis_state,
    alice_branch,
    bob_branch,
    sync_timeout=6,
):
    alice_chaindb = AsyncBeaconChainDBFactory()
    bob_chaindb = AsyncBeaconChainDBFactory()
    peer_pair = ConnectionPairFactory(
        alice_chaindb=alice_chaindb,
        alice_branch=alice_branch,
        bob_chaindb=bob_chaindb,
        bob_branch=bob_branch,
        genesis_state=genesis_state,
        alice_event_bus=event_bus,
        handshake=False,
    )

    async with peer_pair as (alice, bob):
        alice_syncer = BeaconChainSyncerFactory(
            chain_db__db=alice.chain.chaindb.db,
            peer_pool=alice.handshaked_peers,
            event_bus=event_bus,
        )

        try:
            task = asyncio.ensure_future(alice_syncer.run())
            # sync will start when alice request_status
            await alice.request_status(bob.peer_id)
            # Wait sync to complete
            await asyncio.wait_for(task, timeout=sync_timeout)
        except asyncio.TimeoutError:
            # After sync is cancelled, return to let the caller do assertions about the state
            pass
        finally:
            yield alice, bob
Пример #10
0
async def test_request_recent_beacon_blocks(monkeypatch):
    async with ConnectionPairFactory() as (alice, bob):

        # Mock up block database
        head_block = BeaconBlock(
            slot=0,
            parent_root=ZERO_HASH32,
            state_root=ZERO_HASH32,
            signature=EMPTY_SIGNATURE,
            body=BeaconBlockBody(),
        )
        blocks = [head_block.copy(slot=slot) for slot in range(5)]
        mock_root_to_block_db = {block.hash_tree_root: block for block in blocks}

        def get_block_by_hash_tree_root(root):
            validate_word(root)
            if root in mock_root_to_block_db:
                return mock_root_to_block_db[root]
            else:
                raise BlockNotFound

        monkeypatch.setattr(
            bob.chain, "get_block_by_hash_tree_root", get_block_by_hash_tree_root
        )

        requesting_block_roots = [
            blocks[0].hash_tree_root,
            b"\x12" * 32,  # Unknown block root
            blocks[1].hash_tree_root,
            b"\x23" * 32,  # Unknown block root
            blocks[3].hash_tree_root,
        ]
        requested_blocks = await alice.request_recent_beacon_blocks(
            peer_id=bob.peer_id, block_roots=requesting_block_roots
        )

        expected_blocks = [blocks[0], blocks[1], blocks[3]]
        assert len(requested_blocks) == len(expected_blocks)
        assert set(requested_blocks) == set(expected_blocks)
Пример #11
0
async def test_goodbye():
    async with ConnectionPairFactory() as (alice, bob):
        await alice.say_goodbye(bob.peer_id, GoodbyeReasonCode.FAULT_OR_ERROR)
        assert bob.peer_id not in alice.handshaked_peers
        assert await wait_until_true(lambda: alice.peer_id not in bob.handshaked_peers)
Пример #12
0
async def test_handshake_success():
    async with ConnectionPairFactory(handshake=False) as (alice, bob):
        await alice.request_status(bob.peer_id)
        assert bob.peer_id in alice.handshaked_peers
        assert alice.peer_id in bob.handshaked_peers
Пример #13
0
async def test_hello_success():
    async with ConnectionPairFactory(say_hello=False) as (alice, bob):
        await alice.say_hello(bob.peer_id)
        await asyncio.sleep(0.01)
        assert bob.peer_id in alice.handshaked_peers
        assert alice.peer_id in bob.handshaked_peers
Пример #14
0
async def test_connection_factory_with_Libp2pPeer():
    async with ConnectionPairFactory() as (alice, bob):
        assert bob.peer_id in alice.handshaked_peers
        assert alice.peer_id in bob.handshaked_peers
Пример #15
0
async def test_goodbye():
    async with ConnectionPairFactory() as (alice, bob):
        await alice.say_goodbye(bob.peer_id, GoodbyeReasonCode.FAULT_OR_ERROR)
        await asyncio.sleep(0.01)
        assert bob.peer_id not in alice.handshaked_peers
        assert alice.peer_id not in bob.handshaked_peers
Пример #16
0
async def test_request_beacon_blocks_by_range_invalid_request(monkeypatch):
    async with ConnectionPairFactory() as (alice, bob):

        head_slot = 1
        request_head_block_root = b"\x56" * 32
        head_block = SignedBeaconBlockFactory(message__slot=head_slot)

        # TEST: Can not request blocks with `start_slot` greater than head block slot
        start_slot = 2

        def get_block_by_root(root):
            return head_block

        monkeypatch.setattr(bob.chain, "get_block_by_root", get_block_by_root)

        count = 1
        step = 1
        with pytest.raises(RequestFailure):
            await alice.request_beacon_blocks_by_range(
                peer_id=bob.peer_id,
                head_block_root=request_head_block_root,
                start_slot=start_slot,
                count=count,
                step=step,
            )

        # TEST: Can not request fork chain blocks with `start_slot`
        # lower than peer's latest finalized slot
        start_slot = head_slot
        state_machine = bob.chain.get_state_machine()
        old_state = bob.chain.get_head_state()
        new_checkpoint = old_state.finalized_checkpoint.set(
            "epoch", old_state.finalized_checkpoint.epoch + 1
        )

        def get_canonical_block_by_slot(slot):
            raise BlockNotFound

        monkeypatch.setattr(
            bob.chain, "get_canonical_block_by_slot", get_canonical_block_by_slot
        )

        def get_state_machine(at_slot=None):
            class MockStateMachine:
                state = old_state.set("finalized_checkpoint", new_checkpoint)
                config = state_machine.config

            return MockStateMachine()

        def get_head_state():
            return old_state.set("finalized_checkpoint", new_checkpoint)

        monkeypatch.setattr(bob.chain, "get_state_machine", get_state_machine)
        monkeypatch.setattr(bob.chain, "get_head_state", get_head_state)

        with pytest.raises(RequestFailure):
            await alice.request_beacon_blocks_by_range(
                peer_id=bob.peer_id,
                head_block_root=request_head_block_root,
                start_slot=start_slot,
                count=count,
                step=step,
            )
Пример #17
0
async def test_request_beacon_blocks_invalid_request(monkeypatch):
    async with ConnectionPairFactory() as (alice, bob):

        head_slot = 1
        request_head_block_root = b"\x56" * 32
        head_block = BeaconBlock(
            slot=head_slot,
            parent_root=ZERO_HASH32,
            state_root=ZERO_HASH32,
            signature=EMPTY_SIGNATURE,
            body=BeaconBlockBody(),
        )

        # TEST: Can not request blocks with `start_slot` greater than head block slot
        start_slot = 2

        def get_block_by_hash_tree_root(root):
            return head_block

        monkeypatch.setattr(
            bob.chain, "get_block_by_hash_tree_root", get_block_by_hash_tree_root
        )

        count = 1
        step = 1
        with pytest.raises(RequestFailure):
            await alice.request_beacon_blocks(
                peer_id=bob.peer_id,
                head_block_root=request_head_block_root,
                start_slot=start_slot,
                count=count,
                step=step,
            )

        # TEST: Can not request fork chain blocks with `start_slot`
        # lower than peer's latest finalized slot
        start_slot = head_slot
        state_machine = bob.chain.get_state_machine()
        old_state = bob.chain.get_head_state()
        new_checkpoint = old_state.finalized_checkpoint.copy(
            epoch=old_state.finalized_checkpoint.epoch + 1
        )

        def get_canonical_block_by_slot(slot):
            raise BlockNotFound

        monkeypatch.setattr(
            bob.chain, "get_canonical_block_by_slot", get_canonical_block_by_slot
        )

        def get_state_machine(at_slot=None):
            class MockStateMachine:
                state = old_state.copy(finalized_checkpoint=new_checkpoint)
                config = state_machine.config

            return MockStateMachine()

        def get_head_state():
            return old_state.copy(finalized_checkpoint=new_checkpoint)

        monkeypatch.setattr(bob.chain, "get_state_machine", get_state_machine)
        monkeypatch.setattr(bob.chain, "get_head_state", get_head_state)

        with pytest.raises(RequestFailure):
            await alice.request_beacon_blocks(
                peer_id=bob.peer_id,
                head_block_root=request_head_block_root,
                start_slot=start_slot,
                count=count,
                step=step,
            )