Skip to content

Commit d9c423d

Browse files
committed
Add exit multiple validators
1 parent d4bc9f6 commit d9c423d

File tree

1 file changed

+45
-42
lines changed

1 file changed

+45
-42
lines changed

validator_manager/src/exit_validators.rs

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -68,24 +68,24 @@ pub fn cli_app() -> Command {
6868
pub struct ExitConfig {
6969
pub vc_url: SensitiveUrl,
7070
pub vc_token_path: PathBuf,
71-
pub validators_to_exit: PublicKeyBytes,
71+
pub validators_to_exit: Vec<PublicKeyBytes>,
7272
pub beacon_url: Option<SensitiveUrl>,
7373
pub exit_epoch: Option<Epoch>,
7474
}
7575

7676
impl ExitConfig {
7777
fn from_cli(matches: &ArgMatches) -> Result<Self, String> {
78-
// let validator_to_exit_str = clap_utils::parse_required::<String>(matches, VALIDATOR_FLAG)?;
78+
let validators_to_exit_str = clap_utils::parse_required::<String>(matches, VALIDATOR_FLAG)?;
7979

80-
// let validators_to_exit = validators_to_exit_str
81-
// .split(',')
82-
// .map(|s| s.trim().parse())
83-
// .collect::<Result<Vec<PublicKeyBytes>, _>>()?;
80+
let validators_to_exit = validators_to_exit_str
81+
.split(',')
82+
.map(|s| s.trim().parse())
83+
.collect::<Result<Vec<PublicKeyBytes>, _>>()?;
8484

8585
Ok(Self {
8686
vc_url: clap_utils::parse_required(matches, VC_URL_FLAG)?,
8787
vc_token_path: clap_utils::parse_required(matches, VC_TOKEN_FLAG)?,
88-
validators_to_exit: clap_utils::parse_required(matches, VALIDATOR_FLAG)?,
88+
validators_to_exit,
8989
beacon_url: clap_utils::parse_optional(matches, BEACON_URL_FLAG)?,
9090
exit_epoch: clap_utils::parse_optional(matches, EXIT_EPOCH_FLAG)?,
9191
})
@@ -114,47 +114,50 @@ async fn run(config: ExitConfig) -> Result<(), String> {
114114
let (http_client, validators) = vc_http_client(vc_url.clone(), &vc_token_path).await?;
115115

116116
// Check that the validators_to_exit is in the validator client
117-
if !validators
118-
.iter()
119-
.any(|validator| validator.validating_pubkey == validators_to_exit)
120-
{
121-
return Err(format!("Validator {} doesn't exist", validators_to_exit));
117+
for validator_to_exit in &validators_to_exit {
118+
if !validators
119+
.iter()
120+
.any(|validator| &validator.validating_pubkey == validator_to_exit)
121+
{
122+
return Err(format!("Validator {} doesn't exist", validator_to_exit));
123+
}
122124
}
123125

124-
let exit_message = http_client
125-
.post_validator_voluntary_exit(&validators_to_exit, exit_epoch)
126-
.await
127-
.map_err(|e| format!("Failed to generate voluntary exit message: {}", e))?;
128-
129-
let exit_message_json = serde_json::to_string(&exit_message.data);
126+
for validator_to_exit in &validators_to_exit {
127+
let exit_message = http_client
128+
.post_validator_voluntary_exit(validator_to_exit, exit_epoch)
129+
.await
130+
.map_err(|e| format!("Failed to generate voluntary exit message: {}", e))?;
130131

131-
match exit_message_json {
132-
Ok(json) => println!("{}", json),
133-
Err(e) => eprintln!("Failed to serialize voluntary exit message: {}", e),
134-
}
132+
let exit_message_json = serde_json::to_string(&exit_message.data);
135133

136-
if beacon_url.is_some() {
137-
let beacon_node = if let Some(beacon_url) = beacon_url {
138-
BeaconNodeHttpClient::new(
139-
SensitiveUrl::parse(beacon_url.as_ref())
140-
.map_err(|e| format!("Failed to parse beacon http server: {:?}", e))?,
141-
Timeouts::set_all(Duration::from_secs(12)),
142-
)
143-
} else {
144-
return Err("Beacon URL is not provided".into());
145-
};
134+
match exit_message_json {
135+
Ok(json) => println!("{}", json),
136+
Err(e) => eprintln!("Failed to serialize voluntary exit message: {}", e),
137+
}
146138

147-
beacon_node
148-
.post_beacon_pool_voluntary_exits(&exit_message.data)
149-
.await
150-
.map_err(|e| format!("Failed to publish voluntary exit: {}", e))?;
151-
// tokio::time::sleep(std::time::Duration::from_secs(1)).await; // Provides nicer UX.
152-
eprintln!(
153-
"Successfully validated and published voluntary exit for validator {}",
154-
validators_to_exit
155-
);
139+
if beacon_url.is_some() {
140+
let beacon_node = if let Some(ref beacon_url) = beacon_url {
141+
BeaconNodeHttpClient::new(
142+
SensitiveUrl::parse(beacon_url.as_ref())
143+
.map_err(|e| format!("Failed to parse beacon http server: {:?}", e))?,
144+
Timeouts::set_all(Duration::from_secs(12)),
145+
)
146+
} else {
147+
return Err("Beacon URL is not provided".into());
148+
};
149+
150+
beacon_node
151+
.post_beacon_pool_voluntary_exits(&exit_message.data)
152+
.await
153+
.map_err(|e| format!("Failed to publish voluntary exit: {}", e))?;
154+
// tokio::time::sleep(std::time::Duration::from_secs(1)).await; // Provides nicer UX.
155+
eprintln!(
156+
"Successfully validated and published voluntary exit for validator {}",
157+
validator_to_exit
158+
);
159+
}
156160
}
157-
158161
Ok(())
159162
}
160163

0 commit comments

Comments
 (0)