mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 09:16:00 +00:00
Handle status from import
This commit is contained in:
@@ -3,7 +3,7 @@ use eth2::lighthouse_vc::std_types::{InterchangeJsonStr, KeystoreJsonStr};
|
|||||||
use eth2::{
|
use eth2::{
|
||||||
lighthouse_vc::{
|
lighthouse_vc::{
|
||||||
http_client::ValidatorClientHttpClient,
|
http_client::ValidatorClientHttpClient,
|
||||||
std_types::{ImportKeystoresRequest, SingleKeystoreResponse},
|
std_types::{ImportKeystoreStatus, ImportKeystoresRequest, SingleKeystoreResponse, Status},
|
||||||
types::UpdateFeeRecipientRequest,
|
types::UpdateFeeRecipientRequest,
|
||||||
},
|
},
|
||||||
SensitiveUrl,
|
SensitiveUrl,
|
||||||
@@ -31,6 +31,7 @@ pub enum UploadError {
|
|||||||
DuplicateValidator(PublicKeyBytes),
|
DuplicateValidator(PublicKeyBytes),
|
||||||
FailedToListKeys(eth2::Error),
|
FailedToListKeys(eth2::Error),
|
||||||
KeyUploadFailed(eth2::Error),
|
KeyUploadFailed(eth2::Error),
|
||||||
|
IncorrectStatusCount(usize),
|
||||||
FeeRecipientUpdateFailed(eth2::Error),
|
FeeRecipientUpdateFailed(eth2::Error),
|
||||||
PatchValidatorFailed(eth2::Error),
|
PatchValidatorFailed(eth2::Error),
|
||||||
}
|
}
|
||||||
@@ -52,7 +53,7 @@ impl ValidatorSpecification {
|
|||||||
self,
|
self,
|
||||||
http_client: &ValidatorClientHttpClient,
|
http_client: &ValidatorClientHttpClient,
|
||||||
ignore_duplicates: bool,
|
ignore_duplicates: bool,
|
||||||
) -> Result<(), UploadError> {
|
) -> Result<Status<ImportKeystoreStatus>, UploadError> {
|
||||||
let ValidatorSpecification {
|
let ValidatorSpecification {
|
||||||
voting_keystore,
|
voting_keystore,
|
||||||
voting_keystore_password,
|
voting_keystore_password,
|
||||||
@@ -98,14 +99,15 @@ impl ValidatorSpecification {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(e) = http_client.post_keystores(&request).await {
|
let mut statuses = http_client
|
||||||
// Return here *without* writing the deposit JSON file. This might help prevent
|
.post_keystores(&request)
|
||||||
// users from submitting duplicate deposits or deposits for validators that weren't
|
.await
|
||||||
// initialized on a VC.
|
.map_err(UploadError::KeyUploadFailed)?
|
||||||
//
|
.data;
|
||||||
// Next the the user runs with the --ignore-duplicates flag there should be a new,
|
|
||||||
// complete deposit JSON file created.
|
let status = statuses.pop().ok_or(UploadError::IncorrectStatusCount(0))?;
|
||||||
return Err(UploadError::KeyUploadFailed(e));
|
if !statuses.is_empty() {
|
||||||
|
return Err(UploadError::IncorrectStatusCount(statuses.len() + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(fee_recipient) = fee_recipient {
|
if let Some(fee_recipient) = fee_recipient {
|
||||||
@@ -132,7 +134,7 @@ impl ValidatorSpecification {
|
|||||||
.map_err(UploadError::PatchValidatorFailed)?;
|
.map_err(UploadError::PatchValidatorFailed)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use super::common::*;
|
use super::common::*;
|
||||||
use crate::DumpConfig;
|
use crate::DumpConfig;
|
||||||
use clap::{App, Arg, ArgMatches};
|
use clap::{App, Arg, ArgMatches};
|
||||||
use eth2::SensitiveUrl;
|
use eth2::{lighthouse_vc::std_types::ImportKeystoreStatus, SensitiveUrl};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -134,7 +134,38 @@ async fn run<'a>(config: ImportConfig) -> Result<(), String> {
|
|||||||
|
|
||||||
for (i, validator) in validators.into_iter().enumerate() {
|
for (i, validator) in validators.into_iter().enumerate() {
|
||||||
match validator.upload(&http_client, ignore_duplicates).await {
|
match validator.upload(&http_client, ignore_duplicates).await {
|
||||||
Ok(()) => eprintln!("Uploaded keystore {} of {} to the VC", i + 1, count),
|
Ok(status) => {
|
||||||
|
match status.status {
|
||||||
|
ImportKeystoreStatus::Imported => {
|
||||||
|
eprintln!("Uploaded keystore {} of {} to the VC", i + 1, count)
|
||||||
|
}
|
||||||
|
ImportKeystoreStatus::Duplicate => {
|
||||||
|
if ignore_duplicates {
|
||||||
|
eprintln!("Re-uploaded keystore {} of {} to the VC", i + 1, count)
|
||||||
|
} else {
|
||||||
|
eprintln!(
|
||||||
|
"Keystore {} of {} was uploaded to the VC, but it was a duplicate. \
|
||||||
|
Exiting now, use --{} to allow duplicates.",
|
||||||
|
i + 1, count, IGNORE_DUPLICATES_FLAG
|
||||||
|
);
|
||||||
|
return Err(DETECTED_DUPLICATE_MESSAGE.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImportKeystoreStatus::Error => {
|
||||||
|
eprintln!(
|
||||||
|
"Upload of keystore {} of {} failed with message: {:?}. \
|
||||||
|
A potential solution is run this command again \
|
||||||
|
using the --{} flag, however care should be taken to ensure \
|
||||||
|
that there are no duplicate deposits submitted.",
|
||||||
|
i + 1,
|
||||||
|
count,
|
||||||
|
status.message,
|
||||||
|
IGNORE_DUPLICATES_FLAG
|
||||||
|
);
|
||||||
|
return Err(format!("Upload failed with {:?}", status.message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
e @ Err(UploadError::InvalidPublicKey) => {
|
e @ Err(UploadError::InvalidPublicKey) => {
|
||||||
eprintln!("Validator {} has an invalid public key", i);
|
eprintln!("Validator {} has an invalid public key", i);
|
||||||
return Err(format!("{:?}", e));
|
return Err(format!("{:?}", e));
|
||||||
@@ -168,6 +199,18 @@ async fn run<'a>(config: ImportConfig) -> Result<(), String> {
|
|||||||
);
|
);
|
||||||
return Err(format!("{:?}", e));
|
return Err(format!("{:?}", e));
|
||||||
}
|
}
|
||||||
|
Err(UploadError::IncorrectStatusCount(count)) => {
|
||||||
|
eprintln!(
|
||||||
|
"Keystore was uploaded, however the validator client returned an invalid response. \
|
||||||
|
A potential solution is run this command again using the --{} flag, however care \
|
||||||
|
should be taken to ensure that there are no duplicate deposits submitted.",
|
||||||
|
IGNORE_DUPLICATES_FLAG
|
||||||
|
);
|
||||||
|
return Err(format!(
|
||||||
|
"Invalid status count in import response: {}",
|
||||||
|
count
|
||||||
|
));
|
||||||
|
}
|
||||||
Err(UploadError::FeeRecipientUpdateFailed(e)) => {
|
Err(UploadError::FeeRecipientUpdateFailed(e)) => {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Failed to set fee recipient for validator {}. This value may need \
|
"Failed to set fee recipient for validator {}. This value may need \
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ use crate::DumpConfig;
|
|||||||
use clap::{App, Arg, ArgMatches};
|
use clap::{App, Arg, ArgMatches};
|
||||||
use eth2::{
|
use eth2::{
|
||||||
lighthouse_vc::{
|
lighthouse_vc::{
|
||||||
std_types::{DeleteKeystoreStatus, DeleteKeystoresRequest, InterchangeJsonStr, Status},
|
std_types::{
|
||||||
|
DeleteKeystoreStatus, DeleteKeystoresRequest, ImportKeystoreStatus, InterchangeJsonStr,
|
||||||
|
Status,
|
||||||
|
},
|
||||||
types::{ExportKeystoresResponse, SingleExportKeystoresResponse},
|
types::{ExportKeystoresResponse, SingleExportKeystoresResponse},
|
||||||
},
|
},
|
||||||
SensitiveUrl,
|
SensitiveUrl,
|
||||||
@@ -399,7 +402,37 @@ async fn run<'a>(config: MoveConfig) -> Result<(), String> {
|
|||||||
.upload(&dest_http_client, ignore_duplicates)
|
.upload(&dest_http_client, ignore_duplicates)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(()) => break,
|
Ok(status) => {
|
||||||
|
match status.status {
|
||||||
|
ImportKeystoreStatus::Imported => {
|
||||||
|
eprintln!("Moved keystore {} of {}", i + 1, count);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ImportKeystoreStatus::Duplicate => {
|
||||||
|
eprintln!("Moved duplicate keystore {} of {} to the VC", i + 1, count);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ImportKeystoreStatus::Error => {
|
||||||
|
eprintln!(
|
||||||
|
"Upload of keystore {} of {} failed with message: {:?}. \
|
||||||
|
A potential solution is run this command again \
|
||||||
|
using the --{} flag, however care should be taken to ensure \
|
||||||
|
that there are no duplicate deposits submitted.",
|
||||||
|
i + 1,
|
||||||
|
count,
|
||||||
|
status.message,
|
||||||
|
IGNORE_DUPLICATES_FLAG
|
||||||
|
);
|
||||||
|
// Retry uploading this validator.
|
||||||
|
sleep_with_retry_message(
|
||||||
|
&pubkey_to_move,
|
||||||
|
keystore_derivation_path.as_deref(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
return Err(format!("Upload failed with {:?}", status.message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
e @ Err(UploadError::InvalidPublicKey) => {
|
e @ Err(UploadError::InvalidPublicKey) => {
|
||||||
eprintln!("Validator {} has an invalid public key", i);
|
eprintln!("Validator {} has an invalid public key", i);
|
||||||
return Err(format!("{:?}", e));
|
return Err(format!("{:?}", e));
|
||||||
@@ -429,6 +462,18 @@ async fn run<'a>(config: MoveConfig) -> Result<(), String> {
|
|||||||
sleep_with_retry_message(&pubkey_to_move, keystore_derivation_path.as_deref())
|
sleep_with_retry_message(&pubkey_to_move, keystore_derivation_path.as_deref())
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
Err(UploadError::IncorrectStatusCount(count)) => {
|
||||||
|
eprintln!(
|
||||||
|
"Keystore was uploaded, however the validator client returned an invalid response. \
|
||||||
|
A potential solution is run this command again using the --{} flag, however care \
|
||||||
|
should be taken to ensure that there are no duplicate deposits submitted.",
|
||||||
|
IGNORE_DUPLICATES_FLAG
|
||||||
|
);
|
||||||
|
return Err(format!(
|
||||||
|
"Invalid status count in import response: {}",
|
||||||
|
count
|
||||||
|
));
|
||||||
|
}
|
||||||
Err(UploadError::FeeRecipientUpdateFailed(e)) => {
|
Err(UploadError::FeeRecipientUpdateFailed(e)) => {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Failed to set fee recipient for validator {}. This value may need \
|
"Failed to set fee recipient for validator {}. This value may need \
|
||||||
|
|||||||
Reference in New Issue
Block a user