mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-09 03:31:45 +00:00
Another good candidate for publishing separately from Lighthouse is `sensitive_url` as it's a general utility crate and not related to Ethereum. This PR prepares it to be spun out into its own crate. I've made the `full` field on `SensitiveUrl` private and instead provided an explicit getter called `.expose_full()`. It's a bit ugly for the diff but I prefer the explicit nature of the getter. I've also added some extra tests and doc strings along with feature gating `Serialize` and `Deserialize` implementations behind the `serde` feature. Co-Authored-By: Mac L <mjladson@pm.me>
385 lines
13 KiB
Rust
385 lines
13 KiB
Rust
//! This module contains endpoints that are non-standard and only available on Lighthouse servers.
|
|
|
|
mod attestation_performance;
|
|
mod block_packing_efficiency;
|
|
mod block_rewards;
|
|
mod custody;
|
|
pub mod sync_state;
|
|
|
|
use crate::{
|
|
BeaconNodeHttpClient, DepositData, Error, Hash256, Slot,
|
|
lighthouse::sync_state::SyncState,
|
|
types::{AdminPeer, Epoch, GenericResponse, ValidatorId},
|
|
};
|
|
use proto_array::core::ProtoArray;
|
|
use serde::{Deserialize, Serialize};
|
|
use ssz::four_byte_option_impl;
|
|
use ssz_derive::{Decode, Encode};
|
|
|
|
pub use attestation_performance::{
|
|
AttestationPerformance, AttestationPerformanceQuery, AttestationPerformanceStatistics,
|
|
};
|
|
pub use block_packing_efficiency::{
|
|
BlockPackingEfficiency, BlockPackingEfficiencyQuery, ProposerInfo, UniqueAttestation,
|
|
};
|
|
pub use block_rewards::{AttestationRewards, BlockReward, BlockRewardMeta, BlockRewardsQuery};
|
|
pub use custody::CustodyInfo;
|
|
|
|
// Define "legacy" implementations of `Option<T>` which use four bytes for encoding the union
|
|
// selector.
|
|
four_byte_option_impl!(four_byte_option_u64, u64);
|
|
four_byte_option_impl!(four_byte_option_hash256, Hash256);
|
|
|
|
/// The results of validators voting during an epoch.
|
|
///
|
|
/// Provides information about the current and previous epochs.
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct GlobalValidatorInclusionData {
|
|
/// The total effective balance of all active validators during the _current_ epoch.
|
|
pub current_epoch_active_gwei: u64,
|
|
/// The total effective balance of all validators who attested during the _current_ epoch and
|
|
/// agreed with the state about the beacon block at the first slot of the _current_ epoch.
|
|
pub current_epoch_target_attesting_gwei: u64,
|
|
/// The total effective balance of all validators who attested during the _previous_ epoch and
|
|
/// agreed with the state about the beacon block at the first slot of the _previous_ epoch.
|
|
pub previous_epoch_target_attesting_gwei: u64,
|
|
/// The total effective balance of all validators who attested during the _previous_ epoch and
|
|
/// agreed with the state about the beacon block at the time of attestation.
|
|
pub previous_epoch_head_attesting_gwei: u64,
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct ValidatorInclusionData {
|
|
/// True if the validator has been slashed, ever.
|
|
pub is_slashed: bool,
|
|
/// True if the validator can withdraw in the current epoch.
|
|
pub is_withdrawable_in_current_epoch: bool,
|
|
/// True if the validator was active and not slashed in the state's _current_ epoch.
|
|
pub is_active_unslashed_in_current_epoch: bool,
|
|
/// True if the validator was active and not slashed in the state's _previous_ epoch.
|
|
pub is_active_unslashed_in_previous_epoch: bool,
|
|
/// The validator's effective balance in the _current_ epoch.
|
|
pub current_epoch_effective_balance_gwei: u64,
|
|
/// True if the validator's beacon block root attestation for the first slot of the _current_
|
|
/// epoch matches the block root known to the state.
|
|
pub is_current_epoch_target_attester: bool,
|
|
/// True if the validator's beacon block root attestation for the first slot of the _previous_
|
|
/// epoch matches the block root known to the state.
|
|
pub is_previous_epoch_target_attester: bool,
|
|
/// True if the validator's beacon block root attestation in the _previous_ epoch at the
|
|
/// attestation's slot (`attestation_data.slot`) matches the block root known to the state.
|
|
pub is_previous_epoch_head_attester: bool,
|
|
}
|
|
|
|
/// Reports on the health of the Lighthouse instance.
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
pub struct Health {
|
|
#[serde(flatten)]
|
|
pub system: SystemHealth,
|
|
#[serde(flatten)]
|
|
pub process: ProcessHealth,
|
|
}
|
|
|
|
/// System related health.
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
pub struct SystemHealth {
|
|
/// Total virtual memory on the system
|
|
pub sys_virt_mem_total: u64,
|
|
/// Total virtual memory available for new processes.
|
|
pub sys_virt_mem_available: u64,
|
|
/// Total virtual memory used on the system.
|
|
pub sys_virt_mem_used: u64,
|
|
/// Total virtual memory not used on the system.
|
|
pub sys_virt_mem_free: u64,
|
|
/// Percentage of virtual memory used on the system.
|
|
pub sys_virt_mem_percent: f32,
|
|
/// Total cached virtual memory on the system.
|
|
pub sys_virt_mem_cached: u64,
|
|
/// Total buffered virtual memory on the system.
|
|
pub sys_virt_mem_buffers: u64,
|
|
|
|
/// System load average over 1 minute.
|
|
pub sys_loadavg_1: f64,
|
|
/// System load average over 5 minutes.
|
|
pub sys_loadavg_5: f64,
|
|
/// System load average over 15 minutes.
|
|
pub sys_loadavg_15: f64,
|
|
|
|
/// Total cpu cores.
|
|
pub cpu_cores: u64,
|
|
/// Total cpu threads.
|
|
pub cpu_threads: u64,
|
|
|
|
/// Total time spent in kernel mode.
|
|
pub system_seconds_total: u64,
|
|
/// Total time spent in user mode.
|
|
pub user_seconds_total: u64,
|
|
/// Total time spent in waiting for io.
|
|
pub iowait_seconds_total: u64,
|
|
/// Total idle cpu time.
|
|
pub idle_seconds_total: u64,
|
|
/// Total cpu time.
|
|
pub cpu_time_total: u64,
|
|
|
|
/// Total capacity of disk.
|
|
pub disk_node_bytes_total: u64,
|
|
/// Free space in disk.
|
|
pub disk_node_bytes_free: u64,
|
|
/// Number of disk reads.
|
|
pub disk_node_reads_total: u64,
|
|
/// Number of disk writes.
|
|
pub disk_node_writes_total: u64,
|
|
|
|
/// Total bytes received over all network interfaces.
|
|
pub network_node_bytes_total_received: u64,
|
|
/// Total bytes sent over all network interfaces.
|
|
pub network_node_bytes_total_transmit: u64,
|
|
|
|
/// Boot time
|
|
pub misc_node_boot_ts_seconds: u64,
|
|
/// OS
|
|
pub misc_os: String,
|
|
}
|
|
|
|
/// Process specific health
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
pub struct ProcessHealth {
|
|
/// The pid of this process.
|
|
pub pid: u32,
|
|
/// The number of threads used by this pid.
|
|
pub pid_num_threads: i64,
|
|
/// The total resident memory used by this pid.
|
|
pub pid_mem_resident_set_size: u64,
|
|
/// The total virtual memory used by this pid.
|
|
pub pid_mem_virtual_memory_size: u64,
|
|
/// The total shared memory used by this pid.
|
|
pub pid_mem_shared_memory_size: u64,
|
|
/// Number of cpu seconds consumed by this pid.
|
|
pub pid_process_seconds_total: u64,
|
|
}
|
|
|
|
/// A fully parsed eth1 deposit contract log.
|
|
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Encode, Decode)]
|
|
pub struct DepositLog {
|
|
pub deposit_data: DepositData,
|
|
/// The block number of the log that included this `DepositData`.
|
|
pub block_number: u64,
|
|
/// The index included with the deposit log.
|
|
pub index: u64,
|
|
/// True if the signature is valid.
|
|
pub signature_is_valid: bool,
|
|
}
|
|
|
|
impl BeaconNodeHttpClient {
|
|
/// `GET lighthouse/health`
|
|
pub async fn get_lighthouse_health(&self) -> Result<GenericResponse<Health>, Error> {
|
|
let mut path = self.server.expose_full().clone();
|
|
|
|
path.path_segments_mut()
|
|
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
|
.push("lighthouse")
|
|
.push("health");
|
|
|
|
self.get(path).await
|
|
}
|
|
|
|
/// `GET lighthouse/syncing`
|
|
pub async fn get_lighthouse_syncing(&self) -> Result<GenericResponse<SyncState>, Error> {
|
|
let mut path = self.server.expose_full().clone();
|
|
|
|
path.path_segments_mut()
|
|
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
|
.push("lighthouse")
|
|
.push("syncing");
|
|
|
|
self.get(path).await
|
|
}
|
|
|
|
/// `GET lighthouse/custody/info`
|
|
pub async fn get_lighthouse_custody_info(&self) -> Result<CustodyInfo, Error> {
|
|
let mut path = self.server.expose_full().clone();
|
|
|
|
path.path_segments_mut()
|
|
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
|
.push("lighthouse")
|
|
.push("custody")
|
|
.push("info");
|
|
|
|
self.get(path).await
|
|
}
|
|
|
|
/// `POST lighthouse/custody/backfill`
|
|
pub async fn post_lighthouse_custody_backfill(&self) -> Result<(), Error> {
|
|
let mut path = self.server.expose_full().clone();
|
|
|
|
path.path_segments_mut()
|
|
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
|
.push("lighthouse")
|
|
.push("custody")
|
|
.push("backfill");
|
|
|
|
self.post(path, &()).await
|
|
}
|
|
|
|
/*
|
|
* Note:
|
|
*
|
|
* The `lighthouse/peers` endpoints do not have functions here. We are yet to implement
|
|
* `Deserialize` on the `PeerInfo` struct since it contains use of `Instant`. This could be
|
|
* fairly simply achieved, if desired.
|
|
*/
|
|
|
|
/// `GET lighthouse/proto_array`
|
|
pub async fn get_lighthouse_proto_array(&self) -> Result<GenericResponse<ProtoArray>, Error> {
|
|
let mut path = self.server.expose_full().clone();
|
|
|
|
path.path_segments_mut()
|
|
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
|
.push("lighthouse")
|
|
.push("proto_array");
|
|
|
|
self.get(path).await
|
|
}
|
|
|
|
/// `GET lighthouse/validator_inclusion/{epoch}/global`
|
|
pub async fn get_lighthouse_validator_inclusion_global(
|
|
&self,
|
|
epoch: Epoch,
|
|
) -> Result<GenericResponse<GlobalValidatorInclusionData>, Error> {
|
|
let mut path = self.server.expose_full().clone();
|
|
|
|
path.path_segments_mut()
|
|
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
|
.push("lighthouse")
|
|
.push("validator_inclusion")
|
|
.push(&epoch.to_string())
|
|
.push("global");
|
|
|
|
self.get(path).await
|
|
}
|
|
|
|
/// `GET lighthouse/validator_inclusion/{epoch}/{validator_id}`
|
|
pub async fn get_lighthouse_validator_inclusion(
|
|
&self,
|
|
epoch: Epoch,
|
|
validator_id: ValidatorId,
|
|
) -> Result<GenericResponse<Option<ValidatorInclusionData>>, Error> {
|
|
let mut path = self.server.expose_full().clone();
|
|
|
|
path.path_segments_mut()
|
|
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
|
.push("lighthouse")
|
|
.push("validator_inclusion")
|
|
.push(&epoch.to_string())
|
|
.push(&validator_id.to_string());
|
|
|
|
self.get(path).await
|
|
}
|
|
|
|
/// `POST lighthouse/database/reconstruct`
|
|
pub async fn post_lighthouse_database_reconstruct(&self) -> Result<String, Error> {
|
|
let mut path = self.server.expose_full().clone();
|
|
|
|
path.path_segments_mut()
|
|
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
|
.push("lighthouse")
|
|
.push("database")
|
|
.push("reconstruct");
|
|
|
|
self.post_with_response(path, &()).await
|
|
}
|
|
|
|
/// `POST lighthouse/add_peer`
|
|
pub async fn post_lighthouse_add_peer(&self, req: AdminPeer) -> Result<(), Error> {
|
|
let mut path = self.server.expose_full().clone();
|
|
|
|
path.path_segments_mut()
|
|
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
|
.push("lighthouse")
|
|
.push("add_peer");
|
|
|
|
self.post_with_response(path, &req).await
|
|
}
|
|
|
|
/// `POST lighthouse/remove_peer`
|
|
pub async fn post_lighthouse_remove_peer(&self, req: AdminPeer) -> Result<(), Error> {
|
|
let mut path = self.server.expose_full().clone();
|
|
|
|
path.path_segments_mut()
|
|
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
|
.push("lighthouse")
|
|
.push("remove_peer");
|
|
|
|
self.post_with_response(path, &req).await
|
|
}
|
|
|
|
/*
|
|
Analysis endpoints.
|
|
*/
|
|
|
|
/// `GET` lighthouse/analysis/block_rewards?start_slot,end_slot
|
|
pub async fn get_lighthouse_analysis_block_rewards(
|
|
&self,
|
|
start_slot: Slot,
|
|
end_slot: Slot,
|
|
) -> Result<Vec<BlockReward>, Error> {
|
|
let mut path = self.server.expose_full().clone();
|
|
|
|
path.path_segments_mut()
|
|
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
|
.push("lighthouse")
|
|
.push("analysis")
|
|
.push("block_rewards");
|
|
|
|
path.query_pairs_mut()
|
|
.append_pair("start_slot", &start_slot.to_string())
|
|
.append_pair("end_slot", &end_slot.to_string());
|
|
|
|
self.get(path).await
|
|
}
|
|
|
|
/// `GET` lighthouse/analysis/block_packing?start_epoch,end_epoch
|
|
pub async fn get_lighthouse_analysis_block_packing(
|
|
&self,
|
|
start_epoch: Epoch,
|
|
end_epoch: Epoch,
|
|
) -> Result<Vec<BlockPackingEfficiency>, Error> {
|
|
let mut path = self.server.expose_full().clone();
|
|
|
|
path.path_segments_mut()
|
|
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
|
.push("lighthouse")
|
|
.push("analysis")
|
|
.push("block_packing_efficiency");
|
|
|
|
path.query_pairs_mut()
|
|
.append_pair("start_epoch", &start_epoch.to_string())
|
|
.append_pair("end_epoch", &end_epoch.to_string());
|
|
|
|
self.get(path).await
|
|
}
|
|
|
|
/// `GET` lighthouse/analysis/attestation_performance/{index}?start_epoch,end_epoch
|
|
pub async fn get_lighthouse_analysis_attestation_performance(
|
|
&self,
|
|
start_epoch: Epoch,
|
|
end_epoch: Epoch,
|
|
target: String,
|
|
) -> Result<Vec<AttestationPerformance>, Error> {
|
|
let mut path = self.server.expose_full().clone();
|
|
|
|
path.path_segments_mut()
|
|
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
|
.push("lighthouse")
|
|
.push("analysis")
|
|
.push("attestation_performance")
|
|
.push(&target);
|
|
|
|
path.query_pairs_mut()
|
|
.append_pair("start_epoch", &start_epoch.to_string())
|
|
.append_pair("end_epoch", &end_epoch.to_string());
|
|
|
|
self.get(path).await
|
|
}
|
|
}
|