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

Adapted remote keystore for Obol #12

Merged
merged 1 commit into from
Oct 18, 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
13 changes: 12 additions & 1 deletion src/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,12 @@
ssv_api_base_url = 'https://api.ssv.network/api/v4'
ssv_api_timeout = 10

remote_signer_url: str = config('remote_signer_url', default='')
remote_signer_url: str = config('REMOTE_SIGNER_URL', default='')
remote_signer_timeout: int = config('REMOTE_SIGNER_TIMEOUT', cast=int, default=10)

# validations

# Check OBOL_KEYSTORES_DIR
if (
not remote_signer_url
and cluster_type == OBOL
Expand All @@ -63,6 +64,15 @@
):
raise RuntimeError('OBOL_KEYSTORES_DIR or OBOL_KEYSTORES_DIR_TEMPLATE must be set')

# Check cluster type for remote signer
if remote_signer_url and cluster_type != OBOL:
raise RuntimeError('Remote signer keystore is implemented for Obol only')

# Check OBOL_CLUSTER_LOCK_FILE
if cluster_type == OBOL and not obol_cluster_lock_file:
raise RuntimeError('OBOL_CLUSTER_LOCK_FILE must be set')

# Check SSV_OPERATOR_KEY_FILE
if (
not remote_signer_url
and cluster_type == SSV
Expand All @@ -71,6 +81,7 @@
):
raise RuntimeError('SSV_OPERATOR_KEY_FILE or SSV_OPERATOR_KEY_FILE_TEMPLATE must be set')

# Check SSV_OPERATOR_PASSWORD_FILE
if (
not remote_signer_url
and cluster_type == SSV
Expand Down
4 changes: 2 additions & 2 deletions src/validators/keystores/load.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
from src.config.settings import OBOL, SSV
from src.validators.keystores.base import BaseKeystore
from src.validators.keystores.obol import ObolKeystore
from src.validators.keystores.remote import RemoteSignerKeystore
from src.validators.keystores.obol_remote import ObolRemoteKeystore
from src.validators.keystores.ssv import SSVKeystore

logger = cast(ExtendedLogger, logging.getLogger(__name__))


async def load_keystore() -> BaseKeystore:
if settings.remote_signer_url:
remote_keystore = await RemoteSignerKeystore.load()
remote_keystore = await ObolRemoteKeystore.load()
logger.info(
'Using remote signer at %s for %i public keys',
settings.remote_signer_url,
Expand Down
3 changes: 0 additions & 3 deletions src/validators/keystores/obol.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ async def load_from_dir(keystores_dir: Path, node_index: int) -> 'ObolKeystore':

@staticmethod
def load_cluster_lock() -> dict:
if not settings.obol_cluster_lock_file:
raise RuntimeError('OBOL_CLUSTER_LOCK_FILE must be set')

return json.load(open(settings.obol_cluster_lock_file, encoding='ascii'))

@staticmethod
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import dataclasses
import json
import logging
from dataclasses import dataclass
from typing import cast
Expand Down Expand Up @@ -45,14 +46,40 @@ class VoluntaryExitRequestModel:
voluntary_exit: VoluntaryExitMessage


class RemoteSignerKeystore(BaseKeystore):
def __init__(self, public_keys: list[HexStr]):
class ObolRemoteKeystore(BaseKeystore):
"""
Similar to RemoteKeystore from Stakewise Operator.
Also pubkey_to_share attribute is filled using cluster lock file.
"""

def __init__(self, public_keys: list[HexStr], pubkey_to_share: dict[HexStr, HexStr]):
self._public_keys = public_keys
self.pubkey_to_share = pubkey_to_share

@staticmethod
async def load() -> 'BaseKeystore':
public_keys = await RemoteSignerKeystore._get_remote_signer_public_keys()
return RemoteSignerKeystore(public_keys)
if settings.obol_node_index is None:
raise RuntimeError('OBOL_NODE_INDEX must be set')

public_keys = await ObolRemoteKeystore._get_remote_signer_public_keys()
pubkey_to_share = ObolRemoteKeystore.get_pubkey_to_share(settings.obol_node_index)
return ObolRemoteKeystore(public_keys, pubkey_to_share)

@staticmethod
def load_cluster_lock() -> dict:
return json.load(open(settings.obol_cluster_lock_file, encoding='ascii'))

@staticmethod
def get_pubkey_to_share(node_index: int) -> dict[HexStr, HexStr]:
cluster_lock = ObolRemoteKeystore.load_cluster_lock()

pub_key_to_share = {}
for dv in cluster_lock['distributed_validators']:
public_key = dv['distributed_public_key']
public_key_share = dv['public_shares'][node_index]
pub_key_to_share[public_key] = public_key_share

return pub_key_to_share

def __bool__(self) -> bool:
return bool(self._public_keys)
Expand Down
Loading