Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added limit as a configurable variable to DeployablePredictionAgent #532

Merged
merged 8 commits into from
Oct 29, 2024
1,147 changes: 595 additions & 552 deletions poetry.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions prediction_market_agent_tooling/config.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import typing as t

from gnosis.eth import EthereumClient
from gnosis.safe import Safe
from pydantic.types import SecretStr
from pydantic.v1.types import SecretStr as SecretStrV1
from pydantic_settings import BaseSettings, SettingsConfigDict
from safe_eth.eth import EthereumClient
from safe_eth.safe.safe import SafeV141

from prediction_market_agent_tooling.gtypes import (
ChecksumAddress,
Expand Down Expand Up @@ -200,6 +200,6 @@ def check_if_is_safe_owner(self, ethereum_client: EthereumClient) -> bool:
if not self.SAFE_ADDRESS:
raise ValueError("Cannot check ownership if safe_address is not defined.")

s = Safe(self.SAFE_ADDRESS, ethereum_client) # type: ignore[abstract]
s = SafeV141(self.SAFE_ADDRESS, ethereum_client)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for using SafeV141 instead of just Safe? Is it safe ( 😁 )? Safe in a sense that what if the agent is using different version of it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mypy complains because Safe is an abstract class.
SafeV141 is the latest version , and the one we create for all our agents (

)

public_key_from_signer = private_key_to_public_key(self.bet_from_private_key)
return s.retrieve_is_owner(public_key_from_signer)
4 changes: 2 additions & 2 deletions prediction_market_agent_tooling/deploy/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ def get_gcloud_fname(self, market_type: MarketType) -> str:

class DeployablePredictionAgent(DeployableAgent):
bet_on_n_markets_per_run: int = 1
n_markets_to_fetch: int = MAX_AVAILABLE_MARKETS
min_balance_to_keep_in_native_currency: xDai | None = xdai_type(0.1)
allow_invalid_questions: bool = False
same_market_trade_interval: TradeInterval = FixedInterval(timedelta(hours=24))
Expand Down Expand Up @@ -376,14 +377,13 @@ def answer_binary_market(self, market: AgentMarket) -> ProbabilisticAnswer | Non
def get_markets(
self,
market_type: MarketType,
limit: int = MAX_AVAILABLE_MARKETS,
sort_by: SortBy = SortBy.CLOSING_SOONEST,
filter_by: FilterBy = FilterBy.OPEN,
) -> t.Sequence[AgentMarket]:
cls = market_type.market_class
# Fetch the soonest closing markets to choose from
available_markets = cls.get_binary_markets(
limit=limit, sort_by=sort_by, filter_by=filter_by
limit=self.n_markets_to_fetch, sort_by=sort_by, filter_by=filter_by
)
return available_markets

Expand Down
12 changes: 6 additions & 6 deletions prediction_market_agent_tooling/tools/safe.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
from eth_account.signers.local import LocalAccount
from eth_typing import ChecksumAddress
from gnosis.eth import EthereumClient
from gnosis.eth.constants import NULL_ADDRESS
from gnosis.eth.contracts import get_safe_V1_4_1_contract
from gnosis.safe.proxy_factory import ProxyFactoryV141
from gnosis.safe.safe import Safe
from safe_cli.safe_addresses import (
get_default_fallback_handler_address,
get_proxy_factory_address,
get_safe_contract_address,
get_safe_l2_contract_address,
)
from safe_eth.eth import EthereumClient
from safe_eth.eth.constants import NULL_ADDRESS
from safe_eth.eth.contracts import get_safe_V1_4_1_contract
from safe_eth.safe.proxy_factory import ProxyFactoryV141
from safe_eth.safe.safe import SafeV141
from web3.types import Wei

from prediction_market_agent_tooling.loggers import logger
Expand Down Expand Up @@ -87,7 +87,7 @@ def create_safe(

# We ignore mypy below because using the proper class SafeV141 yields an error and mypy
# doesn't understand that there is a hacky factory method (__new__) on this abstract class.
safe_version = Safe(safe_contract_address, ethereum_client).retrieve_version() # type: ignore
safe_version = SafeV141(safe_contract_address, ethereum_client).retrieve_version()
gabrielfior marked this conversation as resolved.
Show resolved Hide resolved
logger.info(
f"Safe-master-copy={safe_contract_address} version={safe_version}\n"
f"Fallback-handler={fallback_handler}\n"
Expand Down
8 changes: 4 additions & 4 deletions prediction_market_agent_tooling/tools/web3_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import tenacity
from eth_account import Account
from eth_typing import URI
from gnosis.eth import EthereumClient
from gnosis.safe.safe import Safe
from pydantic.types import SecretStr
from safe_eth.eth import EthereumClient
from safe_eth.safe.safe import SafeV141
from web3 import Web3
from web3.constants import HASH_ZERO
from web3.types import AccessList, AccessListEntry, Nonce, TxParams, TxReceipt, Wei
Expand Down Expand Up @@ -200,7 +200,7 @@ def send_function_on_contract_tx(
# Don't retry on `reverted` messages, as they would always fail again.
retry=tenacity.retry_if_exception_message(match=NOT_REVERTED_ICASE_REGEX_PATTERN),
wait=tenacity.wait_chain(*[tenacity.wait_fixed(n) for n in range(1, 10)]),
stop=tenacity.stop_after_attempt(9),
stop=tenacity.stop_after_attempt(5),
after=lambda x: logger.debug(
f"send_function_on_contract_tx_using_safe failed, {x.attempt_number=}."
),
Expand All @@ -219,7 +219,7 @@ def send_function_on_contract_tx_using_safe(
if not web3.provider.endpoint_uri: # type: ignore
raise EnvironmentError("RPC_URL not available in web3 object.")
ethereum_client = EthereumClient(ethereum_node_url=URI(web3.provider.endpoint_uri)) # type: ignore
s = Safe(safe_address, ethereum_client) # type: ignore
s = SafeV141(safe_address, ethereum_client)
safe_master_copy_address = s.retrieve_master_copy_address()
eoa_public_key = private_key_to_public_key(from_private_key)
# See https://ethereum.stackexchange.com/questions/123750/how-to-implement-eip-2930-access-list for details,
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "prediction-market-agent-tooling"
version = "0.55.0"
version = "0.55.1"
description = "Tools to benchmark, deploy and monitor prediction market agents."
authors = ["Gnosis"]
readme = "README.md"
Expand Down Expand Up @@ -36,7 +36,7 @@ langchain-openai = { version = "^0.1.0", optional = true}
google-api-python-client = { version = "2.95.0", optional = true}
subgrounds = "^1.9.1"
loguru = "^0.7.2"
safe-eth-py = "^6.0.0b14"
safe-eth-py = "^6.0.0b41"
eth-account = ">=0.8.0,<0.12.0"
prompt-toolkit = "^3.0.43"
safe-cli = "^1.0.0"
Expand Down
2 changes: 1 addition & 1 deletion scripts/create_safe_for_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import typer
from eth_account import Account
from eth_typing import URI
from gnosis.eth import EthereumClient
from pydantic import SecretStr
from safe_eth.eth import EthereumClient
from web3 import Web3

from prediction_market_agent_tooling.gtypes import PrivateKey, xDai
Expand Down
2 changes: 1 addition & 1 deletion tests_integration_with_local_chain/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from dotenv import load_dotenv
from eth_account import Account
from eth_account.signers.local import LocalAccount
from gnosis.eth import EthereumClient
from safe_eth.eth import EthereumClient
from web3 import Web3

from prediction_market_agent_tooling.config import APIKeys
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@


def is_contract(web3: Web3, contract_address: ChecksumAddress) -> bool:
# From gnosis.eth.EthereumClient
return bool(web3.eth.get_code(contract_address))


Expand Down
8 changes: 4 additions & 4 deletions tests_integration_with_local_chain/safe/conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest
from eth_account import Account
from gnosis.eth import EthereumClient
from gnosis.safe import Safe
from safe_eth.eth import EthereumClient
from safe_eth.safe.safe import SafeV141
from web3 import Web3

from prediction_market_agent_tooling.config import APIKeys
Expand All @@ -14,7 +14,7 @@ def print_current_block(web3: Web3) -> None:


@pytest.fixture(scope="module")
def test_safe(local_web3: Web3, test_keys: APIKeys) -> Safe:
def test_safe(local_web3: Web3, test_keys: APIKeys) -> SafeV141:
web3 = local_web3
print_current_block(web3)
# local_ethereum_client = EthereumClient(URI(f"http://localhost:{port}"))
Expand All @@ -32,5 +32,5 @@ def test_safe(local_web3: Web3, test_keys: APIKeys) -> Safe:
threshold=1,
)
assert safe_address is not None, "Safe needs to be deployed."
deployed_safe = Safe(safe_address, local_ethereum_client) # type: ignore[abstract]
deployed_safe = SafeV141(safe_address, local_ethereum_client)
return deployed_safe
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from ape_test import TestAccount
from eth_account import Account
from gnosis.safe import Safe
from safe_eth.safe import Safe
from web3 import Web3

from prediction_market_agent_tooling.config import APIKeys
Expand Down
8 changes: 4 additions & 4 deletions tests_integration_with_local_chain/safe/test_safe.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from eth_account import Account
from gnosis.eth import EthereumClient
from gnosis.safe import Safe
from pydantic import SecretStr
from safe_eth.eth import EthereumClient
from safe_eth.safe.safe import SafeV141
from web3 import Web3

from prediction_market_agent_tooling.config import APIKeys
Expand Down Expand Up @@ -31,7 +31,7 @@
def test_create_safe(
local_ethereum_client: EthereumClient,
test_keys: APIKeys,
test_safe: Safe,
test_safe: SafeV141,
) -> None:
account = Account.from_key(test_keys.bet_from_private_key.get_secret_value())
version = test_safe.retrieve_version()
Expand All @@ -47,7 +47,7 @@ def test_send_function_on_contract_tx_using_safe(
local_ethereum_client: EthereumClient,
local_web3: Web3,
test_keys: APIKeys,
test_safe: Safe,
test_safe: SafeV141,
) -> None:
print_current_block(local_web3)

Expand Down
Loading