-
Notifications
You must be signed in to change notification settings - Fork 21
Nodes manager registration only #700
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
Changes from all commits
f071df3
0d9cc6f
a891e0b
bf3bab8
0472644
c25973a
39ae716
9b73270
f62ca6f
967cb2c
722eef0
1461a46
55e73e2
df0c168
bddd47a
0abf534
d8ffd65
e8dc553
d7db0a5
c4c4cb2
00dad4e
90440b7
ca37031
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,12 +6,18 @@ | |
| import click | ||
| from eth_typing import ChecksumAddress | ||
| from sw_utils import InterruptHandler | ||
| from web3.types import Gwei | ||
|
|
||
| from src.common.clients import close_clients, setup_clients | ||
| from src.common.logging import LOG_LEVELS, setup_logging | ||
| from src.common.protocol_config import update_oracles_cache | ||
| from src.common.typings import ValidatorType | ||
| from src.common.utils import log_verbose | ||
| from src.common.validators import validate_eth_address | ||
| from src.config.networks import AVAILABLE_NETWORKS, NETWORKS | ||
| from src.common.validators import ( | ||
| validate_eth_address, | ||
| validate_max_validator_balance_gwei, | ||
| ) | ||
| from src.config.networks import AVAILABLE_NETWORKS, MAINNET, NETWORKS | ||
| from src.config.settings import ( | ||
| DEFAULT_CONSENSUS_ENDPOINT, | ||
| DEFAULT_EXECUTION_ENDPOINT, | ||
|
|
@@ -21,14 +27,68 @@ | |
| ) | ||
| from src.node_manager.startup_check import startup_checks | ||
| from src.node_manager.tasks import NodeManagerTask | ||
| from src.validators.database import NetworkValidatorCrud | ||
| from src.validators.keystores.load import load_keystore | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| @click.option( | ||
| '--withdrawals-address', | ||
| '--keystores-password-file', | ||
| type=click.Path(exists=True, file_okay=True, dir_okay=False), | ||
| envvar='KEYSTORES_PASSWORD_FILE', | ||
| help='Absolute path to the password file for decrypting keystores.', | ||
| ) | ||
| @click.option( | ||
| '--keystores-dir', | ||
| type=click.Path(exists=True, file_okay=False, dir_okay=True), | ||
| envvar='KEYSTORES_DIR', | ||
| help='Absolute path to the directory with all the encrypted keystores.', | ||
| ) | ||
| @click.option( | ||
| '--wallet-password-file', | ||
| type=click.Path(exists=True, file_okay=True, dir_okay=False), | ||
| envvar='WALLET_PASSWORD_FILE', | ||
| help='Absolute path to the wallet password file.', | ||
| ) | ||
| @click.option( | ||
| '--wallet-file', | ||
| type=click.Path(exists=True, file_okay=True, dir_okay=False), | ||
| envvar='WALLET_FILE', | ||
| help='Absolute path to the wallet.', | ||
| ) | ||
| @click.option( | ||
| '--max-validator-balance-gwei', | ||
| type=int, | ||
| envvar='MAX_VALIDATOR_BALANCE_GWEI', | ||
| help=f'The maximum validator balance in Gwei. ' | ||
| f'Default is {NETWORKS[MAINNET].MAX_VALIDATOR_BALANCE_GWEI} Gwei', | ||
| callback=validate_max_validator_balance_gwei, | ||
| ) | ||
| @click.option( | ||
| '--validator-type', | ||
| help='Type of the validators to register:' | ||
| f' {ValidatorType.V1.value} or {ValidatorType.V2.value}.', | ||
| envvar='VALIDATOR_TYPE', | ||
| default=ValidatorType.V2.value, | ||
| type=click.Choice( | ||
| [x.value for x in ValidatorType], | ||
| case_sensitive=False, | ||
| ), | ||
| callback=lambda ctx, param, value: ValidatorType(value), | ||
| show_default=True, | ||
| ) | ||
| @click.option( | ||
| '--max-fee-per-gas-gwei', | ||
| type=int, | ||
| envvar='MAX_FEE_PER_GAS_GWEI', | ||
| help=f'Maximum fee per gas for transactions. ' | ||
| f'Default is {NETWORKS[MAINNET].MAX_FEE_PER_GAS_GWEI} Gwei', | ||
| ) | ||
| @click.option( | ||
| '--operator-address', | ||
| callback=validate_eth_address, | ||
| envvar='WITHDRAWALS_ADDRESS', | ||
| envvar='OPERATOR_ADDRESS', | ||
| prompt='Enter your operator withdrawals (cold wallet) address', | ||
| help='The operator withdrawals (cold wallet) address.', | ||
| ) | ||
|
|
@@ -96,7 +156,7 @@ | |
| show_default=True, | ||
| ) | ||
| @click.command(help='Start node manager operator service') | ||
| # pylint: disable-next=too-many-arguments | ||
| # pylint: disable-next=too-many-arguments,too-many-locals | ||
| def node_manager_start( | ||
| consensus_endpoints: str, | ||
| execution_endpoints: str, | ||
|
|
@@ -106,7 +166,14 @@ def node_manager_start( | |
| log_level: str, | ||
| log_format: str, | ||
| network: str, | ||
| withdrawals_address: ChecksumAddress, | ||
| operator_address: ChecksumAddress, | ||
| max_fee_per_gas_gwei: int | None, | ||
| validator_type: ValidatorType, | ||
| max_validator_balance_gwei: int | None, | ||
| wallet_file: str | None, | ||
| wallet_password_file: str | None, | ||
| keystores_dir: str | None, | ||
| keystores_password_file: str | None, | ||
| ) -> None: | ||
| network_config = NETWORKS[network] | ||
| vault = network_config.COMMUNITY_VAULT_CONTRACT_ADDRESS | ||
|
|
@@ -122,27 +189,50 @@ def node_manager_start( | |
| verbose=verbose, | ||
| log_level=log_level, | ||
| log_format=log_format, | ||
| max_fee_per_gas_gwei=max_fee_per_gas_gwei, | ||
| validator_type=validator_type, | ||
| max_validator_balance_gwei=( | ||
| Gwei(max_validator_balance_gwei) if max_validator_balance_gwei else None | ||
| ), | ||
|
Comment on lines
+194
to
+196
|
||
| keystores_dir=keystores_dir, | ||
| keystores_password_file=keystores_password_file, | ||
| wallet_file=wallet_file, | ||
| wallet_password_file=wallet_password_file, | ||
| ) | ||
|
|
||
| try: | ||
| asyncio.run(_start(withdrawals_address)) | ||
| asyncio.run(_start(operator_address)) | ||
| except Exception as e: | ||
| log_verbose(e) | ||
| sys.exit(1) | ||
|
|
||
|
|
||
| async def _start(withdrawals_address: ChecksumAddress) -> None: | ||
| async def _start( | ||
| operator_address: ChecksumAddress, | ||
| ) -> None: | ||
| setup_logging() | ||
| await setup_clients() | ||
|
|
||
| if not settings.skip_startup_checks: | ||
| await startup_checks(withdrawals_address) | ||
| await startup_checks(operator_address) | ||
| try: | ||
| NetworkValidatorCrud().setup() | ||
|
|
||
| keystore = await load_keystore() | ||
|
|
||
| # start operator tasks | ||
| logger.info('Updating oracles cache...') | ||
| await update_oracles_cache() | ||
|
|
||
| logger.info( | ||
| 'Started node manager service, polling eligibility for %s', | ||
| withdrawals_address, | ||
| operator_address, | ||
| ) | ||
| with InterruptHandler() as interrupt_handler: | ||
| await NodeManagerTask(withdrawals_address).run(interrupt_handler) | ||
| task = NodeManagerTask( | ||
| operator_address=operator_address, | ||
| keystore=keystore, | ||
| ) | ||
| await task.run(interrupt_handler) | ||
| finally: | ||
| await close_clients() | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CLI help states a default value, but the option does not set a Click
default=..., somax_validator_balance_gweiwill beNonewhen omitted. Ifsettings.configure(...)appliesNoneliterally, this can override the intended network default and break V2 deposit splitting. Set an explicit Click default (preferably derived from the selected network), or avoid passing the field tosettings.configurewhen the option is unset.