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:
@@ -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),
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user