From 4fff2e67a3b39190d3b68456a9788f266e1461a3 Mon Sep 17 00:00:00 2001 From: angrybayblade Date: Tue, 5 Dec 2023 10:15:38 +0530 Subject: [PATCH 1/4] fix: enable gas estimation --- mech_client/cli.py | 23 +++++++++++++- mech_client/interact.py | 70 ++++++++++++++++++++++++++++++++++------- 2 files changed, 80 insertions(+), 13 deletions(-) diff --git a/mech_client/cli.py b/mech_client/cli.py index 89aa216..5b5df8e 100644 --- a/mech_client/cli.py +++ b/mech_client/cli.py @@ -57,12 +57,30 @@ def cli() -> None: ), help="Data verification method (on-chain/off-chain)", ) -def interact( +@click.option( + "--retries", + type=int, + help="Number of retries for sending a transaction", +) +@click.option( + "--timeout", + type=float, + help="Timeout to wait for the transaction", +) +@click.option( + "--sleep", + type=float, + help="Amount of sleep before retrying the transaction", +) +def interact( # pylint: disable=too-many-arguments prompt: str, agent_id: int, tool: Optional[str], key: Optional[str], confirm: Optional[str] = None, + retries: Optional[int] = None, + timeout: Optional[float] = None, + sleep: Optional[float] = None, ) -> None: """Interact with a mech specifying a prompt and tool.""" try: @@ -76,6 +94,9 @@ def interact( if confirm is not None else ConfirmationType.WAIT_FOR_BOTH ), + retries=retries, + timeout=timeout, + sleep=sleep, ) except (ValueError, FileNotFoundError) as e: raise click.ClickException(str(e)) from e diff --git a/mech_client/interact.py b/mech_client/interact.py index 7814942..63fc78d 100644 --- a/mech_client/interact.py +++ b/mech_client/interact.py @@ -28,7 +28,9 @@ import asyncio import json import os +import time import warnings +from datetime import datetime from enum import Enum from pathlib import Path from typing import Any, List, Optional, Tuple @@ -63,6 +65,7 @@ "chain_id": 100, "poa_chain": False, "default_gas_price_strategy": "eip1559", + "is_gas_estimation_enabled": True, } PRIVATE_KEY_FILE_PATH = "ethereum_private_key.txt" @@ -72,6 +75,10 @@ ) GNOSISSCAN_API_URL = "https://api.gnosisscan.io/api?module=contract&action=getabi&address={contract_address}" +MAX_RETRIES = 3 +WAIT_SLEEP = 3.0 +TIMEOUT = 60.0 + # Ignore a specific warning message warnings.filterwarnings("ignore", "The log with transaction hash.*") @@ -179,13 +186,16 @@ def fetch_tools(agent_id: int, ledger_api: EthereumApi) -> List[str]: return response["tools"] -def send_request( # pylint: disable=too-many-arguments +def send_request( # pylint: disable=too-many-arguments,too-many-locals crypto: EthereumCrypto, ledger_api: EthereumApi, mech_contract: Web3Contract, prompt: str, tool: str, price: int = 10_000_000_000_000_000, + retries: Optional[int] = None, + timeout: Optional[float] = None, + sleep: Optional[float] = None, ) -> None: """ Sends a request to the mech. @@ -202,22 +212,46 @@ def send_request( # pylint: disable=too-many-arguments :type tool: str :param price: The price for the request (default: 10_000_000_000_000_000). :type price: int + :param retries: Number of retries for sending a transaction + :type retries: int + :param timeout: Timeout to wait for the transaction + :type timeout: float + :param sleep: Amount of sleep before retrying the transaction + :type sleep: float """ v1_file_hash_hex_truncated, v1_file_hash_hex = push_metadata_to_ipfs(prompt, tool) print(f"Prompt uploaded: https://gateway.autonolas.tech/ipfs/{v1_file_hash_hex}") method_name = "request" methord_args = {"data": v1_file_hash_hex_truncated} tx_args = {"sender_address": crypto.address, "value": price} - raw_transaction = ledger_api.build_transaction( - contract_instance=mech_contract, - method_name=method_name, - method_args=methord_args, - tx_args=tx_args, - ) - raw_transaction["gas"] = 50_000 - signed_transaction = crypto.sign_transaction(raw_transaction) - transaction_digest = ledger_api.send_signed_transaction(signed_transaction) - print(f"Transaction sent: https://gnosisscan.io/tx/{transaction_digest}") + + tries = 0 + retries = retries or MAX_RETRIES + timeout = timeout or TIMEOUT + sleep = sleep or WAIT_SLEEP + deadline = datetime.now().timestamp() + timeout + + while tries < retries and datetime.now().timestamp() < deadline: + try: + raw_transaction = ledger_api.build_transaction( + contract_instance=mech_contract, + method_name=method_name, + method_args=methord_args, + tx_args=tx_args, + raise_on_try=True, + ) + signed_transaction = crypto.sign_transaction(raw_transaction) + transaction_digest = ledger_api.send_signed_transaction( + signed_transaction, + raise_on_try=True, + ) + print(f"Transaction sent: https://gnosisscan.io/tx/{transaction_digest}") + return + except Exception as e: # pylint: disable=broad-except + print( + f"Error occured while sending the transaction: {e}; Retrying in {sleep}" + ) + time.sleep(sleep) def wait_for_data_url( @@ -269,12 +303,15 @@ async def _wait_for_tasks() -> Any: # type: ignore return result -def interact( +def interact( # pylint: disable=too-many-arguments,too-many-locals prompt: str, agent_id: int, tool: Optional[str] = None, private_key_path: Optional[str] = None, confirmation_type: ConfirmationType = ConfirmationType.WAIT_FOR_BOTH, + retries: Optional[int] = None, + timeout: Optional[float] = None, + sleep: Optional[float] = None, ) -> Any: """ Interact with agent mech contract. @@ -290,6 +327,12 @@ def interact( :param confirmation_type: The confirmation type for the interaction (default: ConfirmationType.WAIT_FOR_BOTH). :type confirmation_type: ConfirmationType :return: The data received from on-chain/off-chain. + :param retries: Number of retries for sending a transaction + :type retries: int + :param timeout: Timeout to wait for the transaction + :type timeout: float + :param sleep: Amount of sleep before retrying the transaction + :type sleep: float :rtype: Any """ contract_address = query_agent_address(agent_id=agent_id) @@ -317,6 +360,9 @@ def interact( mech_contract=mech_contract, prompt=prompt, tool=tool, + retries=retries, + timeout=timeout, + sleep=sleep, ) request_id = watch_for_request_id( wss=wss, mech_contract=mech_contract, ledger_api=ledger_api From a392d07d36930a25b2b7211bb374ffb8685c4751 Mon Sep 17 00:00:00 2001 From: angrybayblade Date: Tue, 5 Dec 2023 10:16:18 +0530 Subject: [PATCH 2/4] fix: pin tomte --- .github/workflows/workflow.yml | 2 +- pyproject.toml | 2 +- tox.ini | 27 ++++++++++++++++++--------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index 9fe0a11..8a3d125 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -27,7 +27,7 @@ jobs: sudo apt-get update --fix-missing sudo apt-get autoremove sudo apt-get autoclean - pip install tomte[tox]==0.2.14 + pip install tomte[tox]==0.2.15 pip install --user --upgrade setuptools sudo npm install -g markdown-spellcheck - name: Security checks diff --git a/pyproject.toml b/pyproject.toml index 7fec58f..6670998 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,7 +39,7 @@ mechx = "mech_client.cli:cli" [tool.poetry.group.dev.dependencies] open-autonomy = "==0.13.8" -tomte = {extras = ["tox"], version = "==0.2.14"} +tomte = {extras = ["tox"], version = "==0.2.15"} [build-system] requires = ["poetry-core"] diff --git a/tox.ini b/tox.ini index cf9c91b..be8dab2 100644 --- a/tox.ini +++ b/tox.ini @@ -11,39 +11,45 @@ deps = [testenv:bandit] skipsdist = True skip_install = True -deps = tomte[bandit]==0.2.14 +deps = + tomte[bandit]==0.2.15 commands = bandit -s B101 -r mech_client/ [testenv:black] skipsdist = True skip_install = True -deps = tomte[black]==0.2.14 +deps = + tomte[black]==0.2.15 commands = black mech_client/ [testenv:black-check] skipsdist = True skip_install = True -deps = tomte[black]==0.2.14 +deps = + tomte[black]==0.2.15 commands = black --check mech_client/ [testenv:isort] skipsdist = True skip_install = True -deps = tomte[isort]==0.2.14 +deps = + tomte[isort]==0.2.15 commands = isort mech_client/ --gitignore [testenv:isort-check] skipsdist = True skip_install = True -deps = tomte[isort]==0.2.14 +deps = + tomte[isort]==0.2.15 commands = isort --check-only --gitignore mech_client/ [testenv:flake8] skipsdist = True skip_install = True -deps = tomte[flake8]==0.2.14 +deps = + tomte[flake8]==0.2.15 commands = flake8 mech_client/ @@ -65,13 +71,15 @@ commands = pylint --ignore-patterns=".*_pb2.py" --ignore-paths="^packages/valory [testenv:safety] skipsdist = True skip_install = True -deps = tomte[safety]==0.2.14 +deps = + tomte[safety]==0.2.15 commands = safety check -i 37524 -i 38038 -i 37776 -i 38039 -i 39621 -i 40291 -i 39706 -i 41002 -i 51358 -i 51499 [testenv:darglint] skipsdist = True skip_install = True -deps = tomte[darglint]==0.2.14 +deps = + tomte[darglint]==0.2.15 commands = darglint mech_client [testenv:vulture] @@ -86,7 +94,8 @@ commands = whitelist_externals = mdspell skipsdist = True usedevelop = True -deps = tomte[cli]==0.2.14 +deps = + tomte[cli]==0.2.15 commands = tomte check-spelling [flake8] From 7c937684c79ca4d9ba68e0a402149c104c0b1204 Mon Sep 17 00:00:00 2001 From: angrybayblade Date: Tue, 5 Dec 2023 10:16:54 +0530 Subject: [PATCH 3/4] feat: bump v0.2.9 --- mech_client/__init__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mech_client/__init__.py b/mech_client/__init__.py index 915221d..60f405d 100644 --- a/mech_client/__init__.py +++ b/mech_client/__init__.py @@ -1,3 +1,3 @@ """Mech client.""" -__version__ = "0.2.8" +__version__ = "0.2.9" diff --git a/pyproject.toml b/pyproject.toml index 6670998..d6dfd24 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mech-client" -version = "0.2.8" +version = "0.2.9" description = "Basic client to interact with a mech" authors = ["David Minarsch "] readme = "README.md" From 0ccc1776e65cd14b939534ed46a633378eaf4d34 Mon Sep 17 00:00:00 2001 From: angrybayblade Date: Tue, 5 Dec 2023 10:20:12 +0530 Subject: [PATCH 4/4] fix: trial increament --- mech_client/interact.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mech_client/interact.py b/mech_client/interact.py index 63fc78d..33ad0f9 100644 --- a/mech_client/interact.py +++ b/mech_client/interact.py @@ -232,6 +232,7 @@ def send_request( # pylint: disable=too-many-arguments,too-many-locals deadline = datetime.now().timestamp() + timeout while tries < retries and datetime.now().timestamp() < deadline: + tries += 1 try: raw_transaction = ledger_api.build_transaction( contract_instance=mech_contract,