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

System tests #837

Merged
merged 32 commits into from
Aug 17, 2023
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
c85329b
Agent0 docstrings
slundqui Aug 16, 2023
da6d02a
Moving chainsync main function to be within the package
slundqui Aug 16, 2023
37c62a8
Chain fixture now returns all addresses. Adding bot to system test
slundqui Aug 16, 2023
654284c
Adding import
slundqui Aug 16, 2023
8369559
Moving get_web3_and_hyperdrive_contracts from agent0 to ethpy
slundqui Aug 16, 2023
cc39c9a
Using new ethpy utilities to get web3 and contracts in chainsync
slundqui Aug 16, 2023
37a46df
Cleanup of acquire_data
slundqui Aug 16, 2023
a0399df
More cleanup
slundqui Aug 16, 2023
4e17a19
Minor import change
slundqui Aug 16, 2023
e65d650
Parameterizing acquire data for system tests
slundqui Aug 16, 2023
31779c5
Updating system tests to include acquire_data
slundqui Aug 16, 2023
6cf16cf
Adding in conftest to allow for vscode debugging of pytest
slundqui Aug 16, 2023
f59e642
Linking to source
slundqui Aug 16, 2023
3b1eced
Updating debug conf test name
slundqui Aug 16, 2023
6b90a6f
Fixing bug with inconsistent db schema between BigInteger and Decimal…
slundqui Aug 16, 2023
0cf8c5c
Adjusting starting block for system test
slundqui Aug 16, 2023
be16171
Removing unnecessary pass
slundqui Aug 16, 2023
a310dc6
Resolving timestretch todo
slundqui Aug 17, 2023
0ab1466
Using explicit scale in postgres to match fixedpoint notation
slundqui Aug 17, 2023
3b0094f
First steps in comparing values in system test
slundqui Aug 17, 2023
aaf710e
Adding comments on high precision numeric types in postgres
slundqui Aug 17, 2023
a65a5e1
Updating comments and docstrings
slundqui Aug 17, 2023
ea69d86
Removing extra acquire_data in system test
slundqui Aug 17, 2023
cb2ba50
Fixing tests and adding pool config check to system test
slundqui Aug 17, 2023
8e40c3e
Fixing a bug in cycle_trade_policy
slundqui Aug 17, 2023
0befebe
Adding coerce float to other getter functions. Updating system tests
slundqui Aug 17, 2023
ea0b63f
System test now goes through txns and checks wallets
slundqui Aug 17, 2023
32ce636
formatting changes
slundqui Aug 17, 2023
55bf464
lint
slundqui Aug 17, 2023
efda644
Updating readme with foundary prereq
slundqui Aug 17, 2023
55846bf
Adding comment for precision and scale
slundqui Aug 17, 2023
018885d
Updating todo comment
slundqui Aug 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Hack to allow for vscode debugger to throw exception immediately
# instead of allowing pytest to catch the exception and report
# Based on https://stackoverflow.com/questions/62419998/how-can-i-get-pytest-to-not-catch-exceptions/62563106#62563106

# Use this in conjunction with the following launch.json configuration:
# {
# "name": "Debug Current Test",
# "type": "python",
# "request": "launch",
# "module": "pytest",
# "args": ["${file}"],
# "console": "integratedTerminal",
# "justMyCode": true,
# "env": {
# "_PYTEST_RAISE": "1"
# },
# },

# Ignore docstrings for this file
# pylint: disable=missing-docstring


import os

import pytest

if os.getenv("_PYTEST_RAISE", "0") != "0":

@pytest.hookimpl(tryfirst=True)
def pytest_exception_interact(call):
raise call.excinfo.value

@pytest.hookimpl(tryfirst=True)
def pytest_internalerror(excinfo):
raise excinfo.value
7 changes: 6 additions & 1 deletion lib/agent0/agent0/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
"""Account key config and various helper functions"""
from .accounts_config import AccountKeyConfig, build_account_config_from_env, initialize_accounts
from .accounts_config import (
AccountKeyConfig,
build_account_config_from_env,
build_account_key_config_from_agent_config,
initialize_accounts,
)
41 changes: 35 additions & 6 deletions lib/agent0/agent0/accounts_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,33 @@ def to_env_str(self) -> str:


def initialize_accounts(
agent_config: list[AgentConfig], env_file: str | None = None, random_seed: int = 1, develop: bool = False
agent_config: list[AgentConfig],
env_file: str | None = None,
random_seed: int = 1,
develop: bool = False,
) -> AccountKeyConfig:
"""
Build or load an accounts environment file.
If it doesn't exist, create it based on agent_config.
(if develop is off, print instructions on adding in user private key and running script to fund agents).
If it does exist, read it in and use it.

Arguments
---------
agent_config: list[AgentConfig]
The list of agent configs that define policies and arguments.
env_file: str | None
The path to the env file to write/load from. Defaults to `accounts.env`.
random_seed: int
Random seed to use for initializing budgets.
develop: bool
Flag for development mode. If False, will exit if env_file doesn't exist and print instructions
on how to fund bot.

Returns
-------
AccountKeyConfig
The account config object linked to the env file.
"""
# Default location
if env_file is None:
Expand Down Expand Up @@ -102,21 +122,23 @@ def initialize_accounts(


def build_account_key_config_from_agent_config(
agent_configs: list[AgentConfig], random_seed: int, user_key: str | None = None
agent_configs: list[AgentConfig], random_seed: int = 1, user_key: str | None = None
) -> AccountKeyConfig:
"""Build an Account Config from a provided agent config.

Arguments
--------
agent_config: list[AgentConfig]
The list of agent configs that define policies and arguments.
random_seed: int
The seed to initialize the random generator to pass for each bot
user_key: str
The provided user key to use
agent_configs: list[AgentConfig]
The provided agent configs

Returns
-------
AccountConfig
Config settings required to connect to the eth node
AccountKeyConfig
The account config object linked to the env file.
"""
rng = np.random.default_rng(random_seed)
agent_private_keys = []
Expand Down Expand Up @@ -151,6 +173,13 @@ def build_account_key_config_from_agent_config(
def build_account_config_from_env(env_file: str | None = None, user_key: str | None = None) -> AccountKeyConfig:
"""Build an Account Config from environmental variables.

Arguments
--------
env_file: str | None
The path to the env file to load from. Defaults to `accounts.env`.
user_key: str
The provided user key to use

Returns
-------
AccountConfig
Expand Down
2 changes: 1 addition & 1 deletion lib/agent0/agent0/hyperdrive/exec/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
from .fund_agents import fund_agents
from .get_agent_accounts import get_agent_accounts
from .run_agents import run_agents
from .setup_experiment import get_web3_and_contracts, register_username, setup_experiment
from .setup_experiment import register_username, setup_experiment
from .trade_loop import get_wait_for_new_block, trade_if_new_block
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
from eth_account.account import Account
from ethpy import EthConfig
from ethpy.base import set_anvil_account_balance, smart_contract_transact
from ethpy.hyperdrive.addresses import HyperdriveAddresses

from .setup_experiment import get_web3_and_contracts
from ethpy.hyperdrive import HyperdriveAddresses, get_web3_and_hyperdrive_contracts


def create_and_fund_user_account(
Expand Down Expand Up @@ -38,7 +36,7 @@ def create_and_fund_user_account(
user_private_key = make_private_key(extra_entropy="FAKE USER") # argument value can be any str
user_account = HyperdriveAgent(Account().from_key(user_private_key))

web3, base_token_contract, _ = get_web3_and_contracts(eth_config, contract_addresses)
web3, base_token_contract, _ = get_web3_and_hyperdrive_contracts(eth_config, contract_addresses)

eth_balance = sum((int(budget) for budget in account_key_config.AGENT_ETH_BUDGETS)) * 2 # double for good measure
_ = set_anvil_account_balance(web3, user_account.address, eth_balance)
Expand Down
2 changes: 1 addition & 1 deletion lib/agent0/agent0/hyperdrive/exec/fund_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
smart_contract_read,
smart_contract_transact,
)
from ethpy.hyperdrive.addresses import HyperdriveAddresses
from ethpy.hyperdrive import HyperdriveAddresses


def fund_agents(
Expand Down
20 changes: 9 additions & 11 deletions lib/agent0/agent0/hyperdrive/exec/run_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from agent0.base.config import DEFAULT_USERNAME, AgentConfig, EnvironmentConfig
from eth_typing import BlockNumber
from ethpy import EthConfig, build_eth_config
from ethpy.hyperdrive.addresses import HyperdriveAddresses, fetch_hyperdrive_address_from_url
from ethpy.hyperdrive import HyperdriveAddresses, fetch_hyperdrive_address_from_url

from .create_and_fund_user_account import create_and_fund_user_account
from .fund_agents import fund_agents
Expand All @@ -26,7 +26,7 @@ def run_agents(
account_key_config: AccountKeyConfig,
develop: bool = False,
eth_config: EthConfig | None = None,
override_addresses: HyperdriveAddresses | None = None,
contract_addresses: HyperdriveAddresses | None = None,
) -> None:
"""Entrypoint to run agents.

Expand All @@ -43,24 +43,22 @@ def run_agents(
eth_config: EthConfig | None
Configuration for urls to the rpc and artifacts. If not set, will look for addresses
in eth.env.
override_addresses: HyperdriveAddresses | None
contract_addresses: HyperdriveAddresses | None
If set, will use these addresses instead of querying the artifact url
defined in eth_config.
"""

# Defaults to looking for eth_config env
if eth_config is None:
eth_config = build_eth_config()

# Set sane logging defaults to avoid spam from dependencies
logging.getLogger("urllib3").setLevel(logging.WARNING)
logging.getLogger("web3").setLevel(logging.WARNING)
warnings.filterwarnings("ignore", category=UserWarning, module="web3.contract.base_contract")

# Get addresses either from artifacts url defined in eth_config or from override_addresses
if override_addresses is not None:
contract_addresses = override_addresses
else:
# Defaults to looking for eth_config env
if eth_config is None:
eth_config = build_eth_config()

# Get addresses either from artifacts url defined in eth_config or from contract_addresses
if contract_addresses is None:
contract_addresses = fetch_hyperdrive_address_from_url(os.path.join(eth_config.ARTIFACTS_URL, "addresses.json"))

if develop: # setup env automatically & fund the agents
Expand Down
42 changes: 2 additions & 40 deletions lib/agent0/agent0/hyperdrive/exec/setup_experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
from agent0.hyperdrive.exec.crash_report import setup_hyperdrive_crash_report_logging
from elfpy.utils import logs
from ethpy import EthConfig
from ethpy.base import initialize_web3_with_http_provider, load_all_abis
from ethpy.hyperdrive.addresses import HyperdriveAddresses
from ethpy.hyperdrive import HyperdriveAddresses, get_web3_and_hyperdrive_contracts
from web3 import Web3
from web3.contract.contract import Contract

Expand Down Expand Up @@ -65,7 +64,7 @@ def setup_experiment(
log_format_string=environment_config.log_formatter,
)
setup_hyperdrive_crash_report_logging()
web3, base_token_contract, hyperdrive_contract = get_web3_and_contracts(eth_config, contract_addresses)
web3, base_token_contract, hyperdrive_contract = get_web3_and_hyperdrive_contracts(eth_config, contract_addresses)
# load agent policies
# rng is shared by the agents and can be accessed via `agent_accounts[idx].policy.rng`
agent_accounts = get_agent_accounts(
Expand All @@ -74,43 +73,6 @@ def setup_experiment(
return web3, base_token_contract, hyperdrive_contract, agent_accounts


def get_web3_and_contracts(
eth_config: EthConfig, contract_addresses: HyperdriveAddresses
) -> tuple[Web3, Contract, Contract]:
"""Get the web3 container and the ERC20Base and Hyperdrive contracts.

Arguments
---------
eth_config: EthConfig
Configuration for urls to the rpc and artifacts.
contract_addresses: HyperdriveAddresses
Configuration for defining various contract addresses.

Returns
-------
tuple[Web3, Contract, Contract]
A tuple containing:
- The web3 container
- The base token contract
- The hyperdrive contract
"""
# point to chain env
web3 = initialize_web3_with_http_provider(eth_config.RPC_URL, reset_provider=False)
# setup base contract interface
abis = load_all_abis(eth_config.ABI_DIR)
# set up the ERC20 contract for minting base tokens
# TODO is there a better way to pass in base and hyperdrive abi?
base_token_contract: Contract = web3.eth.contract(
abi=abis["ERC20Mintable"], address=web3.to_checksum_address(contract_addresses.base_token)
)
# set up hyperdrive contract
hyperdrive_contract: Contract = web3.eth.contract(
abi=abis["IHyperdrive"],
address=web3.to_checksum_address(contract_addresses.mock_hyperdrive),
)
return web3, base_token_contract, hyperdrive_contract


def register_username(register_url: str, wallet_addrs: list[str], username: str) -> None:
"""Registers the username with the flask server.

Expand Down
2 changes: 2 additions & 0 deletions lib/agent0/agent0/test_fixtures/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
"""Test fixtures for agent0"""
from .cycle_trade_policy import AgentDoneException, cycle_trade_policy
Loading
Loading