@@ -144,17 +144,46 @@ async fn run<E: EthSpec>(config: ExitConfig) -> Result<(), String> {
144144 validators_to_exit = validators. iter ( ) . map ( |v| v. validating_pubkey ) . collect ( ) ;
145145 }
146146
147- for validator_to_exit in validators_to_exit {
147+ // Beacon node data to be used later
148+ let beacon_node = if let Some ( ref beacon_url) = beacon_url {
149+ BeaconNodeHttpClient :: new (
150+ SensitiveUrl :: parse ( beacon_url. as_ref ( ) )
151+ . map_err ( |e| format ! ( "Failed to parse beacon http server: {:?}" , e) ) ?,
152+ Timeouts :: set_all ( Duration :: from_secs ( 12 ) ) ,
153+ )
154+ } else {
155+ return Err ( "Beacon URL is not provided" . into ( ) ) ;
156+ } ;
157+
158+ let genesis_data = beacon_node
159+ . get_beacon_genesis ( )
160+ . await
161+ . map_err ( |e| format ! ( "Failed to get genesis data: {}" , e) ) ?
162+ . data ;
163+
164+ let config_and_preset = beacon_node
165+ . get_config_spec :: < ConfigAndPreset > ( )
166+ . await
167+ . map_err ( |e| format ! ( "Failed to get config spec: {}" , e) ) ?
168+ . data ;
169+
170+ let spec = ChainSpec :: from_config :: < E > ( config_and_preset. config ( ) )
171+ . ok_or ( "Failed to create chain spec" ) ?;
172+
173+ let current_epoch = get_current_epoch :: < E > ( genesis_data. genesis_time , & spec)
174+ . ok_or ( "Failed to get current epoch. Please check your system time" ) ?;
175+
176+ for validator_to_exit in & validators_to_exit {
148177 // Check that the validators_to_exit is in the validator client
149178 if !validators
150179 . iter ( )
151- . any ( |validator| validator. validating_pubkey == validator_to_exit)
180+ . any ( |validator| & validator. validating_pubkey == validator_to_exit)
152181 {
153182 return Err ( format ! ( "Validator {} doesn't exist" , validator_to_exit) ) ;
154183 }
155184
156185 let exit_message = http_client
157- . post_validator_voluntary_exit ( & validator_to_exit, exit_epoch)
186+ . post_validator_voluntary_exit ( validator_to_exit, exit_epoch)
158187 . await
159188 . map_err ( |e| format ! ( "Failed to generate voluntary exit message: {}" , e) ) ?;
160189
@@ -168,16 +197,6 @@ async fn run<E: EthSpec>(config: ExitConfig) -> Result<(), String> {
168197
169198 // only publish the voluntary exit if the --beacon-node flag is present
170199 if beacon_url. is_some ( ) {
171- let beacon_node = if let Some ( ref beacon_url) = beacon_url {
172- BeaconNodeHttpClient :: new (
173- SensitiveUrl :: parse ( beacon_url. as_ref ( ) )
174- . map_err ( |e| format ! ( "Failed to parse beacon http server: {:?}" , e) ) ?,
175- Timeouts :: set_all ( Duration :: from_secs ( 12 ) ) ,
176- )
177- } else {
178- return Err ( "Beacon URL is not provided" . into ( ) ) ;
179- } ;
180-
181200 if beacon_node
182201 . get_node_syncing ( )
183202 . await
@@ -191,38 +210,20 @@ async fn run<E: EthSpec>(config: ExitConfig) -> Result<(), String> {
191210 ) ;
192211 }
193212
194- let genesis_data = beacon_node
195- . get_beacon_genesis ( )
196- . await
197- . map_err ( |e| format ! ( "Failed to get genesis data: {}" , e) ) ?
198- . data ;
199-
200- let config_and_preset = beacon_node
201- . get_config_spec :: < ConfigAndPreset > ( )
202- . await
203- . map_err ( |e| format ! ( "Failed to get config spec: {}" , e) ) ?
204- . data ;
205-
206- let spec = ChainSpec :: from_config :: < E > ( config_and_preset. config ( ) )
207- . ok_or_else ( || "Failed to create chain spec" . to_string ( ) ) ?;
208-
209213 let validator_data = beacon_node
210- . get_beacon_states_validator_id (
211- StateId :: Head ,
212- & ValidatorId :: PublicKey ( validator_to_exit) ,
213- )
214+ . get_beacon_states_validator_id ( StateId :: Head , & ValidatorId :: PublicKey ( * validator_to_exit) )
214215 . await
215216 . map_err ( |e| format ! ( "Failed to get validator details: {:?}" , e) ) ?
216217 . ok_or_else ( || {
217218 format ! (
218219 "Validator {} is not present in the beacon state. \
219- Please ensure that your beacon node is synced and the validator has been deposited.",
220- validator_to_exit) } ) ?
220+ Please ensure that your beacon node is synced and the validator has been deposited.",
221+ validator_to_exit
222+ )
223+ } ) ?
221224 . data ;
222225
223226 let activation_epoch = validator_data. validator . activation_epoch ;
224- let current_epoch = get_current_epoch :: < E > ( genesis_data. genesis_time , & spec)
225- . ok_or ( "Failed to get current epoch. Please check your system time" ) ?;
226227
227228 // Check if validator is eligible for exit
228229 if validator_data. status == ValidatorStatus :: ActiveOngoing
@@ -250,47 +251,49 @@ async fn run<E: EthSpec>(config: ExitConfig) -> Result<(), String> {
250251 validator_to_exit
251252 ) ;
252253 }
254+ }
255+ }
253256
254- sleep ( Duration :: from_secs ( spec. seconds_per_slot ) ) . await ;
257+ sleep ( Duration :: from_secs ( spec. seconds_per_slot ) ) . await ;
255258
256- // Check validator status after publishing voluntary exit
257- let updated_validator_data = beacon_node
258- . get_beacon_states_validator_id (
259- StateId :: Head ,
260- & ValidatorId :: PublicKey ( validator_to_exit) ,
259+ // Check validator status after publishing voluntary exit
260+ for validator_to_exit in validators_to_exit {
261+ let updated_validator_data = beacon_node
262+ . get_beacon_states_validator_id (
263+ StateId :: Head ,
264+ & ValidatorId :: PublicKey ( validator_to_exit) ,
265+ )
266+ . await
267+ . map_err ( |e| format ! ( "Failed to get updated validator details: {:?}" , e) ) ?
268+ . ok_or_else ( || {
269+ format ! (
270+ "Validator {} is not present in the beacon state" ,
271+ validator_to_exit
261272 )
262- . await
263- . map_err ( |e| format ! ( "Failed to get updated validator details: {:?}" , e) ) ?
264- . ok_or_else ( || {
265- format ! (
266- "Validator {} is not present in the beacon state" ,
267- validator_to_exit
268- )
269- } ) ?
270- . data ;
273+ } ) ?
274+ . data ;
271275
272- match updated_validator_data. status {
273- ValidatorStatus :: ActiveExiting => {
274- let exit_epoch = updated_validator_data. validator . exit_epoch ;
275- let withdrawal_epoch = updated_validator_data. validator . withdrawable_epoch ;
276+ match updated_validator_data. status {
277+ ValidatorStatus :: ActiveExiting => {
278+ let exit_epoch = updated_validator_data. validator . exit_epoch ;
279+ let withdrawal_epoch = updated_validator_data. validator . withdrawable_epoch ;
276280
277- eprintln ! ( "Voluntary exit has been accepted into the beacon chain, but not yet finalized. \
281+ eprintln ! ( "Voluntary exit has been accepted into the beacon chain, but not yet finalized. \
278282 Finalization may take several minutes or longer. Before finalization there is a low \
279283 probability that the exit may be reverted.") ;
280- eprintln ! (
281- "Current epoch: {}, Exit epoch: {}, Withdrawable epoch: {}" ,
282- current_epoch, exit_epoch, withdrawal_epoch
283- ) ;
284- eprintln ! ( "Please keep your validator running till exit epoch" ) ;
285- eprintln ! (
286- "Exit epoch in approximately {} secs" ,
287- ( exit_epoch - current_epoch) * spec. seconds_per_slot * E :: slots_per_epoch( )
288- ) ;
289- }
290-
291- _ => {
292- eprintln ! ( "Waiting for voluntary exit to be accepted into the beacon chain..." )
293- }
284+ eprintln ! (
285+ "Current epoch: {}, Exit epoch: {}, Withdrawable epoch: {}" ,
286+ current_epoch, exit_epoch, withdrawal_epoch
287+ ) ;
288+ eprintln ! ( "Please keep your validator running till exit epoch" ) ;
289+ eprintln ! (
290+ "Exit epoch in approximately {} secs" ,
291+ ( exit_epoch - current_epoch) * spec. seconds_per_slot * E :: slots_per_epoch( )
292+ ) ;
293+ }
294+
295+ _ => {
296+ eprintln ! ( "Waiting for voluntary exit to be accepted into the beacon chain..." )
294297 }
295298 }
296299 }
0 commit comments