use crate::types::StatusError;
use near_primitives::congestion_info::CongestionInfo;
use near_primitives::types::{EpochId, ShardId};
use near_primitives::views::{
CatchupStatusView, ChainProcessingInfo, EpochValidatorInfo, RequestedStatePartsView,
SyncStatusView,
};
use near_primitives::{
block_header::ApprovalInner,
hash::CryptoHash,
sharding::ChunkHash,
types::{AccountId, BlockHeight},
views::ValidatorInfo,
};
use near_time::Utc;
use std::collections::HashMap;
use std::str::FromStr;
use strum::Display;
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct TrackedShardsView {
pub shards_tracked_this_epoch: Vec<bool>,
pub shards_tracked_next_epoch: Vec<bool>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct EpochInfoView {
pub epoch_height: u64,
pub epoch_id: CryptoHash,
pub height: BlockHeight,
pub first_block: Option<(CryptoHash, Utc)>,
pub block_producers: Vec<ValidatorInfo>,
pub chunk_producers: Vec<String>,
pub chunk_validators: Vec<String>,
pub validator_info: Option<EpochValidatorInfo>,
pub protocol_version: u32,
pub sync_hash: Option<CryptoHash>,
pub shards_size_and_parts: Vec<(u64, u64, bool)>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct DebugChunkStatus {
pub shard_id: u64,
pub chunk_hash: ChunkHash,
pub chunk_producer: Option<AccountId>,
pub gas_used: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub processing_time_ms: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub congestion_level: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub congestion_info: Option<CongestionInfo>,
#[serde(skip_serializing_if = "Option::is_none")]
pub endorsement_ratio: Option<f64>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct DebugBlockStatus {
pub block_hash: CryptoHash,
pub prev_block_hash: CryptoHash,
pub block_height: u64,
pub block_timestamp: u64,
pub block_producer: Option<AccountId>,
pub full_block_missing: bool, pub is_on_canonical_chain: bool,
pub chunks: Vec<DebugChunkStatus>,
#[serde(skip_serializing_if = "Option::is_none")]
pub processing_time_ms: Option<u64>,
pub gas_price_ratio: f64,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct MissedHeightInfo {
pub block_height: u64,
pub block_producer: Option<AccountId>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct DebugBlockStatusData {
pub blocks: Vec<DebugBlockStatus>,
pub missed_heights: Vec<MissedHeightInfo>,
pub head: CryptoHash,
pub header_head: CryptoHash,
}
#[derive(serde::Serialize, Debug, Clone)]
pub struct ApprovalHistoryEntry {
pub parent_height: BlockHeight,
pub target_height: BlockHeight,
pub approval_creation_time: Utc,
pub timer_started_ago_millis: u64,
pub expected_delay_millis: u64,
}
#[derive(serde::Serialize, Debug, Default, Clone)]
pub struct ChunkProduction {
pub chunk_production_time: Option<Utc>,
pub chunk_production_duration_millis: Option<u64>,
}
#[derive(serde::Serialize, Debug, Clone, Default)]
pub struct BlockProduction {
pub approvals: ApprovalAtHeightStatus,
pub chunks_collection_time: Vec<ChunkCollection>,
pub block_production_time: Option<Utc>,
pub block_included: bool,
}
#[derive(serde::Serialize, Debug, Clone)]
pub struct ChunkCollection {
pub chunk_producer: AccountId,
pub received_time: Option<Utc>,
pub chunk_included: bool,
}
#[derive(serde::Serialize, Debug, Default)]
pub struct ProductionAtHeight {
pub block_production: Option<BlockProduction>,
pub chunk_production: HashMap<ShardId, ChunkProduction>,
}
#[derive(serde::Serialize, Debug, Default, Clone)]
pub struct ApprovalAtHeightStatus {
pub approvals: HashMap<AccountId, (ApprovalInner, Utc)>,
pub ready_at: Option<Utc>,
}
#[derive(serde::Serialize, Debug)]
pub struct ValidatorStatus {
pub validator_name: Option<AccountId>,
pub shards: u64,
pub head_height: u64,
pub validators: Option<Vec<(AccountId, u64)>>,
pub approval_history: Vec<ApprovalHistoryEntry>,
pub production: Vec<(BlockHeight, ProductionAtHeight)>,
pub banned_chunk_producers: Vec<(EpochId, Vec<AccountId>)>,
}
#[derive(Debug, Display)]
pub enum DebugBlocksStartingMode {
All,
JumpToBlockMiss,
JumpToChunkMiss,
JumpToBlockProduced,
JumpToAllChunksIncluded,
}
impl FromStr for DebugBlocksStartingMode {
type Err = String;
fn from_str(input: &str) -> Result<DebugBlocksStartingMode, Self::Err> {
match input {
"all" => Ok(DebugBlocksStartingMode::All),
"first_block_miss" => Ok(DebugBlocksStartingMode::JumpToBlockMiss),
"first_chunk_miss" => Ok(DebugBlocksStartingMode::JumpToChunkMiss),
"first_block_produced" => Ok(DebugBlocksStartingMode::JumpToBlockProduced),
"all_chunks_included" => Ok(DebugBlocksStartingMode::JumpToAllChunksIncluded),
_ => Err(format!("Invalid input: {}", input)),
}
}
}
impl<'de> serde::Deserialize<'de> for DebugBlocksStartingMode {
fn deserialize<D>(deserializer: D) -> Result<DebugBlocksStartingMode, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
DebugBlocksStartingMode::from_str(&s).map_err(serde::de::Error::custom)
}
}
#[derive(serde::Deserialize, Debug)]
pub struct DebugBlockStatusQuery {
pub starting_height: Option<u64>,
#[serde(default = "default_block_status_mode")]
pub mode: DebugBlocksStartingMode,
#[serde(default = "default_block_status_num_blocks")]
pub num_blocks: u64,
}
impl Default for DebugBlockStatusQuery {
fn default() -> Self {
Self {
starting_height: None,
mode: default_block_status_mode(),
num_blocks: default_block_status_num_blocks(),
}
}
}
fn default_block_status_mode() -> DebugBlocksStartingMode {
DebugBlocksStartingMode::All
}
fn default_block_status_num_blocks() -> u64 {
50
}
#[derive(Debug)]
pub enum DebugStatus {
SyncStatus,
TrackedShards,
EpochInfo(Option<EpochId>),
BlockStatus(DebugBlockStatusQuery),
ValidatorStatus,
CatchupStatus,
ChainProcessingStatus,
RequestedStateParts,
}
impl actix::Message for DebugStatus {
type Result = Result<DebugStatusResponse, StatusError>;
}
#[derive(serde::Serialize, Debug)]
pub enum DebugStatusResponse {
SyncStatus(SyncStatusView),
CatchupStatus(Vec<CatchupStatusView>),
TrackedShards(TrackedShardsView),
EpochInfo(Vec<EpochInfoView>),
BlockStatus(DebugBlockStatusData),
ValidatorStatus(ValidatorStatus),
ChainProcessingStatus(ChainProcessingInfo),
RequestedStateParts(Vec<RequestedStatePartsView>),
}