Skip to content

Commit db6449d

Browse files
Adapted remote keystore for Obol (#12)
1 parent e55f275 commit db6449d

File tree

4 files changed

+45
-10
lines changed

4 files changed

+45
-10
lines changed

src/config/settings.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,12 @@
5050
ssv_api_base_url = 'https://api.ssv.network/api/v4'
5151
ssv_api_timeout = 10
5252

53-
remote_signer_url: str = config('remote_signer_url', default='')
53+
remote_signer_url: str = config('REMOTE_SIGNER_URL', default='')
5454
remote_signer_timeout: int = config('REMOTE_SIGNER_TIMEOUT', cast=int, default=10)
5555

5656
# validations
5757

58+
# Check OBOL_KEYSTORES_DIR
5859
if (
5960
not remote_signer_url
6061
and cluster_type == OBOL
@@ -63,6 +64,15 @@
6364
):
6465
raise RuntimeError('OBOL_KEYSTORES_DIR or OBOL_KEYSTORES_DIR_TEMPLATE must be set')
6566

67+
# Check cluster type for remote signer
68+
if remote_signer_url and cluster_type != OBOL:
69+
raise RuntimeError('Remote signer keystore is implemented for Obol only')
70+
71+
# Check OBOL_CLUSTER_LOCK_FILE
72+
if cluster_type == OBOL and not obol_cluster_lock_file:
73+
raise RuntimeError('OBOL_CLUSTER_LOCK_FILE must be set')
74+
75+
# Check SSV_OPERATOR_KEY_FILE
6676
if (
6777
not remote_signer_url
6878
and cluster_type == SSV
@@ -71,6 +81,7 @@
7181
):
7282
raise RuntimeError('SSV_OPERATOR_KEY_FILE or SSV_OPERATOR_KEY_FILE_TEMPLATE must be set')
7383

84+
# Check SSV_OPERATOR_PASSWORD_FILE
7485
if (
7586
not remote_signer_url
7687
and cluster_type == SSV

src/validators/keystores/load.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
from src.config.settings import OBOL, SSV
77
from src.validators.keystores.base import BaseKeystore
88
from src.validators.keystores.obol import ObolKeystore
9-
from src.validators.keystores.remote import RemoteSignerKeystore
9+
from src.validators.keystores.obol_remote import ObolRemoteKeystore
1010
from src.validators.keystores.ssv import SSVKeystore
1111

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

1414

1515
async def load_keystore() -> BaseKeystore:
1616
if settings.remote_signer_url:
17-
remote_keystore = await RemoteSignerKeystore.load()
17+
remote_keystore = await ObolRemoteKeystore.load()
1818
logger.info(
1919
'Using remote signer at %s for %i public keys',
2020
settings.remote_signer_url,

src/validators/keystores/obol.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,6 @@ async def load_from_dir(keystores_dir: Path, node_index: int) -> 'ObolKeystore':
6060

6161
@staticmethod
6262
def load_cluster_lock() -> dict:
63-
if not settings.obol_cluster_lock_file:
64-
raise RuntimeError('OBOL_CLUSTER_LOCK_FILE must be set')
65-
6663
return json.load(open(settings.obol_cluster_lock_file, encoding='ascii'))
6764

6865
@staticmethod
Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import dataclasses
2+
import json
23
import logging
34
from dataclasses import dataclass
45
from typing import cast
@@ -45,14 +46,40 @@ class VoluntaryExitRequestModel:
4546
voluntary_exit: VoluntaryExitMessage
4647

4748

48-
class RemoteSignerKeystore(BaseKeystore):
49-
def __init__(self, public_keys: list[HexStr]):
49+
class ObolRemoteKeystore(BaseKeystore):
50+
"""
51+
Similar to RemoteKeystore from Stakewise Operator.
52+
Also pubkey_to_share attribute is filled using cluster lock file.
53+
"""
54+
55+
def __init__(self, public_keys: list[HexStr], pubkey_to_share: dict[HexStr, HexStr]):
5056
self._public_keys = public_keys
57+
self.pubkey_to_share = pubkey_to_share
5158

5259
@staticmethod
5360
async def load() -> 'BaseKeystore':
54-
public_keys = await RemoteSignerKeystore._get_remote_signer_public_keys()
55-
return RemoteSignerKeystore(public_keys)
61+
if settings.obol_node_index is None:
62+
raise RuntimeError('OBOL_NODE_INDEX must be set')
63+
64+
public_keys = await ObolRemoteKeystore._get_remote_signer_public_keys()
65+
pubkey_to_share = ObolRemoteKeystore.get_pubkey_to_share(settings.obol_node_index)
66+
return ObolRemoteKeystore(public_keys, pubkey_to_share)
67+
68+
@staticmethod
69+
def load_cluster_lock() -> dict:
70+
return json.load(open(settings.obol_cluster_lock_file, encoding='ascii'))
71+
72+
@staticmethod
73+
def get_pubkey_to_share(node_index: int) -> dict[HexStr, HexStr]:
74+
cluster_lock = ObolRemoteKeystore.load_cluster_lock()
75+
76+
pub_key_to_share = {}
77+
for dv in cluster_lock['distributed_validators']:
78+
public_key = dv['distributed_public_key']
79+
public_key_share = dv['public_shares'][node_index]
80+
pub_key_to_share[public_key] = public_key_share
81+
82+
return pub_key_to_share
5683

5784
def __bool__(self) -> bool:
5885
return bool(self._public_keys)

0 commit comments

Comments
 (0)