Improve README, add foundry to docker, add handler to build targets

This commit is contained in:
Thales Lima
2024-08-02 04:03:09 +02:00
committed by tvinagre
parent 11619bf8be
commit 8ea02613a2
8 changed files with 135 additions and 35 deletions

View File

@@ -1,5 +1,5 @@
SUBSTREAMS_PATH=../substreams/ethereum-curve
RPC_URL=https://mainnet.infura.io/v3/your-infura-key
DATABASE_URL: "postgres://postgres:mypassword@db:5432/tycho_indexer_0"
SUBSTREAMS_API_TOKEN="changeme"
DOMAIN_OWNER="AWSAccountId"
export SUBSTREAMS_PACKAGE=ethereum-curve
export RPC_URL=https://mainnet.infura.io/v3/your-infura-key
export DATABASE_URL: "postgres://postgres:mypassword@db:5432/tycho_indexer_0"
export SUBSTREAMS_API_TOKEN="changeme"
export DOMAIN_OWNER="AWSAccountId"

View File

@@ -4,6 +4,14 @@ FROM --platform=linux/amd64 continuumio/miniconda3:24.4.0-0
# Set the working directory in the container to /app
WORKDIR /app
# Install Foundry
RUN apt-get update && apt-get install -y curl
RUN curl -L https://foundry.paradigm.xyz | bash
RUN /bin/bash -c "source $HOME/.bashrc && $HOME/.foundry/bin/foundryup"
#
# Add Foundry to PATH
ENV PATH /root/.foundry/bin:$PATH
# Add current directory code to /app in container
ADD . /app/testing
@@ -22,7 +30,7 @@ RUN apt-get update \
&& apt-get clean
ARG PIP_INDEX_URL
RUN /bin/bash -c "source activate myenv && cd testing && pip install --no-cache-dir -r src/requirements.txt && cd -"
RUN /bin/bash -c "source activate myenv && cd testing && pip install --no-cache-dir -r requirements.txt && cd -"
# Make port 80 available to the world outside this container
EXPOSE 80

View File

@@ -33,9 +33,27 @@ Please place this Runtime file under the respective `substream` directory inside
Export the required environment variables for the execution. You can find the available environment variables in the `.env.default` file.
Please create a `.env` file in the `testing` directory and set the required environment variables.
The variable SUBSTREAMS_PATH should be a relative reference to the directory containing the Substreams module that you want to test.
#### Environment Variables
Example: `SUBSTREAMS_PATH=../substreams/ethereum-curve`
**SUBSTREAMS_PACKAGE**
- **Description**: Specifies the Substreams module that you want to test
- **Example**: `export SUBSTREAMS_PACKAGE=ethereum-balancer`
**DATABASE_URL**
- **Description**: The connection string for the PostgreSQL database. It includes the username, password, host, port, and database name. It's already set to the default for the Docker container.
- **Example**: `export DATABASE_URL="postgres://postgres:mypassword@localhost:5431/tycho_indexer_0`
**RPC_URL**
- **Description**: The URL for the Ethereum RPC endpoint. This is used to fetch the storage data. The node needs to be an archive node, and support [debug_storageRangeAt](https://www.quicknode.com/docs/ethereum/debug_storageRangeAt).
- **Example**: `export RPC_URL="https://ethereum-mainnet.core.chainstack.com/123123123123"`
**SUBSTREAMS_API_TOKEN**
- **Description**: The API token for accessing Substreams services. This token is required for authentication.
- **Example**: `export SUBSTREAMS_API_TOKEN=eyJhbGci...`
**DOMAIN_OWNER**
- **Description**: The domain owner identifier for Propellerhead's AWS account, used for authenticating on the private PyPI repository.
- **Example**: `export DOMAIN_OWNER=123456789`
### Step 2: Build and the Testing Script

0
testing/__init__.py Normal file
View File

View File

@@ -20,7 +20,6 @@ services:
args:
PIP_INDEX_URL: ${PIP_INDEX_URL}
volumes:
# - ${SUBSTREAMS_PATH}:/app/substreams/my_substream
- ../substreams:/app/substreams
- ../proto:/app/proto
- ./tycho-indexer:/bin/tycho-indexer
@@ -33,13 +32,15 @@ services:
- db
env_file:
- ".env"
environment:
- DATABASE_URL=postgres://postgres:mypassword@db:5432/tycho_indexer_0
command:
- "python"
- "testing/src/runner/cli.py"
- "--package"
- "ethereum-balancer"
- "--with_binary_logs"
- "--db_url"
- ${SUBSTREAMS_PACKAGE}
- "--tycho-logs"
- "--db-url"
- "postgres://postgres:mypassword@db:5432/tycho_indexer_0"
volumes:
postgres_data:

View File

@@ -12,7 +12,7 @@ set +a
# Check if DOMAIN_OWNER is set
if [ -z "$DOMAIN_OWNER" ]; then
echo "DOMAIN_OWNER environment variable is not set."
exit 1
return 1
fi
# Fetch the CODEARTIFACT_AUTH_TOKEN

View File

@@ -0,0 +1,44 @@
import os
import subprocess
from typing import Optional
class AdapterContractHandler:
@staticmethod
def build_target(
src_path: str,
adapter_contract: str,
signature: Optional[str],
args: Optional[str],
):
"""
Runs the buildRuntime Bash script in a subprocess with the provided arguments.
:param src_path: Path to the script to be executed.
:param adapter_contract: The contract name to be passed to the script.
:param signature: The constructor signature to be passed to the script.
:param args: The constructor arguments to be passed to the script.
"""
script_path = "scripts/buildRuntime.sh"
cmd = [script_path, "-c", adapter_contract]
if signature:
cmd.extend(["-s", signature, "-a", args])
try:
# Running the bash script with the provided arguments
result = subprocess.run(
[script_path, "-c", adapter_contract, "-s", signature, "-a", args],
cwd=src_path,
capture_output=True,
text=True,
check=True,
)
# Print standard output and error for debugging
print("Output:\n", result.stdout)
if result.stderr:
print("Errors:\n", result.stderr)
except subprocess.CalledProcessError as e:
print(f"An error occurred: {e}")
print("Error Output:\n", e.stderr)

View File

@@ -10,6 +10,8 @@ import traceback
import yaml
from pydantic import BaseModel
from adapter_handler import AdapterContractHandler
from tycho_client.decoders import ThirdPartyPoolTychoDecoder
from tycho_client.models import Blockchain, EVMBlock
from tycho_client.tycho_adapter import TychoPoolStateStreamAdapter
@@ -46,13 +48,19 @@ class SimulationFailure(BaseModel):
class TestRunner:
def __init__(self, package: str, with_binary_logs: bool, db_url: str, vm_traces: bool):
def __init__(
self, package: str, with_binary_logs: bool, db_url: str, vm_traces: bool
):
self.repo_root = os.getcwd()
config_path = os.path.join(self.repo_root, "substreams", package, "test_assets.yaml")
config_path = os.path.join(
self.repo_root, "substreams", package, "test_assets.yaml"
)
self.config = load_config(config_path)
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_runner = TychoRunner(
db_url, with_binary_logs, self.config["initialized_accounts"]
)
self.tycho_rpc_client = TychoRPCClient()
self.db_url = db_url
self._vm_traces = vm_traces
@@ -151,15 +159,20 @@ class TestRunner:
f"from rpc call and {tycho_balance} from Substreams"
)
contract_states = self.tycho_rpc_client.get_contract_state()
filtered_components = {'protocol_components': [pc for pc in protocol_components["protocol_components"] if
pc["id"] in [c["id"].lower() for c in
expected_state["protocol_components"] if
c.get("skip_simulation", False) is False]]}
filtered_components = {
"protocol_components": [
pc
for pc in protocol_components["protocol_components"]
if pc["id"]
in [
c["id"].lower()
for c in expected_state["protocol_components"]
if c.get("skip_simulation", False) is False
]
]
}
simulation_failures = self.simulate_get_amount_out(
stop_block,
protocol_states,
filtered_components,
contract_states,
stop_block, protocol_states, filtered_components, contract_states
)
if len(simulation_failures):
error_msgs = []
@@ -196,10 +209,24 @@ class TestRunner:
failed_simulations: dict[str, list[SimulationFailure]] = dict()
for protocol in protocol_type_names:
adapter_contract = os.path.join(
self.adapters_src, "out", f"{self.config['adapter_contract']}.sol",
f"{self.config['adapter_contract']}.evm.runtime"
self.adapters_src,
"out",
f"{self.config['adapter_contract']}.sol",
f"{self.config['adapter_contract']}.evm.runtime",
)
if not os.path.exists(adapter_contract):
print("Adapter contract not found. Building it ...")
AdapterContractHandler.build_target(
self.adapters_src,
self.config["adapter_contract"],
self.config["adapter_build_signature"],
self.config["adapter_build_args"],
)
decoder = ThirdPartyPoolTychoDecoder(
adapter_contract, 0, trace=self._vm_traces
)
decoder = ThirdPartyPoolTychoDecoder(adapter_contract, 0, trace=self._vm_traces)
stream_adapter = TychoPoolStateStreamAdapter(
tycho_url="0.0.0.0:4242",
protocol=protocol,
@@ -219,7 +246,9 @@ class TestRunner:
pool_state.tokens, 2
):
# Try to sell 0.1% of the protocol balance
sell_amount = Decimal("0.001") * pool_state.balances[sell_token.address]
sell_amount = (
Decimal("0.001") * pool_state.balances[sell_token.address]
)
try:
amount_out, gas_used, _ = pool_state.get_amount_out(
sell_token, sell_amount, buy_token