diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 52c7cad..bc2229a 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -27,7 +27,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install flake8 pytest + python -m pip install flake8 pytest pytest-asyncio if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Lint with flake8 run: | diff --git a/.gitignore b/.gitignore index dda7a5c..ff72835 100644 --- a/.gitignore +++ b/.gitignore @@ -161,6 +161,10 @@ cython_debug/ /test/primitives/mytonlib_test.py /test/primitives/usr/ .idea -/tests/contracts/wallets/priv_key.py +/feats/contracts/wallets/priv_key.py /pytoniq/tlb/code_generator.py /main.py +/venv39 +/venv_new +/feats +.DS_Store diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index f451484..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include pytoniq/adnl -exclude pytoniq/adnl/overlay.py diff --git a/examples/adnl/adnl.py b/examples/adnl/adnl.py index cba1f21..d8a80fc 100644 --- a/examples/adnl/adnl.py +++ b/examples/adnl/adnl.py @@ -13,6 +13,20 @@ async def main(): # start adnl receiving server await adnl.start() + # can set default handler for any query + adnl.set_default_query_handler(handler=lambda i: print(i)) + + # or provide function to process specific queries + def process_get_capabilities_request(_): + return { + '@type': 'tonNode.capabilities', + 'version': 2, + 'capabilities': 1, + } + + adnl.set_query_handler(type_='overlay.getCapabilities', + handler=lambda i: process_get_capabilities_request(i)) + # take peer from public config peer = Node('172.104.59.125', 14432, "/YDNd+IwRUgL0mq21oC0L3RxrS8gTu0nciSPUrhqR78=", adnl) await adnl.connect_to_peer(peer) diff --git a/pytoniq/__init__.py b/pytoniq/__init__.py index 5846f2b..281a5ac 100644 --- a/pytoniq/__init__.py +++ b/pytoniq/__init__.py @@ -1,8 +1,8 @@ -from pytoniq_core.boc import * from .contract import * -from pytoniq_core.crypto import * from .liteclient import * from .adnl import * +from pytoniq_core.boc import * +from pytoniq_core.crypto import * from pytoniq_core.proof import * from pytoniq_core.tl import * from pytoniq_core.tlb import * diff --git a/pytoniq/adnl/__init__.py b/pytoniq/adnl/__init__.py index aa85091..743a999 100644 --- a/pytoniq/adnl/__init__.py +++ b/pytoniq/adnl/__init__.py @@ -1,2 +1,3 @@ from .adnl import AdnlTransport, AdnlTransportError, AdnlChannel, Node from .dht import DhtNode, DhtError, DhtClient, DhtValueNotFoundError +from .overlay import OverlayTransport, OverlayNode, OverlayTransportError diff --git a/pytoniq/adnl/adnl.py b/pytoniq/adnl/adnl.py index f5629eb..f4bdf5b 100644 --- a/pytoniq/adnl/adnl.py +++ b/pytoniq/adnl/adnl.py @@ -1,9 +1,10 @@ import asyncio import base64 +import inspect import logging +import random import time import hashlib -import types import typing from asyncio import transports from typing import Any @@ -18,7 +19,7 @@ class SocketProtocol(asyncio.DatagramProtocol): def __init__(self, timeout: int = 10): # https://github.com/eerimoq/asyncudp/blob/main/asyncudp/__init__.py self._error = None - self._packets = asyncio.Queue(1000) + self._packets = asyncio.Queue(10000) self.timeout = timeout self.logger = logging.getLogger(self.__class__.__name__) @@ -35,7 +36,7 @@ def error_received(self, exc: Exception) -> None: super().error_received(exc) async def receive(self): - return await asyncio.wait_for(self._packets.get(), self.timeout) # TODO improve timeout + return await self._packets.get() class Node(Server): @@ -73,7 +74,11 @@ def start_ping(self): async def ping(self): while True: self.sending = True - await self.send_ping() + try: + await self.send_ping() + except asyncio.TimeoutError: # todo + self.transport.peers.pop(self.key_id) + await self.disconnect() self.sending = False self.logger.debug(f'pinged {self.key_id.hex()}') await asyncio.sleep(3) @@ -106,7 +111,7 @@ class AdnlTransport: def __init__(self, private_key: bytes = None, tl_schemas_path: str = None, - local_address: tuple = ('0.0.0.0', 12000), + local_address: tuple = ('0.0.0.0', None), *args, **kwargs ) -> None: """ @@ -117,12 +122,16 @@ def __init__(self, self.loop: asyncio.AbstractEventLoop = None self.timeout = kwargs.get('timeout', 10) self.listener = None + self.logger = logging.getLogger(self.__class__.__name__) self.tasks: typing.Dict[str, asyncio.Future] = {} self.query_handlers: typing.Dict[str, typing.Callable] = {} + self.custom_handlers: typing.Dict[str, typing.Callable] = {} """########### connection ###########""" self.transport: asyncio.DatagramTransport = None self.protocol: SocketProtocol = None + if local_address[1] is None: + local_address = local_address[0], random.randint(10000, 60000) self.local_address = local_address """########### TL ###########""" @@ -229,9 +238,10 @@ def _decrypt_any(self, resp_packet: bytes) -> typing.Tuple[bytes, typing.Optiona decrypted = channel.decrypt(encrypted, checksum) assert hashlib.sha256(decrypted).digest() == checksum, 'invalid checksum' return decrypted, self.peers.get(peer_id) - raise AdnlTransportError(f'unknown key id from node: {key_id.hex()}') + # TODO make new connection + self.logger.debug(f'unknown key id from node: {key_id.hex()}') - def process_outcoming_message(self, message: dict) -> typing.Optional[asyncio.Future]: + def _process_outcoming_message(self, message: dict) -> typing.Optional[asyncio.Future]: future = self.loop.create_future() type_ = message['@type'] if type_ == 'adnl.message.query': @@ -239,19 +249,19 @@ def process_outcoming_message(self, message: dict) -> typing.Optional[asyncio.Fu elif type_ == 'adnl.message.createChannel': self.tasks[message.get('key')] = future else: - raise AdnlTransportError(f'unexpected message sending as a client: {message}') + return return future def _create_futures(self, data: dict) -> typing.List[asyncio.Future]: futures = [] if data.get('message'): - future = self.process_outcoming_message(data['message']) + future = self._process_outcoming_message(data['message']) if future is not None: futures.append(future) if data.get('messages'): for message in data['messages']: - future = self.process_outcoming_message(message) + future = self._process_outcoming_message(message) if future is not None: futures.append(future) return futures @@ -260,27 +270,100 @@ def _create_futures(self, data: dict) -> typing.List[asyncio.Future]: async def _receive(futures: typing.List[asyncio.Future]) -> list: return list(await asyncio.gather(*futures)) - async def process_incoming_message(self, message: dict): + async def _process_incoming_message(self, message: dict, peer: Node): if message['@type'] == 'adnl.message.answer': future = self.tasks.pop(message.get('query_id')) future.set_result(message['answer']) elif message['@type'] == 'adnl.message.confirmChannel': - future = self.tasks.pop(message.get('peer_key')) - future.set_result(message) + if message.get('peer_key') in self.tasks: + future = self.tasks.pop(message.get('peer_key')) + future.set_result(message) elif message['@type'] == 'adnl.message.query': - query = message.get('query') - handler = self.query_handlers.get(query['@type']) - if handler: - handler(query) + if peer is None: + self.logger.info(f'Received query message from unknown peer') + # not implemented, todo: make connection with new peer + return + await self._process_query_message(message, peer) + elif message['@type'] == 'adnl.message.custom': + if peer is None: + # should not ever happen fixme + self.logger.info(f'Received custom message from unknown peer') + return + await self._process_custom_message(message, peer) else: - raise AdnlTransportError(f'unexpected message type received as a client: {message}') + raise AdnlTransportError(f'unexpected message type received: {message}') + + async def _process_query_message(self, message: dict, peer: Node): + query = message.get('query') + # it's divided into separate method because some higher level protocols over ADNL need specific query processing + await self._process_query_handler(message, query, peer) + + async def _process_query_handler(self, message: dict, query: dict, peer: Node): + # try to get handler for specific query and if there is no, try to get default handler + handler = self.query_handlers.get(query['@type'], self.query_handlers.get(None)) + if handler: + if inspect.iscoroutinefunction(handler): + response = await handler(query) + else: + response = handler(query) + if response is not None: + await self.send_answer_message(response, message.get('query_id'), peer) + + async def _process_custom_message(self, message: dict, peer: Node): + data = message.get('data') + await self._process_custom_message_handler(data, peer) + + async def _process_custom_message_handler(self, data: dict, peer: Node): + handler = self.custom_handlers.get(data['@type'], self.custom_handlers.get(None)) + if handler: + if inspect.iscoroutinefunction(handler): + response = await handler(data) + else: + response = handler(data) + if response is not None: + await self.send_custom_message(response, peer) + + def set_query_handler(self, type_: str, handler: typing.Callable) -> None: + """ + :param type_: TL type of message + :param handler: function to handle message. **Must** return dict or bytes or None. If + None returned than answer won't be sent to the sender + :return: + """ + self.query_handlers[type_] = handler + + def set_default_query_handler(self, handler: typing.Callable): + """ + Same as `set_query_handler` when there is no handlers for query specific type. + :param handler: + :return: + """ + self.set_query_handler(None, handler) + + def set_custom_message_handler(self, type_: str, handler: typing.Callable): + """ + :param type_: TL type of message + :param handler: function to handle message. **Must** return dict or bytes or None. If + None returned than answer won't be sent to the sender. + :return: + """ + self.custom_handlers[type_] = handler + + def set_default_custom_message_handler(self, handler: typing.Callable): + """ + Same as `set_custom_message_handler` when there is no handlers for query specific type. + :param handler: + :return: + """ + self.set_custom_message_handler(None, handler) async def listen(self): while True: if not self.tasks: - await asyncio.sleep(0) - continue - packet, addr = await self.protocol.receive() + packet, addr = await self.protocol.receive() + else: + packet, addr = await self.protocol.receive() + decrypted, peer = self._decrypt_any(packet) if decrypted is None: continue @@ -294,10 +377,10 @@ async def listen(self): messages = response.get('messages') if message: - await self.process_incoming_message(message) + await self._process_incoming_message(message, peer) if messages: for message in messages: - await self.process_incoming_message(message) + await self._process_incoming_message(message, peer) async def send_message_in_channel(self, data: dict, channel: typing.Optional[AdnlChannel] = None, peer: Node = None) -> list: @@ -357,25 +440,33 @@ async def send_message_outside_channel(self, data: dict, peer: Node) -> list: peer.inc_seqno() else: raise Exception(f'sending seqno {sending_seqno}, client seqno: {peer.seqno}') - - result = await asyncio.wait_for(self._receive(futures), self.timeout) - return result + if futures: + result = await asyncio.wait_for(self._receive(futures), self.timeout) + return result async def start(self): self.loop = asyncio.get_running_loop() self.transport, self.protocol = await self.loop.create_datagram_endpoint( lambda: SocketProtocol(timeout=self.timeout), - local_addr=self.local_address + local_addr=self.local_address, + reuse_port=True ) self.listener = self.loop.create_task(self.listen()) return + def _get_default_message(self): + return { + '@type': 'adnl.message.query', + 'query_id': get_random(32), + 'query': self.schemas.get_by_name('dht.getSignedAddressList').little_id() + } + async def connect_to_peer(self, peer: Node) -> list: """ Connects to the peer, creates channel and asks for a signed list in channel. - :return: response dict for dht.getSignedAddressList + :param peer: peer connect to + :return: response dict for default message """ - # self.transport, self.protocol = await self.loop.create_datagram_endpoint(lambda: SocketProtocol(timeout=self.timeout)) ts = int(time.time()) channel_client = Client(Client.generate_ed25519_private_key()) @@ -385,16 +476,13 @@ async def connect_to_peer(self, peer: Node) -> list: 'date': ts } - get_addr_list_message = { - '@type': 'adnl.message.query', - 'query_id': get_random(32), - 'query': self.schemas.get_by_name('dht.getSignedAddressList').little_id() - } + default_message = self._get_default_message() from_ = self.schemas.serialize(self.schemas.get_by_name('pub.ed25519'), data={'key': self.client.ed25519_public.encode().hex()}) data = { 'from': from_, - 'messages': [create_channel_message, get_addr_list_message], + 'from_short': {'id': self.client.get_key_id().hex()}, + 'messages': [create_channel_message, default_message], 'address': { 'addrs': [], 'version': ts, @@ -418,22 +506,16 @@ async def connect_to_peer(self, peer: Node) -> list: self.channels[peer.get_key_id()] = channel peer.channels.append(channel) - # test channel: todo remove - - data = { - 'message': get_addr_list_message, - } - - result = await self.send_message_in_channel(data, channel, peer) peer.start_ping() peer.connected = True + self.peers[peer.key_id] = peer - return result + return messages[1] async def close(self): self.transport.close() - async def send_query_message(self, tl_schema_name: str, data: dict, peer: Node) -> list[dict]: + async def send_query_message(self, tl_schema_name: str, data: dict, peer: Node) -> typing.List[dict]: message = { '@type': 'adnl.message.query', 'query_id': get_random(32), @@ -450,10 +532,19 @@ async def send_query_message(self, tl_schema_name: str, data: dict, peer: Node) result = await self.send_message_in_channel(data, None, peer) return result - async def send_answer_message(self, ): - pass - async def send_custom_message(self, message: bytes, peer) -> list: - # TODO test + async def send_answer_message(self, response: typing.Union[dict, bytes], query_id: bytes, peer: Node): + message = { + '@type': 'adnl.message.answer', + 'query_id': query_id, + 'answer': response + } + + data = { + 'message': message, + } + return await self.send_message_in_channel(data, None, peer) + + async def send_custom_message(self, message: typing.Union[dict, bytes], peer: Node) -> list: custom_message = { '@type': 'adnl.message.custom', @@ -464,5 +555,5 @@ async def send_custom_message(self, message: bytes, peer) -> list: 'message': custom_message, } - result = await self.send_message_in_channel(data, peer) + result = await self.send_message_in_channel(data, None, peer) return result diff --git a/pytoniq/adnl/dht.py b/pytoniq/adnl/dht.py index bc23442..09404f1 100644 --- a/pytoniq/adnl/dht.py +++ b/pytoniq/adnl/dht.py @@ -7,11 +7,12 @@ import struct import requests -from pytoniq_core.crypto.ciphers import Client +from pytoniq_core.crypto.ciphers import Client, Server from pytoniq_core.crypto.signature import verify_sign from pytoniq_core.tl import TlGenerator from .adnl import Node, AdnlTransport +from .overlay import OverlayNode, OverlayTransport class DhtError(Exception): @@ -82,16 +83,20 @@ async def close(self): for node in self.nodes_set: await node.disconnect() - def get_dht_key_id_tl(self, id_: bytes, name: bytes = b'address', idx: int = 0): + def get_dht_key_id_tl(self, id_: typing.Union[bytes, str], name: bytes = b'address', idx: int = 0): + if isinstance(id_, str): + id_ = bytes.fromhex(id_) dht_key_sch = self.schemas.get_by_name('dht.key') serialized = self.schemas.serialize(dht_key_sch, data={'id': id_.hex(), 'name': name, 'idx': idx}) return hashlib.sha256(serialized).digest() @staticmethod - def get_dht_key_id(id_: bytes, name: bytes = b'address', idx: int = 0): + def get_dht_key_id(id_: typing.Union[bytes, str], name: bytes = b'address', idx: int = 0): """ Same as the method above but without using TlGenerator """ + if isinstance(id_, str): + id_ = bytes.fromhex(id_) to_hash = b'\x8f\xdeg\xf6' + id_ + len(name).to_bytes(1, 'big') + name + idx.to_bytes(4, 'little') return hashlib.sha256(to_hash).digest() @@ -216,6 +221,44 @@ async def store_value(self, key: dict, value: bytes, private_key: bytes, data |= {'signature': signature} return await self.raw_store_value(data, try_find_after) + async def get_overlay_nodes(self, overlay_id: typing.Union[bytes, str], overlay_transport: OverlayTransport): + resp = await self.find_value(key=self.get_dht_key_id_tl(overlay_id, name=b'nodes'), timeout=30) + nodes = resp['value']['value']['nodes'] + result = [] + for node in nodes: + result.append(await self.get_overlay_node(node, overlay_transport)) + return result + + async def get_overlay_node(self, node: dict, overlay_transport: OverlayTransport) -> typing.Optional[OverlayNode]: + """ + :param node: dict overlay.node TL schema + :param overlay_transport: + :return: OverlayNode or None + """ + pub_k = bytes.fromhex(node['id']['key']) + adnl_addr = Server('', 0, pub_key=pub_k).get_key_id() + + to_sign = self.schemas.serialize( + schema=self.schemas.get_by_name('overlay.node.toSign'), + data={'id': {'id': adnl_addr.hex()}, 'overlay': node['overlay'], 'version': node['version']} + ) + + if not verify_sign(pub_k, to_sign, node['signature']): + raise Exception('invalid node signature!') + + try: + resp = await self.find_value(key=self.get_dht_key_id_tl(id_=adnl_addr), timeout=5) + except asyncio.TimeoutError: + return None + + node_addr = resp['value']['value']['addrs'][0] + host = socket.inet_ntoa(struct.pack('>i', node_addr['ip'])) + port = node_addr['port'] + pub_k = base64.b64encode(bytes.fromhex(resp['value']['key']['id']['key'])).decode() + + node = OverlayNode(peer_host=host, peer_port=port, peer_pub_key=pub_k, transport=overlay_transport) + return node + @classmethod def from_config(cls, config: dict, adnl_transport: AdnlTransport): nodes = [] diff --git a/pytoniq/adnl/overlay.py b/pytoniq/adnl/overlay.py new file mode 100644 index 0000000..9a21178 --- /dev/null +++ b/pytoniq/adnl/overlay.py @@ -0,0 +1,151 @@ +import time +import hashlib +import typing + +from pytoniq_core.tl.generator import TlGenerator + +from pytoniq_core.crypto.ciphers import get_random + +from .adnl import Node, AdnlTransport, AdnlTransportError + + +class OverlayTransportError(AdnlTransportError): + pass + + +class OverlayNode(Node): + + def __init__( + self, + peer_host: str, # ipv4 host + peer_port: int, # port + peer_pub_key: str, + transport: "OverlayTransport" + ): + self.transport: "OverlayTransport" = None + super().__init__(peer_host, peer_port, peer_pub_key, transport) + + async def send_ping(self) -> None: + peers = [ + self.transport.get_signed_myself() + ] + await self.transport.send_query_message('overlay.getRandomPeers', {'peers': {'nodes': peers}}, peer=self) + + +class OverlayTransport(AdnlTransport): + + def __init__(self, + private_key: bytes = None, + tl_schemas_path: str = None, + local_address: tuple = ('0.0.0.0', None), + overlay_id: typing.Union[str, bytes] = None, + *args, **kwargs + ) -> None: + + super().__init__(private_key, tl_schemas_path, local_address, *args, **kwargs) + if overlay_id is None: + raise OverlayTransportError('must provide overlay id in OverlayTransport') + + if isinstance(overlay_id, bytes): + overlay_id = overlay_id.hex() + + self.overlay_id = overlay_id + + @staticmethod + def get_overlay_id(workchain: int = 0, shard: int = -9223372036854775808) -> str: + schemes = TlGenerator.with_default_schemas().generate() + + sch = schemes.get_by_name('tonNode.shardPublicOverlayId') + data = { + "workchain": workchain, + "shard": shard, + "zero_state_file_hash": "5e994fcf4d425c0a6ce6a792594b7173205f740a39cd56f537defd28b48a0f6e" + } + + key_id = hashlib.sha256(schemes.serialize(sch, data)).digest() + + sch = schemes.get_by_name('pub.overlay') + data = { + 'name': key_id + } + + key_id = schemes.serialize(sch, data) + + return hashlib.sha256(key_id).digest().hex() + + async def _process_query_message(self, message: dict, peer: OverlayNode): + query = message.get('query') + if isinstance(query, list): + if query[0]['@type'] == 'overlay.query': + assert query[0]['overlay'] == self.overlay_id, 'Unknown overlay id received' + query = query[-1] + await self._process_query_handler(message, query, peer) + + async def _process_custom_message(self, message: dict, peer: Node): + data = message.get('data') + if isinstance(data, list): + if data[0]['@type'] == 'overlay.query': + assert data[0]['overlay'] == self.overlay_id, 'Unknown overlay id received' + data = data[-1] + await self._process_custom_message_handler(data, peer) + + def get_signed_myself(self): + ts = int(time.time()) + + overlay_node_data = {'id': {'@type': 'pub.ed25519', 'key': self.client.ed25519_public.encode().hex()}, + 'overlay': self.overlay_id, 'version': ts, 'signature': b''} + + overlay_node_to_sign = self.schemas.serialize(self.schemas.get_by_name('overlay.node.toSign'), + {'id': {'id': self.client.get_key_id().hex()}, + 'overlay': self.overlay_id, + 'version': overlay_node_data['version']}) + signature = self.client.sign(overlay_node_to_sign) + + overlay_node = overlay_node_data | {'signature': signature} + return overlay_node + + async def send_query_message(self, tl_schema_name: str, data: dict, peer: Node) -> typing.List[dict]: + + message = { + '@type': 'adnl.message.query', + 'query_id': get_random(32), + 'query': self.schemas.serialize(self.schemas.get_by_name('overlay.query'), data={'overlay': self.overlay_id}) + + self.schemas.serialize(self.schemas.get_by_name(tl_schema_name), data) + } + data = { + 'message': message, + } + + result = await self.send_message_in_channel(data, None, peer) + return result + + def get_message_with_overlay_prefix(self, schema_name: str, data: dict) -> bytes: + return (self.schemas.serialize( + schema=self.schemas.get_by_name('overlay.query'), + data={'overlay': self.overlay_id}) + + self.schemas.serialize( + schema=self.schemas.get_by_name(schema_name), + data=data) + ) + + def _get_default_message(self): + peers = [ + self.get_signed_myself() + ] + return { + '@type': 'adnl.message.query', + 'query_id': get_random(32), + 'query': self.get_message_with_overlay_prefix('overlay.getRandomPeers', {'peers': {'nodes': peers}}) + } + + async def get_random_peers(self, peer: OverlayNode): + overlay_node = self.get_signed_myself() + + peers = [ + overlay_node + ] + return await self.send_query_message(tl_schema_name='overlay.getRandomPeers', data={'peers': {'nodes': peers}}, + peer=peer) + + async def get_capabilities(self, peer: OverlayNode): + return await self.send_query_message(tl_schema_name='tonNode.getCapabilities', data={}, peer=peer) diff --git a/setup.py b/setup.py index 8b0b80a..afbe68a 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,6 @@ long_description=long_description, long_description_content_type="text/markdown", packages=setuptools.find_packages('.', exclude=['tests', 'examples']), - include_package_data=True, classifiers=[ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", diff --git a/tests/.blockstore/64c44f08ffffffff800000000000000001de3721c63f1e61eae198dfe35236efae24f6254dd80f94acc6f3f5232d7d2959ef40259b93c8806af8aac83d32f94a11cccae8d9555d3fc0ba74ee5b1ecd1d0fce0417.blks b/tests/.blockstore/64c44f08ffffffff800000000000000001de3721c63f1e61eae198dfe35236efae24f6254dd80f94acc6f3f5232d7d2959ef40259b93c8806af8aac83d32f94a11cccae8d9555d3fc0ba74ee5b1ecd1d0fce0417.blks deleted file mode 100644 index d0a98cc..0000000 Binary files a/tests/.blockstore/64c44f08ffffffff800000000000000001de3721c63f1e61eae198dfe35236efae24f6254dd80f94acc6f3f5232d7d2959ef40259b93c8806af8aac83d32f94a11cccae8d9555d3fc0ba74ee5b1ecd1d0fce0417.blks and /dev/null differ diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/block_proofs.py b/tests/block_proofs.py deleted file mode 100644 index 2e2e99d..0000000 --- a/tests/block_proofs.py +++ /dev/null @@ -1,55 +0,0 @@ -import asyncio -import time - -from tonpylib.liteclient.client import LiteClient -from tonpylib.tl.block import BlockIdExt - -host = '65.21.141.231' -port = 17728 - -pub_key_b64 = 'BYSVpL7aPk0kU5CtlsIae/8mf2B/NrBi7DKmepcjX6Q=' - - -async def main(): - client = LiteClient( - host, - port, - pub_key_b64 - ) - await client.connect() - - await client.get_masterchain_info() - last = BlockIdExt.from_dict((await client.get_masterchain_info_ext())['last']) - - blk, blk_data = await client.lookup_block(-1, -9223372036854775808, last.seqno - 100) - await client.get_shard_block_proof(client.last_shard_blocks[0]) - # await client.get_shard_block_proof(blk) - # input() - await client.get_block_proof(known_block=last, target_block=blk) - - init_block = BlockIdExt.from_dict({ - "root_hash": "61192b72664cbcb06f8da9f0282c8bdf0e2871e18fb457e0c7cca6d502822bfe", - "seqno": 27747086, - "file_hash": "378db1ccf9c98c3944de1c4f5ce6fea4dcd7a26811b695f9019ccc3e7200e35b", - "workchain": -1, - "shard": -9223372036854775808 - }) - - init2_block = BlockIdExt.from_dict({ - "workchain": -1, - "shard": -9223372036854775808, - "seqno": 18155329, - "root_hash": "8b239a9f2e1c3c4daeea1fd49bb3809870d0f8d6daf009be83fa992793383fd3", - "file_hash": "62a9a58b7808520b772a3794e27d9dd5999c277478cc904c61684cfad645e15f" - }) - - s = time.time() - - await client.get_block_proof(known_block=init_block, target_block=blk) - print(time.time() - s) - - await client.close() - - -if __name__ == '__main__': - asyncio.run(main(), debug=True) diff --git a/tests/blocks.py b/tests/blocks.py deleted file mode 100644 index f5e2c02..0000000 --- a/tests/blocks.py +++ /dev/null @@ -1,46 +0,0 @@ -from tonpylib.boc import Cell, Builder, Slice -from tonpylib.tlb.block import Block, ShardIdent - - -boc = b'\xb5\xee\x9cr\xe2\x02\x01-\x00\x01\x00\x00$,\x00\x00\x00$\x00\xcc\x00\xf2\x01\x88\x02j\x03\x06\x038\x03Z\x03i\x03\x82\x03\x9c\x04\x0c\x04|\x04\xc8\x05p\x05\xb0\x06\xa2\x06\xbc\x07d\x07\xa4\x08\x96\t\x06\tS\tv\t\x9a\nF\nf\n\x86\n\xa6\n\xc2\n\xde\n\xfa\x0b\x16\x0b2\x0bN\x0bj\x0c\x10\x0c\x94\x0c\xb8\x0c\xd8\r$\rp\r\x90\r\xb0\r\xd0\r\xf0\x0e\x10\x0e0\x0eP\x0ep\x0e\x90\x0f:\x0f\xc2\x10 \x102\x10\xb0\x10\xfc\x11\xc8\x11\xe8\x11\xf6\x12\x14\x122\x12P\x12p\x12\x8e\x12\xac\x12\xca\x12\xe8\x13\x06\x13$\x13B\x13\xd8\x13\xe6\x13\xf4\x14\x02\x14\x10\x14\x1e\x14,\x14:\x14H\x14V\x14d\x14\xb0\x14\xbe\x14\xcc\x14\xda\x14\xe8\x14\xf6\x15\x04\x15\x12\x15 \x15.\x15<\x15J\x15\x96\x15\xa4\x15\xb2\x15\xc0\x15\xce\x15\xdc\x15\xea\x15\xf8\x16\x06\x16\x14\x16`\x16\x84\x16\xa8\x16\xf5\x17\xa0\x17\xc0\x17\xe0\x18-\x18y\x18\x98\x18\xb4\x19\x01\x19M\x19h\x19\x84\x19\xd1\x1a\x1d\x1a8\x1aT\x1a\xa1\x1a\xed\x1b\x08\x1bU\x1bp\x1c\x16\x1cc\x1c\xe6\x1d3\x1d\x85\x1d\xd0\x1d\xf0\x1e=\x1e\x89\x1e\xa8\x1e\xc8\x1f\x15\x1f4\x1f\x81\x1f\xcd\x1f\xec 9 X x \xc5 \xe4!1!}!\x9c!\xe9"\x08"\xb2"\xff#\x86#\xd3$0$}$\x8e%\x0c%Y%\xa5%\xf1&\xbc\'\t\'(\'6\'\x83\'\xa0\'\xed(\n(W(t(\xc1(\xe0)-)J)\x97)\xb4*\x01*\x1e*k*\x88*\xd5*\xf2+?+\\+\xa9+\xc6+\xe4,\x92,\xdf-+-\xc0-\xce.\x1b.(.u.\x82.\xcf.\xdc.\xea/7/D/\x91/\xdd/\xea070D0R0\x9f0\xeb0\xf81E1R2\x082\xbe2\xcc2\xda2\xe8353B3\x8f3\x9c3\xe93\xf64C4P4\x9d4\xaa4\xf75\x045Q5^5\xab5\xb86\x056\x126_6l7 7\x988L8\x998\xa68\xf39\x009\x0e9[9h9\xb5:\x01:\x0e:\x1c:i:\xb5:\xc2:\xd0;\x1d;i;v;\x84;\xd1<\x84=8=D=J=T=|=\xd0=\xe0>\x88?,?8?D?\xca@\x8aA\x10A"A\xc6B\x86B\x8dC\x13C$C\xc8C\xd5D\x18D"E\x06E\x1eE,E;E\xfbF\x04F\x8aF\xa6GWG\xf8HY\x04\x10\x11\xefU\xaa\xff\xff\xff\x11\x00\x01\x00\x02\x00\x03\x00\x04\x01\xa0\x9b\xc7\xa9\x87\x00\x00\x00\x00\x04\x01\x01\xd1\xd3\x91\x00\x00\x00\x01\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00d\x93F\xbd\x00\x00#+U\x9e>\xc0\x00\x00#+U\x9e>\xc4f\n7\xb1\x00\x06\xdd\xe3\x01\xd1\xd3\x8e\x01\xd1\xccg\xc4\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00.\x00\x05\x02\x19>\xbf\x98\xb7J\x12\xf0\x02\x11\xa0"\x90 \x00\x06\x00\x07\n\x8a\x04w\'-\xb5\xa4k\x8a\xb8%\x7f\x0c\x86\xc1S#\xfd\x02\xc0\xd2\xde\xdf\xff\xa4~\xf0\xaf\x19d\x80\xb2h\x84\xa0\xae\x80\x11\x90\x02y4=\xad\xcf\xa7)\x19\x07D,,$\xdb\xaa\xd0\x94\xce;\xc1\x9a\x02\xff\xc5\x10x\x01o\x01o\x00\x0b\x00\x0c\x14\x89\x16\x82\xba<8"\xb5_\xe2\xd2\x9e\xa1U\';\xc4\xf9\xfc\xf5WP\xb3\x89G\xec\xd5a\xf9\xda\x96g\xc7\x00\x07J3\xf6\xfd{h\x92\x0c:\xec\x8a!\x11o\x06\xac\x1a\xe3\xeb\xcd\x12\x02\xb4\xb5\xda\x811>\xa5\xe0\xb1\xbbsr\nr\xf3r\xae\x9d\xb3(\xf5p\xef\xd8\xa6C\xe4\xb8\x9c\x14\x0b\x8a\xb0\x0c\x15O\xb3-\xe1\x89UD\x84{\x9a\x94\xc0\x01\x0b\x01\x0c\x01\r\x01\x0e\x00\x98\x00\x00#+U\x8e\xfc\x84\x01\xd1\xd3\x90\x0f\x1e\xbe\xd3\xfe\x98\xc4\xfc.7\x9d\x1e\xb6\x98*;Rv!\xbf\n\xc3\xe2\x1eMbD\x18c7\xaa\xbc\xbeI\xd6\xd7\xbdL.\xf4\xf1\xf9\x08\x83z\x957\xbc\x1a\xff\xe7\xa5\xdc\x86\x19\x88`\xcd\xb6\xa3yY\x90\xab\x02%\x82\r5M\xc3\x7f\xe72\xec\x10i\xaanl\x96\xb9\xa7\xc0\x08\x00\x08\x00\x08\x00\x1dC\xc1\xb5D\x12P\x97\x80\x10\x91\x95O\xc4\x00\x08\x02\x01 \x00\t\x00\n\x00\x15\xbe\x00\x00\x03\xbc\xb3U\xabFj\xd0\x00\x15\xbf\xff\xff\xff\xbc\xbd\x0e\xfd\xa5c\xd0$[\x90#\xaf\xe2\xff\xff\xff\x11\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x01\xd1\xd3\x90\x00\x00\x00\x01d\x93F\xba\x00\x00#+U\x8e\xfc\x84\x01\xd1\xd3\x8d`\x00\r\x00\x0e\x00\x0f\x00\x10$[\x90#\xaf\xe2\xff\xff\xff\x11\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x01\xd1\xd3\x91\x00\x00\x00\x01d\x93F\xbd\x00\x00#+U\x9e>\xc4\x01\xd1\xd3\x8e`\x00\x11\x00\x12\x00\x13\x00\x14(H\x01\x01\xe8\xfdJ^||[\xef\x06B\xd7\x7f\x9d\xe0\x05f\x0f\xbeK\x05c\xdeI\xe4\xd1hl\xbb/\x84\xca\xf4\x00\x012\x13\xa1\x16\xf1\xdb\xe0\x90}#\xe0!\xd5\x86\xb4\x8d@HPA\xe4\xe0\xf1\xdb\xa3\xaa\xe4Tv\xb73\xd9\x01Y\xf5\x00\x9d\xd1\xb9\xee\xb7\x96E\xe7O\x9cpD\xe1\xc8\x0f,r\xda\x85\xfam\xba\xb22\x9eb\xc6\xfeD\xc7\x01n\x00\x13\x82\x084\xd57\r\xff\x9c\xcb\xb0\x00\x17\x00\x87"3\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x82\r5M\xc3\x7f\xe72\xe8(\x00\x87\x00\x164U7\x8b\xf5\xbb\xaa:\x16T\xde\x18\xae\xc4\r\x88\xaa?Dn\xe6\xee\xd5*C\xaa\x90\xaa-\xc3ji\x83X\x0b`T\xdc\x03\x97\xe6\xd6V\x99\xa0\x016\xfe\x16\x8bY\x87\x1e\x01\xdcc\xba\xd4\x00\x00FV\xab\x1d\xf9\x05\x004"{\xcf\xf333333333333333333333333333333334\x0b\x18\xc1\xa8@\x80\x00\x00\x00\x00\x00\x00\x8c\xadV;\xf2\x0e\x01\x9bb\x1e\xad\xeep\x04\x16\xd0\x00\x9d\x005"Qh\x12\xdb\xb0\xd6\xc9$\x9e\x11nX.G_<\rqM"c\x96\x94#\xee\xf2\xc4\xae9m\x91*\x97\xe3\x8cz\x94H\xc1\x9e\xb2\x8c\x00\x02"\x01 \x00\xf7\x00`"\x01 \x00a\x00\xfa"\x01 \x00b\x00\xfc"\x01 \x00\xfd\x00c"\x01 \x00d\x01\x00"\x01 \x01\x01\x00e"\x01 \x00f\x01\x04"\x01 \x01\x05\x00g"\x01 \x00h\x01\x08(H\x01\x01\xf0\xb53\x00N\x1a_\x0f6\xeb\x0e\x83\x96q\x07:\x96\xf6\xce.C\xfa#wOg\xbfl\xe8!\x92z\x00\x01#\x13\x01\x04\x1aj\x9b\x9b%\xaei\xf8\x00j\x00k\x00\x87#\x13\x01\x02Q\xf5\xdfU\xcf0\\\xf8\x00l\x00m\x00\x87(H\x01\x01~\x83\x1ea\xdb}h\xa6\x17T\xcf\xea;a\xb4\xbc@g\xf6\xe6\x90\x17\x0b\xbb\x06\xd4\x10\xe06\xfd\x1f\\\x01l3\x13\x0b\x0b\xe2\x199\xdbbQ\x83=\xe1%\x88\xa9\xb1\x00hm\xf1\xb6\xfa\x87\xb2Q\xf1\x90\x0f\r\xde\xa6\xe1\xa2\x03\r\x8e\x86H\xe4\xa7L\\\xcaAz\xa2,\x0f\xa3\x17\x00\x93\xe5\x1a(\x01\x04\x87m\xf0e\xb1\x9b\x18\x0b\x00\'\x00\x10\x01\x01\x9d\xe2\xff\x83\xc6\xf0Q\x18\x00\x85\x00\x86\x00\x87"\x13\x01\x00\xb4\x12\xdf\xd2\x08@\x0b\xe8\x00n\x00o"\x13\x01\x00?\x9c\xbd<\xd0b\xab\x88\x00p\x00q(H\x01\x01/\xbd\x9c\x8c\xfb\xf9\xfd2\x03\xed-rX\x909=\xc9I=D\x9bUp\n>:\xe6m\x94v\x10\x19\x00\'(H\x01\x01\xf4\xbc#\xf2\x94\xf9\x82\xbd?8en\x0b\xddKw\xff@\x9d\xe1}\xb0h\xf5,n\xc4\x04T4Y/\x00\x1a"\x13\x01\x00/\xc60\x1ar\xfe\xd3\xa8\x00r\x00s"\x0f\x00\xda}&\x16\xbe#\xa8\x00t\x00u(H\x01\x01\xe3\x9aQH\xc5u\xd8\x00\xc8\xc2\x81\x04]"\x1b\xf8\xe7:\x96\xd3U\x19\xe1Q\x14 \x8a\x90:\\H\xb5\x00\x1b(H\x01\x01\xa7M\xa0W1\xc1&\xd1\x80N\xf67$\xcf^8\xa8\x8d`\x8a\xa5\xc1wKT\xb4\xeb:`\x0b4s\x00\x19"\x0f\x00\xcb\x81I\xd0\x90tH\x00v\x00w"\x0f\x00\xc3\x0fN\x05\xc0\x83\xe8\x00x\x00y(H\x01\x01X.9FRqFL\xb3\t\xe77U\x86\n>%Z\x8e\xb1]s\xab\xef\x04\xb8\xa3\xb7\xf7Y\xc4\x9e\x00\x17(H\x01\x01\xe2\xcf\xb0S\x05\x89\xbe;>\xc5Dy\xec\xf8\xb2\xc9\xd89\xe8\xf9=a \x12\xe8z?\x91\xc6#\xcd\x98\x00\x15"\x0f\x00\xc2\xb0W\xefc\xbc\xa8\x00z\x00{"\x0f\x00\xc2\xb0O\xc2\xdc\xaf\x08\x00|\x00}(H\x01\x017\xe4\xb1\xa4\x90\xf9\xe7\xee\xef1Z\xf5\n4\xa1\xc5S\xe9\x8b\xe0\xb0\x05C\x1aE\x19\xb1\x89G\x8f{L\x00\x0b(H\x01\x01`~.C\xe8\xe6\x83V\xb4\xb6J\xe7x^\xd1\xac\x8a9\x8fa\xf1\xacB \xbbD\xa2\xff\xbd\x03\xf2u\x00\x11"\x0f@0\x0b\xed\xf1\x12L\xe2\x00~\x00\x7f(H\x01\x01\xa2H\xb8\x1f"3<\xc2\x8fkgD\xe4)\x8a\xef\xcd\x9bo-\xc5\xd7\xc9\x9e\x1d\xa1\xb2\x8c7\xf3\xaa\x0c\x00\x07"\x0f\x00\xc0/\xae\xd8\xd0_\x08\x00\x80\x00\x81!\x9d\xbc\xea\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xa8\x18\x05\xf53\x06\xb4t\xb1\x18<\xe3\xbd|G\xeaR`\xa9\xd3d\x13\xd0\xfe\xd8\x93S\xd8\xf3*\x12\xa7@\x7f\x8cr\x7fUE"\x00\x00FV\xab<}\x87\x00\x82(H\x01\x01\x01C\xb3\xd2\xddg\x1b%YT1U\xe0\x03\xf8G\x02.Q\x0b:W\xaf\xab\xbc\xa0]@i\xc3\'\xef\x00\r"w\xcf\xf5UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUT\x12\xc2\xc2y`\x80\x00\x00\x00\x00\x00\x00\x8c\xadVx\xfb\x11\x80_S0kGU\xd0\x00\x83\x00\x84(H\x01\x01d\xa49p\xf2\x00z\x1d\xa6\xd6\xfc\x81w<\xc0\x95\xd1\xcc\'\x0e\x815\x9eG\x1f;\x03F\x9a\xbe\xb7\xb5\x00\x0c!I\x00\x00\x00(\xcb\xb9\xd1\x06)TC\x9a\x83\xa9\x1f\'\x83_\xb9\xd2\xe3\xe7\x98\x91\x03Ve\x0c\xea\x0e\x80\x86T\x06$\xffk\xbe\xf6\xe3\x89\x88\x7f\x00%"\x13\x01\x015\x8d\xe7<\xeeh\xb0(\x00\x88\x00\x89(H\x01\x01\xa5\xa7\xd2@W\xd8d;%\'p\x9d\x98l\xda8F\xad\xcb>\xdd\xc3-(\xec!\xf6\x9e\x17\xdb\xaa\xef\x00\x01(H\x01\x01(\xcc]P\x16\x9aT\t\x88|\xcf\x8a\xc8\xae\xffj\x91\x9c"\x11\\\xb3\xd4L)b\x143\xa0/U0\x00#"\x13\x01\x01\x1b-r/\x94dS\x88\x00\x8a\x00\x8b"\x13\x01\x00\xe4\xa9\xc7\xd51w\xdd(\x00\x8c\x00\x8d(H\x01\x01\x10\x9f\xcf\x0c\x12\xf7\x9f\x1e\xbc\xe4\xdf:\x8fdS\x9ap\xdd\x98\xc1(\xee\xbaU\xf3k\xde\x99RE\xf8\xda\x00$"\x13\x01\x00\xcd\xbecL\xb282\x88\x00\x8e\x00\x8f(H\x01\x01\x07^\t\xa340\x1a3\xc6\xdd\xdb\xb5\xb3\xf4\xbe\x93\xdd\x1cG\x9a\xec\x84[\xecN\x11\xe9\x1f\x8a\xf7\x19\x93\x00\x17(H\x01\x01\x1f\x15\x02\xef\xe2\xaeR\x95M\xfa\xb3\x7f5\xb1\xe2\x93G\x18\xe72f\xf9?\x0e-[f\x96\xc0\xf3\xa2*\x00\x18"\x13\x01\x00\xcd\xb1\x15l\xb8\xa1XH\x00\x90\x00\x91(H\x01\x017O\xeb\x1f?\xcb\xa4d3\xa8\x91\xb6\xb1\xb9\xd7\x086u\x13o"\x00\xfa\x1cI_\x83Og\x97H4\x00\x14"\x13\x01\x00\xcd\xb1\x11\xd9\x8fM\x86\xc8\x00\x92\x00\x93"\x13\x01\x00\xcd\xb1\x114\xe4\xbb\x7f\x08\x00\x94\x00\x95(H\x01\x01\xc9\xc8\xee\x15M\xf9\xab\x9f\xe0h3\xdd{-L\xf2!\x1d\x85W\xd8R \xaaS\x19l\xc1\xd2\xd1\xd71\x00\x13"\x13\x01\x00\xcd\xb1\x10\xdfv\xa6\xe3\xe8\x00\x96\x00\x97(H\x01\x01\xb2\xf0\x88\x8e8\xf9\xa9)\xb5n\x04\xa3\xb9n\xe6\x85\xffd\xe23\xd5i\xd2\xae\x82\x81?\x993o\x8a\x0f\x00\x11(H\x01\x01\xda\xa7\x17\x18\x08\xbb\x15 \xca\xe9P\xb1tNaU\xaarm\xdf\xab4\x88\x1e\xb9!3\x8d\xeb|\xa0e\x00\x11"\x13\x01\x00\xcd\xb1\x10\x11s\x9c\x00H\x00\x98\x00\x99(H\x01\x01r)\xf0l\xe0}\x83i\tc\x95S\x88\x10\x0c+\x01!\x99H\xb5\xcd{\xd2\x1c:\xb4\xf9\xdf@\xea\xf4\x00\x10"\x13\x01\x00\xcd\xb1\x0fmD\x1aF\xe8\x00\x9a\x00\x9b!\xa1\xbc\xd9\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x98 \x19\xb6!\xedc\xa3\x00\xc4F{n\xc0>6R\x14\xe2$\x9e\xbb\xe6\xc2\r\x8b%e\xac\xb4B\x91\xf7L\x93yx\xb8\xcd\x8f^\xb0\x00\x00FV\xab<}\x85\x00\x9c(H\x01\x01Pr^\xeeR\xe8d2\xf8Fi\x8a\x08\xac\x15:g\xbc\x9a\xd9\xc1`\x13\n\xf9\x07\xc3\xbe\xf0_)H\x00\x07"{\xcf\xf333333333333333333333333333333334\x0b\x18\xc1\xa8@\x80\x00\x00\x00\x00\x00\x00\x8c\xadVx\xfb\x0e\x01\x9bb\x1e\xd6:0\x0cV\xd0\x00\x9d\x00\x9e(H\x01\x01b\x17\xf8r\xc9\x9f\xaf\xcb\x87\x0f,\x11\xa3b\xf5\x939\xbe\x95\t_p\xd0\x0b\x9c\xff/m\xcdi\xd3\xdd\x00\x0e"Qh\x12\xdb\xb0\xd6\xc9$\x9e\x11nX.G_<\rqM"c\x96\x94#\xee\xf2\xc4\xae9O\xc9\xfe\x00\xf1\xe6\xb0\x06\x98\x10\x92\x0f\xcf&\xa8$M\xb2\x84\x9f\xe5U\x06\x0b\x00\x07"\x05\x8fd\x93\x00\xa1\x00\xa2!u\xa0\x9e\x10\xc9\'\x9e\x10\x00\x01\x00\x01nX.G_<\rqM"c\x96\x94#\xee\xf2\xc4\xae9L+E\xd7\\\x1a\xad9=;\x95\x1ci\xea\x1c\xbf[^9\xf0\xfa\xf4\x00\x11"\xbf\x00\x01\xab\xc2qS\x00\x06\xdd\xe4\xe0\x00\x04ej\xb1\xdf\x90\x88\x00\x01\x19W$b\x940\x0e\x8ec:\xa5\xb1\xc0"\x88\x9a`i@\xfe^\xe0\x14\x9d\xe3\x1d\x88`\xeaj\'\xd2g\xec_\xe9\x9c\xe2\x0e5A[\x96\xf0\x87\x9875?\x83[\x01K\n\xb6\xf3B^YQ\x1b\xaeF\xa0\xfaB\xf3\x87\xd9=jk\xb1\xf8\xbe\x00\xa7\x00\xa8(H\x01\x01\xb2\x0e6\xa3\xb3jL\xde\xe6\x01\x10ld.\x90q\x8b\nX\xda\xf2\x00u=\xbb1\x89\xf9V\xb4\x94\xb6\x00\x01"\x13\xc3\xc0\x00\x08\xca\xd5c\xbf! \x00\xa9\x00\xaa"\x01 \x00\xc3\x00\xc4(H\x01\x01%\x8d`.\xaa!\xd6!cM\xcf\x86i*\xea\xe3\x08\xff<\xf8\x88\xf3\xed\xaf\xc6\xa5\xb2\x18H\xd72\xf9\x00\x18"\x11 \x00\x04ej\xb1\xdf\x90\x90\x00\xab\x00\xac(H\x01\x01\xa0|\xb3\xb9\x1b\x82\x01_\xc8b\x90\x1cGF\xa6~)\xa0\x87\'\x00\xc9\x99s$\xb6\xd5\x9b\xcbhw$\x00\x17"\x11 \x00\x04ej\xb1\xdf\x90\x90\x00\xad\x00\xae(H\x01\x01F\xcc\xea(\xf93\x86\xabN\xc0\xbd\x0f\x99)u<\x88\xe9,\xd5\xc3aL\xc0\xd4\x89\xba\xd5\xa7\x85\xc9\xc5\x00\x16"\x11H\x00\x01\x19Z\xacw\xe4$\x00\xaf\x00\xb0(H\x01\x01\x16\x11\x91\x13na\x05\xe3)\\?L\x0f\'@\x1d\xfeW (\xa8\xc5]\xe0\x1f\xa1@\x04\x80\xb6\x15\xd2\x00\x14"\x13p\x80\x00\x11\x95\xaa\xc7~B@\x00\xb1\x00\xb2(H\x01\x01\x12\xb8\xe4\x85\x87Q\x023\xde\x10\xb9?\x9c\xa2\x0fY\x0e\x99:O\x7fI\x95\x16H^\xcf\x14\xfb\xc3\xd0]\x00\x10"\x11 \x00\x04ej\xb1\xdf\x90\x90\x00\xb3\x00\xb4(H\x01\x01\xd2\xc8\x95\x11\xf9\xe9P\x12@9n\xfc\xa7\xb0\x0be\xb3w<\xfc\xb5\x10\xc38\xa4\x18\xcd \\\x18\xe59\x00\x0f"\x11 \x00\x04ej\xb1\xdf\x90\x90\x00\xb5\x00\xb6(H\x01\x01\xbb\x87D\x87\xb0\x18\xb9\x949\xb4\x8c\xc3\xf9\xed\x88y8\xa5n\x96\xbd\x18WT[\xd9^A\x1ev\xacI\x00\x0e"\x11H\x00\x01\x19Z\xacw\xe4$\x00\xb7\x00\xb8(H\x01\x01_\xdd\xe4\xdb\xfc\xb4\xa6\xd2\\\xcb\xd9H9\xd5\x17\x94\x9e\xc24[\x03\x10\xd6-\xf0\xfc\xe2v\xb7\xb6\xb0l\x00\x0c"\x11`\x00\x00FV\xab\x1d\xf9\t\x00\xb9\x00\xba(H\x01\x01\xc2\x85\xa3\x12\xc4u\x9f\x8e;\xc9x|\xe3[\xbaKz\x86X\xeb\x8a7\x9f\xa7\xd5\x06v\xe2\xfaE\x84J\x00\t"\x11\x00\x00\x04ej\xb1\xdf\x90\x90\x00\xbb\x00\xbc(H\x01\x01Z\xe1\xcd\xbf^\x10l\xf24|\x0fQ\x1a]\xba,\xc2\xd3q\x01Z\\bF\xf9\x1f\xe6\x9e\t\xd9\x90\x92\x00\x08"\x11\x00\x00\x04ej\xb1\xdf\x90\x90\x00\xbd\x00\xbe(H\x01\x01B\xa4J\xd5e%\xcd\x0er\xbc\x80\xfaHZ\xd5\xa8ai\xee\x83\x08m\x99\x9fA\x7f/\x05$\xdc\xa4\x81\x00\x07"\x11`\x00\x00FV\xab\x1d\xf9\t\x00\xbf\x00\xc0"\x11\x00\x00\x04ej\xaf\xf7H\x90\x00\xc1\x00\xc2\x00\xaa\xd0\x00\x00FV\xab\x1d\xf9\x08\x00\x00#+U\x8e\xfc\x84\x01\xd1\xd3\x90\x0f\x1e\xbe\xd3\xfe\x98\xc4\xfc.7\x9d\x1e\xb6\x98*;Rv!\xbf\n\xc3\xe2\x1eMbD\x18c7\xaa\xbc\xbeI\xd6\xd7\xbdL.\xf4\xf1\xf9\x08\x83z\x957\xbc\x1a\xff\xe7\xa5\xdc\x86\x19\x88`\xcd\xb6\xa3yY\x90\xab(H\x01\x01\x9dU\x97\x0c\xb7\xff\xf3\x9c\xba\xc3\xfa\xdb\xea\x8c=\xf2/\xe6\x89\xf49\x12@CZ\xa8(k\xe4\x8a\\I\x00\x03(H\x01\x017zLhU \xeb\x9c\xbb@)\xb3zn\xfcG\xcbA\xff\xca\xdf\xbb\xaaHg\xbaT\xab2\xe5\x82\xbe\x00\x032\x01cq\xb3\xefb6.\x8b\x02\x8e\x05%\x9dD\xe7~\xce6<\xe8\xe0\x1d\x9f\xfe/+Cz\xc2\xf4xj\xd5-V\x9b\x00\xc0\xae\x9e\xe0\x10\x83\xc38\xfe\x97\xdfDw\x9d\xb9\xa1\xfc\xaa\x11Tf\xaeP;\xe6G\xf3\x00\x10\x00\r \x00\xdb\x00\xdc"\x01 \x00\xc5\x00\xc6(H\x01\x01(\x85\xf4%X\x91\x83Q\xbc\xb6\xe7\x99e\xb8\xf9\xbb\x8ar\xb3\x06\x02L\x9b\x00N\x8f\x06S\xad\xe0\x8a\xb2\x00\x0f"\x01 \x00\xc7\x00\xc8(H\x01\x01\xd8\xbfr\xec\xcb\xbf\xe2\xa0\xd4;\xad\xe0\xec\x9e\x16>p\x91\xee\x1e\xc1\xe9*\x7f\x05*\xea\xd9\xe5\xf8\xe6F\x00\r"\x01 \x00\xc9\x00\xca(H\x01\x01"_\xd8O\xad\xf1\xc2\xda\xaf\x98\xe7\xe5W\x94\x12\x0c\x14pj\x89\xdb\xf1\x87LZ\x92~#M\xb7\xe5\x94\x00\x0c"\x01 \x00\xcb\x00\xcc"\x01 \x00\xcd\x00\xce(H\x01\x01\xd4\xd2\xcbql\x17\x8f`\x00\x02\x0c\xdb}zICt\xd0\xd3\x96\x9f\n\x10\xcfb\xae;\x81\xe1\xeeX\xb8\x00\x0b"\x01 \x00\xcf\x00\xd0(H\x01\x01\x1dd{\xdc\xa0e\xe3\xc9\xa3\xa5\x95V\xe8\x8a\x87\xaa\xb3\x9e\x84\xc5^x\x07\xbbZ" \xda\x99yP*\x00\n(H\x01\x01c\'\xf1!c\xc6\x99e\x972PY\'>m\xb1n*\xa8\xe9\xca\x1c\xe3\xd3TP\x87\xfd\x9b9O\xee\x00\t"\x01 \x00\xd1\x00\xd2(H\x01\x01$\xc2~\xcc\x91\xee6\x17\x8e\x8d\xfbZ`b\xa6\xbd\x8a\xa0\x9a\xa3\xab\xe9[\x8b\xfe\xb5\r\xe7\xfe};\xea\x00\x08"\x01 \x00\xd3\x00\xd4"\x01 \x00\xd5\x00\xd6(H\x01\x01\x07\x1fQmA\xf6\xd9\\\x1f|6\xb6\xdf\xf8}\xebZ\x82\xe2\x8d\x94\x0f\x06\xa3d\xa1\x87c=\x06\x0c\x01\x00\x05(H\x01\x01\xd9|\x9c\xaeFF\x9c^\xbc\x1f\xa7\xe9CJ\x93d\xd5L\x12\x14\xb3\xb5>\xf0\x0f\xee \x8a"8\xf6\xe8\x00\x05"\x01 \x00\xd7\x00\xd8(H\x01\x01\xd7P\xe7\xc2\xf2\xb58C\xd3\xff\x91\xa1t\x1a\xeb\xdf\x8a\xa5x\xfdi\x15]\xb1m\xbf\xd2U\\1R\xa5\x00\x03\x02\x01 \x00\xd9\x00\xda\x00\xb1\xbd\x14O\xc4e$]\xd8\x024\x15X\x95\xb3?kS\xd9\x08^H\xb46\x98\xd2\xa4\x80\xe2{o\xdd\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x1eP\xdf\x00\x00\x00\x00\x00\x00\x00\n@\x00\x00\x01[Y\x9b\xf2@\x00\x00\x076\xcf\x15\x12`\x00\xb1\xbd\n\xbav\xcc\xa3\xd5\xc3\xbfb\x99\x0f\x92\xe2pP.*\xc00U>\xcc\xb7\x86%U\x12\x11\xeejQ\x19$\xd1\xaf@\x00\x00\x00\x00\x00\x000\x00\x00\x00\x01\xbf7S\xa1\x00\x00\x00\x1e\x94\x0f(a\xd9$\xcd\xb8\x80\x00\x00\x00\x00\x00\x00\x16\x80\x00\x00\x01\x964zb@\x00\x00\x0e\xc2\x93\xccQ\xe0"\x01 \x00\xdd\x00\xde"\x01 \x00\xf5\x00\xf6"\x01 \x00\xdf\x00\xe0(H\x01\x01\xfa\xff^\xd8efJ\xf2z\x9a!\xe264\xfc\xddtQ\x9b\xdc\xb1\'\xf5\x8e\x8f8_\xdd\x1f\xff\xf2\xb9\x00\x0e"\x01 \x00\xe1\x00\xe2(H\x01\x01\xb8\xd1:\xb8\x13}.\xb6\xf6\xbf\xaa\x15\xec\x86X3\xd2\xedD\x13b\xfe\xf5L\xa5\xe3\xf4\x081\xff\x9a9\x00\x0c"\x01 \x00\xe3\x00\xe4(H\x01\x01*\xf2\x19\x9d\xe4K&>\x8c_\\\xc7\xab\x91}A1J\xa1bJ\xc0PUA\xdc\xeb,ZH\xafz\x00\x0b"\x01 \x00\xe5\x00\xe6(H\x01\x01\x99h\xb5\x9fV5\xb0\x81W\x96\xf5\x80P\xf3\xcc\x97\xec\x85\x0fm\xcd[\xc4D\x17\xda\x94\xf6\x81\xc2t\x88\x00\n"\x01 \x00\xe7\x00\xe8(H\x01\x01\xd6y-\xeb\x1f\xb8\xa3\xee\xfb\xf3/\xee%?\x0b\xfa\x90\xd7\x9c\xf7\xf7\xe4\xa4Z\xf9\x86,\xd3\xbb\x10\x03,\x00\x08"\x01 \x00\xe9\x00\xea(H\x01\x01\xebS\xb7\x1f\x8c\xbcyp\x18;\xd8\xdb\xb7\xca\xe1\xb0\xdf\x16\xe1XF\xd5\xa1\xf6`\x1a\x0eQ\x976\xd6\xc3\x00\x07"\x01 \x00\xeb\x00\xec(H\x01\x01\x0b\xb3\xfeB\xdf\x8em\x92\xbdPr\x85\xa3PT\x8e\\\x92\xff\x1f\x8b\xa2<\x9a\xf5"\xb1\xde\xca\x82?6\x00\x05"\x01 \x00\xed\x00\xee(H\x01\x01\xd6\x08\xab\xfb\x9f\xf0\xc3\xc1,%jO\x81j\xdc\x1b\x18\x9at\x9a\n\xd0F\xf5qy\x05\xf5\xb4\x01\xe85\x00\x05"\x01 \x00\xef\x00\xf0(H\x01\x01\xdb\x80h\xfc\xdfyi%\xfe\x93\'K\x9f/%\x037\xaf\xb0l\xd7Q\xb7me\x9cJ\xed\xb2\xe8\xedd\x00\x03\x02\x01H\x00\xf1\x00\xf2(H\x01\x01\xa61\x08\x1ft\x9cv\xd1VU\x08\xa8#Z\x071G7\xcd\xf9\x07\x19\x978\x9e\xefw>.\xcfV0\x00\x01\x02\x01 \x00\xf3\x00\xf4\x00\xb0\xbc\xad4j:tk\xf6\xf2\x13/dBJ\x0b\x03DpJD\x0f\xa5\xd0W\xb0\xd6\x13\xda\xd6\xa0\xc1D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x7f6\xf4\x00\x00\x00\x00\x00\x00\x00F\x00\x00\x00\x06\xb0\xd0\xbeq\x00\x00\x00.\xe6mS\x8d\x00s\xde(\xc9&\x8dz\x00\x00\x00\x00\x03\xa3\xa7 \x00\x00\x04\xd7K{j\x8e\x00\x00\x9c\x89\xc8\xe0u\xc6\xc9&\x8dz\x00\x00\x00\x00\x16[\rz\x00\x00\x04\xd5\xed\xc04\xa8\x00\x00\x9c\x08\x17/%i\x00\xaf\xbcN\x8b$\xb4Z\t\xf0\x86\xe1\xdb\x8d\xd3MS-\xa7U{cJ\xb2\xcf\x8f\x9aQ(\xa7K\xde\x1c\x08\xc9\x06\x99\xda\x00\x00\x00\x00\x00\x00\x01\x82\x00\x00\x00\x0eK\xa2\x97\xd4\x00\x00\x00\xfa\xc3!\xd7`\xc9\x06\x9b`\x00\x00\x00\x00\x00\x00\x00\x86\x00\x00\x00\t\xf8\xea\x91\xd4\x00\x00\x00L\xf8\x13M\x83(H\x01\x01N~T\xad\xe9\x02g\x89\xae\x17\xd8\x97\xc6\x7f\x07\xd8\xb8\xf4\x97%\xb2\x1d9R\x8c.\x80\xf8\x8a1\xfeF\x00\x0e"\x01 \x00\xf7\x00\xf8(H\x01\x01}:\xedR\xba\xdd>\x9b\xc2Y\xcf\x9cn\xaa\x89\x9aV\x07\x02\x9b(Ja\x17]\xc5\xff\xba\xf4\tXM\x00\x0c"\x01 \x00\xf9\x00\xfa"\x01 \x00\xfb\x00\xfc(H\x01\x01\x8d\x91\xe1\xad|\xd62\xe6\xe8\xc0\x04\xdcoN\xc9\xf6\x1b\x8f_w=$\xe1~\x8f\xae6\xbci\xdaP\xf2\x00\x0b"\x01 \x00\xfd\x00\xfe(H\x01\x01\xa6\xe4YfR\x0f,@\xe5\x02\xcde\xef_<\x14\xa0\xd6\xcf\xe4R\x07\n0-eh\xe6_=\x842\x00\t(H\x01\x01\xab\x8cl[1\xb0\xe7n2\xa8\xf5`\x1b\xfd\x86\xd2T\xfbZ5\t(\x85\xe6(\xa3[\xaet@\x1b\xac\x00\x08"\x01 \x00\xff\x01\x00"\x01 \x01\x01\x01\x02(H\x01\x011\xdb\xb6\xc0\xcae\x0c\xdcc"3\',a|\xdb\xb0\xf0X\x82\x85-\xde\xb3\xb5\xa24\x88\xb2\\C\x83\x00\x06(H\x01\x01ew\xe0\xcc\xee\xbf\xd7\xc3Q7]\x01(\x12zU\xa3\x93\xb1c!~4\x85\x04\xf5|\xdc\xe1\\S\xf9\x00\x06"\x01 \x01\x03\x01\x04"\x01 \x01\x05\x01\x06(H\x01\x01\x9c\xf4\xdeC(\xa0\x89Q\x8a\x00\x0c\x0c\xfc5 z\n\xff\x17\x99d/\x17Y*\xd0\x1f\xbcEV\xea:\x00\x03(H\x01\x01\xff\xa5j\xb5c\x00\x82{dR\'\xc6\x85\x10\xd1\xa5M05\x9a\xea\xd9:.\xfd\xa2\x08\t\xf9\xcd\x84!\x00\x04"\x01 \x01\x07\x01\x08\x02\x01X\x01\t\x01\n(H\x01\x01&\x99\xfa\xfe}\x0c\xfd_"\xb3\x8f\x96\xda*\xd7\n]gA"\xeb\xd1\x00<\xf1\xceG7R\r\x08\x19\x00\x02\x00\xb0\xbc\x99\x86\x9c\xc5\x92\xecu\'4ezV\x93\xaa\nL1\xd8$\xe3\x9a\xbd\x9a\x99sy\x1b @\x90\xc4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x8eIN\x00\x00\x00\x00\x00\x00\x00-\x00\x00\x00\x03d\xf8Jm\x00\x00\x00\x1f\xb7\xec\x7f\t\x00\xb0\xbc\xb47rg\xd1A\xe2O\x8cs\x16\xc3\x9f\xdfL\xf7\xbe\xc1T\xbd\xdfv1IW\xfe\xcc\xbe#Rd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x93F\xbd\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\x07\xdb\xce\xc6\xb4\x00\x00\x00+\xe67\x18\xb8\x01\x03\x80 \x01\x0f\x00\x01\x02\x01\x01\x82\x01\x10\x03\x17\xcc\xa5hx6\xa8\x82C\xb9\xac\xa0\x04\x01\x1f\x01 \x01!\x02G\xa0\x0c4\xbbC\xcc\x1eT&\x84\xee\xfc\xa9\xe3E\xbfS\xbe\xdcj\xfb\x1a@3\x1c[y\r\x82\xe6J\x9f_`\x06\x10\x01%\x01&\x02\x03@@\x01\x11\x01\x12\x03\x97\xbf\xb33333333333333333333333333333333\x02\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\xcf\x80\x00\x08\xca\xd5g\x8f\xb0\x04\x01\x13\x01\x14\x01\x15\x02\x97\xbf\x95UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU\x02\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xd0\x00\x00\x08\xca\xd5g\x8f\xb0\xc1\x01\x1a\x01\x1c\x01\x03P@\x01\x16\x01\x03@@\x01&\x00\x82r?w\x9f\xa8\\\xa3yL\x03\xfe\xd9\xd3\xbb\xbe\x9f\x85\x13\xd4\x82\x9d\x8c\x84*^\x1e\xf2\xbeY\xd379\x03Y\x7f\x0e\xe5I}r\x7f\xccy\x7f\xdf\x01\x84G\xce\xc6}j\'\x17\xc0\xd2T)\x99\xb1\xed4J\xfb\xff\x03\xafs33333333333333333333333333333330\x00\x022\xb5Y\xe3\xec\x1d\xd2\xc3\xd4\x90;\xf8\x80>\x8f\x9d\x8e\x8a\x94\xd1\xc4l@\xed\xb1\xf1\xb7\xf0\xb4Z\xcc8\xf0\x0e\xe3\x1d\xd6\xa0\x00\x022\xb5X\xef\xc8&I4k\xd0\x00\x14\x08\x01\x1b\x01\x17\x01\x18\x00\x82r?w\x9f\xa8\\\xa3yL\x03\xfe\xd9\xd3\xbb\xbe\x9f\x85\x13\xd4\x82\x9d\x8c\x84*^\x1e\xf2\xbeY\xd379\x03\xa0\x8fd\xd0\xedEi\x101\x1f\x03\xc3\x17D\xfb\x9e\xe1`\xf1D\xedT\x83\xb0d\xec\x12\x9f8\xe4\xff\xaa\x02\x05 0$\x01\x19\x01,\x00\xa0C\x01\x90\x08X;\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xafuUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUP\x00\x022\xb5Y\xe3\xec5\xda\xfa\xaa\xf6\xfe\xea\xad\xc0/\xa6s\rP\x18\x1c\xbc2\x00\xbd\x16\'\x8f\xd6{\x07\xc8_\x94\xdd\xaf\x85\xe0\x00\x022\xb5X\xef\xc86I4k\xd0\x00\x14\x08\x01\x1b\x01\x1c\x01\x1d\x00\x01 \x00\x82r\x93\xa0W#\xab\xf8\x8fA\xa8\x9c\xa2k]\x10\xe1\x11\xf1I\xa4]\\\x803\xac\x01C|B\x02\xabF\xbe\x81&\xfb@c{T^\\\xe1\x82Q\x91]y\xb0\x886R\x97F~\xc7\x8db\xb8\xe3V\x8c\xa0\x87C\x02\x0500$\x01\x1e\x01,\x00\xa0A\x81\xb0\x08X;\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x03\xd0@\x01"\x00?\xb0\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00!\xe0\xda\xa2\t\x0e\xe6\xb2\x80\x08x6\xa8\x82C\xb9\xac\xa0\x04\x01\x01P\x01$\x01\xdbP\x11C\xbe8\x0e\x8e\x9c\x88\x00\x01\x19Z\xacw\xe4\x00\x00\x01\x19Z\xacw\xe4$\xc3\xe1\xa4&T\x96\xcf\x86\xa9\x87\xd4:j\xb0\xd2h\x1f\xca\x0e>!&\xb8\x87d\n\xce\xc8LWJ\x1f\x929\x92\x86\x92\xfc\xc7R\xc4\xd1%\x90;\xee\x15\xda\x97\xae\xa7\xb7\x0b\x80\xe2Q8\xcd\xdb\xe9J\xd9\xe2h\x80\x006\xf5\xd4\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x8e\x9cs$\x9a5\xd2\x01#\x00\x13C\xc1\xb5D\x12\x1d\xcde\x00 \x02\x01a\x01%\x01&\x01\x06F\x06\x00\x01*\x03\xafs33333333333333333333333333333330\x00\x022\xb5Y\xe3\xec&\x7f\xad\x8b\x8a\x8f\xeb\xf0\xe43\xf3\xec\x12D=\x03\x91|%\xcbXA\\\x8a\x8e\xed[\xcd\x97\xa65\xc9\xb0\x00\x022\xb5Y\xe3\xec\x16I4k\xd0\x00\x14\x08\x01\'\x01(\x01)\x01\x01\xa0\x01*\x00\x82r\xa0\x8fd\xd0\xedEi\x101\x1f\x03\xc3\x17D\xfb\x9e\xe1`\xf1D\xedT\x83\xb0d\xec\x12\x9f8\xe4\xff\xaaY\x7f\x0e\xe5I}r\x7f\xccy\x7f\xdf\x01\x84G\xce\xc6}j\'\x17\xc0\xd2T)\x99\xb1\xed4J\xfb\xff\x02\x0f\x04\t(K\xc0\x08X\x11\x01+\x01,\x00\xabi\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01?\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xd2\x84\xbc\x00\x84\x00\x00\x00FV\xab<}\x80\xc9&\x8dz@\x00\x9eB\xafl\x10\x81T\x00\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01-E-\xa4I\xe5\x0b\x8c\xf7\xdd\'\x86\x1f\x14a"\xaf\xe1\xb5F\xbb\x8bp\xfc\x82\x16\xf0\xc6\x14\x13\x9f\x8e\x04\xc1\x0e\xfc\xf5' - -cs = Cell.one_from_boc(boc).begin_parse() -# print(cs) - - -print(Block.deserialize(cs)) - -# {'global_id': -239, 'info': {'version': 0, 'not_master': 0, 'after_merge': 0, 'before_split': 0, 'after_split': 0, 'want_split': False, 'want_merge': True, 'key_block': False, 'vert_seqno_incr': 0, 'flags': 1, 'seqno': 30528401, 'vert_seqno': 1, 'shard': {'shard_pfx_bits': 0, 'workchain_id': -1, 'shard_prefix': 0}, 'gen_utime': 1687373501, 'start_lt': 38669027000000, 'end_lt': 38669027000004, 'gen_validator_list_hash_short': 1711945649, 'gen_catchain_seqno': 450019, 'min_ref_mc_seqno': 30528398, 'prev_key_block_seqno': 30526567, 'gen_software': {'version': 3, 'capabilities': 46}, 'master_ref': None, 'prev_ref': {'type_': 'prev_blk_info', 'prev': {'end_lt': 38669026000004, 'seqno': 30528400, 'root_hash': '0f1ebed3fe98c4fc2e379d1eb6982a3b527621bf0ac3e21e4d6244186337aabc', 'file_hash': 'be49d6d7bd4c2ef4f1f908837a9537bc1affe7a5dc86198860cdb6a3795990ab'}}, 'prev_vert_ref': None}, 'value_flow': {'type_': 'value_flow_v2', 'from_prev_blk': {'grams': 2365327534108603182, 'other': {'dict': {239: None, 4294967279: None}}}, 'to_next_blk': {'grams': 2365327536812815183, 'other': {'dict': {239: None, 4294967279: None}}}, 'imported': {'grams': None, 'other': {'dict': None}}, 'exported': {'grams': None, 'other': {'dict': None}}, 'fees_collected': {'grams': 2704212001, 'other': {'dict': None}}, 'burned': {'grams': 4212000, 'other': {'dict': None}}, 'fees_imported': {'grams': 1008424001, 'other': {'dict': None}}, 'recovered': {'grams': 2704212001, 'other': {'dict': None}}, 'created': {'grams': 1700000000, 'other': {'dict': None}}, 'minted': {'grams': None, 'other': {'dict': None}}}, 'state_update': {'cell': 2 refs>, 'old_hash': b"\x04w'-\xb5\xa4k\x8a\xb8%\x7f\x0c\x86\xc1S#\xfd\x02\xc0\xd2\xde\xdf\xff\xa4~\xf0\xaf\x19d\x80\xb2h", 'new_hash': b'\x84\xa0\xae\x80\x11\x90\x02y4=\xad\xcf\xa7)\x19\x07D,,$\xdb\xaa\xd0\x94\xce;\xc1\x9a\x02\xff\xc5\x10', 'old': {'type_': '_', 'shard_state_unsplit': {'global_id': -239, 'shard_id': {'shard_pfx_bits': 0, 'workchain_id': -1, 'shard_prefix': 0}, 'seq_no': 30528400, 'vert_seq_no': 1, 'gen_utime': 1687373498, 'gen_lt': 38669026000004, 'min_ref_mc_seqno': 30528397, 'out_msg_queue_info': 0 refs>, 'before_split': 0, 'accounts': ({'0011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011': {'account': {'addr': Address, 'storage_stat': {'used': {'cells': 1420, 'bits': 434434, 'public_cells': None}, 'last_paid': 0, 'due_payment': None}, 'storage': {'last_trans_lt': 38669026000003, 'balance': {'grams': 463176397338820624, 'other': {'dict': None}}, 'state': {'type_': 'account_active', 'state_init': {'split_depth': None, 'special': {'tick': True, 'tock': False}, 'code': 0 refs>, 'data': 2 refs>, 'library': None}}}}, 'last_trans_hash': b'\xdd,=I\x03\xbf\x88\x03\xe8\xf9\xd8\xe8\xa9M\x1cF\xc4\x0e\xdb\x1f\x1b\x7f\x0bE\xac\xc3\x8f\x00\xee1\xddj', 'last_trans_lt': 38669026000002}, '0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101': {'account': {'addr': Address, 'storage_stat': {'used': {'cells': 2401, 'bits': 648578, 'public_cells': None}, 'last_paid': 0, 'due_payment': None}, 'storage': {'last_trans_lt': 38669026000004, 'balance': {'grams': 1637670300957, 'other': {'dict': None}}, 'state': {'type_': 'account_active', 'state_init': {'split_depth': None, 'special': {'tick': False, 'tock': True}, 'code': 0 refs>, 'data': 1 refs>, 'library': None}}}}, 'last_trans_hash': b']\xaf\xaa\xafo\xee\xaa\xdc\x02\xfag0\xd5\x01\x81\xcb\xc3 \x0b\xd1bx\xfdg\xb0|\x85\xf9M\xda\xf8^', 'last_trans_lt': 38669026000003}}, [{'split_depth': 0, 'balance': {'grams': 234935682672639239, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 463176397338820624, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 463176397627707926, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 463176419664322529, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 463176447314769662, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 463176458780990423, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 463176480882125845, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 463176603713014433, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 463293628683567475, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 514903760739024584, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 637659092150919803, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 697054334118282592, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 931990016790921831, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 1637670300957, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 1638375260920, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 1639572457884, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 23650205361528, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 23651302448613, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 26914147140639, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 101199336735650, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 232998498070813, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 107577870478997149, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 143242080926504284, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 405489986549448799, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 1337480003340370630, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 2365327534108603182, 'other': {'dict': None}}}]), 'overload_history': 0, 'underload_history': 18446744073709551615, 'total_balance': {'grams': 2365327534108603182, 'other': {'dict': None}}, 'total_validator_fees': {'grams': None, 'other': {'dict': None}}, 'libraries': None, 'master_ref': None, 'custom': {'shard_hashes': None, 'config': {'config_addr': '5555555555555555555555555555555555555555555555555555555555555555', 'config': None}, 'flags': 1, 'validator_info': {'validator_list_hash_short': 907348710, 'catchain_seqno': 450019, 'nx_cc_updated': False}, 'prev_blocks': ({}, [{'key': False, 'max_end_lt': 38669025000004}, {'key': False, 'max_end_lt': 38669025000004}, {'key': False, 'max_end_lt': 38669025000004}, {'key': False, 'max_end_lt': 38669025000004}, {'key': True, 'max_end_lt': 38669025000004}, {'key': True, 'max_end_lt': 38669025000004}, {'key': True, 'max_end_lt': 38669025000004}, {'key': True, 'max_end_lt': 38669025000004}, {'key': True, 'max_end_lt': 38669025000004}, {'key': True, 'max_end_lt': 38669025000004}, {'key': True, 'max_end_lt': 38669025000004}, {'key': True, 'max_end_lt': 38669025000004}]), 'after_key_block': True, 'last_key_block': {'end_lt': 38667130000006, 'seqno': 30526567, 'root_hash': '54b6380451134c0d281fcbdc0293bc63b10c1d4d44fa4cfd8bfd339c41c6a82b', 'file_hash': '72de10f306e6a7f06b60296156de684bcb2a2375c8d41f485e70fb27ad4d763f'}, 'block_create_stats': {'counters': {}}, 'global_balance': {'grams': 5088092522396870767, 'other': {'dict': None}}}}}, 'new': {'type_': '_', 'shard_state_unsplit': {'global_id': -239, 'shard_id': {'shard_pfx_bits': 0, 'workchain_id': -1, 'shard_prefix': 0}, 'seq_no': 30528401, 'vert_seq_no': 1, 'gen_utime': 1687373501, 'gen_lt': 38669027000004, 'min_ref_mc_seqno': 30528398, 'out_msg_queue_info': 1 refs>, 'before_split': 0, 'accounts': ({'0011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011': {'account': {'addr': Address, 'storage_stat': {'used': {'cells': 1420, 'bits': 434434, 'public_cells': None}, 'last_paid': 0, 'due_payment': None}, 'storage': {'last_trans_lt': 38669027000003, 'balance': {'grams': 463176400043032625, 'other': {'dict': None}}, 'state': {'type_': 'account_active', 'state_init': {'split_depth': None, 'special': {'tick': True, 'tock': False}, 'code': 0 refs>, 'data': 2 refs>, 'library': None}}}}, 'last_trans_hash': b'#=\xb7`\x1f\x1b)\nq\x12O]\xf3a\x06\xc5\x92\xb2\xd6Z!H\xfb\xa6I\xbc\xbc\\f\xc7\xafX', 'last_trans_lt': 38669027000002}, '0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101': {'account': {'addr': Address, 'storage_stat': {'used': {'cells': 2401, 'bits': 648578, 'public_cells': None}, 'last_paid': 0, 'due_payment': None}, 'storage': {'last_trans_lt': 38669027000004, 'balance': {'grams': 1637670300957, 'other': {'dict': None}}, 'state': {'type_': 'account_active', 'state_init': {'split_depth': None, 'special': {'tick': False, 'tock': True}, 'code': 0 refs>, 'data': 1 refs>, 'library': None}}}}, 'last_trans_hash': b'X\x8c\x1eq\xde\xbe#\xf5)0T\xe9\xb2\t\xe8\x7flI\xa9\xecy\x95\tS\xa0?\xc69?\xaa\xa2\x91', 'last_trans_lt': 38669027000003}}, [{'split_depth': 0, 'balance': {'grams': 463176400043032625, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 463176400331919927, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 463176422368534530, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 463176450018981663, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 463176461485202424, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 463176483586337846, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 463176606417226434, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 463293631387779476, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 514903763443236585, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 637659094855131804, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 697054336822494593, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 931990019495133832, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 1637670300957, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 1638375260920, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 1639572457884, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 23650205361528, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 23651302448613, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 26914147140639, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 101199336735650, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 232998498070813, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 107577870478997149, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 143242080926504284, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 405489986549448799, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 1337480006044582631, 'other': {'dict': None}}}, {'split_depth': 0, 'balance': {'grams': 2365327536812815183, 'other': {'dict': None}}}]), 'overload_history': 0, 'underload_history': 18446744073709551615, 'total_balance': {'grams': 2365327536812815183, 'other': {'dict': None}}, 'total_validator_fees': {'grams': None, 'other': {'dict': None}}, 'libraries': None, 'master_ref': None, 'custom': {'shard_hashes': {}, 'config': {'config_addr': '5555555555555555555555555555555555555555555555555555555555555555', 'config': None}, 'flags': 1, 'validator_info': {'validator_list_hash_short': 2881646931, 'catchain_seqno': 450020, 'nx_cc_updated': True}, 'prev_blocks': ({'111010001110100111001': {'key': False, 'blk_ref': {'end_lt': 38669026000004, 'seqno': 30528400, 'root_hash': '0f1ebed3fe98c4fc2e379d1eb6982a3b527621bf0ac3e21e4d6244186337aabc', 'file_hash': 'be49d6d7bd4c2ef4f1f908837a9537bc1affe7a5dc86198860cdb6a3795990ab'}}}, [{'key': False, 'max_end_lt': 38669025000004}, {'key': False, 'max_end_lt': 38669026000004}, {'key': False, 'max_end_lt': 38669026000004}, {'key': False, 'max_end_lt': 38669026000004}, {'key': False, 'max_end_lt': 38669026000004}, {'key': False, 'max_end_lt': 38669026000004}, {'key': True, 'max_end_lt': 38669026000004}, {'key': True, 'max_end_lt': 38669026000004}, {'key': True, 'max_end_lt': 38669026000004}, {'key': True, 'max_end_lt': 38669026000004}, {'key': True, 'max_end_lt': 38669026000004}, {'key': True, 'max_end_lt': 38669026000004}, {'key': True, 'max_end_lt': 38669026000004}, {'key': True, 'max_end_lt': 38669026000004}]), 'after_key_block': True, 'last_key_block': {'end_lt': 38667130000006, 'seqno': 30526567, 'root_hash': '54b6380451134c0d281fcbdc0293bc63b10c1d4d44fa4cfd8bfd339c41c6a82b', 'file_hash': '72de10f306e6a7f06b60296156de684bcb2a2375c8d41f485e70fb27ad4d763f'}, 'block_create_stats': {'counters': {0: {'mc_blocks': {'last_updated': 1687373501, 'total': 30528400, 'cnt2048': 2661365429575, 'cnt65536': 86057797303011}, 'shard_blocks': {'last_updated': 1687373501, 'total': 187532989, 'cnt2048': 2658431670868, 'cnt65536': 85779281318580}}, 4336700104570319019722566015333818283253382211335791928245523545617002720: {'mc_blocks': {'last_updated': 1686326509, 'total': 193, 'cnt2048': 30699244522, 'cnt65536': 538507799472}, 'shard_blocks': {'last_updated': 1686326704, 'total': 67, 'cnt2048': 21415413994, 'cnt65536': 165289764545}}, 12059255298826860038837437148619684974234556625177760406712394609930669076: {'mc_blocks': {'last_updated': 0, 'total': 0, 'cnt2048': 0, 'cnt65536': 0}, 'shard_blocks': {'last_updated': 1686058740, 'total': 70, 'cnt2048': 28736274033, 'cnt65536': 201434420109}}, 51863313810199422589872419518070243423886138765764086248917808182268300364044: {'mc_blocks': {'last_updated': 0, 'total': 0, 'cnt2048': 0, 'cnt65536': 0}, 'shard_blocks': {'last_updated': 1687046478, 'total': 45, 'cnt2048': 14578895469, 'cnt65536': 136229715721}}, 51873328604120795319737868682466104158360180307598117037734355238902888019238: {'mc_blocks': {'last_updated': 0, 'total': 0, 'cnt2048': 0, 'cnt65536': 0}, 'shard_blocks': {'last_updated': 1687373501, 'total': 68, 'cnt2048': 33752532660, 'cnt65536': 188545964216}}, 110090611392466960446193407272603252000621402700859945402911165406782221449030: {'mc_blocks': {'last_updated': 0, 'total': 0, 'cnt2048': 0, 'cnt65536': 0}, 'shard_blocks': {'last_updated': 1685668732, 'total': 41, 'cnt2048': 23310266313, 'cnt65536': 123937248329}}, 110114647926562186152021928392089007623807837124212290197099930255887114672788: {'mc_blocks': {'last_updated': 1687373501, 'total': 192, 'cnt2048': 30012165764, 'cnt65536': 525332160903}, 'shard_blocks': {'last_updated': 1687369442, 'total': 90, 'cnt2048': 27259955593, 'cnt65536': 253576032583}}}}, 'global_balance': {'grams': 5088092525096870767, 'other': {'dict': None}}}}}}, 'extra': {'in_msg_descr': 1 refs>, 'out_msg_descr': 0 refs>, 'account_blocks': 1 refs>, 'rand_seed': b'{h\x92\x0c:\xec\x8a!\x11o\x06\xac\x1a\xe3\xeb\xcd\x12\x02\xb4\xb5\xda\x811>\xa5\xe0\xb1\xbbsr\nr', 'created_by': b'\xf3r\xae\x9d\xb3(\xf5p\xef\xd8\xa6C\xe4\xb8\x9c\x14\x0b\x8a\xb0\x0c\x15O\xb3-\xe1\x89UD\x84{\x9a\x94', 'custom': {'key_block': 0, 'shard_hashes': {}, 'shard_fees': 0 refs>, 'prev_blk_signatures': None, 'recover_create_msg': 2 refs>, 'mint_msg': None, 'config': None}}} - - -import asyncio -import time - -from tonpylib.liteclient.client_tcp import AdnlClientTcp - - -host = '65.21.141.231' -port = 17728 - -pub_key_b64 = 'BYSVpL7aPk0kU5CtlsIae/8mf2B/NrBi7DKmepcjX6Q=' - - -async def main(): - client = AdnlClientTcp( - host, - port, - pub_key_b64 - ) - await client.connect() - block_id, block = await client.lookup_block(-1, -9223372036854775808, 30293401) - full_block = await client.get_block(block_id['workchain'], block_id['shard'], block_id['seqno'], block_id['root_hash'], block_id['file_hash']) - print(full_block) - await client.close() - - -if __name__ == '__main__': - asyncio.run(main(), debug=True) - # asyncio.get_event_loop().run_until_complete(main()) - - # client.connect() - diff --git a/tests/compare_to_pytonlib.py b/tests/compare_to_pytonlib.py deleted file mode 100644 index 3a9d355..0000000 --- a/tests/compare_to_pytonlib.py +++ /dev/null @@ -1,38 +0,0 @@ -import asyncio -import time -from pathlib import Path - -import requests -from pytonlib import TonlibClient -from test_tcp import test as tonpy - - -async def get_client(ls_index: int) -> TonlibClient: - url = 'https://ton.org/global-config.json' - - config ={'@type': 'config.global', 'dht': {'@type': 'dht.config.global', 'k': 6, 'a': 3, 'static_nodes': {'@type': 'dht.nodes', 'nodes': [{'@type': 'dht.node', 'id': {'@type': 'pub.ed25519', 'key': '6PGkPQSbyFp12esf1NqmDOaLoFA8i9+Mp5+cAx5wtTU='}, 'addr_list': {'@type': 'adnl.addressList', 'addrs': [{'@type': 'adnl.address.udp', 'ip': -1185526007, 'port': 22096}], 'version': 0, 'reinit_date': 0, 'priority': 0, 'expire_at': 0}, 'version': -1, 'signature': 'L4N1+dzXLlkmT5iPnvsmsixzXU0L6kPKApqMdcrGP5d9ssMhn69SzHFK+yIzvG6zQ9oRb4TnqPBaKShjjj2OBg=='}, {'@type': 'dht.node', 'id': {'@type': 'pub.ed25519', 'key': '4R0C/zU56k+x2HGMsLWjX2rP/SpoTPIHSSAmidGlsb8='}, 'addr_list': {'@type': 'adnl.addressList', 'addrs': [{'@type': 'adnl.address.udp', 'ip': -1952265919, 'port': 14395}], 'version': 0, 'reinit_date': 0, 'priority': 0, 'expire_at': 0}, 'version': -1, 'signature': '0uwWyCFn2KjPnnlbSFYXLZdwIakaSgI9WyRo87J3iCGwb5TvJSztgA224A9kNAXeutOrXMIPYv1b8Zt8ImsrCg=='}, {'@type': 'dht.node', 'id': {'@type': 'pub.ed25519', 'key': '/YDNd+IwRUgL0mq21oC0L3RxrS8gTu0nciSPUrhqR78='}, 'addr_list': {'@type': 'adnl.addressList', 'addrs': [{'@type': 'adnl.address.udp', 'ip': -1402455171, 'port': 14432}], 'version': 0, 'reinit_date': 0, 'priority': 0, 'expire_at': 0}, 'version': -1, 'signature': '6+oVk6HDtIFbwYi9khCc8B+fTFceBUo1PWZDVTkb4l84tscvr5QpzAkdK7sS5xGzxM7V7YYQ6gUQPrsP9xcLAw=='}, {'@type': 'dht.node', 'id': {'@type': 'pub.ed25519', 'key': 'DA0H568bb+LoO2LGY80PgPee59jTPCqqSJJzt1SH+KE='}, 'addr_list': {'@type': 'adnl.addressList', 'addrs': [{'@type': 'adnl.address.udp', 'ip': -1402397332, 'port': 14583}], 'version': 0, 'reinit_date': 0, 'priority': 0, 'expire_at': 0}, 'version': -1, 'signature': 'cL79gDTrixhaM9AlkCdZWccCts7ieQYQBmPxb/R7d7zHw3bEHL8Le96CFJoB1KHu8C85iDpFK8qlrGl1Yt/ZDg=='}, {'@type': 'dht.node', 'id': {'@type': 'pub.ed25519', 'key': 'fZnkoIAxrTd4xeBgVpZFRm5SvVvSx7eN3Vbe8c83YMk='}, 'addr_list': {'@type': 'adnl.addressList', 'addrs': [{'@type': 'adnl.address.udp', 'ip': 1091897261, 'port': 15813}], 'version': 0, 'reinit_date': 0, 'priority': 0, 'expire_at': 0}, 'version': -1, 'signature': 'cmaMrV/9wuaHOOyXYjoxBnckJktJqrQZ2i+YaY3ehIyiL3LkW81OQ91vm8zzsx1kwwadGZNzgq4hI4PCB/U5Dw=='}, {'@type': 'dht.node', 'id': {'@type': 'pub.ed25519', 'key': 'zDBLsKjns4bBqQokzY0wOzC2vwbOeiE1J7aOjfCp5mg='}, 'addr_list': {'@type': 'adnl.addressList', 'addrs': [{'@type': 'adnl.address.udp', 'ip': -1573440928, 'port': 12821}], 'version': 0, 'reinit_date': 0, 'priority': 0, 'expire_at': 0}, 'version': -1, 'signature': 'qORMhem9RyG7wnNYF822YL3EXwEoTO82h2TarFbjd0jikMIGizAdir1JyxSfyKkhHdFKGcLMeoPb2dfMIvQwAA=='}, {'@type': 'dht.node', 'id': {'@type': 'pub.ed25519', 'key': 'CU9ytJok8WBnpl29T740gfC/h69kgvQJp7FJMq/N60g='}, 'addr_list': {'@type': 'adnl.addressList', 'addrs': [{'@type': 'adnl.address.udp', 'ip': 391653587, 'port': 15895}], 'version': 0, 'reinit_date': 0, 'priority': 0, 'expire_at': 0}, 'version': -1, 'signature': 'DKyGF2nPRxmerpIHxE5FN1Lod3zvJu728NP0iYc1hpNyPvl5epu+7amjimLy1VdzNqFzTJAoJ/gqPPMkXS/kDw=='}, {'@type': 'dht.node', 'id': {'@type': 'pub.ed25519', 'key': 'MJr8xja0xpu9DoisFXBrkNHNx1XozR7HHw9fJdSyEdo='}, 'addr_list': {'@type': 'adnl.addressList', 'addrs': [{'@type': 'adnl.address.udp', 'ip': -2018147130, 'port': 6302}], 'version': 0, 'reinit_date': 0, 'priority': 0, 'expire_at': 0}, 'version': -1, 'signature': 'XcR5JaWcf4QMdI8urLSc1zwv5+9nCuItSE1EDa0dSwYF15R/BtJoKU5YHA4/T8SiO18aVPQk2SL1pbhevuMrAQ=='}, {'@type': 'dht.node', 'id': {'@type': 'pub.ed25519', 'key': 'Fhldu4zlnb20/TUj9TXElZkiEmbndIiE/DXrbGKu+0c='}, 'addr_list': {'@type': 'adnl.addressList', 'addrs': [{'@type': 'adnl.address.udp', 'ip': -2018147075, 'port': 6302}], 'version': 0, 'reinit_date': 0, 'priority': 0, 'expire_at': 0}, 'version': -1, 'signature': 'nUGB77UAkd2+ZAL5PgInb3TvtuLLXJEJ2icjAUKLv4qIGB3c/O9k/v0NKwSzhsMP0ljeTGbcIoMDw24qf3goCg=='}, {'@type': 'dht.node', 'id': {'@type': 'pub.ed25519', 'key': 'gzUNJnBJhdpooYCE8juKZo2y4tYDIQfoCvFm0yBr7y0='}, 'addr_list': {'@type': 'adnl.addressList', 'addrs': [{'@type': 'adnl.address.udp', 'ip': 89013260, 'port': 54390}], 'version': 0, 'reinit_date': 0, 'priority': 0, 'expire_at': 0}, 'version': -1, 'signature': 'LCrCkjmkMn6AZHW2I+oRm1gHK7CyBPfcb6LwsltskCPpNECyBl1GxZTX45n0xZtLgyBd/bOqMPBfawpQwWt1BA=='}, {'@type': 'dht.node', 'id': {'@type': 'pub.ed25519', 'key': 'jXiLaOQz1HPayilWgBWhV9xJhUIqfU95t+KFKQPIpXg='}, 'addr_list': {'@type': 'adnl.addressList', 'addrs': [{'@type': 'adnl.address.udp', 'ip': 94452896, 'port': 12485}], 'version': 0, 'reinit_date': 0, 'priority': 0, 'expire_at': 0}, 'version': -1, 'signature': 'fKSZh9nXMx+YblkQXn3I/bndTD0JZ1yAtK/tXPIGruNglpe9sWMXR+8fy3YogPhLJMdjNiMom1ya+tWG7qvBAQ=='}, {'@type': 'dht.node', 'id': {'@type': 'pub.ed25519', 'key': 'vhFPq+tgjJi+4ZbEOHBo4qjpqhBdSCzNZBdgXyj3NK8='}, 'addr_list': {'@type': 'adnl.addressList', 'addrs': [{'@type': 'adnl.address.udp', 'ip': 85383775, 'port': 36752}], 'version': 0, 'reinit_date': 0, 'priority': 0, 'expire_at': 0}, 'version': -1, 'signature': 'kBwAIgJVkz8AIOGoZcZcXWgNmWq8MSBWB2VhS8Pd+f9LLPIeeFxlDTtwAe8Kj7NkHDSDC+bPXLGQZvPv0+wHCg=='}, {'@type': 'dht.node', 'id': {'@type': 'pub.ed25519', 'key': 'sbsuMcdyYFSRQ0sG86/n+ZQ5FX3zOWm1aCVuHwXdgs0='}, 'addr_list': {'@type': 'adnl.addressList', 'addrs': [{'@type': 'adnl.address.udp', 'ip': 759132846, 'port': 50187}], 'version': 0, 'reinit_date': 0, 'priority': 0, 'expire_at': 0}, 'version': -1, 'signature': '9FJwbFw3IECRFkb9bA54YaexjDmlNBArimWkh+BvW88mjm3K2i5V2uaBPS3GubvXWOwdHLE2lzQBobgZRGMyCg=='}, {'@type': 'dht.node', 'id': {'@type': 'pub.ed25519', 'key': 'aeMgdMdkkbkfAS4+n4BEGgtqhkf2/zXrVWWECOJ/h3A='}, 'addr_list': {'@type': 'adnl.addressList', 'addrs': [{'@type': 'adnl.address.udp', 'ip': -1481887565, 'port': 25975}], 'version': 0, 'reinit_date': 0, 'priority': 0, 'expire_at': 0}, 'version': -1, 'signature': 'z5ogivZWpQchkS4UR4wB7i2pfOpMwX9Nd/USxinL9LvJPa+/Aw3F1AytR9FX0BqDftxIYvblBYAB5JyAmlj+AA=='}, {'@type': 'dht.node', 'id': {'@type': 'pub.ed25519', 'key': 'rNzhnAlmtRn9rTzW6o2568S6bbOXly7ddO1olDws5wM='}, 'addr_list': {'@type': 'adnl.addressList', 'addrs': [{'@type': 'adnl.address.udp', 'ip': -2134428422, 'port': 45943}], 'version': 0, 'reinit_date': 0, 'priority': 0, 'expire_at': 0}, 'version': -1, 'signature': 'sn/+ZfkfCSw2bHnEnv04AXX/Goyw7+StHBPQOdPr+wvdbaJ761D7hyiMNdQGbuZv2Ep2cXJpiwylnZItrwdUDg=='}]}}, 'liteservers': [{'ip': 84478511, 'port': 19949, 'id': {'@type': 'pub.ed25519', 'key': 'n4VDnSCUuSpjnCyUk9e3QOOd6o0ItSWYbTnW3Wnn8wk='}}, {'ip': 84478479, 'port': 48014, 'id': {'@type': 'pub.ed25519', 'key': '3XO67K/qi+gu3T9v8G2hx1yNmWZhccL3O7SoosFo8G0='}}, {'ip': -2018135749, 'port': 53312, 'id': {'@type': 'pub.ed25519', 'key': 'aF91CuUHuuOv9rm2W5+O/4h38M3sRm40DtSdRxQhmtQ='}}, {'ip': -2018145068, 'port': 13206, 'id': {'@type': 'pub.ed25519', 'key': 'K0t3+IWLOXHYMvMcrGZDPs+pn58a17LFbnXoQkKc2xw='}}, {'ip': -2018145059, 'port': 46995, 'id': {'@type': 'pub.ed25519', 'key': 'wQE0MVhXNWUXpWiW5Bk8cAirIh5NNG3cZM1/fSVKIts='}}, {'ip': 1091931625, 'port': 30131, 'id': {'@type': 'pub.ed25519', 'key': 'wrQaeIFispPfHndEBc0s0fx7GSp8UFFvebnytQQfc6A='}}, {'ip': 1091931590, 'port': 47160, 'id': {'@type': 'pub.ed25519', 'key': 'vOe1Xqt/1AQ2Z56Pr+1Rnw+f0NmAA7rNCZFIHeChB7o='}}, {'ip': 1091931623, 'port': 17728, 'id': {'@type': 'pub.ed25519', 'key': 'BYSVpL7aPk0kU5CtlsIae/8mf2B/NrBi7DKmepcjX6Q='}}, {'ip': 1091931589, 'port': 13570, 'id': {'@type': 'pub.ed25519', 'key': 'iVQH71cymoNgnrhOT35tl/Y7k86X5iVuu5Vf68KmifQ='}}, {'ip': -1539021362, 'port': 52995, 'id': {'@type': 'pub.ed25519', 'key': 'QnGFe9kihW+TKacEvvxFWqVXeRxCB6ChjjhNTrL7+/k='}}, {'ip': -1539021936, 'port': 20334, 'id': {'@type': 'pub.ed25519', 'key': 'gyLh12v4hBRtyBygvvbbO2HqEtgl+ojpeRJKt4gkMq0='}}, {'ip': -1136338705, 'port': 19925, 'id': {'@type': 'pub.ed25519', 'key': 'ucho5bEkufbKN1JR1BGHpkObq602whJn3Q3UwhtgSo4='}}, {'ip': 868465979, 'port': 19434, 'id': {'@type': 'pub.ed25519', 'key': 'J5CwYXuCZWVPgiFPW+NY2roBwDWpRRtANHSTYTRSVtI='}}, {'ip': 868466060, 'port': 23067, 'id': {'@type': 'pub.ed25519', 'key': 'vX8d0i31zB0prVuZK8fBkt37WnEpuEHrb7PElk4FJ1o='}}, {'ip': -2018147130, 'port': 53560, 'id': {'@type': 'pub.ed25519', 'key': 'NlYhh/xf4uQpE+7EzgorPHqIaqildznrpajJTRRH2HU='}}, {'ip': -2018147075, 'port': 46529, 'id': {'@type': 'pub.ed25519', 'key': 'jLO6yoooqUQqg4/1QXflpv2qGCoXmzZCR+bOsYJ2hxw='}}, {'ip': 908566172, 'port': 51565, 'id': {'@type': 'pub.ed25519', 'key': 'TDg+ILLlRugRB4Kpg3wXjPcoc+d+Eeb7kuVe16CS9z8='}}, {'ip': -1185526007, 'port': 4701, 'id': {'@type': 'pub.ed25519', 'key': 'G6cNAr6wXBBByWDzddEWP5xMFsAcp6y13fXA8Q7EJlM='}}], 'validator': {'@type': 'validator.config.global', 'zero_state': {'workchain': -1, 'shard': -9223372036854775808, 'seqno': 0, 'root_hash': 'F6OpKZKqvqeFp6CQmFomXNMfMj2EnaUSOXN+Mh+wVWk=', 'file_hash': 'XplPz01CXAps5qeSWUtxcyBfdAo5zVb1N979KLSKD24='}, 'init_block': {'root_hash': 'YRkrcmZMvLBvjanwKCyL3w4oceGPtFfgx8ym1QKCK/4=', 'seqno': 27747086, 'file_hash': 'N42xzPnJjDlE3hxPXOb+pNzXomgRtpX5AZzMPnIA41s=', 'workchain': -1, 'shard': -9223372036854775808}, 'hardforks': [{'file_hash': 't/9VBPODF7Zdh4nsnA49dprO69nQNMqYL+zk5bCjV/8=', 'seqno': 8536841, 'root_hash': '08Kpc9XxrMKC6BF/FeNHPS3MEL1/Vi/fQU/C9ELUrkc=', 'workchain': -1, 'shard': -9223372036854775808}]}} - - keystore_dir = '/tmp/ton_keystore' - Path(keystore_dir).mkdir(parents=True, exist_ok=True) - - client = TonlibClient(ls_index=ls_index, config=config, keystore=keystore_dir, tonlib_timeout=10) - await client.init() - - return client - - -async def pytonlib(req_num: int): - client = await get_client(7) - tasks = [client.get_masterchain_info() for _ in range(req_num)] - s = time.time() - await asyncio.gather(*tasks) - t = time.time() - s - await client.close() - return t - -if __name__ == '__main__': - t1 = asyncio.run(pytonlib(1000)) - t2 = asyncio.run(tonpy(1000)) - print(t1, t2) - result = 'tonpy' if t2 < t1 else 'pytonlib' - print('winner:', result) diff --git a/tests/config.py b/tests/config.py deleted file mode 100644 index a9a9f1c..0000000 --- a/tests/config.py +++ /dev/null @@ -1,34 +0,0 @@ -import asyncio -import time - -from tonpylib.liteclient.client_tcp import AdnlClientTcp -from tonpylib.tl.block import BlockIdExt - -host = '65.21.141.231' -port = 17728 - -pub_key_b64 = 'BYSVpL7aPk0kU5CtlsIae/8mf2B/NrBi7DKmepcjX6Q=' - - -async def main(): - client = AdnlClientTcp( - host, - port, - pub_key_b64 - ) - await client.connect() - - await client.get_masterchain_info() - # last = BlockIdExt.from_dict((await client.get_masterchain_info_ext())['last']) - - params = await client.get_config_all() - print(params) - - params = await client.get_config_params([1, 2, 3, 4]) - print(params) - - await client.close() - - -if __name__ == '__main__': - asyncio.run(main(), debug=True) diff --git a/tests/contracts/wallets/wallet.py b/tests/contracts/wallets/wallet.py deleted file mode 100644 index 4df3b29..0000000 --- a/tests/contracts/wallets/wallet.py +++ /dev/null @@ -1,70 +0,0 @@ -import asyncio -import time - -from priv_key import wallet_mnemonics -from tonpylib.boc.address import Address -from tonpylib.boc.cell import Cell -from tonpylib.liteclient.client import LiteClient -from tonpylib.tl.block import BlockIdExt -from tonpylib.contract.contract import Contract -from tonpylib.contract.wallets.wallet import WalletV3R2, WalletV3R1, WalletV4R2, Wallet -from tonpylib.contract.wallets.highload import HighloadWallet - -host = '65.21.141.231' -port = 17728 - -pub_key_b64 = 'BYSVpL7aPk0kU5CtlsIae/8mf2B/NrBi7DKmepcjX6Q=' - - -async def main(): - client = LiteClient( - host, - port, - pub_key_b64 - ) - await client.connect() - hw_m = ['truly', 'pluck', 'arm', 'quantum', 'endorse', 'tell', 'album', 'mandate', 'grief', 'salon', 'bridge', 'annual', 'pretty', 'pepper', 'climb', 'slow', 'misery', 'lunar', 'balcony', 'sick', 'student', 'post', 'prefer', 'guard'] - - m, hw = await HighloadWallet.create(provider=client, wc=0, ) - hw = await HighloadWallet.from_mnemonic(provider=client, mnemonics=hw_m,) - print(hw) - w = await WalletV4R2.from_mnemonic(provider=client, mnemonics=wallet_mnemonics) - # await hw.transfer(['EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG', 'EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG'], amounts=[1000, 1000], bodies=[None, None], state_inits=[None, None]) - print(w) - - print(hw.old_queries, hw.last_cleaned) - # await w.deploy_via_internal(hw) - - # await new_w.deploy_via_external() - # await w.transfer(destination=Address('EQAXA8eBIhU3Jlsd0ydlqfSMrB7Sqigdgh4pLmQJ_kb9DHg9').to_str(is_user_friendly=True, is_bounceable=False), amount=1 * 10**7, body='hello') - input() - c = await Contract.from_address(client, Address((0, b'o[\xc6y\x86\xe0d0\x96\x1d\x9d\xf0\x043\x92jL\xd9.Y}\xdd\x8a\xa6\x046E\xac \xbd\x17\x83'))) - print(c) - print(c.is_uninitialized) - - wallet = await WalletV3R2.from_address(provider=client, address='EQCA1BI4QRZ8qYmskSRDzJmkucGodYRTZCf_b9hckjla6dZl') - print(wallet) - print(await wallet.get_seqno()) - print(wallet.seqno) - print(wallet.public_key) - print(await wallet.get_public_key()) - - wallet2 = await WalletV3R1.from_address(provider=client, address='EQBVXzBT4lcTA3S7gxrg4hnl5fnsDKj4oNEzNp09aQxkwj1f') - print(await wallet2.get_seqno()) - print(wallet2.seqno) - print(wallet2.public_key) - # print(await wallet2.get_public_key()) - - wallet3 = await WalletV4R2.from_address(provider=client, address='EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG') - - print(await wallet3.get_seqno()) - print(wallet3.seqno) - print(wallet3.public_key) - print(await wallet3.get_public_key()) - print(wallet3.plugins) - print(await wallet3.get_plugin_list()) - print(await wallet3.is_plugin_installed(address=Address('EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG'))) - - -if __name__ == '__main__': - asyncio.run(main()) diff --git a/tests/main.py b/tests/main.py deleted file mode 100644 index 982c80f..0000000 --- a/tests/main.py +++ /dev/null @@ -1,99 +0,0 @@ -import asyncio -import time - -from tonpylib.liteclient.client import LiteClient -from tonpylib.tl.block import BlockIdExt - -host = '65.21.141.231' -port = 17728 - -pub_key_b64 = 'BYSVpL7aPk0kU5CtlsIae/8mf2B/NrBi7DKmepcjX6Q=' - - -async def main(): - client = LiteClient( - host, - port, - pub_key_b64 - ) - await client.connect() - - await client.get_masterchain_info() - last = BlockIdExt.from_dict((await client.get_masterchain_info_ext())['last']) - # s = time.time() - # print(await client.wait_masterchain_seqno(last['seqno'] + 2, 10)) - # print(time.time() - s) - # state = await client.raw_get_all_shards_info(BlockIdExt.from_dict(last)) - - # blk, blk_data = await client.lookup_block(-1, 0, 31041506) - #31058790 - # blk, blk_data = await client.lookup_block(-1, 0, 31068099) - lst, last_data = await client.lookup_block(-1, 0, last.seqno) - # blk, blk_data = await client.lookup_block(-1, 0, last_data.info.prev_key_block_seqno - 100) # key block - blk, blk_data = await client.lookup_block(-1, -9223372036854775808, last.seqno - 100) - await client.raw_get_block(blk) - - init_block = BlockIdExt.from_dict({ - "root_hash": "61192b72664cbcb06f8da9f0282c8bdf0e2871e18fb457e0c7cca6d502822bfe", - "seqno": 27747086, - "file_hash": "378db1ccf9c98c3944de1c4f5ce6fea4dcd7a26811b695f9019ccc3e7200e35b", - "workchain": -1, - "shard": -9223372036854775808 - }) - - - # print(blk_data.info.prev_key_block_seqno) - - # a, b = await client.raw_get_block_proof(known_block=init_block, target_block=last) - s = time.time() - - await client.get_block_proof(known_block=last, target_block=blk) - # await client.get_block_proof(known_block=init_block, target_block=last) - print(time.time() - s) - # print(a, b) - # await client.raw_get_block_proof(known_block=last, target_block=blk) - - input() - block_trs = await client.raw_get_block_transactions(blk) - block_trs = await client.raw_get_block_transactions_ext(blk) - print(block_trs) - input() - trs = await client.get_transactions('EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG', 32) - # trs = await client.raw_get_transactions('EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG', 10) - tr = await client.get_one_transaction('Ef8zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM0vF', lt=39202528000001, block=blk) - - print(tr) - - # trs = await client.raw_get_transactions('EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG', 16) - trs = await client.get_transactions('EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG', 32) - - print(trs[0]) - input() - tr = await client.get_one_transaction('Ef8zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM0vF', lt=39202528000001, block=blk) - print(tr) - state = await client.raw_get_shard_info(BlockIdExt.from_dict(last), wc=0, shard=last['shard'], exact=True) - input() - state = await client.raw_get_all_shards_info(BlockIdExt.from_dict(last)) - resp = await client.get_time() - resp = await client.get_version() - resp = await client.get_state(last['workchain'], last['shard'], last['seqno'], last['root_hash'], last['file_hash']) - resp = await client.get_block(last['workchain'], last['shard'], last['seqno'], last['root_hash'], last['file_hash']) - resp = await client.lookup_block(last['workchain'], last['shard'], last['seqno']) - - resp = await client.get_block_header(last['workchain'], last['shard'], last['seqno'], last['root_hash'], last['file_hash']) - - raw_state = await client.raw_get_account_state('EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG') - state = await client.get_account_state('EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG') - - print(raw_state) # {'last_trans_lt': 39064423000006, 'balance': {'grams': 445885900290, 'other': {'dict': None}}, 'state': {'type_': 'account_active', 'state_init': {'split_depth': None, 'special': None, 'code': 1 refs>, 'data': 0 refs>, 'library': None}}} - print(state) # - - stack = await client.run_get_method(address='EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG', method='seqno', stack=[]) - - print(stack) # [231] - - await client.close() - - -if __name__ == '__main__': - asyncio.run(main(), debug=True) diff --git a/tests/performance/crc.py b/tests/performance/crc.py deleted file mode 100644 index d517c78..0000000 --- a/tests/performance/crc.py +++ /dev/null @@ -1,35 +0,0 @@ -import timeit - - -schema = b'tcp.ping random_id:long = tcp.Pong' -# schema = b'abcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdwwabcsdww' - -code1 = f''' -hex(binascii.crc32({schema})) -''' - -code2 = f''' -hex(zlib.crc32({schema})) -''' - -code3 = f''' -hex(fastcrc.crc32.iso_hdlc({schema})) -''' - -number = 10**6 - -t1 = timeit.timeit(code1, number=number, setup='import binascii') -t2 = timeit.timeit(code2, number=number, setup='import zlib') -t3 = timeit.timeit(code3, number=number, setup='import fastcrc') - -result = { - 'binascii': t1, - 'zlib': t2, - 'fastcrc': t3 -} - - -if __name__ == '__main__': - print('\n'.join([i[0] + ': ' + str(i[1]) for i in result.items()])) - print('winner: ', sorted(result.items(), key=lambda i: i[1])[0][0]) - # the winner is usually zlib and sometimes binascii diff --git a/tests/performance/string_find.py b/tests/performance/string_find.py deleted file mode 100644 index 46bfce5..0000000 --- a/tests/performance/string_find.py +++ /dev/null @@ -1,35 +0,0 @@ -import timeit -import random -import string -import re - -letters = string.ascii_lowercase + ';' + '(' + ')' + ' ' - -string = ''.join(random.choice(letters) for i in range(1000)) - -code1 = ''' -if '#' in string: - print('yes') -''' - -code2 = f''' -for i in string: - if i is '#': - print('yes') - break -''' - - -number = 10**5 -t1 = timeit.timeit(code1, number=number, globals=globals()) -t2 = timeit.timeit(code2, number=number, globals=globals()) - -result = { - 'in': t1, - 'for': t2, -} - -if __name__ == '__main__': - print(result) - print('winner: ', sorted(result.items(), key=lambda i: i[1])[0][0]) - # the winner is .replace() diff --git a/tests/performance/string_replace.py b/tests/performance/string_replace.py deleted file mode 100644 index 5faad5e..0000000 --- a/tests/performance/string_replace.py +++ /dev/null @@ -1,41 +0,0 @@ -import timeit -import random -import string -import re - -# printing lowercase -letters = string.ascii_lowercase + ';' + '(' + ')' + ' ' - -string = ''.join(random.choice(letters) for i in range(1000)) - -code1 = ''' -string.replace(';', '').replace('(', '').replace(')', '') -''' - -code2 = f''' -new_schema = '' -restricted = {';', '(', ')'} -for c in string: - if c not in restricted: - new_schema += c -''' - -code3 = f''' -re.sub('\(|\)|;', '', string) -''' - -number = 10**4 * 3 -t1 = timeit.timeit(code1, number=number, globals=globals()) -t2 = timeit.timeit(code2, number=number, globals=globals()) -t3 = timeit.timeit(code3, number=number, globals=globals()) - -result = { - 'replace': t1, - 'clear': t2, - 're': t3 -} - -if __name__ == '__main__': - print(result) - print('winner: ', sorted(result.items(), key=lambda i: i[1])[0][0]) - # the winner is .replace() diff --git a/tests/primitives/async_tcp.py b/tests/primitives/async_tcp.py deleted file mode 100644 index 181cf15..0000000 --- a/tests/primitives/async_tcp.py +++ /dev/null @@ -1,83 +0,0 @@ -import asyncio -import time -from queue import Queue - -from crypto import Server, result, enc_cipher, dec_cipher -from ping_pong import get_ping_request, parse_pong - - -async def send(writer, data: bytes): - print(f'Send: {data}') - writer.write(data) - await writer.drain() - - -async def recieve(reader, len: int): - data = await reader.read(len) - print(f'Received: {data}') - return data - - -async def close(writer): - print('Close the connection') - writer.close() - await writer.wait_closed() - - -async def listen(reader): - global is_listening - # while True: - is_listening = True - - if queue.qsize() == 0: - await asyncio.sleep(0.1) - - for i in range(queue.qsize()): - data = await reader.read(80) - queue.get().set_result(dec_cipher.decrypt(data)) - is_listening = False - # for i in queue: - # data = await reader.read(80) - # i.set_result(dec_cipher.decrypt(data)) - - -queue = Queue() -amount = 100 -is_listening = False - - -async def ping(writer, reader): - global queue - ping_result, qid = get_ping_request() - # print(qid) - await send(writer, ping_result) - cor_result = asyncio.get_running_loop().create_future() - # queue.append(cor_result) - queue.put(cor_result) - if not is_listening: - await listen(reader) - # cor_result.set_result(True) - await cor_result - if not is_listening: - await listen(reader) - - parse_pong(cor_result.result(), qid) - print('Passed!') - - -async def main(): - reader, writer = await asyncio.open_connection(Server.host, Server.port) - await send(writer, result) - - data = await recieve(reader, 100) - print(dec_cipher.decrypt(data)) - - # await ping(writer, reader) - start = time.time() - tasks = [ping(writer, reader) for _ in range(amount)] - # await listen(reader) - await asyncio.gather(*tasks) - print(time.time() - start) - -if __name__ == '__main__': - asyncio.run(main()) diff --git a/tests/primitives/async_tcp2.py b/tests/primitives/async_tcp2.py deleted file mode 100644 index f4c4538..0000000 --- a/tests/primitives/async_tcp2.py +++ /dev/null @@ -1,57 +0,0 @@ -import asyncio -import socket -import time - -from crypto import Server, result, enc_cipher, dec_cipher -from ping_pong import get_ping_request, parse_pong - -s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - -s.connect((Server.host, Server.port)) -print('connected') -print('sending:', result) -s.send(result) -print('sent') -data = s.recv(1024) -print('Received', data) -print(dec_cipher.decrypt(data)) - -start = time.time() -qids = [] -amount = 5 - - -def send(future): - global qids - ping_result, qid = get_ping_request() - print('sending:', ping_result) - s.send(ping_result) - future.set_result(True) - qids.append(qid) - - -def recieve(i): - data = s.recv(80) - print('recieved:', data) - data = dec_cipher.decrypt(data) - print(i) - parse_pong(data, qids[i]) - - -async def ping(i): - future = asyncio.get_event_loop().create_future() - asyncio.get_event_loop().run_in_executor(None, lambda: send(future)) - await future - asyncio.get_event_loop().run_in_executor(None, lambda: recieve(i)) - - -async def main(): - start = time.time() - tasks = [ping(i) for i in range(amount)] - # await listen(reader) - await asyncio.gather(*tasks) - print(time.time() - start) - - -if __name__ == '__main__': - asyncio.run(main()) diff --git a/tests/primitives/asyncio_tcp3.py b/tests/primitives/asyncio_tcp3.py deleted file mode 100644 index 7f9fece..0000000 --- a/tests/primitives/asyncio_tcp3.py +++ /dev/null @@ -1,94 +0,0 @@ -import asyncio -import hashlib -import time -from queue import Queue - -from crypto import Server, result, enc_cipher, dec_cipher, get_random_bytes -from ping_pong import get_ping_request, parse_pong - - -async def send(writer, data: bytes, i=None): - print(f'Send: {i}') - writer.write(data) - await writer.drain() - - -async def recieve(reader, len: int): - data = await reader.read(len) - print(f'Received: {data}') - return data - - -async def close(writer): - print('Close the connection') - writer.close() - await writer.wait_closed() - - -async def listen(reader): - while True: - if queue.qsize() == 0: - await asyncio.sleep(0.1) - continue - - for i in range(queue.qsize()): - data = await reader.read(4) - l = int(dec_cipher.decrypt(data)[::-1].hex(), 16) - print(i, l) - data = await reader.read(l) - queue.get().set_result(dec_cipher.decrypt(data)) - - -queue = Queue() -amount = 1000 - - -async def ping(writer): - global queue - ping_result, qid = get_ping_request() - await send(writer, ping_result) - cor_result = asyncio.get_running_loop().create_future() - queue.put(cor_result) - await cor_result - parse_pong(cor_result.result(), qid) - print('Passed!') - - -async def get_masterchain_info(writer, i): - data = 0x74.to_bytes(byteorder='little', length=4) # length - nonce = get_random_bytes(32) - data += nonce - data += 0x7af98bb4.to_bytes(byteorder='big', length=4) - data += get_random_bytes(32) - data += b'\x0c' - data += b'\xdf\x06\x8c\x79' - data += b'\x04' - data += b'\x2e\xe6\xb5\x89' - data += b'\x00\x00\x00' - data += b'\x00\x00\x00' - data += hashlib.sha256(data[4:]).digest() - - await send(writer, enc_cipher.encrypt(data), i) - cor_result = asyncio.get_running_loop().create_future() - queue.put(cor_result) - await cor_result - # print(cor_result.result()) - - -async def main(): - reader, writer = await asyncio.open_connection(Server.host, Server.port) - await send(writer, result) - - data = await recieve(reader, 100) - print(dec_cipher.decrypt(data)) - - # await ping(writer, reader) - start = time.time() - tasks = [get_masterchain_info(writer, i) for i in range(amount)] - asyncio.create_task(listen(reader)) - await asyncio.gather(*tasks) - print(time.time() - start) - - -if __name__ == '__main__': - asyncio.run(main()) diff --git a/tests/primitives/crypto.py b/tests/primitives/crypto.py deleted file mode 100644 index e754211..0000000 --- a/tests/primitives/crypto.py +++ /dev/null @@ -1,68 +0,0 @@ -import base64 - -from nacl.signing import SigningKey -from nacl.signing import SigningKey as EdPrivate, VerifyKey as EdPublic -from nacl.bindings import crypto_sign_ed25519_sk_to_pk -from nacl.public import Box, PublicKey as CurvePublic, PrivateKey as CurvePrivate - -from Cryptodome.Random import get_random_bytes -from Cryptodome.Cipher import AES -from Cryptodome.Util import Counter - -from hashlib import sha256 - -from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes -from keys import get_shared - - -class Server: - host = '65.21.141.231' - port = 17728 - - pub_key_b64 = 'BYSVpL7aPk0kU5CtlsIae/8mf2B/NrBi7DKmepcjX6Q=' - - pub_key = base64.b64decode(pub_key_b64) - - ed25519_public = EdPublic(pub_key) - x25519_public = ed25519_public.to_curve25519_public_key() - - -class Client: - ed25519_private = EdPrivate.generate() - # ed25519_private = EdPrivate(b'\xf2\x12\x85\x95\xf7*a\x7f\x0f\xf6\x89p\xe3\xf6\xfbJ\xf6[\x12|:\xe4\x81\x1b$D\xf3\x91\x10\xbe\x18!') - ed25519_public = ed25519_private.verify_key - x25519_private = ed25519_private.to_curve25519_private_key() - x25519_public = x25519_private.public_key - # secret_key = bytes(sk) - # public_key = bytes(pk) - - -rand = get_random_bytes(160) -# rand = b'\xa3E\t\xb83(\xb1\xad\x84\xd6\xde\xfa\xb8\x1b\xec>\x88\xb6\x10\x9c,\xf06\x1b\x0c1\xe7\xcdj\x88Z\xd5\xdd\xac\xeeT\rY\x00\rStnS\xd4\xb5t\xc1\xec\x9bAX\xf21\x1d\x8b\xb8\xdeela0-\xb6Y80\xb4T(\xd9\x17O\xff\xd4\x05#BY\xfc@\xb0\x05\xde\x03}= 1500: - time.sleep(0.05) - s.recv_into(buffer, 4) - print(i) - # data = s.recvmsg(4, 1) - data = buffer[:4] - del buffer[:4] - dlen = dec_cipher2.update(data) - dlen = int(dlen[:4][::-1].hex(), 16) - print(dlen) - s.recv_into(buffer, dlen) - data = dec_cipher2.update(buffer[:dlen]) - del buffer[:dlen] - print(len(data)) - - -if __name__ == '__main__': - main() diff --git a/tests/primitives/tcp.py b/tests/primitives/tcp.py deleted file mode 100644 index 659785b..0000000 --- a/tests/primitives/tcp.py +++ /dev/null @@ -1,34 +0,0 @@ -import socket -import time - -from crypto import Server, result, enc_cipher, dec_cipher -from ping_pong import get_ping_request, parse_pong - -s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - -s.connect((Server.host, Server.port)) -print('connected') -print('sending:', result) -s.send(result) -print('sent') -data = s.recv(1024) -print('Received', data) -print(dec_cipher.decrypt(data)) - -start = time.time() -qids = [] -amount = 6000 -for i in range(amount): - ping_result, qid = get_ping_request() - print('sending:', ping_result) - s.send(ping_result) - qids.append(qid) - -for i in range(amount): - data = s.recv(80) - data = dec_cipher.decrypt(data) - parse_pong(data, qids[i]) - - -if __name__ == '__main__': - print(time.time() - start) # less than 1 sec for 500 ping-pong requests! diff --git a/tests/proof_boc.py b/tests/proof_boc.py deleted file mode 100644 index 7679769..0000000 --- a/tests/proof_boc.py +++ /dev/null @@ -1,26 +0,0 @@ -import base64 - -from tonpylib.boc.builder import Builder -from tonpylib.boc.cell import Cell -from tonpylib.boc.exotic import check_proof, ProofError -from tonpylib.boc.tvm_bitarray import TvmBitarray - -a = TvmBitarray(1023) -a.extend('1001') -print(a) -b = a.copy() -print(b) -del b[0] -print(a, b) -input() - -boc = 'te6ccgECYgEACyUACUYDHBrwE80zumF8DbEFfxmvE2dh+0MzQLoDix1KTUphruQBbwEkW5Ajr+L///8RAP////8AAAAAAAAAAAHRa4UAAAABZJHyoAAAIyTyERLEAdFrgGACAwQFKEgBAf2AN/5YcJC9V0wg2Qwe0UrJmbifP4PANE0FAoqbo/+OAAEoSAEBWr29376eAIu/xr5XeKKaTEVLX3YlrsHbRe9OPO9YPAgBbiIzAAAAAAAAAAD//////////4INBTIMYs+VSCgGByRVzCaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqsI04j5ZQAPLfggJCgsoSAEBpafSQFfYZDslJ3CdmGzaOEatyz7dwy0o7CH2nhfbqu8AAShIAQEd4Th21/vJTwVTGxljdYMJUidNAIqr/APCJCZ6IWpU/wARKEgBAen0sIeA7FYN7N8tD1vUqc5igpFgp1niZSMuOhJNHOkwAAIoSAEBdgxTYUnecYsgaE6smg9KGTfMsRnQr/KFaWIHeLoJ5JUAESK/AAHobk2HAAbchGAABGSeQDoQiAABGQ8ehc4gDonLpLI72R1Ii6+J7jRi8fY8hVaS2ud34OimjsuE9WKfJ8vHhrOe1VlXQKR0XLroPkJhfzJtIFQ+g9xT+xY6pQVBrai+DA0oSAEBsg42o7NqTN7mARBsZC6QcYsKWNryAHU9uzGJ+Va0lLYAASITw8AACMk8gHQhIA4PKEgBAQFey6xNLA27tZGZD1zVBJBJ6mZEI528bmZ9PU+1hzbzABEiESAAArQo53Ao8BARIhEgAARknkA6EJBAQSIRIAABjB1cHCiQEhMoSAEBlUO7XGgf/F/vf05IJ9rC7u5yIq2pC8EIyWz9jVtqbtkAFyIRIAAAxLK6A0iQFBUoSAEBXWyaLJqRMSoY6QRJ51EC/uxys2lXnHuadGfUdsCmXr4AFiIRIAAAWc4KXPiQFhcoSAEBcKJuoHxow9V+DeKyC93L8obbxbEXAns1AYnnNRLHcMAAFSIRIAAAK+JwneiQGBkoSAEBH8tCxJpe9331IXjrh4w/6ghATTtAehvVbRfv6PNj8WQAFCIRIAAAFSvlIjCQGhsoSAEBGozJKvJsUFd3OsFRANs3ATW6GJ+N4KQ38uyK1Rg6CYgAEyIRIAAAChJCLgCQHB0oSAEBk9aXPytIbY/OftwmE/4g27+NYFRAZy3B/n7bxoOCAnIAEiIRIAAABIVQRyCQHh8oSAEBO9bMT9H34YZDk/eLaHWj0mxwYM2lpEgEfA6pkTtzqbYAESIRIAAAAh50VPiQICEoSAEBQWadWStUc1uuwtBdNui136hF+uGRfjupxE005ljzpI8AECIRIAAAAQ9unjiQIiMoSAEB+UDjlcCyRkv/OH1vq6rIiggQri0hD6gyjn9W6EQn5IUADyIRIAAAAIelMHCQJCUoSAEB+Yyk0xeNiLvDxga2UI/Xakvk0fVpZePlVWWwg4KZBXMADiIRIAAAAEPzBQCQJicoSAEBOxY9QtPN7VEQ4pGV8IvOmFtjspkm38wzaPSu7aYqWrcADSIRIAAAACHqQECQKCkoSAEB6onDLQiNMo00vZXzV3JqjN/oplrIqSdW9etJEIXMqyAADCIRIAAAABDzN9mQKisoSAEB+8TcMYnmKO5tE+dDKf7SyPLBPuz7hIMou1UA3tOe+oUACyIRIAAAAAh6kBGQLC0oSAEBnUwZUKdhSrmP05KX5/PDkMJPmWxfdb3+SahmrkzqAy8ACiIRIAAAAAQ9SAmQLi8oSAEBaHboGGG4P40ukDosEsrGpHGGp85NUBzv+PM9Zkf8NcwACSIRIAAAAAIZ31GQMDEoSAEBUBHVccSAhbeuHWvsBBT4CvJ0tXg9da7Z2ekiH6C3mrAACCIRIAAAAAEDZkGQMjMoSAEB64WUHafrbUtf5zLAQ2QD5tJ23eyTbMlBuIQvYkY2n9MAByIRIAAAAAB/ytmQNDUoSAEBnWF00W9ZHSsKAqf7bnFFTrdQrn0RmBsohu8qFCid2lIABiIRIAAAAABCwdmQNjcoSAEBw8Wnz0LZAQbcXz+sy28qA0KY8BFg7GZvS4oSJjNlR70ABSIRIAAAAAAkPVmQODkoSAEBzUeMKD1Rgb9KwSlBIRGjeY8ft3LcrZu6FSwSO7wnaNQABCIRIAAAAAATEtGQOjsoSAEBoTUwUkpFzXqVIHwTqs7Ign90MYUDtTwmQa7QFFw3YWAAAyIRIAAAAAALcbGQPD0oSAEBn7lTAadhrAZfzs8Ki5zHO96H99IgVqWEuOEsSv3Gx9YAAiIRIAAAAAAB6EmQPj8oSAEBy9KEtx9zsGKLZ/wkmByboOlMdm/JgKZcJuQ89qeaRUoAAQCpIAAAAAAAAAAQAAAAAAAAAAAAAAABejqSmSqr6nhaegkJhaJlzTHzI9hJ2lEjlzfjIfsFVpXplPz01CXAps5qeSWUtxcyBfdAo5zVb1N979KLSKD26ChIAQGV1AHAeZkpjlDM1VCBAC8XcliOhyc+V14rgr1l+ACXLwAAKEgBAaB8s7kbggFfyGKQHEdGpn4poIcnAMmZcyS21ZvLaHckABciESAABGSeQDoQkEJDKEgBAUbM6ij5M4arTsC9D5kpdTyI6SzVw2FMwNSJutWnhcnFABYiEUgAARknkA6EJERFKEgBARYRkRNuYQXjKVw/TA8nQB3+VyAoqMVd4B+hQASAthXSABQiE3CAABGSeQDoQkBGRyhIAQESuOSFh1ECM94QuT+cog9ZDpk6T39JlRZIXs8U+8PQXQAQIhFIAAEZJ5AOhCRISShIAQEkhNGXQbEmO4azpZLQh4Nx0e5ViwD17Ck+VE4SOLWuFgAOIhEAAARknkA6EJBKSyhIAQGq94ddW3vWF8bR7YbC7avyuTgsHjcuPlwXe7iAOkrxdwANIhFAAAEZJ5AOhCRMTShIAQGkvwch0ekSpyRkDaPbWY77XwIyPg6MzRIf+Cn0lG3COQALIhFAAAEZJ5AOhCROTyIRAAAEZJtUi9CQUFEoSAEB9/DXIRlWGD6vZAQb6sBxeGpfg4Zl39hcH4HaXMAqyo8ACShIAQHznTlrvlryZAgOe1IYlm1nymuIm+UQq9d4t378BJweLAAIIhEAAARkm1SL0JBSUyhIAQGwC3NEveaact30oZ5hNc6UVxIdShOmImXzzMeUVTqOOQAHIhEAAARkm1SL0JBUVShIAQEiw3b1nSQ2ustL+BNETtm7i3NQ5XqJp3AeE5fSS057ogAGIhEAAARkm1SL0JBWVyhIAQEruozk3Gfjn96vtN9ljHbNN7PENUQPswph2n9n4VHG+QAFIhEAAARkm1SL0JBYWShIAQHGf6twseyAL0FSmtdI7R9yu0EjUbP/cIB4xVnlyoozjAAEIhEAAARkm1SL0JBaWyIRAAAEZJtFSZCQXF0oSAEBUFwxd4MjzBy9KEOJaBHH7XPUxqbSmDK/aJpp7RPSbEcAAyhIAQGkBEgPP/vE0AjBg0BzFelOWKCag5VqTEP2/zW2ysF9iAACIhEAAARkm0VJkJBeXyhIAQHrYMJugL70poiuEBHH3oxN/APWcejsQFmUJ7IZw3E8JQABIhEAAARkm0VJkJBgYShIAQHRFVNJaaMhp22jeFya5tClvbxOzmpXDDI9FgOb9/IiWgAAAKkAAARkm0VJkIAAAjJNoqTIQB0Wn3M8ZqSpBg1BUY3ptO3RGvr5P75LYqrcyu8cyYxJrIyOYpDuX/fou7AFDJADVYsT2e9ljVV/jBRrEHS2APATZ+hI' - -cell = Cell.one_from_boc(boc) -print(cell) -check_proof(cell, bytes.fromhex('1C1AF013CD33BA617C0DB1057F19AF136761FB433340BA038B1D4A4D4A61AEE4')) -print('passed') -try: - check_proof(cell, bytes.fromhex('2C1AF013CD33BA617C0DB1057F19AF136761FB433340BA038B1D4A4D4A61AEE4')) -except ProofError: - print('passed') diff --git a/tests/test_adnl.py b/tests/test_adnl.py new file mode 100644 index 0000000..163a5f7 --- /dev/null +++ b/tests/test_adnl.py @@ -0,0 +1,40 @@ +import asyncio +import logging + +from pytoniq.adnl.adnl import AdnlTransport, Node + + +adnl = AdnlTransport(timeout=3) + + +async def test_connection(): + + # start adnl receiving server + await adnl.start() + + # take peer from public config + peer = Node('172.104.59.125', 14432, "/YDNd+IwRUgL0mq21oC0L3RxrS8gTu0nciSPUrhqR78=", adnl) + await adnl.connect_to_peer(peer) + + # ask peer for something + await peer.get_signed_address_list() + + # send pings to peer + await asyncio.sleep(2) + + await peer.disconnect() + + # add another peer + peer = Node('5.161.60.160', 12485, "jXiLaOQz1HPayilWgBWhV9xJhUIqfU95t+KFKQPIpXg=", adnl) + + # second way to connect to peer + await peer.connect() + + # 2 adnl channels + print(adnl.channels) + + # check for pings + await asyncio.sleep(10) + + # stop adnl receiving server + await adnl.close() diff --git a/tests/test_dht.py b/tests/test_dht.py new file mode 100644 index 0000000..014a039 --- /dev/null +++ b/tests/test_dht.py @@ -0,0 +1,25 @@ +import asyncio +import hashlib +import logging +import time +from pytoniq_core.crypto.ciphers import Server + +from pytoniq.adnl.adnl import AdnlTransport +from pytoniq.adnl.dht import DhtClient, DhtNode + + +adnl = AdnlTransport(timeout=5) + + +client = DhtClient.from_mainnet_config(adnl) + + +async def test_dht(): + logging.basicConfig(level=logging.DEBUG) + await adnl.start() + + foundation_adnl_addr = '516618cf6cbe9004f6883e742c9a2e3ca53ed02e3e36f4cef62a98ee1e449174' + resp = await client.find_value(key=DhtClient.get_dht_key_id(bytes.fromhex(foundation_adnl_addr))) + print(resp) + + assert resp['@type'] == 'dht.valueFound' diff --git a/tests/test_liteclient.py b/tests/test_liteclient.py new file mode 100644 index 0000000..8ba10ff --- /dev/null +++ b/tests/test_liteclient.py @@ -0,0 +1,53 @@ +import logging + +import pytest + +import random +from pytoniq import LiteClient + + +@pytest.mark.asyncio +async def test_init(): + client = LiteClient.from_mainnet_config(random.randint(0, 13), trust_level=2) + await client.connect() + await client.close() + + client = LiteClient.from_testnet_config(random.randint(0, 5), trust_level=2) + await client.connect() + await client.close() + + client = LiteClient.from_mainnet_config(random.randint(0, 13), trust_level=1) + await client.connect() + await client.close() + + client = LiteClient.from_testnet_config(random.randint(0, 5), trust_level=1) + await client.connect() + await client.close() + + client = LiteClient.from_mainnet_config(random.randint(0, 13), trust_level=0) + await client.connect() + await client.close() + + client = LiteClient.from_testnet_config(random.randint(0, 5), trust_level=0) + await client.connect() + await client.close() + + +@pytest.mark.asyncio +async def test_methods(): + client = LiteClient.from_mainnet_config(random.randint(0, 13), trust_level=2) + await client.connect() + await client.get_masterchain_info() + await client.get_config_all() + await client.raw_get_block(client.last_mc_block) + await client.close() + + +@pytest.mark.asyncio +async def test_get_method(): + client = LiteClient.from_mainnet_config(random.randint(0, 13), trust_level=2) + await client.connect() + + result = await client.run_get_method(address='EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG', method='seqno', + stack=[]) + assert isinstance(result[0], int) diff --git a/tests/test_tcp.py b/tests/test_tcp.py deleted file mode 100644 index e58184a..0000000 --- a/tests/test_tcp.py +++ /dev/null @@ -1,66 +0,0 @@ -import asyncio -import time - -from tonpylib.liteclient.client_tcp import AdnlClientTcp - - -host = '65.21.141.231' -port = 17728 - -pub_key_b64 = 'BYSVpL7aPk0kU5CtlsIae/8mf2B/NrBi7DKmepcjX6Q=' - - -async def test(req_num: int): - client = AdnlClientTcp( - host, - port, - pub_key_b64 - ) - await client.connect() - tasks = [client.get_masterchain_info() for _ in range(req_num)] - - start = time.perf_counter() - res = await asyncio.gather(*tasks) - t = time.perf_counter() - start - - assert len(res) == req_num - - # its like .cancel(), will be implemented directly in client class - for i in asyncio.all_tasks(client.loop): - if i.get_name() in ('pinger', 'listener'): - i.cancel() - - return t - - -async def main(): - client = AdnlClientTcp( - host, - port, - pub_key_b64 - ) - await client.connect() - - await client.get_masterchain_info() - last = (await client.get_masterchain_info_ext())['last'] - resp = await client.get_time() - resp = await client.get_version() - resp = await client.get_state(last['workchain'], last['shard'], last['seqno'], last['root_hash'], last['file_hash']) - resp = await client.get_block_header(last['workchain'], last['shard'], last['seqno'], last['root_hash'], last['file_hash']) - - raw_state = await client.raw_get_account_state('EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG') - state = await client.get_account_state('EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG') - - print(raw_state) # {'last_trans_lt': 39064423000006, 'balance': {'grams': 445885900290, 'other': {'dict': None}}, 'state': {'type_': 'account_active', 'state_init': {'split_depth': None, 'special': None, 'code': 1 refs>, 'data': 0 refs>, 'library': None}}} - print(state) # - - stack = await client.run_get_method(address='EQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XggGG', method='seqno', stack=[]) - - print(stack) # [231] - - - await client.close() - - -if __name__ == '__main__': - asyncio.run(main(), debug=True) diff --git a/tests/transaction.py b/tests/transaction.py deleted file mode 100644 index 65f97c5..0000000 --- a/tests/transaction.py +++ /dev/null @@ -1,10 +0,0 @@ -from tonpylib.tlb.transaction import Transaction -from tonpylib.boc import Slice - - -tr = Transaction.deserialize(Slice.one_from_boc('te6cckECCwEAAooAA7V29bxnmG4GQwlh2d8AQzkmpM2S5Zfd2KpgQ2RawgvReCAAAjh2UOZ8EmfYY7twvuUOrougQECn1a8v+8Khkar3WYfmmj4ugLlgAAI4djJh/BZKaXZQADRrCOFoAQIDAgHgBAUAgnIfe3+B4gmbJuZACS2EVFKUCdVnxYs3SyeuvTRnv7es5YiTTeCreA/MjvG+1DQ46RRafusQvXI0LlFVIJXHRE52Ag8MR0YZk88EQAkKAeGIAN63jPMNwMhhLDs74AhnJNSZslyy+7sVTAhsi1hBei8EAcy6nD0IcxtS52vxMGvbYLIH4hd9INJNmejf+WhDqUVa057yz141PasAeV7ZM+xO535HGudTJ0bQ2BZ48xVGCBFNTRi7JTS86AAABzAAHAYBAd8HAYBiAH/qbo2oN2FxeOeipG2TrNbRcm8xpWmoYQQDLxr3yCavIAmJaAAAAAAAAAAAAAAAAAAAAAAAAGSms2kAAAAACAHJaADet4zzDcDIYSw7O+AIZyTUmbJcsvu7FUwIbItYQXovBQA/9TdG1BuwuLxz0VI2ydZraLk3mNK01DCCAZeNe+QTV5AExLQABhx2hAAARw7KHM+EyU0uygAAAAAyU1m0gAAAAEAIAEsAAABkgA3reM8w3AyGEsOzvgCGck1JmyXLL7uxVMCGyLWEF6LwUACdQZ2DE4gAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABvyYqsbEwcdlgAAAAAAAIAAAAAAAJFBDXxsFRWGo0cMh18c/9irixvvLHPoj5wMP3mMXp+UkCQImRjCre4')) -print(tr) -# {'account_addr': '6f5bc67986e06430961d9df00433926a4cd92e597ddd8aa6043645ac20bd1782', 'lt': 39064423000001, 'prev_trans_hash': b'&}\x86;\xb7\x0b\xeeP\xea\xe8\xba\x04\x04\n}Z\xf2\xff\xbc*\x19\x1a\xafu\x98~i\xa3\xe2\xe8\x0b\x96', 'prev_trans_lt': 39064391000001, 'now': 1688639333, 'outmsg_cnt': 1, 'orig_status': {'type_': 'active'}, 'end_status': {'type_': 'active'}, 'in_msg': {'info': {'src': None, 'dest': Address, 'import_fee': None}, 'init': None, 'body': 1 refs>}, 'out_msgs': [{'info': {'ihr_disabled': True, 'bounce': True, 'bounced': False, 'src': Address, 'dest': Address, 'value': {'grams': 20000000, 'other': {'dict': None}}, 'value_coins': 20000000, 'ihr_fee': None, 'fwd_fee': 932674, 'created_lt': 39064423000002, 'created_at': 1688639333}, 'init': None, 'body': 1 refs>}], 'total_fees': {'grams': 5785355, 'other': {'dict': None}}, 'state_update': {'old_hash': b"\x1f{\x7f\x81\xe2\t\x9b&\xe6@\t-\x84TR\x94\t\xd5g\xc5\x8b7K'\xae\xbd4g\xbf\xb7\xac\xe5", 'new_hash': b'\x88\x93M\xe0\xabx\x0f\xcc\x8e\xf1\xbe\xd448\xe9\x14Z~\xeb\x10\xbdr4.QU \x95\xc7DNv'}, 'description': {'type_': 'ordinary', 'credit_first': True, 'storage_ph': {'storage_fees_collected': 29, 'storage_fees_due': None, 'status_change': {'type_': 'unchanged'}}, 'credit_ph': None, 'compute_ph': {'type_': 'vm', 'success': True, 'msg_state_used': False, 'account_activated': False, 'gas_fees': 3308000, 'gas_used': 3308, 'gas_limit': None, 'gas_credit': 10000, 'mode': 0, 'exit_code': 0, 'exit_arg': None, 'vm_steps': 68, 'vm_init_state_hash': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'vm_final_state_hash': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'}, 'action': {'success': True, 'valid': True, 'no_funds': False, 'status_change': {'type_': 'unchanged'}, 'total_fwd_fees': 1399000, 'total_action_fees': 466326, 'result_code': 0, 'result_arg': None, 'tot_actions': 1, 'spec_actions': 0, 'skipped_actions': 0, 'msgs_created': 1, 'action_list_hash': b'"\x82\x1a\xf8\xd8*+\rF\x8e\x19\x0e\xbe9\xff\xb1W\x167\xdeX\xe7\xd1\x1f8\x18~\xf3\x18\xbd?)', 'tot_msg_size': {'cells': 2, 'bits': 1100}}, 'aborted': False, 'bounce': None, 'destroyed': False}} - -print(tr.description.compute_ph) -# {'type_': 'vm', 'success': True, 'msg_state_used': False, 'account_activated': False, 'gas_fees': 3308000, 'gas_used': 3308, 'gas_limit': None, 'gas_credit': 10000, 'mode': 0, 'exit_code': 0, 'exit_arg': None, 'vm_steps': 68, 'vm_init_state_hash': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'vm_final_state_hash': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'} diff --git a/tests/trust_levels.py b/tests/trust_levels.py deleted file mode 100644 index e833b0a..0000000 --- a/tests/trust_levels.py +++ /dev/null @@ -1,38 +0,0 @@ -import asyncio -import time - -from tonpylib.boc.address import Address -from tonpylib.boc.cell import Cell -from tonpylib.liteclient.client import LiteClient -from tonpylib.tl.block import BlockIdExt - - -host = '65.21.141.231' -port = 17728 - -pub_key_b64 = 'BYSVpL7aPk0kU5CtlsIae/8mf2B/NrBi7DKmepcjX6Q=' - - -async def main(): - - init_block = BlockIdExt.from_dict({ - "root_hash": "61192b72664cbcb06f8da9f0282c8bdf0e2871e18fb457e0c7cca6d502822bfe", - "seqno": 27747086, - "file_hash": "378db1ccf9c98c3944de1c4f5ce6fea4dcd7a26811b695f9019ccc3e7200e35b", - "workchain": -1, - "shard": -9223372036854775808 - }) - - client = LiteClient( - host, - port, - pub_key_b64, - trust_level=0, - init_key_block=init_block - ) - await client.connect() - print(await client.get_masterchain_info()) - - -if __name__ == '__main__': - asyncio.run(main(), debug=True) diff --git a/tests/udp/connection.py b/tests/udp/connection.py deleted file mode 100644 index d924e2a..0000000 --- a/tests/udp/connection.py +++ /dev/null @@ -1,35 +0,0 @@ -import asyncio -import logging - -from pytoniq.adnl.udp_client import AdnlUdpClient - - -# host = '65.21.7.173' -# port = 15813 -# pub_k = 'fZnkoIAxrTd4xeBgVpZFRm5SvVvSx7eN3Vbe8c83YMk=' - -host = "172.104.59.125" -port = 14432 -pub_k = "/YDNd+IwRUgL0mq21oC0L3RxrS8gTu0nciSPUrhqR78=" - - -async def main(): - client = AdnlUdpClient( - host=host, - port=port, - server_pub_key=pub_k, - ) - - await client.connect() - # print(await asyncio.gather(*[client.get_signed_address_list() for _ in range(50)])) - print(await client.get_signed_address_list()) - - resp = await client.send_query_message('dht.findValue', data={'key': 'b30af0538916421b46df4ce580bf3a29316831e0c3323a7f156df0236c5b2f75', 'k': 6}) - - print(resp) - - # print(await client.send_custom_message(b'hello')) -# logging.basicConfig(level=5) - -if __name__ == '__main__': - asyncio.run(main()) diff --git a/tests/udp/dht.py b/tests/udp/dht.py deleted file mode 100644 index 8cf3a19..0000000 --- a/tests/udp/dht.py +++ /dev/null @@ -1,46 +0,0 @@ -import asyncio -import logging -import time - -from pytoniq.adnl.udp_client import AdnlUdpClient -from pytoniq.adnl.dht import DhtClient - - -# host = '65.21.7.173' -# port = 15813 -# pub_k = 'fZnkoIAxrTd4xeBgVpZFRm5SvVvSx7eN3Vbe8c83YMk=' - -host = "172.104.59.125" -port = 14432 -pub_k = "/YDNd+IwRUgL0mq21oC0L3RxrS8gTu0nciSPUrhqR78=" - - -async def main(): - udp_client = AdnlUdpClient( - host=host, - port=port, - server_pub_key=pub_k, - timeout=2 - ) - - client = DhtClient([udp_client]) - - # print(DhtClient.get_dht_key_id(bytes.fromhex('516618cf6cbe9004f6883e742c9a2e3ca53ed02e3e36f4cef62a98ee1e449174')).hex()) - # print(client.get_dht_key_id_tl(bytes.fromhex('516618cf6cbe9004f6883e742c9a2e3ca53ed02e3e36f4cef62a98ee1e449174')).hex()) - - # await client.connect() - s = time.time() - print(await client.find_value(key=DhtClient.get_dht_key_id(bytes.fromhex('516618cf6cbe9004f6883e742c9a2e3ca53ed02e3e36f4cef62a98ee1e449174')))) - print(time.time() - s) - # print(await asyncio.gather(*[client.get_signed_address_list() for _ in range(50)])) - # print(await client.get_signed_address_list()) - - # resp = await udp_client.send_query_message('dht.findValue', data={'key': 'b30af0538916421b46df4ce580bf3a29316831e0c3323a7f156df0236c5b2f75', 'k': 6}) - # - # print(resp) - - # print(await client.send_custom_message(b'hello')) -# logging.basicConfig(level=5) - -if __name__ == '__main__': - asyncio.run(main()) diff --git a/tests/vm_stack.py b/tests/vm_stack.py deleted file mode 100644 index 88e7294..0000000 --- a/tests/vm_stack.py +++ /dev/null @@ -1,23 +0,0 @@ -from tonpylib.boc.cell import Cell -from tonpylib.boc.slice import Slice -from tonpylib.boc.builder import Builder -from tonpylib.tlb.vm_stack import VmStack, VmTuple - - -boc = b'\xb5\xee\x9cr\x02\x02\x01<\x00\x01\x00\x00\x13\xc3\x00\x00\x03\x0c\x00\x00\x01\x07\x00\x02\x00\x01\x00\x02\x00\x03\x00\x00\x02\x06\x07\x00\x05\x00\x04\x00\xf8\x02\x06\x07\x00\x02\x00\n\x00\x0b\x02\x00\x00\x05\x00\xf8\x02\x00\x00\x06\x00\x07\x02\x00\x00\x08\x00\xf8\x00\x12\x01\x00\x00\x00Vl\xa6\xc5\xf3\x01\t\x04\x00\x10\xb0 \x00\t\x00C\x80\x1eL\xc2\x04"\x83\x85\x13MR\x18c\xe7\xf9\x82\xbde\xbd\x01\xe9\x94\xfc\xc9\x1e\xc8\xea\xa5g\xa90[\xa80\x02\x06\x07\x00\x05\x00\x0c\x00\xf8\x02\x06\x07\x00\x02\x00\x12\x00\x13\x02\x00\x00\r\x00\xf8\x02\x00\x00\x0e\x00\x0f\x02\x00\x00\x10\x00\xf8\x00\x12\x01\x00\x00\x00E\xcdx\xf6\x00\x01\t\x04\x00\x10\xb0 \x00\x11\x00C\x80\x1c\xd1\x94\x94\xb8\x15\xa9E\xe6g\x9dG\xc3>\nB`\xd4\xfa\x1c[g\xb9\xc4\xbbN&\xd8\xca;\x07n\xd0\x02\x06\x07\x00\x05\x00\x14\x00\xf8\x02\x06\x07\x00\x02\x00\x1a\x00\x1b\x02\x00\x00\x15\x00\xf8\x02\x00\x00\x16\x00\x17\x02\x00\x00\x18\x00\xf8\x00\x12\x01\x00\x00\x001"E\n0\x01\t\x04\x00\x10\xb0 \x00\x19\x00C\x80\x1b\x04\x7f5\xf9\x12\x0e\\\x88r\xaex\xa0u\xfc\xba\x19\xd3\xefa\x83\xcc\n\\=C\xd1\xa9\xcd\xbb\xd9Rp\x02\x06\x07\x00\x05\x00\x1c\x00\xf8\x02\x06\x07\x00\x02\x00"\x00#\x02\x00\x00\x1d\x00\xf8\x02\x00\x00\x1e\x00\x1f\x02\x00\x00 \x00\xf8\x00\x12\x01\x00\x00\x00\rQb\xbc\x00\x01\t\x04\x00\x10\xb0 \x00!\x00C\x80\x1a\x16&\x97\xfb\xf2l\x8b\xa3\xdf\x9b)\xa8\xf2\t0w\xa2R\xbe\xc3\xbc\x06\xbc\xf4A4`\xfa-\x86\xfa\x90\x02\x06\x07\x00\x05\x00$\x00\xf8\x02\x06\x07\x00\x02\x00+\x00,\x02\x00\x00%\x00&\x02\x00\x00\'\x00\xf8\x00\x12\x01\x00\x00\x00\xe8\xd4\xa5\x10\x00\x02\x00\x00(\x00)\x01\t\x04\x00\x10\xb0 \x00*\x00\x12\x01\x00\x00\n\x06\xd1\xb0\xd0\x0c\x00C\x80\x1a\x0cj\xd7\xf8\xd2]]7\xb9q\x8f\xc9\x8a\x10\xae\xbfui\xdd\x91\xc3\xe7n\xadF\xdc3\x1b\x02E\x1b\xb0\x02\x06\x07\x00\x05\x00-\x00\xf8\x02\x06\x07\x00\x02\x003\x004\x02\x00\x00.\x00\xf8\x02\x00\x00/\x000\x02\x00\x001\x00\xf8\x00\x12\x01\x00\x00\x00\x00\x0b\xeb\xc2\x00\x01\t\x04\x00\x10\xb0 \x002\x00C\x80\x197?\xeb\xacN\xb1\xf8\x8dVPp\x0e\xd5\xc9}\xdb\x8f\xb3\xac\xcd\x08\xc6\\\xd4"\n \x01\xf7\xaf\xde0\x02\x06\x07\x00\x05\x005\x00\xf8\x02\x06\x07\x00\x02\x00;\x00<\x02\x00\x006\x00\xf8\x02\x00\x007\x00\xf8\x02\x00\x008\x009\x01\t\x04\x00\x10\xb0 \x00:\x00\x12\x01\x00\x00Z\xaf"V\x1a\x8d\x00C\x80\x18TR\x83\x89\xa5pQSh\xb6>\xc7\xaad\xa3P\x9d\x919\x9c\xd5\x00\xe1_>\xde\xc4\xcd\xa7\xa6\xa4\x10\x02\x06\x07\x00\x05\x00=\x00\xf8\x02\x06\x07\x00\x02\x00C\x00D\x02\x00\x00>\x00\xf8\x02\x00\x00?\x00@\x02\x00\x00A\x00\xf8\x00\x12\x01\x00\x00\x00\x0c\xc2U\xa4\x00\x01\t\x04\x00\x10\xb0 \x00B\x00C\x80\x18Q!3\xcfl7{\xdd,\xd89\x11Y~JEg\tvo~f\xa1\x05\xf7C\xb4\x9chP5P\x02\x06\x07\x00\x05\x00E\x00\xf8\x02\x06\x07\x00\x02\x00K\x00L\x02\x00\x00F\x00\xf8\x02\x00\x00G\x00\xf8\x02\x00\x00H\x00I\x01\t\x04\x00\x10\xb0 \x00J\x00\x12\x01\x00\x00 \x950v=0\x00C\x80\x180\x98S\xb8u\xd5I\x8f:\xbb\xdd\xb9zjm\x1c3k\x12\x1a\x14\xce\xe0-Us\x9f\xa6\xb0\x03\x9a0\x02\x06\x07\x00\x05\x00M\x00\xf8\x02\x06\x07\x00\x02\x00S\x00T\x02\x00\x00N\x00\xf8\x02\x00\x00O\x00P\x02\x00\x00Q\x00\xf8\x00\x12\x01\x00\x00\x00\x0cK \x10\x00\x01\t\x04\x00\x10\xb0 \x00R\x00C\x80\x17t\xef\x07m\x97\xb7\x8c\xff\x08!\x03\x8a\xafN\xb4\xbf\xa5\x0e:\x7f\xb3\xabI\xb0\x11\xdf\\w8Z\x0cp\x02\x06\x07\x00\x05\x00U\x00\xf8\x02\x06\x07\x00\x02\x00[\x00\\\x02\x00\x00V\x00\xf8\x02\x00\x00W\x00X\x02\x00\x00Y\x00\xf8\x00\x12\x01\x00\x00\x00\x19\x90\x97\n\x00\x01\t\x04\x00\x10\xb0 \x00Z\x00C\x80\x16\x97\xe9O>Pn\x16J\xb4\xa6\'\xa9n\xeb\x0b\x8ekAv}\xa5L\xd7\xb6\x96\xf5\xca\xecY\xa1\xa5\xf0\x02\x06\x07\x00\x05\x00]\x00\xf8\x02\x06\x07\x00\x02\x00c\x00d\x02\x00\x00^\x00\xf8\x02\x00\x00_\x00\xf8\x02\x00\x00`\x00a\x01\t\x04\x00\x10\xb0 \x00b\x00\x12\x01\x00\x00\t\xb9M\xdc\xd4=\x00C\x80\x13R\xc3\x1e\x81\xb8Y\xbb`a+X\x02G\x9f\xbbX\x91\xa72Zsv\x02"!\x7fh\x9a\xf1]\xcdP\x02\x06\x07\x00\x05\x00e\x00\xf8\x02\x06\x07\x00\x02\x00k\x00l\x02\x00\x00f\x00\xf8\x02\x00\x00g\x00\xf8\x02\x00\x00h\x00i\x01\t\x04\x00\x10\xb0 \x00j\x00\x12\x01\x00\x06E:hw\x06r\x00C\x80\x11\x8a\xbb\xeeMo\x95\xf0\xe5\t\xcb9 *MX\xf6J\xf6\xef\x17S\x7f\xbd7\x93\xd2\xc8\x936\xda?\x10\x02\x06\x07\x00\x05\x00m\x00\xf8\x02\x06\x07\x00\x02\x00s\x00t\x02\x00\x00n\x00\xf8\x02\x00\x00o\x00p\x02\x00\x00q\x00\xf8\x00\x12\x01\x00\x00\x00\r\xb0\xc0\xcc\x00\x01\t\x04\x00\x10\xb0 \x00r\x00C\x80\x101\xfb^\x9b\xff\x88\xaf4\x94\xee\x14\x11\x07\x1d{\xfd6u\xa1#\xae\xa6\x04\xdfF\xb0\x95\xc2g_\xd4\x10\x02\x06\x07\x00\x05\x00u\x00\xf8\x02\x06\x07\x00\x02\x00{\x00|\x02\x00\x00v\x00\xf8\x02\x00\x00w\x00\xf8\x02\x00\x00x\x00y\x01\t\x04\x00\x10\xb0 \x00z\x00\x12\x01\x00\x00\tZ\xb5\x08\x01\x03\x00C\x80\x10\x04\xb0N\xbb\xba\xbdb\xb6>\xc7"\x17\xc8\x01\x01}x@\x10\x17\xd7\x84\x00\x80}\x10\x17\xd7\x84\x02\x02\x01 \x01\x02\x01\x03\x02\x01 \x01 \x01!\x02\x01 \x01\x04\x01\x05\x02\x01 \x01\x12\x01\x13\x02\x01 \x01\x06\x01\x07\x02\x01 \x01\x0e\x01\x0f\x02\x01 \x01\x08\x01\t\x00q\xbf6\x93\xeb\xa3\xc076R\xa3#\xe4\x1e\xa9j\x00\xae[-\xd4\x8c\xc1\x85\x08}\xe5\xf9\xc8\x16 u&\\\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\xde\xa9|a\x80\x9a\xd6~&\xde@\x01\x02\x01b\x01\n\x01\x0b\x00q\xbe\xe0\xbf\x17U\x82.\xb9F*\xe8N\x95C\xbe`\xc1\x0e\xda\xa0\xa7\x9d\x86\xb9\x94\x85[k$\xc2\n\xf0h\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05c\xef&\xa3h\x01\x81!\x0e\x18\x87f\x82\x003\xdf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x0f\xba\xf9\xbb%\x9a\x00\x08\x02\x01 \x01\x0c\x01\r\x00o\xbd\xd4\xc0\xb2\xe8\x92\xcaw\xb0\xdd+V\xbbo\x9b\xa8k\x87\xfeA>\xf2-\x7f/0}\x10\x85\x89\xcc\x8f\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\'\xbd?\xc2\x01\xa8\x0ej,\xb7p\x00 \x00q\xbd\xcf\x0b&U\xf7pB\xe5\xf1\x92\xa2\xcc\x8a#\xc32\x1bq\ru\xc7\xf6\xca\xa2\xc3,\xb2{\x0e\xb6\x80\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00SC\xea#\xed\xb0$i\xd0\xf6\xc8\x00\x00 \x02\x02u\x01\x10\x01\x11\x00q\xbf9\xd6\x8a\x9b91\xe6r\xcc)>:\xe4?\xfe\xbb(p\x80\x14\xc4\xb9\xc3\x1e\xca\xf7\xc6-\xfc\xc7\xa1h\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02.\xecXiI\x87\x81\xc1\xa2fX@\x01\x00o\xbe\x1f\xe1\xfa\xf4\x08\xe8\x1e\xb9\xe5\x89 \xf9\xe7c\x00+TB\x1f5\x9fo\xa4\xde\x19*\xb1J-z\x7f\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x82\x97(@\n\xd1\\\x7f \x00\x10\x00q\xbe\'\xd4\xf07\x15-\xae\xaa\xfa\xd4x\x9fU;\xe5\xdf>9X\xcc\xdf=o\xf7w\xceC\x16 \x9f\xd6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&[\x93T-\xd8\x1bU\xad\xce\xdd\x88\x00\x10\x02\x01 \x01\x14\x01\x15\x02\x01 \x01\x1c\x01\x1d\x02\x01 \x01\x16\x01\x17\x02\x01j\x01\x1a\x01\x1b\x02\x01 \x01\x18\x01\x19\x00o\xbe\xc1d\xa3\x1e\xefR\x1e\xf9\xe6\xcd\xe2?\xae$\xa8\xe7H\xe7\x9eH\x14i\x0b\xac#\xa7I\xa5W\x94\xaa@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x054>\xa2>\xd8\x01B\xfav\xbc \x02\x00q\xbe\xa9K\x99\xa4\x9e\x90\xd4c\xfb|\xee\x816\x1b\x8c\x90\x91\xe3?&j\x03@\x03\xcakkF\x84\xfa\x810\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xe1\xec>6\x90\x03Q?Q\xf8\x0c\x00\x04\x00o\xbe\xbepy\xa9$h\x7f\xff{6\xc3\'\xae\xe5J_!lU\xe9\xc49(\xc7\xb3U\xa4\xc6N\xc8\xbd\xb0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x90\x05\x0bxP\x02\x87mc_\x00\x04\x00q\xbej\x82\xb84\xc5X\xa7\x9c\x87+M\x04\\\x89f\xd0\x86\x12 ?\x12{\xc5\xc9(\xe5\xfc\n\xd8I\xd2\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15WIx\xbel\x05\xdc\xea\x98\xfc\xda\x00\x08\x00o\xbe@p\x00\x18\xd20\x04\x1f@\xbd\xdcln\xf7?\xb5TH3\xd8\'(\x97\xa6\xfa#Ii3oU \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01+\x86\x01\xf5\xe0\x05\x12\x88\x87\x9c\x00\x08\x00o\xbf4\xbbcg\x1d\xa9b\xeb\x8f\x0cY\xd7\xa6\xb30Gr\x15\xe8\xbel7f\xbdH\xe9\xda\xff!)\x89\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\xe8)r\x84\x00\xa2h\xe8w\x80\x01\x02\x01X\x01\x1e\x01\x1f\x00q\xbe\x86\xcb\x01>*XS\xcf\xc6\x02;\xf9E+\xd0Z\xa2i\xfb\xb4\x18\x14\xb8\xfa\xf9\xc8\xb5wv\x15\xedp\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07e!\x15"v\x0b\xd6\x95\xd3\xfa\xb6\x00\x04\x00o\xbe\x8b>\n@\xaah\x91\x81\xf7\xf0\xd5S&c\x80x\xc3V\xf6\xd6l\xbb\x93\xeb^\xb2\x84\x82%\xd3b\xd0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\xd6J\xdc\t \x02\xba/3c\x00\x04\x02\x01 \x01"\x01#\x02\x01 \x01,\x01-\x02\x01 \x01$\x01%\x02\x01X\x01*\x01+\x02\x01 \x01&\x01\'\x00q\xbf*Xc\xd07\x0b7l\x0c%k\x00H\xf3\xf7k\x124\xe6KNn\xc0DD/\xed\x13^+\xb9\xa8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x9cf\xc9$\x95\x82l\xb3\xc93n\xc0\x01\x02\x01b\x01(\x01)\x00s\xbe\xe2\xae\xfb\x93[\xe5|9Br\xceH\n\x93V=\x92\xbd\xbb\xc5\xd4\xdf\xefM\xe4\xf4\xb2$\xcd\xb6\x8f\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x058\xcd\x92I+\x83 \x85\x1a\x0eq\xc7\x00\x02\x00q\xbe\t`\x9dwuz\xc5l}\x8eD.x\xf5\x08\xd1\x9b\xb6T\xffA2\xd5#`\x9d\x19b@R\xe7@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&6\xd8_\x9eX%\x1bM\xd2\xb8\x00\x00\x10\x00o\xbe#\xf6\xbd7\xff\x11^i)\xdc("\x0e:\xf7\xfal\xebBG]L\t\xbe\x8da+\x84\xce\xbf\xa8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\xa1f\x1a\x8b\xc0\n\x1ba\x81\x98\x00\x10\x00o\xbe\xe5\xfaS\xcf\x94\x1b\x85\x92\xad)\x89\xea[\xba\xc2\xe3\x9a\xd0]\x9fiS5\xed\xa5\xbdr\xbb\x16hix\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x1d\xdc\xde\xec\xf8\x01Fd%\xc2\x80\x02\x00o\xbe\xdd;\xc1\xdbe\xed\xe3?\xc2\x08@\xe2\xab\xd3\xad/\xe9C\x8e\x9f\xec\xea\xd2l\x04w\xd7\x1d\xce\x16\x83\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xa5\x1cr\xf0\x01C\x12\xc8\x04\x00\x02\x02\x01 \x01.\x01/\x02\x01 \x01:\x01;\x02\x01 \x010\x011\x02\x01 \x016\x017\x02\x01H\x012\x013\x00m\xbe\xcd\xcf\xfa\xeb\x13\xac~#U\x94\x1c\x03\xb5r_v\xe3\xec\xeb3B1\x975\x08\x82\x88\x00}\xeb\xf7\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01!\xc7\x9f\xf3`\x01\x02\xfa\xf0\x80\x02\x00q\xbep\x98S\xb8u\xd5I\x8f:\xbb\xdd\xb9zjm\x1c3k\x12\x1a\x14\xce\xe0-Us\x9f\xa6\xb0\x03\x9a \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\xba\x86D\x9e,@VX\xba\xc4\x00\x00\x08\x02\x02r\x014\x015\x00n\xbdR\x13<\xf6\xc3w\xbd\xd2\xcd\x83\x91\x15\x97\xe4\xa4Vp\x97f\xf7\xe6j\x10_t;I\xc6\x85\x03T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x1fBL\xe5\xd0\x00P\xcc%Z@\x00\x00p\xbdE(8\x9aW\x05\x156\x8bc\xecz\xa6J5\t\xd9\x13\x99\xcdP\x0e\x15\xf3\xed\xecL\xdazj@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\'{\x8f\x04(\xcb7\xdd\xd2`\xc7@\x00\x02\x02p\x018\x019\x00o\xbe\xc1\x1f\xcd~D\x83\x97"\x1c\xab\x9e(\x1d\x7f.\x86t\xfb\xd8`\xf3\x02\x97\x0fP\xf4jsn\xf6T\x98\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xc2\xd7z{H\x01LH\x91B\x8c\x02\x00{\xbd\xf1\xab_\xe3Iut\xde\xe5\xc6?&(B\xba\xfd\xd5\xa7vG\x0f\x9d\xba\xb5\x1bp\xccl\t\x14n\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xd0m\x08\xf50P6\x8d\x86\x80b\xf4jR\x88\x00\x00 \x00o\xbd\xd8\x9a_\xef\xc9\xb2.\x8f~l\xa6\xa3\xc8$\xc1\xde\x89J\xfb\x0e\xf0\x1a\xf3\xd1\x04\xd1\x83\xe8\xb6\x1b\xea\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07tD`\xe7\x80\x145E\x8a\xf0\x00 \x00o\xbf\x1a2\x92\x97\x02\xb5(\xbc\xcc\xf3\xa8\xf8g\xc1HL\x1a\x9fC\x8bl\xf78\x97i\xc4\xdb\x19G`\xed\xd8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x83$\xf6\xb7$\x00\xa8\xb9\xaf\x1e\xc0\x01\x00o\xbf\t\x98@\x84Pp\xa2i\xaaC\x0c|\xff0W\xac\xb7\xa0=2\x9f\x99#\xd9\x1dT\xac\xf5&\x0bu\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xcb\x0c\xe5\xd0\x00\xaa\xcd\x94\xd8\xbea' -cell = Cell.one_from_boc(boc) -slice = Slice.one_from_boc(boc) -deser = VmStack.deserialize(slice) -ser = VmStack.serialize(deser) -deser2 = VmStack.deserialize(Slice.one_from_boc(ser.to_boc())) -print(deser) -print(deser2) -# [ 0 refs>, 0, 371190056435, 0, 0] >, 0 refs>, 0, 299800000000, 0, 0] >, 0 refs>, 0, 211028347440, 0, 0] >, 0 refs>, 0, 57200000000, 0, 0] >, 0 refs>, 11024404107276, 0, 1000000000000, 0] >, 0 refs>, 0, 200000000, 0, 0] >, 0 refs>, 99708241844877, 0, 0, 0] >, 0 refs>, 0, 54800000000, 0, 0] >, 0 refs>, 35825135271216, 0, 0, 0] >, 0 refs>, 0, 52800000000, 0, 0] >, 0 refs>, 0, 109800000000, 0, 0] >, 0 refs>, 10691479917629, 0, 0, 0] >, 0 refs>, 1764967023314546, 0, 0, 0] >, 0 refs>, 0, 58800000000, 0, 0] >, 0 refs>, 10285188907267, 0, 0, 0] >, 0 refs>, 0, 499800000000, 0, 0] >, 0 refs>, 13310506560185, 0, 0, 0] >, 0 refs>, 0, 82800000000, 0, 0] >, 0 refs>, 0, 79600000000, 0, 0] >, 0 refs>, 3226934553962, 0, 0, 0] >, 0 refs>, 0, 51168080000, 0, 0] >, 0 refs>, 0, 63800000000, 0, 0] >, 0 refs>, 0, 178664800000000, 0, 0] >, 0 refs>, 33468978521014, 0, 0, 0] >, 0 refs>, 7574850317514, 0, 0, 0] >, 0 refs>, 0, 449600000000, 0, 0] >, 0 refs>, 2696097964290, 0, 0, 0] >, 0 refs>, 0, 4965928148378, 0, 0] >, 0 refs>, 5018849987275, 0, 0, 0] >, 0 refs>, 8041463960, 0, 0, 0] >, 0 refs>, 8647864062669, 0, 0, 0] >, None] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] -# [ 0 refs>, 0, 371190056435, 0, 0] >, 0 refs>, 0, 299800000000, 0, 0] >, 0 refs>, 0, 211028347440, 0, 0] >, 0 refs>, 0, 57200000000, 0, 0] >, 0 refs>, 11024404107276, 0, 1000000000000, 0] >, 0 refs>, 0, 200000000, 0, 0] >, 0 refs>, 99708241844877, 0, 0, 0] >, 0 refs>, 0, 54800000000, 0, 0] >, 0 refs>, 35825135271216, 0, 0, 0] >, 0 refs>, 0, 52800000000, 0, 0] >, 0 refs>, 0, 109800000000, 0, 0] >, 0 refs>, 10691479917629, 0, 0, 0] >, 0 refs>, 1764967023314546, 0, 0, 0] >, 0 refs>, 0, 58800000000, 0, 0] >, 0 refs>, 10285188907267, 0, 0, 0] >, 0 refs>, 0, 499800000000, 0, 0] >, 0 refs>, 13310506560185, 0, 0, 0] >, 0 refs>, 0, 82800000000, 0, 0] >, 0 refs>, 0, 79600000000, 0, 0] >, 0 refs>, 3226934553962, 0, 0, 0] >, 0 refs>, 0, 51168080000, 0, 0] >, 0 refs>, 0, 63800000000, 0, 0] >, 0 refs>, 0, 178664800000000, 0, 0] >, 0 refs>, 33468978521014, 0, 0, 0] >, 0 refs>, 7574850317514, 0, 0, 0] >, 0 refs>, 0, 449600000000, 0, 0] >, 0 refs>, 2696097964290, 0, 0, 0] >, 0 refs>, 0, 4965928148378, 0, 0] >, 0 refs>, 5018849987275, 0, 0, 0] >, 0 refs>, 8041463960, 0, 0, 0] >, 0 refs>, 8647864062669, 0, 0, 0] >, None] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] >] - -tuple = VmTuple([1, 2, 3, Cell.empty()]) -print(tuple) -# 0 refs>] > -stack = VmStack.serialize([tuple, 4, 5, 6, Builder().store_uint(15, 13)]) -print(VmStack.deserialize(stack.begin_parse())) -# [ 0 refs>] >, 4, 5, 6, 0 refs>] diff --git a/update.sh b/update.sh deleted file mode 100644 index a489a50..0000000 --- a/update.sh +++ /dev/null @@ -1,3 +0,0 @@ -rm -rf build/ dist/ -python setup.py sdist bdist_wheel -python -m twine upload dist/*