From ec435d60947eddf65af0d4360cb07df43120f0e2 Mon Sep 17 00:00:00 2001 From: Florian Pellissier <111426680+flopell@users.noreply.github.com> Date: Thu, 25 Jul 2024 15:02:57 +0200 Subject: [PATCH] refactor: Several testing SDK improvements such as: fix db reset, use latest wheel, print trace in case of failure and add logic to pull stateless contracts --- testing/Dockerfile | 2 +- testing/runner.py | 4 +- testing/tycho-client/setup.py | 2 +- testing/tycho-client/tycho_client/decoders.py | 15 ++++++- testing/tycho-client/tycho_client/utils.py | 40 +++++++++++++++++++ testing/tycho.py | 2 +- 6 files changed, 59 insertions(+), 6 deletions(-) diff --git a/testing/Dockerfile b/testing/Dockerfile index 700cb0a..e71f4c1 100644 --- a/testing/Dockerfile +++ b/testing/Dockerfile @@ -7,7 +7,7 @@ WORKDIR /app # Add current directory code to /app in container ADD . /app/testing -RUN chmod +x /app/testing/tycho-indexer +RUN chmod +x /app/testing/tycho-indexer-linux-x64 # Create a new conda environment and install pip RUN conda create -n myenv pip python=3.9 diff --git a/testing/runner.py b/testing/runner.py index 6d46de5..cf684ff 100644 --- a/testing/runner.py +++ b/testing/runner.py @@ -6,6 +6,7 @@ from collections import defaultdict from datetime import datetime from decimal import Decimal from pathlib import Path +import traceback import yaml from pydantic import BaseModel @@ -164,7 +165,8 @@ class TestRunner: return TestResult.Passed() except Exception as e: - return TestResult.Failed(str(e)) + error_message = f"An error occurred: {str(e)}\n" + traceback.format_exc() + return TestResult.Failed(error_message) def simulate_get_amount_out( self, diff --git a/testing/tycho-client/setup.py b/testing/tycho-client/setup.py index 0053b58..a47dfe8 100644 --- a/testing/tycho-client/setup.py +++ b/testing/tycho-client/setup.py @@ -22,7 +22,7 @@ def get_wheel_file(): return str( path / "wheels" - / f"protosim_py-0.4.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + / f"protosim_py-0.4.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" ) else: raise RuntimeError("Unsupported platform or architecture") diff --git a/testing/tycho-client/tycho_client/decoders.py b/testing/tycho-client/tycho_client/decoders.py index 540f6d5..52b6e01 100644 --- a/testing/tycho-client/tycho_client/decoders.py +++ b/testing/tycho-client/tycho_client/decoders.py @@ -73,12 +73,23 @@ class ThirdPartyPoolTychoDecoder: pool_id = attributes.get("pool_id") or component["id"] balance_owner = attributes.get("balance_owner") stateless_contracts = {} + static_attributes = snap["component"]["static_attributes"] + + index = 0 + while f"stateless_contract_addr_{index}" in static_attributes: + encoded_address = static_attributes[f"stateless_contract_addr_{index}"] + address = bytes.fromhex(encoded_address[2:] if encoded_address.startswith('0x') else encoded_address).decode('utf-8') + + code = static_attributes.get(f"stateless_contract_code_{index}") or get_code_for_address(address) + stateless_contracts[address] = code + index += 1 + index = 0 while f"stateless_contract_addr_{index}" in attributes: address = attributes[f"stateless_contract_addr_{index}"] - code = attributes[f"stateless_contract_code_{index}"] + code = attributes.get(f"stateless_contract_code_{index}") or get_code_for_address(address) stateless_contracts[address] = code - index += 1 + index += 1 return { "balance_owner": balance_owner, "pool_id": pool_id, diff --git a/testing/tycho-client/tycho_client/utils.py b/testing/tycho-client/tycho_client/utils.py index f743728..325d716 100644 --- a/testing/tycho-client/tycho_client/utils.py +++ b/testing/tycho-client/tycho_client/utils.py @@ -11,6 +11,7 @@ import eth_abi from eth_typing import HexStr from hexbytes import HexBytes from protosim_py import SimulationEngine, AccountInfo +import requests from web3 import Web3 from .constants import EXTERNAL_ACCOUNT, MAX_BALANCE, ASSETS_FOLDER @@ -299,3 +300,42 @@ def maybe_coerce_error( repr(pool_state), ) return err + + +def exec_rpc_method(url, method, params, timeout=240) -> dict: + payload = {"jsonrpc": "2.0", "method": method, "params": params, "id": 1} + headers = {"Content-Type": "application/json"} + + r = requests.post(url, data=json.dumps(payload), headers=headers, timeout=timeout) + + if r.status_code >= 400: + raise RuntimeError( + "RPC failed: status_code not ok. (method {}: {})".format( + method, r.status_code + ) + ) + data = r.json() + + if "result" in data: + return data["result"] + elif "error" in data: + raise RuntimeError( + "RPC failed with Error {} - {}".format(data["error"], method) + ) + + +def get_code_for_address(address: str, connection_string: str = None): + if connection_string is None: + connection_string = os.getenv("RPC_URL") + if connection_string is None: + raise EnvironmentError("RPC_URL environment variable is not set") + + method = "eth_getCode" + params = [address, "latest"] + + try: + code = exec_rpc_method(connection_string, method, params) + return bytes.fromhex(code[2:]) + except RuntimeError as e: + print(f"Error fetching code for address {address}: {e}") + return None \ No newline at end of file diff --git a/testing/tycho.py b/testing/tycho.py index d601f7e..fc917d0 100644 --- a/testing/tycho.py +++ b/testing/tycho.py @@ -183,7 +183,7 @@ class TychoRunner: cursor = conn.cursor() cursor.execute( - sql.SQL("DROP DATABASE IF EXISTS {}").format( + sql.SQL("DROP DATABASE IF EXISTS {} WITH (FORCE)").format( sql.Identifier("tycho_indexer_0") ) )