1+ import json
12import os
23from os import mkdir
34from os .path import exists , join
4- from typing import List
5+ from typing import Dict , List
56
67import click
78import yaml
89
10+ from stakewise_cli .networks import AVAILABLE_NETWORKS , MAINNET , NETWORKS
911from stakewise_cli .storages .database import Database , check_db_connection
1012from stakewise_cli .utils import is_lists_equal
1113from stakewise_cli .validators import validate_db_uri , validate_env_name
1214
1315PUBLIC_KEYS_CSV_FILENAME = "validator_keys.csv"
1416LIGHTHOUSE_CONFIG_FILENAME = "validator_definitions.yml"
1517SIGNER_CONFIG_FILENAME = "signer_keys.yml"
18+ SIGNER_PROPOSER_CONFIG_FILENAME = "proposerConfig.json"
1619WEB3SIGNER_URL_ENV = "WEB3SIGNER_URL"
1720
1821
1922@click .command (help = "Synchronizes validator public keys from the database" )
23+ @click .option (
24+ "--network" ,
25+ default = MAINNET ,
26+ help = "The network to generate the deposit data for" ,
27+ prompt = "Enter the network name" ,
28+ type = click .Choice (
29+ AVAILABLE_NETWORKS ,
30+ case_sensitive = False ,
31+ ),
32+ )
2033@click .option (
2134 "--db-url" ,
2235 help = "The database connection address." ,
3952 default = WEB3SIGNER_URL_ENV ,
4053 callback = validate_env_name ,
4154)
55+ @click .option (
56+ "--solo-fees-file" ,
57+ help = "The path to solo validator's fee distribution path" ,
58+ type = click .Path (exists = True , file_okay = True , dir_okay = False ),
59+ )
4260def sync_validator_keys (
43- db_url : str , index : int , output_dir : str , web3signer_url_env : str
61+ network : str ,
62+ db_url : str ,
63+ index : int ,
64+ output_dir : str ,
65+ web3signer_url_env : str ,
66+ solo_fees_file : str ,
4467) -> None :
4568 """
4669 The command is running by the init container in validator pods.
@@ -67,10 +90,19 @@ def sync_validator_keys(
6790 )
6891 return
6992
93+ default_fee_recipient = NETWORKS [network ]["FEE_DISTRIBUTION_CONTRACT_ADDRESS" ]
94+ solo_fee_mapping = {}
95+ if solo_fees_file :
96+ with open (solo_fees_file ) as f :
97+ solo_fee_mapping = json .load (f )
98+
7099 # save lighthouse config
71100 web3signer_url = os .environ [web3signer_url_env ]
72101 lighthouse_config = _generate_lighthouse_config (
73- public_keys = keys , web3signer_url = web3signer_url
102+ public_keys = keys ,
103+ web3signer_url = web3signer_url ,
104+ default_fee_recipient = default_fee_recipient ,
105+ solo_fee_mapping = solo_fee_mapping ,
74106 )
75107 with open (join (output_dir , LIGHTHOUSE_CONFIG_FILENAME ), "w" ) as f :
76108 f .write (lighthouse_config )
@@ -79,6 +111,12 @@ def sync_validator_keys(
79111 signer_keys_config = _generate_signer_keys_config (public_keys = keys )
80112 with open (join (output_dir , SIGNER_CONFIG_FILENAME ), "w" ) as f :
81113 f .write (signer_keys_config )
114+ proposer_config = _generate_proposer_config (
115+ default_fee_recipient = default_fee_recipient ,
116+ solo_fee_mapping = solo_fee_mapping ,
117+ )
118+ with open (join (output_dir , SIGNER_PROPOSER_CONFIG_FILENAME ), "w" ) as f :
119+ f .write (proposer_config )
82120
83121 click .secho (
84122 f"The validator now uses { len (keys )} public keys.\n " ,
@@ -87,7 +125,12 @@ def sync_validator_keys(
87125 )
88126
89127
90- def _generate_lighthouse_config (public_keys : List [str ], web3signer_url : str ) -> str :
128+ def _generate_lighthouse_config (
129+ public_keys : List [str ],
130+ web3signer_url : str ,
131+ default_fee_recipient : str ,
132+ solo_fee_mapping : Dict [str , str ],
133+ ) -> str :
91134 """
92135 Generate config for Lighthouse clients
93136 """
@@ -97,6 +140,9 @@ def _generate_lighthouse_config(public_keys: List[str], web3signer_url: str) ->
97140 "voting_public_key" : public_key ,
98141 "type" : "web3signer" ,
99142 "url" : web3signer_url ,
143+ "suggested_fee_recipient" : solo_fee_mapping .get (
144+ public_key , default_fee_recipient
145+ ),
100146 }
101147 for public_key in public_keys
102148 ]
@@ -121,3 +167,31 @@ def _generate_signer_keys_config(public_keys: List[str]) -> str:
121167 """
122168 keys = "," .join ([f'"{ public_key } "' for public_key in public_keys ])
123169 return f"""validators-external-signer-public-keys: [{ keys } ]"""
170+
171+
172+ def _generate_proposer_config (
173+ default_fee_recipient : str , solo_fee_mapping : Dict [str , str ]
174+ ) -> str :
175+ """
176+ Generate config for Teku and Prysm clients
177+ """
178+ config = {
179+ "proposer_config" : {
180+ ** {
181+ public_key : {
182+ "fee_recipient" : fee_recipient ,
183+ "builder" : {
184+ "enabled" : True ,
185+ },
186+ }
187+ for public_key , fee_recipient in solo_fee_mapping .items ()
188+ }
189+ },
190+ "default_config" : {
191+ "fee_recipient" : default_fee_recipient ,
192+ "builder" : {
193+ "enabled" : True ,
194+ },
195+ },
196+ }
197+ return json .dumps (config )
0 commit comments