mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-20 22:38:34 +00:00
Beacon state validator id filter (#1803)
## Issue Addressed Michael's comment here: https://github.com/sigp/lighthouse/issues/1434#issuecomment-708834079 Resolves #1808 ## Proposed Changes - Add query param `id` and `status` to the `validators` endpoint - Add string serialization and deserialization for `ValidatorStatus` - Drop `Epoch` from `ValidatorStatus` variants ## Additional Info Please provide any additional information. For example, future considerations or information useful for reviewers.
This commit is contained in:
@@ -210,12 +210,14 @@ impl BeaconNodeHttpClient {
|
||||
self.get_opt(path).await
|
||||
}
|
||||
|
||||
/// `GET beacon/states/{state_id}/validators`
|
||||
/// `GET beacon/states/{state_id}/validators?id,status`
|
||||
///
|
||||
/// Returns `Ok(None)` on a 404 error.
|
||||
pub async fn get_beacon_states_validators(
|
||||
&self,
|
||||
state_id: StateId,
|
||||
ids: Option<&[ValidatorId]>,
|
||||
statuses: Option<&[ValidatorStatus]>,
|
||||
) -> Result<Option<GenericResponse<Vec<ValidatorData>>>, Error> {
|
||||
let mut path = self.eth_path()?;
|
||||
|
||||
@@ -226,6 +228,24 @@ impl BeaconNodeHttpClient {
|
||||
.push(&state_id.to_string())
|
||||
.push("validators");
|
||||
|
||||
if let Some(ids) = ids {
|
||||
let id_string = ids
|
||||
.iter()
|
||||
.map(|i| i.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
path.query_pairs_mut().append_pair("id", &id_string);
|
||||
}
|
||||
|
||||
if let Some(statuses) = statuses {
|
||||
let status_string = statuses
|
||||
.iter()
|
||||
.map(|i| i.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
path.query_pairs_mut().append_pair("status", &status_string);
|
||||
}
|
||||
|
||||
self.get_opt(path).await
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ pub struct FinalityCheckpointsData {
|
||||
pub finalized: Checkpoint,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum ValidatorId {
|
||||
PublicKey(PublicKeyBytes),
|
||||
Index(u64),
|
||||
@@ -211,17 +211,18 @@ pub struct ValidatorData {
|
||||
//
|
||||
// https://hackmd.io/bQxMDRt1RbS1TLno8K4NPg?view
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ValidatorStatus {
|
||||
Unknown,
|
||||
WaitingForEligibility,
|
||||
WaitingForFinality,
|
||||
WaitingInQueue,
|
||||
StandbyForActive(Epoch),
|
||||
StandbyForActive,
|
||||
Active,
|
||||
ActiveAwaitingVoluntaryExit(Epoch),
|
||||
ActiveAwaitingSlashedExit(Epoch),
|
||||
ExitedVoluntarily(Epoch),
|
||||
ExitedSlashed(Epoch),
|
||||
ActiveAwaitingVoluntaryExit,
|
||||
ActiveAwaitingSlashedExit,
|
||||
ExitedVoluntarily,
|
||||
ExitedSlashed,
|
||||
Withdrawable,
|
||||
Withdrawn,
|
||||
}
|
||||
@@ -238,22 +239,22 @@ impl ValidatorStatus {
|
||||
ValidatorStatus::Withdrawable
|
||||
} else if validator.is_exited_at(epoch) {
|
||||
if validator.slashed {
|
||||
ValidatorStatus::ExitedSlashed(validator.withdrawable_epoch)
|
||||
ValidatorStatus::ExitedSlashed
|
||||
} else {
|
||||
ValidatorStatus::ExitedVoluntarily(validator.withdrawable_epoch)
|
||||
ValidatorStatus::ExitedVoluntarily
|
||||
}
|
||||
} else if validator.is_active_at(epoch) {
|
||||
if validator.exit_epoch < far_future_epoch {
|
||||
if validator.slashed {
|
||||
ValidatorStatus::ActiveAwaitingSlashedExit(validator.exit_epoch)
|
||||
ValidatorStatus::ActiveAwaitingSlashedExit
|
||||
} else {
|
||||
ValidatorStatus::ActiveAwaitingVoluntaryExit(validator.exit_epoch)
|
||||
ValidatorStatus::ActiveAwaitingVoluntaryExit
|
||||
}
|
||||
} else {
|
||||
ValidatorStatus::Active
|
||||
}
|
||||
} else if validator.activation_epoch < far_future_epoch {
|
||||
ValidatorStatus::StandbyForActive(validator.activation_epoch)
|
||||
ValidatorStatus::StandbyForActive
|
||||
} else if validator.activation_eligibility_epoch < far_future_epoch {
|
||||
if finalized_epoch < validator.activation_eligibility_epoch {
|
||||
ValidatorStatus::WaitingForFinality
|
||||
@@ -269,12 +270,61 @@ impl ValidatorStatus {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for ValidatorStatus {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"unknown" => Ok(ValidatorStatus::Unknown),
|
||||
"waiting_for_eligibility" => Ok(ValidatorStatus::WaitingForEligibility),
|
||||
"waiting_for_finality" => Ok(ValidatorStatus::WaitingForFinality),
|
||||
"waiting_in_queue" => Ok(ValidatorStatus::WaitingInQueue),
|
||||
"standby_for_active" => Ok(ValidatorStatus::StandbyForActive),
|
||||
"active" => Ok(ValidatorStatus::Active),
|
||||
"active_awaiting_voluntary_exit" => Ok(ValidatorStatus::ActiveAwaitingVoluntaryExit),
|
||||
"active_awaiting_slashed_exit" => Ok(ValidatorStatus::ActiveAwaitingSlashedExit),
|
||||
"exited_voluntarily" => Ok(ValidatorStatus::ExitedVoluntarily),
|
||||
"exited_slashed" => Ok(ValidatorStatus::ExitedSlashed),
|
||||
"withdrawable" => Ok(ValidatorStatus::Withdrawable),
|
||||
"withdrawn" => Ok(ValidatorStatus::Withdrawn),
|
||||
_ => Err(format!("{} cannot be parsed as a validator status.", s)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ValidatorStatus {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ValidatorStatus::Unknown => write!(f, "unknown"),
|
||||
ValidatorStatus::WaitingForEligibility => write!(f, "waiting_for_eligibility"),
|
||||
ValidatorStatus::WaitingForFinality => write!(f, "waiting_for_finality"),
|
||||
ValidatorStatus::WaitingInQueue => write!(f, "waiting_in_queue"),
|
||||
ValidatorStatus::StandbyForActive => write!(f, "standby_for_active"),
|
||||
ValidatorStatus::Active => write!(f, "active"),
|
||||
ValidatorStatus::ActiveAwaitingVoluntaryExit => {
|
||||
write!(f, "active_awaiting_voluntary_exit")
|
||||
}
|
||||
ValidatorStatus::ActiveAwaitingSlashedExit => write!(f, "active_awaiting_slashed_exit"),
|
||||
ValidatorStatus::ExitedVoluntarily => write!(f, "exited_voluntarily"),
|
||||
ValidatorStatus::ExitedSlashed => write!(f, "exited_slashed"),
|
||||
ValidatorStatus::Withdrawable => write!(f, "withdrawable"),
|
||||
ValidatorStatus::Withdrawn => write!(f, "withdrawn"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct CommitteesQuery {
|
||||
pub slot: Option<Slot>,
|
||||
pub index: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct ValidatorsQuery {
|
||||
pub id: Option<QueryVec<ValidatorId>>,
|
||||
pub status: Option<QueryVec<ValidatorStatus>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct CommitteeData {
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
|
||||
Reference in New Issue
Block a user