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
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
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)
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
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
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
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)