Skip to content

Commit

Permalink
Revert "Operator relayer separation (#339)"
Browse files Browse the repository at this point in the history
This reverts commit 342f4a2
  • Loading branch information
evgeny-stakewise committed Jul 22, 2024
1 parent f1b569b commit a902bf6
Show file tree
Hide file tree
Showing 19 changed files with 354 additions and 231 deletions.
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ prometheus-client = "==0.17.1"
psycopg2 = "==2.9.9"
pyyaml = "==6.0.1"
python-json-logger = "==2.0.7"
starlette = "==0.36.2"
uvicorn = "==0.27.0"
pydantic = "==2.5.3"

[tool.poetry.group.dev.dependencies]
pylint = "==3.0.1"
Expand Down
11 changes: 11 additions & 0 deletions src/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from starlette.applications import Starlette
from starlette.routing import Route

from src.validators.api.endpoints import get_validators, submit_validators

app = Starlette(
routes=[
Route('/validators', get_validators, methods=['GET']),
Route('/validators', submit_validators, methods=['POST']),
]
)
24 changes: 18 additions & 6 deletions src/commands/start_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
import click
from eth_typing import ChecksumAddress

import src.validators.api.endpoints # noqa # pylint:disable=unused-import
from src.commands.start_base import start_base
from src.common.logging import LOG_LEVELS
from src.common.utils import log_verbose
from src.common.validators import validate_eth_address
from src.common.vault_config import VaultConfig
from src.config.networks import AVAILABLE_NETWORKS
from src.config.settings import (
DEFAULT_API_HOST,
DEFAULT_API_PORT,
DEFAULT_MAX_FEE_PER_GAS_GWEI,
DEFAULT_METRICS_HOST,
DEFAULT_METRICS_PORT,
Expand Down Expand Up @@ -168,11 +171,18 @@
help='The log level.',
)
@click.option(
'--relayer-endpoint',
'--api-endpoint',
type=str,
help='Relayer endpoint.',
prompt='Enter the relayer endpoint',
envvar='RELAYER_ENDPOINT',
help=f'API host. Default is {DEFAULT_API_HOST}.',
envvar='API_HOST',
default=DEFAULT_API_HOST,
)
@click.option(
'--api-port',
type=int,
help=f'API port. Default is {DEFAULT_API_PORT}.',
envvar='API_PORT',
default=DEFAULT_API_PORT,
)
@click.command(help='Start operator service')
# pylint: disable-next=too-many-arguments,too-many-locals
Expand All @@ -196,7 +206,8 @@ def start_api(
hot_wallet_password_file: str | None,
max_fee_per_gas_gwei: int,
database_dir: str | None,
relayer_endpoint: str,
api_host: str,
api_port: int,
) -> None:
vault_config = VaultConfig(vault, Path(data_dir))
if network is None:
Expand Down Expand Up @@ -225,7 +236,8 @@ def start_api(
database_dir=database_dir,
log_level=log_level,
log_format=log_format,
relayer_endpoint=relayer_endpoint,
api_host=api_host,
api_port=api_port,
validators_registration_mode=validators_registration_mode,
)

Expand Down
37 changes: 24 additions & 13 deletions src/commands/start_base.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import asyncio
import logging

import uvicorn
from sw_utils import EventScanner, InterruptHandler

import src
from src.api import app as api_app
from src.common.checks import wait_execution_catch_up_consensus
from src.common.consensus import get_chain_finalized_head
from src.common.execution import WalletTask, update_oracles_cache
Expand All @@ -18,9 +20,8 @@
from src.validators.execution import NetworkValidatorsProcessor
from src.validators.keystores.base import BaseKeystore
from src.validators.keystores.load import load_keystore
from src.validators.relayer import BaseRelayerClient, RelayerClient
from src.validators.tasks import ValidatorsTask, load_genesis_validators
from src.validators.typings import DepositData, ValidatorsRegistrationMode
from src.validators.typings import ValidatorsRegistrationMode
from src.validators.utils import load_deposit_data

logger = logging.getLogger(__name__)
Expand All @@ -39,19 +40,14 @@ async def start_base() -> None:
# load network validators from ipfs dump
await load_genesis_validators()

# load keystore
keystore: BaseKeystore | None = None
deposit_data: DepositData | None = None
relayer: BaseRelayerClient | None = None

# load keystore and deposit data
if settings.validators_registration_mode == ValidatorsRegistrationMode.AUTO:
keystore = await load_keystore()

deposit_data = load_deposit_data(settings.vault, settings.deposit_data_file)
logger.info('Loaded deposit data file %s', settings.deposit_data_file)
else:
relayer = RelayerClient()

# load deposit data
deposit_data = load_deposit_data(settings.vault, settings.deposit_data_file)
logger.info('Loaded deposit data file %s', settings.deposit_data_file)
# start operator tasks

# periodically scan network validator updates
Expand All @@ -67,7 +63,17 @@ async def start_base() -> None:
await update_oracles_cache()

if settings.validators_registration_mode == ValidatorsRegistrationMode.API:
logger.info('Starting api mode')
logger.info('Starting api server')
api_app.state.deposit_data = deposit_data

config = uvicorn.Config(
api_app,
host=settings.api_host,
port=settings.api_port,
log_config=None,
)
server = UvicornServerWithoutSignals(config)
asyncio.create_task(server.serve())

if settings.enable_metrics:
await metrics_server()
Expand All @@ -78,7 +84,6 @@ async def start_base() -> None:
ValidatorsTask(
keystore=keystore,
deposit_data=deposit_data,
relayer=relayer,
).run(interrupt_handler),
ExitSignatureTask(
keystore=keystore,
Expand All @@ -92,6 +97,12 @@ async def start_base() -> None:
await asyncio.gather(*tasks)


class UvicornServerWithoutSignals(uvicorn.Server):
def install_signal_handlers(self) -> None:
# Manage signals in command, not in Uvicorn
pass


def log_start() -> None:
build = get_build_version()
start_str = 'Starting operator service'
Expand Down
3 changes: 0 additions & 3 deletions src/common/contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,6 @@ async def mev_escrow(self) -> ChecksumAddress:
async def version(self) -> int:
return await self.contract.functions.version().call()

async def validators_manager(self):
return await self.contract.functions.validatorsManager().call()


class GnoVaultContract(ContractWrapper, VaultStateMixin):
abi_path = 'abi/IGnoVault.json'
Expand Down
18 changes: 0 additions & 18 deletions src/common/startup_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from web3 import Web3

from src.common.clients import db_client
from src.common.contracts import vault_contract
from src.common.execution import (
check_hot_wallet_balance,
check_vault_address,
Expand All @@ -21,7 +20,6 @@
from src.config.settings import settings
from src.validators.execution import check_deposit_data_root, get_withdrawable_assets
from src.validators.keystores.local import LocalKeystore
from src.validators.typings import ValidatorsRegistrationMode
from src.validators.utils import load_deposit_data

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -240,24 +238,8 @@ async def startup_checks():
wait_for_keystores_dir()
logger.info('Found keystores dir')

await _check_validators_manager()


async def _aiohttp_fetch(session: ClientSession, url: str) -> str:
async with session.get(url=url) as response:
response.raise_for_status()
return url


async def _check_validators_manager() -> None:
if settings.validators_registration_mode == ValidatorsRegistrationMode.API:
if await vault_contract.version() == 1:
raise RuntimeError('Vault version must be 2')

if settings.validators_registration_mode == ValidatorsRegistrationMode.AUTO:
if await vault_contract.version() > 1:
validators_manager = await vault_contract.validators_manager()
if validators_manager != settings.network_config.DEPOSIT_DATA_REGISTRY_CONTRACT_ADDRESS:
raise RuntimeError(
'validators manager address must equal to deposit data registry address'
)
5 changes: 0 additions & 5 deletions src/config/networks.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
@dataclass
# pylint: disable-next=too-many-instance-attributes
class NetworkConfig:
CHAIN_ID: int
WALLET_BALANCE_SYMBOL: str
VAULT_BALANCE_SYMBOL: str
VALIDATORS_REGISTRY_CONTRACT_ADDRESS: ChecksumAddress # consensus deposit contract
Expand Down Expand Up @@ -63,7 +62,6 @@ def IS_SUPPORT_V2_MIGRATION(self) -> bool:

NETWORKS = {
MAINNET: NetworkConfig(
CHAIN_ID=1,
WALLET_BALANCE_SYMBOL='ETH',
VAULT_BALANCE_SYMBOL='ETH',
VALIDATORS_REGISTRY_CONTRACT_ADDRESS=Web3.to_checksum_address(
Expand Down Expand Up @@ -109,7 +107,6 @@ def IS_SUPPORT_V2_MIGRATION(self) -> bool:
RATED_API_URL='https://api.rated.network',
),
HOLESKY: NetworkConfig(
CHAIN_ID=17000,
WALLET_BALANCE_SYMBOL='HolETH',
VAULT_BALANCE_SYMBOL='HolETH',
VALIDATORS_REGISTRY_CONTRACT_ADDRESS=Web3.to_checksum_address(
Expand Down Expand Up @@ -153,7 +150,6 @@ def IS_SUPPORT_V2_MIGRATION(self) -> bool:
RATED_API_URL='https://api.rated.network',
),
GNOSIS: NetworkConfig(
CHAIN_ID=100,
WALLET_BALANCE_SYMBOL='xDAI',
VAULT_BALANCE_SYMBOL='GNO',
VALIDATORS_REGISTRY_CONTRACT_ADDRESS=Web3.to_checksum_address(
Expand Down Expand Up @@ -199,7 +195,6 @@ def IS_SUPPORT_V2_MIGRATION(self) -> bool:
RATED_API_URL='https://api.rated.network',
),
CHIADO: NetworkConfig(
CHAIN_ID=10200,
WALLET_BALANCE_SYMBOL='xDAI',
VAULT_BALANCE_SYMBOL='GNO',
VALIDATORS_REGISTRY_CONTRACT_ADDRESS=Web3.to_checksum_address(
Expand Down
15 changes: 9 additions & 6 deletions src/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
DEFAULT_METRICS_PORT = 9100
DEFAULT_METRICS_PREFIX = 'sw_operator'

DEFAULT_API_HOST = '127.0.0.1'
DEFAULT_API_PORT = 8000

DEFAULT_MIN_VALIDATORS_REGISTRATION = 1


Expand Down Expand Up @@ -68,8 +71,8 @@ class Settings(metaclass=Singleton):
sentry_environment: str
pool_size: int | None

relayer_endpoint: str | None
relayer_timeout: int
api_host: str
api_port: int
validators_registration_mode: ValidatorsRegistrationMode
skip_startup_checks: bool

Expand Down Expand Up @@ -115,7 +118,8 @@ def set(
log_level: str | None = None,
log_format: str | None = None,
pool_size: int | None = None,
relayer_endpoint: str | None = None,
api_host: str = DEFAULT_API_HOST,
api_port: int = DEFAULT_API_PORT,
validators_registration_mode: ValidatorsRegistrationMode = ValidatorsRegistrationMode.AUTO,
min_validators_registration: int = DEFAULT_MIN_VALIDATORS_REGISTRATION,
) -> None:
Expand Down Expand Up @@ -215,9 +219,8 @@ def set(
self.consensus_retry_timeout = decouple_config(
'CONSENSUS_RETRY_TIMEOUT', default=120, cast=int
)
self.relayer_endpoint = relayer_endpoint
self.relayer_timeout = decouple_config('RELAYER_TIMEOUT', default=10, cast=int)

self.api_host = api_host
self.api_port = api_port
self.validators_registration_mode = validators_registration_mode

self.skip_startup_checks = decouple_config('SKIP_STARTUP_CHECKS', default=False, cast=bool)
Expand Down
Empty file added src/validators/api/__init__.py
Empty file.
Loading

0 comments on commit a902bf6

Please sign in to comment.