feat(runner): Support initialized accounts + misc fixes.

Simplifies a lot the setup of testing:

- Looks up tycho-indexer under the usual paths no OS specific naming necessary.
- Simply assumes that protosim can be pulled from our private PyPi
- Navigates the foundry out folder to find solidity runtime binaries

Includes some additional fixes to deal with some attribtues that may have to be reflected to defibot later on.
This commit is contained in:
kayibal
2024-07-25 19:31:47 +01:00
parent fcaae2f643
commit 4c337a36d1
7 changed files with 93 additions and 87 deletions

View File

@@ -46,10 +46,13 @@ class SimulationFailure(BaseModel):
class TestRunner:
def __init__(self, config_path: str, with_binary_logs: bool, db_url: str):
def __init__(self, package: str, with_binary_logs: bool, db_url: str):
self.repo_root = os.getcwd()
config_path = os.path.join(self.repo_root, "substreams", package, "test_assets.yaml")
self.config = load_config(config_path)
self.base_dir = os.path.dirname(config_path)
self.tycho_runner = TychoRunner(with_binary_logs)
self.spkg_src = os.path.join(self.repo_root, "substreams", package)
self.adapters_src = os.path.join(self.repo_root, "evm")
self.tycho_runner = TychoRunner(db_url, with_binary_logs, self.config["initialized_accounts"])
self.tycho_rpc_client = TychoRPCClient()
self.db_url = db_url
self._chain = Blockchain.ethereum
@@ -60,7 +63,7 @@ class TestRunner:
for test in self.config["tests"]:
spkg_path = self.build_spkg(
os.path.join(self.base_dir, self.config["substreams_yaml_path"]),
os.path.join(self.spkg_src, self.config["substreams_yaml_path"]),
lambda data: self.update_initial_block(data, test["start_block"]),
)
self.tycho_runner.run_tycho(
@@ -107,7 +110,7 @@ class TestRunner:
)
if isinstance(value, list):
if set(map(str.lower, value)) != set(
map(str.lower, component[key])
map(str.lower, component[key])
):
return TestResult.Failed(
f"List mismatch for key '{key}': {value} != {component[key]}"
@@ -146,7 +149,6 @@ class TestRunner:
)
contract_states = self.tycho_rpc_client.get_contract_state()
simulation_failures = self.simulate_get_amount_out(
token_balances,
stop_block,
protocol_states,
protocol_components,
@@ -169,12 +171,11 @@ class TestRunner:
return TestResult.Failed(error_message)
def simulate_get_amount_out(
self,
token_balances: dict[str, dict[str, int]],
block_number: int,
protocol_states: dict,
protocol_components: dict,
contract_state: dict,
self,
block_number: int,
protocol_states: dict,
protocol_components: dict,
contract_state: dict,
) -> dict[str, list[SimulationFailure]]:
protocol_type_names = self.config["protocol_type_names"]
@@ -188,7 +189,8 @@ class TestRunner:
failed_simulations: dict[str, list[SimulationFailure]] = dict()
for protocol in protocol_type_names:
adapter_contract = os.path.join(
self.base_dir, "evm", self.config["adapter_contract"]
self.adapters_src, "out", f"{self.config['adapter_contract']}.sol",
f"{self.config['adapter_contract']}.evm.runtime"
)
decoder = ThirdPartyPoolTychoDecoder(adapter_contract, 0, False)
stream_adapter = TychoPoolStateStreamAdapter(
@@ -204,21 +206,17 @@ class TestRunner:
for pool_state in decoded.pool_states.values():
pool_id = pool_state.id_
protocol_balances = token_balances.get(pool_id)
if not protocol_balances:
if not pool_state.balances:
raise ValueError(f"Missing balances for pool {pool_id}")
for sell_token, buy_token in itertools.permutations(
pool_state.tokens, 2
pool_state.tokens, 2
):
# Try to sell 0.1% of the protocol balance
sell_amount = Decimal("0.001") * pool_state.balances[sell_token.address]
try:
# Try to sell 0.1% of the protocol balance
sell_amount = Decimal("0.001") * sell_token.from_onchain_amount(
protocol_balances[sell_token.address]
)
amount_out, gas_used, _ = pool_state.get_amount_out(
sell_token, sell_amount, buy_token
)
# TODO: Should we validate this with an archive node or RPC reader?
print(
f"Amount out for {pool_id}: {sell_amount} {sell_token} -> {amount_out} {buy_token} - "
f"Gas used: {gas_used}"
@@ -233,8 +231,8 @@ class TestRunner:
failed_simulations[pool_id].append(
SimulationFailure(
pool_id=pool_id,
sell_token=sell_token,
buy_token=buy_token,
sell_token=str(sell_token),
buy_token=str(buy_token),
error=str(e),
)
)