Skip to content

Commit

Permalink
feat(all): WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
TobiWo committed Mar 7, 2023
1 parent 67d9b32 commit 9d55e25
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 72 deletions.
50 changes: 28 additions & 22 deletions duties/cli/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,60 +12,66 @@ def __get_raw_arguments() -> Namespace:
Returns:
Namespace: Parsed cli arguments
"""
parser = ArgumentParser()
parser = ArgumentParser(
prog="eth-duties",
description="Tool for logging validator duties",
usage="eth-duties [--help] [...options]",
)
parser.add_argument(
"-b",
"--beacon-node",
type=str,
help="URL to access the beacon node api (default: http://localhost:5052)",
action="store",
default="http://localhost:5052",
)
parser.add_argument(
"-f",
"--validator-file",
type=FileType("r"),
help="File with validator indices where every index is on a separate line",
action="store",
)
parser.add_argument(
"-i",
"--interval",
type=int,
help="Interval in seconds for fetching data from the beacon node (default: 15 seconds)",
help="Interval in seconds for fetching data from the beacon node (default: 15)",
action="store",
default=15,
)
parser.add_argument(
"-l",
"--log",
type=str,
help="Defines log level. Values are 'DEBUG' or 'INFO'. Default is 'INFO'",
help="Defines log level. Values are 'DEBUG' or 'INFO' (default: 'INFO')",
action="store",
default="INFO",
)
parser.add_argument(
"-o",
"--omit-attestation-duties",
help="If supplied upcoming attestation duties will not be printed to the console",
"--log-attestation-duties",
help="If supplied upcoming attestation duties will be logged to the console",
action="store_true",
default=False,
)
parser.add_argument(
"-p",
"--log-pubkeys",
help="If supplied the validator index will be replaced with the pubkey in log messages",
action="store_true",
default=False,
)
parser.add_argument(
"-v",
"--max-attestation-duty-logs",
help=(
"The max. number of validators for which attestation duties will be logged "
"(default: 50)"
),
action="store",
default=50,
)
parser.add_argument(
"--validators",
type=str,
help="One or many validator indices for which next duties will be fetched",
help="One or many validator identifiers for which next duties will be fetched",
action="append",
nargs="*",
)
parser.add_argument(
"--validators-file",
type=FileType("r"),
help="File with validator identifiers where every identifier is on a separate line",
action="store",
)
return parser.parse_args()


Expand All @@ -85,9 +91,9 @@ def __validate_fetching_interval(passed_fetching_interval: int) -> None:


def __validate_provided_validator_flag(
validators: List[str] | None, validator_file: str | None
validators: List[str] | None, validators_file: str | None
) -> None:
if (validators and validator_file) or (not validators and not validator_file):
if (validators and validators_file) or (not validators and not validators_file):
raise ArgumentError(
None,
"ONE of the following flags is required: '--validators|-v', '--validator-file|-f'",
Expand All @@ -102,7 +108,7 @@ def __set_arguments() -> Namespace:
"""
arguments = __get_raw_arguments()
__validate_fetching_interval(arguments.interval)
__validate_provided_validator_flag(arguments.validators, arguments.validator_file)
__validate_provided_validator_flag(arguments.validators, arguments.validators_file)
return arguments


Expand Down
5 changes: 3 additions & 2 deletions duties/constants/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
NEXT_INTERVAL_MESSAGE = "Logging next interval..."
NO_UPCOMING_DUTIES_MESSAGE = "No upcoming duties detected!"
TOO_MANY_PROVIDED_VALIDATORS_FOR_FETCHING_ATTESTATION_DUTIES_MESSAGE = (
"Provided number of validator indices for fetching attestion duties is high (> 100). "
"Provided number of validators for fetching attestion duties is high (> %s). "
"This pollutes the console output and prevents checking important duties. "
"Checking attestion duties will be skipped!"
"Checking attestion duties will be skipped! "
"To increase the max. number of logged attestation duties use '--max-attestation-duty-logs'"
)
HIGHER_PROCESSING_TIME_INFO_MESSAGE = (
"You provided %s validators. Fetching all necessary data may take some time."
Expand Down
69 changes: 36 additions & 33 deletions duties/fetcher/fetch.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,19 @@
"""Module which holds all logic for fetching validator duties
"""

from logging import getLogger
from math import ceil
from typing import List

from cli.arguments import ARGUMENTS
from constants import endpoints, program
from constants import endpoints, logging
from fetcher.data_types import DutyType, ValidatorDuty
from fetcher.parser.validators import get_active_validator_indices
from protocol import ethereum
from protocol.request import CalldataType, send_beacon_api_request

__VALIDATORS = get_active_validator_indices()


def is_provided_validator_count_too_high_for_fetching_attestation_duties() -> bool:
"""Checks whether the number of provided validators is too high
for fetching attestation duties and therefore will not be displayed.
Returns:
bool: is number of provided validators >
MAX_NUMBER_OF_VALIDATORS_FOR_FETCHING_ATTESTATION_DUTIES
"""
if (
len(__VALIDATORS)
> program.MAX_NUMBER_OF_VALIDATORS_FOR_FETCHING_ATTESTATION_DUTIES
):
return True
return False
__LOGGER = getLogger(__name__)


def get_next_attestation_duties() -> dict[str, ValidatorDuty]:
Expand All @@ -41,22 +27,19 @@ def get_next_attestation_duties() -> dict[str, ValidatorDuty]:
current_epoch = ethereum.get_current_epoch()
is_any_duty_outdated: List[bool] = [True]
validator_duties: dict[str, ValidatorDuty] = {}
if (
ARGUMENTS.omit_attestation_duties
or len(__VALIDATORS)
> program.MAX_NUMBER_OF_VALIDATORS_FOR_FETCHING_ATTESTATION_DUTIES
):
return validator_duties
while is_any_duty_outdated:
response_data = __fetch_duty_responses(current_epoch, DutyType.ATTESTATION)
validator_duties = {
data.validator_index: __get_next_attestation_duty(data, validator_duties)
for data in response_data
}
is_any_duty_outdated = [
True for duty in validator_duties.values() if duty.slot == 0
]
current_epoch += 1
if __should_fetch_attestation_duties():
while is_any_duty_outdated:
response_data = __fetch_duty_responses(current_epoch, DutyType.ATTESTATION)
validator_duties = {
data.validator_index: __get_next_attestation_duty(
data, validator_duties
)
for data in response_data
}
is_any_duty_outdated = [
True for duty in validator_duties.values() if duty.slot == 0
]
current_epoch += 1
return validator_duties


Expand Down Expand Up @@ -118,6 +101,26 @@ def get_next_proposing_duties() -> dict[str, ValidatorDuty]:
return __filter_proposing_duties(validator_duties)


def __should_fetch_attestation_duties() -> bool:
"""Checks if attestation duties should be fetched
Returns:
bool: Should attestation duties fetched
"""
if (
len(__VALIDATORS) > ARGUMENTS.max_attestation_duty_logs
and ARGUMENTS.log_attestation_duties
):
__LOGGER.warning(
logging.TOO_MANY_PROVIDED_VALIDATORS_FOR_FETCHING_ATTESTATION_DUTIES_MESSAGE,
ARGUMENTS.max_attestation_duty_logs,
)
return False
if not ARGUMENTS.log_attestation_duties:
return False
return True


def __get_next_attestation_duty(
data: ValidatorDuty, present_duties: dict[str, ValidatorDuty]
) -> ValidatorDuty:
Expand Down
2 changes: 1 addition & 1 deletion duties/fetcher/parser/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ def __create_raw_validator_identifiers() -> Dict[str, ValidatorIdentifier]:
): __create_raw_validator_identifier(
str(validator).strip().replace("\n", "").replace("\r\n", "")
)
for validator in ARGUMENTS.validator_file
for validator in ARGUMENTS.validators_file
}


Expand Down
18 changes: 4 additions & 14 deletions duties/main.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
"""Entrypoint for eth-duties to check for upcoming duties for one or many validators
"""

from logging import Logger, getLogger
from logging import getLogger
from time import sleep
from typing import Callable, List

from cli.arguments import ARGUMENTS
from constants import logging
from constants.program import GRACEFUL_KILLER
from fetcher import fetch
from fetcher.data_types import DutyType, ValidatorDuty
Expand All @@ -17,7 +16,7 @@


def __fetch_validator_duties(
duties: List[ValidatorDuty], logger: Logger
duties: List[ValidatorDuty],
) -> List[ValidatorDuty]:
"""Fetches upcoming validator duties
Expand All @@ -29,16 +28,7 @@ def __fetch_validator_duties(
"""
if not __is_current_data_outdated(duties):
return duties
next_attestation_duties: dict[str, ValidatorDuty] = {}
if (
fetch.is_provided_validator_count_too_high_for_fetching_attestation_duties()
and not ARGUMENTS.omit_attestation_duties
):
logger.warning(
logging.TOO_MANY_PROVIDED_VALIDATORS_FOR_FETCHING_ATTESTATION_DUTIES_MESSAGE
)
else:
next_attestation_duties = fetch.get_next_attestation_duties()
next_attestation_duties = fetch.get_next_attestation_duties()
next_sync_committee_duties = fetch.get_next_sync_committee_duties()
next_proposing_duties = fetch.get_next_proposing_duties()
duties = [
Expand Down Expand Up @@ -81,7 +71,7 @@ def __is_current_data_outdated(current_duties: List[ValidatorDuty]) -> bool:
main_logger = getLogger(__name__)
upcoming_duties: List[ValidatorDuty] = []
while not GRACEFUL_KILLER.kill_now:
upcoming_duties = __fetch_validator_duties(upcoming_duties, main_logger)
upcoming_duties = __fetch_validator_duties(upcoming_duties)
log_time_to_next_duties(upcoming_duties)
sleep(ARGUMENTS.interval)
main_logger.info("Happy staking. See you for next maintenance \U0001F642 !")

0 comments on commit 9d55e25

Please sign in to comment.