From 5c16222bebad0bd219fcebdd3fec891af94e5aed Mon Sep 17 00:00:00 2001 From: cyc60 Date: Mon, 28 Aug 2023 12:10:45 +0300 Subject: [PATCH] Add validator registration deadline Signed-off-by: cyc60 --- src/common/typings.py | 8 ++++++++ src/validators/execution.py | 11 ++++------- src/validators/tasks.py | 20 +++++++++++++++++--- src/validators/typings.py | 17 +++++++++++------ 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/common/typings.py b/src/common/typings.py index ec47096a..00afb18e 100644 --- a/src/common/typings.py +++ b/src/common/typings.py @@ -1,4 +1,5 @@ from dataclasses import dataclass +from datetime import datetime from functools import cached_property from eth_keys.datatypes import PublicKey @@ -45,3 +46,10 @@ class HarvestParams: class OracleApproval: signature: bytes ipfs_hash: str + + +@dataclass +class OraclesApproval: + signatures: bytes + ipfs_hash: str + deadline: datetime diff --git a/src/validators/execution.py b/src/validators/execution.py index 2c33e806..2d76db81 100644 --- a/src/validators/execution.py +++ b/src/validators/execution.py @@ -17,16 +17,11 @@ ) from src.common.ipfs import fetch_harvest_params from src.common.metrics import metrics +from src.common.typings import OraclesApproval from src.config.networks import ETH_NETWORKS from src.config.settings import DEPOSIT_AMOUNT, settings from src.validators.database import NetworkValidatorCrud -from src.validators.typings import ( - DepositData, - Keystores, - NetworkValidator, - OraclesApproval, - Validator, -) +from src.validators.typings import DepositData, Keystores, NetworkValidator, Validator logger = logging.getLogger(__name__) @@ -234,6 +229,7 @@ async def register_single_validator( tx_validators[0], approval.signatures, approval.ipfs_hash, + approval.deadline, ), multi_proof.proof, ] @@ -270,6 +266,7 @@ async def register_multiple_validator( b''.join(tx_validators), approval.signatures, approval.ipfs_hash, + approval.deadline, ), indexes, multi_proof.proof_flags, diff --git a/src/validators/tasks.py b/src/validators/tasks.py index d16bb7d3..1cfb6f7f 100644 --- a/src/validators/tasks.py +++ b/src/validators/tasks.py @@ -1,4 +1,5 @@ import logging +from datetime import datetime, timedelta, timezone from multiproof.standart import MultiProof from sw_utils.typings import Bytes32 @@ -9,7 +10,7 @@ from src.common.contracts import validators_registry_contract from src.common.execution import check_gas_price, get_oracles from src.common.metrics import metrics -from src.common.typings import Oracles +from src.common.typings import Oracles, OraclesApproval from src.common.utils import MGNO_RATE, WAD from src.config.networks import GNOSIS from src.config.settings import DEPOSIT_AMOUNT, settings @@ -27,7 +28,6 @@ DepositData, Keystores, NetworkValidator, - OraclesApproval, Validator, ) from src.validators.utils import send_approval_requests @@ -78,11 +78,20 @@ async def register_validators(keystores: Keystores, deposit_data: DepositData) - validators=validators, ) registry_root = None + deadline = None while True: latest_registry_root = await validators_registry_contract.get_registry_root() + latest_deadline = datetime.now(timezone.utc) + timedelta( + seconds=settings.exit_signature_deadline + ) - if not registry_root or registry_root != latest_registry_root: + if ( + not registry_root + or registry_root != latest_registry_root + or deadline < datetime.now(timezone.utc) + ): registry_root = latest_registry_root + deadline = latest_deadline logger.debug('Fetched latest validators registry root: %s', registry_root) oracles_request = await create_approval_request( @@ -90,6 +99,7 @@ async def register_validators(keystores: Keystores, deposit_data: DepositData) - oracles=oracles, keystores=keystores, validators=validators, + deadline=deadline, multi_proof=multi_proof, ) @@ -122,12 +132,14 @@ async def register_validators(keystores: Keystores, deposit_data: DepositData) - logger.info('Successfully registered validators with public keys %s', pub_keys) +# pylint: disable-next=too-many-arguments async def create_approval_request( oracles: Oracles, keystores: Keystores, validators: list[Validator], registry_root: Bytes32, multi_proof: MultiProof, + deadline: datetime, ) -> ApprovalRequest: """Generate validator registration request data""" @@ -151,6 +163,7 @@ async def create_approval_request( exit_signature_shards=[], proof=multi_proof.proof, proof_flags=multi_proof.proof_flags, + deadline=deadline, ) for validator in validators: shards = get_exit_signature_shards( @@ -186,6 +199,7 @@ async def get_oracles_approval(oracles: Oracles, request: ApprovalRequest) -> Or return OraclesApproval( signatures=signatures, ipfs_hash=ipfs_hash, + deadline=request.deadline, ) diff --git a/src/validators/typings.py b/src/validators/typings.py index 08254b8a..18e35c3e 100644 --- a/src/validators/typings.py +++ b/src/validators/typings.py @@ -1,4 +1,6 @@ +import dataclasses from dataclasses import dataclass +from datetime import datetime from typing import NewType from eth_typing import BlockNumber, ChecksumAddress, HexStr @@ -34,12 +36,6 @@ class ExitSignatureShards: exit_signatures: list[HexStr] -@dataclass -class OraclesApproval: - signatures: bytes - ipfs_hash: str - - @dataclass # pylint: disable-next=too-many-instance-attributes class ApprovalRequest: @@ -52,6 +48,15 @@ class ApprovalRequest: exit_signature_shards: list[list[HexStr]] proof: list[HexStr] proof_flags: list[bool] + deadline: datetime + + def as_json_dict(self) -> dict: + """ + :return: dict which can be serialized by `json.dumps()` + """ + res = dataclasses.asdict(self) + res['deadline'] = int(self.deadline.timestamp()) + return res @dataclass