def test_find_value_request(self): self.assertRaises(ValueError, RequestDatagram.make_find_value, b'1' * 49, b'2' * 48, b'1' * 20) self.assertRaises(ValueError, RequestDatagram.make_find_value, b'1' * 48, b'2' * 49, b'1' * 20) self.assertRaises(ValueError, RequestDatagram.make_find_value, b'1' * 48, b'2' * 48, b'1' * 21) self.assertRaises(ValueError, RequestDatagram.make_find_value, b'1' * 48, b'2' * 48, b'1' * 20, -1) self.assertEqual( 20, len(RequestDatagram.make_find_value(b'1' * 48, b'2' * 48).rpc_id)) # default page argument serialized = RequestDatagram.make_find_value(b'1' * 48, b'2' * 48, b'1' * 20).bencode() decoded = decode_datagram(serialized) self.assertEqual(decoded.packet_type, REQUEST_TYPE) self.assertEqual(decoded.rpc_id, b'1' * 20) self.assertEqual(decoded.node_id, b'1' * 48) self.assertEqual(decoded.method, b'findValue') self.assertListEqual(decoded.args, [b'2' * 48, { b'protocolVersion': 1, b'p': 0 }]) # nondefault page argument serialized = RequestDatagram.make_find_value(b'1' * 48, b'2' * 48, b'1' * 20, 1).bencode() decoded = decode_datagram(serialized) self.assertEqual(decoded.packet_type, REQUEST_TYPE) self.assertEqual(decoded.rpc_id, b'1' * 20) self.assertEqual(decoded.node_id, b'1' * 48) self.assertEqual(decoded.method, b'findValue') self.assertListEqual(decoded.args, [b'2' * 48, { b'protocolVersion': 1, b'p': 1 }])
async def find_value(self, key: bytes, page: int = 0) -> typing.Union[typing.Dict]: """ :return: { b'token': <token bytes>, b'contacts': [(node_id, address, udp_port), ...] <key bytes>: [<blob_peer_compact_address, ...] } """ if len(key) != constants.hash_bits // 8: raise ValueError(f"invalid length of find value key: {len(key)}") response = await self.protocol.send_request( self.peer, RequestDatagram.make_find_value(self.protocol.node_id, key, page=page) ) self.peer_tracker.update_token(self.peer.node_id, response.response[b'token']) return response.response