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

Add DVT Relayer check #420

Merged
merged 4 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions src/common/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def create_db_dir(self) -> None:

class ExecutionClient:
client: AsyncWeb3
is_set_up = False

async def setup(self) -> None:
if not any(settings.execution_endpoints):
Expand All @@ -48,9 +49,12 @@ async def setup(self) -> None:
w3.eth.default_account = hot_wallet.address

self.client = w3
self.is_set_up = True
return None

def __getattr__(self, item): # type: ignore
if not self.is_set_up:
raise RuntimeError('Execution client is not ready. You need to call setup() method')
return getattr(self.client, item)


Expand Down
5 changes: 3 additions & 2 deletions src/common/harvest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from eth_typing import ChecksumAddress
from hexbytes import HexBytes
from web3 import Web3
from web3.types import Wei

Expand Down Expand Up @@ -52,10 +53,10 @@ async def _fetch_harvest_params_from_ipfs(
reward = Wei(vault_data['consensus_reward'])

return HarvestParams(
rewards_root=rewards_root,
rewards_root=HexBytes(rewards_root),
reward=reward,
unlocked_mev_reward=unlocked_mev_reward,
proof=[Web3.to_bytes(hexstr=x) for x in vault_data['proof']],
proof=[HexBytes(Web3.to_bytes(hexstr=x)) for x in vault_data['proof']],
)

return None
49 changes: 38 additions & 11 deletions src/common/startup_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
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.relayer import DvtRelayerClient
from src.validators.typings import RelayerTypes, ValidatorsRegistrationMode
from src.validators.utils import load_deposit_data

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -228,16 +229,9 @@ async def startup_checks() -> None:
await check_hot_wallet_balance()

logger.info('Checking connection to ipfs nodes...')
healthy_ipfs_endpoint = []
for endpoint in settings.ipfs_fetch_endpoints:
client = IpfsFetchClient([endpoint])
try:
await client.fetch_json(IPFS_HASH_EXAMPLE)
except Exception as e:
logger.warning("Can't connect to ipfs node %s: %s", endpoint, e)
else:
healthy_ipfs_endpoint.append(endpoint)
logger.info('Connected to ipfs nodes at %s.', ', '.join(healthy_ipfs_endpoint))
healthy_ipfs_endpoints = await _check_ipfs_endpoints()

logger.info('Connected to ipfs nodes at %s.', ', '.join(healthy_ipfs_endpoints))

logger.info('Checking connection to oracles set...')
healthy_oracles = await collect_healthy_oracles()
Expand All @@ -261,6 +255,13 @@ async def startup_checks() -> None:

await _check_validators_manager()

if (
settings.validators_registration_mode == ValidatorsRegistrationMode.API
and settings.relayer_type == RelayerTypes.DVT
):
logger.info('Checking DVT Relayer endpoint %s...', settings.relayer_endpoint)
await _check_dvt_relayer_endpoint()


async def _check_consensus_nodes_network() -> None:
"""
Expand Down Expand Up @@ -311,6 +312,21 @@ async def _aiohttp_fetch(session: ClientSession, url: str) -> str:
return url


async def _check_ipfs_endpoints() -> list[str]:
healthy_ipfs_endpoints = []

for endpoint in settings.ipfs_fetch_endpoints:
client = IpfsFetchClient([endpoint])
try:
await client.fetch_json(IPFS_HASH_EXAMPLE)
except Exception as e:
logger.warning("Can't connect to ipfs node %s: %s", endpoint, e)
else:
healthy_ipfs_endpoints.append(endpoint)

return healthy_ipfs_endpoints


async def _check_validators_manager() -> None:
if settings.validators_registration_mode == ValidatorsRegistrationMode.AUTO:
if await vault_contract.version() > 1:
Expand All @@ -331,3 +347,14 @@ async def _check_events_logs() -> None:
raise ValueError(
"Can't find oracle config. Please, ensure that EL client didn't prune event logs."
)


async def _check_dvt_relayer_endpoint() -> None:
info = await DvtRelayerClient().get_info()

relayer_network = info['network']
if relayer_network != settings.network:
raise ValueError(
f'Relayer network "{relayer_network}" does not match '
f'Operator network "{settings.network}"'
)
5 changes: 3 additions & 2 deletions src/common/typings.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from dataclasses import dataclass

from hexbytes import HexBytes
from web3.types import Wei


Expand All @@ -11,10 +12,10 @@ class RewardVoteInfo:

@dataclass
class HarvestParams:
rewards_root: bytes
rewards_root: HexBytes
reward: Wei
unlocked_mev_reward: Wei
proof: list[bytes]
proof: list[HexBytes]


@dataclass
Expand Down
11 changes: 11 additions & 0 deletions src/validators/relayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@ async def get_validators(


class DvtRelayerClient:
async def get_info(self) -> dict:
url = urljoin(settings.relayer_endpoint, 'info')
async with aiohttp.ClientSession(
timeout=ClientTimeout(settings.relayer_timeout)
) as session:
resp = await session.get(url)
if 400 <= resp.status < 500:
logger.debug('Relayer response: %s', await resp.read())
evgeny-stakewise marked this conversation as resolved.
Show resolved Hide resolved
resp.raise_for_status()
return await resp.json()

async def get_validators(self, public_keys: list[HexStr]) -> dict:
url = urljoin(settings.relayer_endpoint, 'validators')
jsn = {'public_keys': public_keys}
Expand Down
Loading