Skip to content

Commit

Permalink
Add signer yaml config generation to sync_validator_keys (#54)
Browse files Browse the repository at this point in the history
* Add signer yaml config generation to sync_validator_keys

* Add client specific comments to sync_validator_keys
  • Loading branch information
cyc60 authored Aug 15, 2022
1 parent 3089b3a commit ea17ec9
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
18 changes: 18 additions & 0 deletions stakewise_cli/commands/sync_validator_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

PUBLIC_KEYS_CSV_FILENAME = "validator_keys.csv"
LIGHTHOUSE_CONFIG_FILENAME = "validator_definitions.yml"
SIGNER_CONFIG_FILENAME = "signer_keys.yml"
WEB3SIGNER_URL_ENV = "WEB3SIGNER_URL"


Expand Down Expand Up @@ -81,6 +82,11 @@ def sync_validator_keys(
with open(join(output_dir, LIGHTHOUSE_CONFIG_FILENAME), "w") as f:
f.write(lighthouse_config)

# save external signer public keys
signer_keys_config = _generate_signer_keys_config(public_keys=keys)
with open(join(output_dir, SIGNER_CONFIG_FILENAME), "w") as f:
f.write(signer_keys_config)

click.secho(
f"The validator now uses {len(keys)} public keys.\n",
bold=True,
Expand All @@ -89,6 +95,9 @@ def sync_validator_keys(


def _generate_lighthouse_config(public_keys: List[str], web3signer_url: str) -> str:
"""
Generate config for Lighthouse clients
"""
items = [
{
"enabled": True,
Expand All @@ -100,3 +109,12 @@ def _generate_lighthouse_config(public_keys: List[str], web3signer_url: str) ->
]

return yaml.dump(items, explicit_start=True)


def _generate_signer_keys_config(public_keys: List[str]) -> str:
"""
Generate config for Teku and Prysm clients
"""
items = [{"validators-external-signer-public-keys": public_keys}]

return yaml.dump(items).replace("'", "")[2:]
82 changes: 82 additions & 0 deletions stakewise_cli/tests/test_sync_validator_keys.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import os
import unittest
from unittest.mock import patch

from click.testing import CliRunner
from py_ecc.bls import G2ProofOfPossession
from staking_deposit.key_handling.key_derivation.mnemonic import get_mnemonic
from web3 import Web3

from stakewise_cli.commands.sync_validator_keys import sync_validator_keys
from stakewise_cli.eth2 import WORD_LISTS_PATH, get_mnemonic_signing_key

w3 = Web3()

mnemonic = get_mnemonic(language="english", words_path=WORD_LISTS_PATH)
keys_count = 5
web3_signer_url = "http://web3signer:6174"


def get_public_keys(mnemonic, keys_count):
result = []
for i in range(keys_count):
signing_key = get_mnemonic_signing_key(mnemonic, i, is_legacy=False)
public_key = w3.toHex(G2ProofOfPossession.SkToPk(signing_key.key))
result.append(public_key)
return result


public_keys = get_public_keys(mnemonic=mnemonic, keys_count=keys_count)


@patch("stakewise_cli.commands.sync_validator_keys.check_db_connection")
@patch(
"stakewise_cli.commands.sync_validator_keys.Database.fetch_public_keys_by_validator_index",
return_value=public_keys,
)
@patch.dict(os.environ, {"WEB3SIGNER_URL": web3_signer_url})
class TestCommand(unittest.TestCase):
def test_sync_validator_keys(self, *mocks):
db_url = "postgresql://username:pass@hostname/dbname"
index = 1
runner = CliRunner()
args = [
"--index",
index,
"--db-url",
db_url,
"--output-dir",
"./valdata",
]
with runner.isolated_filesystem():
result = runner.invoke(sync_validator_keys, args)
assert result.exit_code == 0

assert (
f"The validator now uses {keys_count} public keys."
== result.output.strip()
)
with open("./valdata/validator_definitions.yml") as f:
s = """---"""
for public_key in public_keys:
s += f"""
- enabled: true
type: web3signer
url: {web3_signer_url}
voting_public_key: \'{public_key}\'"""
s += "\n"
assert f.read() == s

with open("./valdata/validator_keys.csv") as f:
s = ",".join(public_keys) + "\n"
assert f.read() == s

with open("./valdata/signer_keys.yml") as f:
s = """validators-external-signer-public-keys:\n"""
for public_key in public_keys:
s += f" - {public_key}\n"
assert f.read() == s

result = runner.invoke(sync_validator_keys, args)
assert result.exit_code == 0
assert "Keys already synced to the last version." == result.output.strip()

0 comments on commit ea17ec9

Please sign in to comment.