Ejemplo n.º 1
0
    async def _read_pubsub_msg() -> None:
        writer_closed_task = asyncio.ensure_future(writer.wait_closed())

        while True:
            done, pending = await asyncio.wait(
                [read_varint_prefixed_bytes(reader), writer_closed_task],
                return_when=asyncio.FIRST_COMPLETED,
            )
            done_tasks = tuple(done)
            if writer.is_closing():
                return
            read_task = done_tasks[0]
            # Sanity check
            assert read_task._coro.__name__ == "read_varint_prefixed_bytes"
            msg_bytes = read_task.result()
            ps_msg = p2pd_pb2.PSMessage()
            ps_msg.ParseFromString(msg_bytes)
            # Fill in the message used in py-libp2p
            msg = rpc_pb2.Message(
                from_id=ps_msg.from_id,
                data=ps_msg.data,
                seqno=ps_msg.seqno,
                topicIDs=ps_msg.topicIDs,
                signature=ps_msg.signature,
                key=ps_msg.key,
            )
            queue.put_nowait(msg)
Ejemplo n.º 2
0
def make_pubsub_msg(origin_id: ID, topic_ids: Sequence[str], data: bytes,
                    seqno: bytes) -> rpc_pb2.Message:
    return rpc_pb2.Message(
        from_id=origin_id.to_bytes(),
        seqno=seqno,
        data=data,
        topicIDs=list(topic_ids),
    )
Ejemplo n.º 3
0
async def test_bcc_receive_server_handle_beacon_attestations(receive_server):
    attestation = Attestation.create()
    encoded_attestation = ssz.encode(attestation)
    msg = rpc_pb2.Message(
        from_id=b"my_id",
        seqno=b"\x00" * 8,
        data=encoded_attestation,
        topicIDs=[PUBSUB_TOPIC_BEACON_ATTESTATION],
    )

    assert attestation not in receive_server.unaggregated_attestation_pool

    beacon_attestation_queue = receive_server.topic_msg_queues[
        PUBSUB_TOPIC_BEACON_ATTESTATION]
    # Wait for receive server to process the new attestation
    await beacon_attestation_queue.put(msg)
    await wait_all_messages_processed(beacon_attestation_queue)
    # Check that attestation is put to attestation pool
    assert attestation in receive_server.unaggregated_attestation_pool

    # Put the attestation in the next block
    block = SignedBeaconBlockFactory(
        parent=receive_server.chain.get_canonical_head())
    block = block.transform(("message", "body", "attestations"),
                            (attestation, ))
    encoded_block = ssz.encode(block, SignedBeaconBlock)
    msg = rpc_pb2.Message(
        from_id=b"my_id",
        seqno=b"\x00" * 8,
        data=encoded_block,
        topicIDs=[PUBSUB_TOPIC_BEACON_BLOCK],
    )

    beacon_block_queue = receive_server.topic_msg_queues[
        PUBSUB_TOPIC_BEACON_BLOCK]
    # Wait for receive server to process the new block
    await beacon_block_queue.put(msg)
    await wait_all_messages_processed(beacon_block_queue)
    # Check that attestation is removed from attestation pool
    assert attestation not in receive_server.unaggregated_attestation_pool
Ejemplo n.º 4
0
async def test_bcc_receive_server_handle_beacon_attestations(receive_server):
    attestation = Attestation()
    encoded_attestation = ssz.encode(attestation)
    msg = rpc_pb2.Message(
        from_id=b"my_id",
        seqno=b"\x00" * 8,
        data=encoded_attestation,
        topicIDs=[PUBSUB_TOPIC_BEACON_ATTESTATION],
    )

    assert attestation not in receive_server.attestation_pool

    beacon_attestation_queue = receive_server.topic_msg_queues[
        PUBSUB_TOPIC_BEACON_ATTESTATION]
    # Wait for receive server to process the new attestation
    await beacon_attestation_queue.put(msg)
    await wait_all_messages_processed(beacon_attestation_queue)
    # Check that attestation is put to attestation pool
    assert attestation in receive_server.attestation_pool

    # Put the attestation in the next block
    block = get_blocks(receive_server.chain, num_blocks=1)[0]
    block = block.copy(body=block.body.copy(attestations=[attestation]))
    encoded_block = ssz.encode(block, BeaconBlock)
    msg = rpc_pb2.Message(
        from_id=b"my_id",
        seqno=b"\x00" * 8,
        data=encoded_block,
        topicIDs=[PUBSUB_TOPIC_BEACON_BLOCK],
    )

    beacon_block_queue = receive_server.topic_msg_queues[
        PUBSUB_TOPIC_BEACON_BLOCK]
    # Wait for receive server to process the new block
    await beacon_block_queue.put(msg)
    await wait_all_messages_processed(beacon_block_queue)
    # Check that attestation is removed from attestation pool
    assert attestation not in receive_server.attestation_pool
Ejemplo n.º 5
0
 async def _read_pubsub_msg() -> None:
     while True:
         msg_bytes = await read_varint_prefixed_bytes(stream)
         ps_msg = p2pd_pb2.PSMessage()
         ps_msg.ParseFromString(msg_bytes)
         # Fill in the message used in py-libp2p
         msg = rpc_pb2.Message(
             from_id=ps_msg.from_id,
             data=ps_msg.data,
             seqno=ps_msg.seqno,
             topicIDs=ps_msg.topicIDs,
             signature=ps_msg.signature,
             key=ps_msg.key,
         )
         await send_channel.send(msg)
Ejemplo n.º 6
0
async def test_bcc_receive_server_handle_beacon_blocks(receive_server):
    block = SignedBeaconBlockFactory(parent=receive_server.chain.get_canonical_head())
    encoded_block = ssz.encode(block, SignedBeaconBlock)
    msg = rpc_pb2.Message(
        from_id=b"my_id",
        seqno=b"\x00" * 8,
        data=encoded_block,
        topicIDs=[PUBSUB_TOPIC_BEACON_BLOCK],
    )

    assert receive_server.chain.get_canonical_head() != block

    beacon_block_queue = receive_server.topic_msg_queues[PUBSUB_TOPIC_BEACON_BLOCK]

    await beacon_block_queue.put(msg)
    await wait_all_messages_processed(beacon_block_queue)
    assert receive_server.chain.get_canonical_head() == block
Ejemplo n.º 7
0
async def test_bcc_receive_server_handle_beacon_blocks(receive_server):
    block = get_blocks(receive_server.chain, num_blocks=1)[0]
    encoded_block = ssz.encode(block, BeaconBlock)
    msg = rpc_pb2.Message(
        from_id=b"my_id",
        seqno=b"\x00" * 8,
        data=encoded_block,
        topicIDs=[PUBSUB_TOPIC_BEACON_BLOCK],
    )

    assert receive_server.chain.get_canonical_head() != block

    beacon_block_queue = receive_server.topic_msg_queues[
        PUBSUB_TOPIC_BEACON_BLOCK]
    await beacon_block_queue.put(msg)
    # Wait for receive server to process the new block
    await asyncio.sleep(0.5)
    assert receive_server.chain.get_canonical_head() == block
Ejemplo n.º 8
0
def generate_RPC_packet(origin_id, topics, msg_content, msg_id):
    """
    Generate RPC packet to send over wire
    :param origin_id: peer id of the message origin
    :param topics: list of topics
    :param msg_content: string of content in data
    :param msg_id: seqno for the message
    """
    packet = rpc_pb2.RPC()
    message = rpc_pb2.Message(
        from_id=origin_id.encode('utf-8'),
        seqno=msg_id,
        data=msg_content.encode('utf-8'),
    )

    for topic in topics:
        message.topicIDs.extend([topic.encode('utf-8')])

    packet.publish.extend([message])
    return packet
Ejemplo n.º 9
0
async def test_continuously_read_stream(pubsubs_fsub, monkeypatch):
    stream = FakeNetStream()

    await pubsubs_fsub[0].subscribe(TESTING_TOPIC)

    event_push_msg = asyncio.Event()
    event_handle_subscription = asyncio.Event()
    event_handle_rpc = asyncio.Event()

    async def mock_push_msg(msg_forwarder, msg):
        event_push_msg.set()

    def mock_handle_subscription(origin_id, sub_message):
        event_handle_subscription.set()

    async def mock_handle_rpc(rpc, sender_peer_id):
        event_handle_rpc.set()

    monkeypatch.setattr(pubsubs_fsub[0], "push_msg", mock_push_msg)
    monkeypatch.setattr(
        pubsubs_fsub[0], "handle_subscription", mock_handle_subscription
    )
    monkeypatch.setattr(pubsubs_fsub[0].router, "handle_rpc", mock_handle_rpc)

    async def wait_for_event_occurring(event):
        try:
            await asyncio.wait_for(event.wait(), timeout=1)
        except asyncio.TimeoutError as error:
            event.clear()
            raise asyncio.TimeoutError(
                f"Event {event} is not set before the timeout. "
                "This indicates the mocked functions are not called properly."
            ) from error
        else:
            event.clear()

    # Kick off the task `continuously_read_stream`
    task = asyncio.ensure_future(pubsubs_fsub[0].continuously_read_stream(stream))

    # Test: `push_msg` is called when publishing to a subscribed topic.
    publish_subscribed_topic = rpc_pb2.RPC(
        publish=[rpc_pb2.Message(topicIDs=[TESTING_TOPIC])]
    )
    await stream.write(
        encode_varint_prefixed(publish_subscribed_topic.SerializeToString())
    )
    await wait_for_event_occurring(event_push_msg)
    # Make sure the other events are not emitted.
    with pytest.raises(asyncio.TimeoutError):
        await wait_for_event_occurring(event_handle_subscription)
    with pytest.raises(asyncio.TimeoutError):
        await wait_for_event_occurring(event_handle_rpc)

    # Test: `push_msg` is not called when publishing to a topic-not-subscribed.
    publish_not_subscribed_topic = rpc_pb2.RPC(
        publish=[rpc_pb2.Message(topicIDs=["NOT_SUBSCRIBED"])]
    )
    await stream.write(
        encode_varint_prefixed(publish_not_subscribed_topic.SerializeToString())
    )
    with pytest.raises(asyncio.TimeoutError):
        await wait_for_event_occurring(event_push_msg)

    # Test: `handle_subscription` is called when a subscription message is received.
    subscription_msg = rpc_pb2.RPC(subscriptions=[rpc_pb2.RPC.SubOpts()])
    await stream.write(encode_varint_prefixed(subscription_msg.SerializeToString()))
    await wait_for_event_occurring(event_handle_subscription)
    # Make sure the other events are not emitted.
    with pytest.raises(asyncio.TimeoutError):
        await wait_for_event_occurring(event_push_msg)
    with pytest.raises(asyncio.TimeoutError):
        await wait_for_event_occurring(event_handle_rpc)

    # Test: `handle_rpc` is called when a control message is received.
    control_msg = rpc_pb2.RPC(control=rpc_pb2.ControlMessage())
    await stream.write(encode_varint_prefixed(control_msg.SerializeToString()))
    await wait_for_event_occurring(event_handle_rpc)
    # Make sure the other events are not emitted.
    with pytest.raises(asyncio.TimeoutError):
        await wait_for_event_occurring(event_push_msg)
    with pytest.raises(asyncio.TimeoutError):
        await wait_for_event_occurring(event_handle_subscription)

    task.cancel()
Ejemplo n.º 10
0
async def test_continuously_read_stream(monkeypatch, nursery,
                                        security_protocol):
    async def wait_for_event_occurring(event):
        await trio.hazmat.checkpoint()
        with trio.fail_after(0.1):
            await event.wait()

    class Events(NamedTuple):
        push_msg: trio.Event
        handle_subscription: trio.Event
        handle_rpc: trio.Event

    @contextmanager
    def mock_methods():
        event_push_msg = trio.Event()
        event_handle_subscription = trio.Event()
        event_handle_rpc = trio.Event()

        async def mock_push_msg(msg_forwarder, msg):
            event_push_msg.set()
            await trio.hazmat.checkpoint()

        def mock_handle_subscription(origin_id, sub_message):
            event_handle_subscription.set()

        async def mock_handle_rpc(rpc, sender_peer_id):
            event_handle_rpc.set()
            await trio.hazmat.checkpoint()

        with monkeypatch.context() as m:
            m.setattr(pubsubs_fsub[0], "push_msg", mock_push_msg)
            m.setattr(pubsubs_fsub[0], "handle_subscription",
                      mock_handle_subscription)
            m.setattr(pubsubs_fsub[0].router, "handle_rpc", mock_handle_rpc)
            yield Events(event_push_msg, event_handle_subscription,
                         event_handle_rpc)

    async with PubsubFactory.create_batch_with_floodsub(
            1, security_protocol=security_protocol
    ) as pubsubs_fsub, net_stream_pair_factory(
            security_protocol=security_protocol) as stream_pair:
        await pubsubs_fsub[0].subscribe(TESTING_TOPIC)
        # Kick off the task `continuously_read_stream`
        nursery.start_soon(pubsubs_fsub[0].continuously_read_stream,
                           stream_pair[0])

        # Test: `push_msg` is called when publishing to a subscribed topic.
        publish_subscribed_topic = rpc_pb2.RPC(
            publish=[rpc_pb2.Message(topicIDs=[TESTING_TOPIC])])
        with mock_methods() as events:
            await stream_pair[1].write(
                encode_varint_prefixed(
                    publish_subscribed_topic.SerializeToString()))
            await wait_for_event_occurring(events.push_msg)
            # Make sure the other events are not emitted.
            with pytest.raises(trio.TooSlowError):
                await wait_for_event_occurring(events.handle_subscription)
            with pytest.raises(trio.TooSlowError):
                await wait_for_event_occurring(events.handle_rpc)

        # Test: `push_msg` is not called when publishing to a topic-not-subscribed.
        publish_not_subscribed_topic = rpc_pb2.RPC(
            publish=[rpc_pb2.Message(topicIDs=["NOT_SUBSCRIBED"])])
        with mock_methods() as events:
            await stream_pair[1].write(
                encode_varint_prefixed(
                    publish_not_subscribed_topic.SerializeToString()))
            with pytest.raises(trio.TooSlowError):
                await wait_for_event_occurring(events.push_msg)

        # Test: `handle_subscription` is called when a subscription message is received.
        subscription_msg = rpc_pb2.RPC(subscriptions=[rpc_pb2.RPC.SubOpts()])
        with mock_methods() as events:
            await stream_pair[1].write(
                encode_varint_prefixed(subscription_msg.SerializeToString()))
            await wait_for_event_occurring(events.handle_subscription)
            # Make sure the other events are not emitted.
            with pytest.raises(trio.TooSlowError):
                await wait_for_event_occurring(events.push_msg)
            with pytest.raises(trio.TooSlowError):
                await wait_for_event_occurring(events.handle_rpc)

        # Test: `handle_rpc` is called when a control message is received.
        control_msg = rpc_pb2.RPC(control=rpc_pb2.ControlMessage())
        with mock_methods() as events:
            await stream_pair[1].write(
                encode_varint_prefixed(control_msg.SerializeToString()))
            await wait_for_event_occurring(events.handle_rpc)
            # Make sure the other events are not emitted.
            with pytest.raises(trio.TooSlowError):
                await wait_for_event_occurring(events.push_msg)
            with pytest.raises(trio.TooSlowError):
                await wait_for_event_occurring(events.handle_subscription)
Ejemplo n.º 11
0
def make_pubsub_msg():
    return rpc_pb2.Message()