Example #1
0
async def test_wait_pong(nursery):
    service = MockDiscoveryService([])
    us = service.this_node
    node = NodeFactory()

    async def recv_pong(payload) -> None:
        service.recv_pong_v4(node, payload, b'')

    # Schedule a call to service.recv_pong() simulating a pong from the node we expect.
    token = b'token'
    pong_msg_payload = [us.address.to_endpoint(), token, discovery._get_msg_expiration()]
    nursery.start_soon(recv_pong, pong_msg_payload)

    got_pong = await service.wait_pong_v4(node, token)

    assert got_pong
    # Ensure wait_pong() cleaned up after itself.
    pingid = service._mkpingid(token, node)
    assert pingid not in service.pong_callbacks

    # If the remote node echoed something different than what we expected, wait_pong() would
    # timeout.
    wrong_token = b"foo"
    pong_msg_payload = [us.address.to_endpoint(), wrong_token, discovery._get_msg_expiration()]
    nursery.start_soon(recv_pong, pong_msg_payload)

    got_pong = await service.wait_pong_v4(node, token)

    assert not got_pong
    assert pingid not in service.pong_callbacks
Example #2
0
async def test_wait_pong():
    proto = MockDiscoveryProtocol([])
    us = proto.this_node
    node = random_node()

    token = b'token'
    # Schedule a call to proto.recv_pong() simulating a pong from the node we expect.
    pong_msg_payload = [us.address.to_endpoint(), token, discovery._get_msg_expiration()]
    recv_pong_coroutine = asyncio.coroutine(lambda: proto.recv_pong_v4(node, pong_msg_payload, b''))
    asyncio.ensure_future(recv_pong_coroutine())

    got_pong = await proto.wait_pong_v4(node, token)

    assert got_pong
    # Ensure wait_pong() cleaned up after itself.
    pingid = proto._mkpingid(token, node)
    assert pingid not in proto.pong_callbacks

    # If the remote node echoed something different than what we expected, wait_pong() would
    # timeout.
    wrong_token = b"foo"
    pong_msg_payload = [us.address.to_endpoint(), wrong_token, discovery._get_msg_expiration()]
    recv_pong_coroutine = asyncio.coroutine(lambda: proto.recv_pong_v4(node, pong_msg_payload, b''))
    asyncio.ensure_future(recv_pong_coroutine())

    got_pong = await proto.wait_pong_v4(node, token)

    assert not got_pong
    assert pingid not in proto.pong_callbacks
Example #3
0
async def test_wait_neighbours(nursery):
    service = MockDiscoveryService([])
    addresses = [
        AddressFactory(ip='10.0.0.1'),
        AddressFactory(ip='10.0.0.2'),
        AddressFactory(ip='10.0.0.3'),
        AddressFactory(ip='10.0.0.4')
    ]
    sender = NodeFactory(address=addresses[0])

    # All our nodes are on the same network as the sender to ensure they pass the
    # check_relayed_addr() check, otherwise in some rare cases we may get a random IP address
    # that doesn't and it will be ignored by wait_neighbours, causing the test to fail.
    neighbours = tuple(NodeFactory(address=address) for address in addresses[1:])

    # Schedule a call to service.recv_neighbours_v4() simulating a neighbours response from the
    # node we expect.
    expiration = _get_msg_expiration()
    neighbours_msg_payload = [
        [n.address.to_endpoint() + [n.pubkey.to_bytes()] for n in neighbours],
        expiration]
    nursery.start_soon(service.recv_neighbours_v4, sender, neighbours_msg_payload, b'')

    received_neighbours = await service.wait_neighbours(sender)

    assert neighbours == received_neighbours
    # Ensure wait_neighbours() cleaned up after itself.
    assert not service.neighbours_channels.already_waiting_for(sender)

    # If wait_neighbours() times out, we get an empty list of neighbours.
    received_neighbours = await service.wait_neighbours(sender)

    assert received_neighbours == tuple()
    assert not service.neighbours_channels.already_waiting_for(sender)
Example #4
0
async def test_wait_neighbours(nursery):
    service = MockDiscoveryService([])
    node = NodeFactory()

    # Schedule a call to service.recv_neighbours_v4() simulating a neighbours response from the
    # node we expect.
    neighbours = tuple(NodeFactory.create_batch(3))
    neighbours_msg_payload = [
        [n.address.to_endpoint() + [n.pubkey.to_bytes()] for n in neighbours],
        discovery._get_msg_expiration()]

    async def recv_neighbours() -> None:
        service.recv_neighbours_v4(node, neighbours_msg_payload, b'')
    nursery.start_soon(recv_neighbours)

    received_neighbours = await service.wait_neighbours(node)

    assert neighbours == received_neighbours
    # Ensure wait_neighbours() cleaned up after itself.
    assert node not in service.neighbours_callbacks

    # If wait_neighbours() times out, we get an empty list of neighbours.
    received_neighbours = await service.wait_neighbours(node)

    assert received_neighbours == tuple()
    assert node not in service.neighbours_callbacks
Example #5
0
async def test_wait_neighbours():
    proto = MockDiscoveryProtocol([])
    node = NodeFactory()

    # Schedule a call to proto.recv_neighbours_v4() simulating a neighbours response from the node
    # we expect.
    neighbours = tuple(NodeFactory.create_batch(3))
    neighbours_msg_payload = [[
        n.address.to_endpoint() + [n.pubkey.to_bytes()] for n in neighbours
    ],
                              discovery._get_msg_expiration()]
    recv_neighbours_coroutine = asyncio.coroutine(
        lambda: proto.recv_neighbours_v4(node, neighbours_msg_payload, b''))
    asyncio.ensure_future(recv_neighbours_coroutine())

    received_neighbours = await proto.wait_neighbours(node)

    assert neighbours == received_neighbours
    # Ensure wait_neighbours() cleaned up after itself.
    assert node not in proto.neighbours_callbacks

    # If wait_neighbours() times out, we get an empty list of neighbours.
    received_neighbours = await proto.wait_neighbours(node)

    assert received_neighbours == tuple()
    assert node not in proto.neighbours_callbacks
Example #6
0
async def test_bond(nursery, monkeypatch):
    discovery = MockDiscoveryService([])
    us = discovery.this_node
    node = NodeFactory()
    discovery.node_db.set_enr(node.enr)

    token = b'token'

    async def send_ping(node):
        return token

    # Do not send pings, instead simply return the pingid we'd expect back together with the pong.
    monkeypatch.setattr(discovery, 'send_ping_v4', send_ping)

    # Schedule a call to service.recv_pong() simulating a pong from the node we expect.
    enr_seq = 1
    pong_msg_payload = [
        us.address.to_endpoint(), token,
        _get_msg_expiration(),
        int_to_big_endian(enr_seq)
    ]
    nursery.start_soon(discovery.recv_pong_v4, node, pong_msg_payload, b'')

    bonded = await discovery.bond(node.id)

    assert bonded
    assert discovery.is_bond_valid_with(node.id)

    # Upon successfully bonding, retrieval of the remote's ENR will be scheduled.
    with trio.fail_after(1):
        scheduled_enr_node_id, scheduled_enr_seq = await discovery.pending_enrs_consumer.receive(
        )
    assert scheduled_enr_node_id == node.id
    assert scheduled_enr_seq == enr_seq

    # If we try to bond with any other nodes we'll timeout and bond() will return False.
    node2 = NodeFactory()
    discovery.node_db.set_enr(node2.enr)
    bonded = await discovery.bond(node2.id)

    assert not bonded
Example #7
0
 async def send_malformed_neighbours_v4(node, _):
     nodes = [(b'\xff' * 32, b'\xff', b'\xff', b'\xff')]
     payload = NeighboursPacket(neighbours=nodes, expiration=_get_msg_expiration())
     await bob.send(node, CMD_NEIGHBOURS, payload)