1use near_primitives::congestion_info::CongestionInfo;
4use near_primitives::types::{EpochId, ShardId};
5use near_primitives::views::{
6 CatchupStatusView, ChainProcessingInfo, EpochValidatorInfo, RequestedStatePartsView,
7 SyncStatusView,
8};
9use near_primitives::{
10 block_header::ApprovalInner,
11 hash::CryptoHash,
12 sharding::ChunkHash,
13 types::{AccountId, BlockHeight},
14 views::ValidatorInfo,
15};
16use near_time::Utc;
17use std::collections::HashMap;
18use std::str::FromStr;
19use strum::Display;
20
21#[derive(serde::Serialize, serde::Deserialize, Debug)]
22pub struct TrackedShardsView {
23 pub shards_tracked_this_epoch: Vec<bool>,
24 pub shards_tracked_next_epoch: Vec<bool>,
25}
26
27#[derive(serde::Serialize, serde::Deserialize, Debug)]
28pub struct EpochInfoView {
29 pub epoch_height: u64,
30 pub epoch_id: CryptoHash,
31 pub height: BlockHeight,
32 pub first_block: Option<(CryptoHash, Utc)>,
33 pub block_producers: Vec<ValidatorInfo>,
34 pub chunk_producers: Vec<String>,
35 pub chunk_validators: Vec<String>,
36 pub validator_info: Option<EpochValidatorInfo>,
37 pub protocol_version: u32,
38 pub sync_hash: Option<CryptoHash>,
39 pub shards_size_and_parts: Vec<(u64, u64, bool)>,
40}
41
42#[derive(serde::Serialize, serde::Deserialize, Debug)]
43pub struct DebugChunkStatus {
44 pub shard_id: u64,
45 pub chunk_hash: ChunkHash,
46 pub chunk_producer: Option<AccountId>,
47 pub gas_used: u64,
48 #[serde(skip_serializing_if = "Option::is_none")]
49 pub processing_time_ms: Option<u64>,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 pub congestion_level: Option<f64>,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub congestion_info: Option<CongestionInfo>,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub endorsement_ratio: Option<f64>,
56}
57
58#[derive(serde::Serialize, serde::Deserialize, Debug)]
59pub struct DebugBlockStatus {
60 pub block_hash: CryptoHash,
61 pub prev_block_hash: CryptoHash,
62 pub block_height: u64,
63 pub block_timestamp: u64,
64 pub block_producer: Option<AccountId>,
65 pub full_block_missing: bool, pub is_on_canonical_chain: bool,
67 pub chunks: Vec<DebugChunkStatus>,
68 #[serde(skip_serializing_if = "Option::is_none")]
70 pub processing_time_ms: Option<u64>,
71 pub gas_price_ratio: f64,
72}
73
74#[derive(serde::Serialize, serde::Deserialize, Debug)]
75pub struct MissedHeightInfo {
76 pub block_height: u64,
77 pub block_producer: Option<AccountId>,
78}
79
80#[derive(serde::Serialize, serde::Deserialize, Debug)]
81pub struct DebugBlockStatusData {
82 pub blocks: Vec<DebugBlockStatus>,
83 pub missed_heights: Vec<MissedHeightInfo>,
84 pub head: CryptoHash,
85 pub header_head: CryptoHash,
86}
87
88#[derive(serde::Serialize, Debug, Clone)]
91pub struct ApprovalHistoryEntry {
92 pub parent_height: BlockHeight,
95 pub target_height: BlockHeight,
96 pub approval_creation_time: Utc,
98 pub timer_started_ago_millis: u64,
100 pub expected_delay_millis: u64,
102}
103
104#[derive(serde::Serialize, Debug, Default, Clone)]
107pub struct ChunkProduction {
108 pub chunk_production_time: Option<Utc>,
110 pub chunk_production_duration_millis: Option<u64>,
113}
114#[derive(serde::Serialize, Debug, Clone, Default)]
117pub struct BlockProduction {
118 pub approvals: ApprovalAtHeightStatus,
120 pub chunks_collection_time: Vec<ChunkCollection>,
123 pub block_production_time: Option<Utc>,
125 pub block_included: bool,
127}
128
129#[derive(serde::Serialize, Debug, Clone)]
130pub struct ChunkCollection {
131 pub chunk_producer: AccountId,
133 pub received_time: Option<Utc>,
136 pub chunk_included: bool,
138}
139
140#[derive(serde::Serialize, Debug, Default)]
144pub struct ProductionAtHeight {
145 pub block_production: Option<BlockProduction>,
148 pub chunk_production: HashMap<ShardId, ChunkProduction>,
150}
151
152#[derive(serde::Serialize, Debug, Default, Clone)]
154pub struct ApprovalAtHeightStatus {
155 pub approvals: HashMap<AccountId, (ApprovalInner, Utc)>,
157 pub ready_at: Option<Utc>,
159}
160
161#[derive(serde::Serialize, Debug)]
162pub struct ValidatorStatus {
163 pub validator_name: Option<AccountId>,
164 pub shards: u64,
166 pub head_height: u64,
168 pub validators: Option<Vec<(AccountId, u64)>>,
170 pub approval_history: Vec<ApprovalHistoryEntry>,
172 pub production: Vec<(BlockHeight, ProductionAtHeight)>,
176 pub banned_chunk_producers: Vec<(EpochId, Vec<AccountId>)>,
178}
179
180#[derive(Debug, Display)]
182pub enum DebugBlocksStartingMode {
183 All,
185 JumpToBlockMiss,
187 JumpToChunkMiss,
189 JumpToBlockProduced,
191 JumpToAllChunksIncluded,
193}
194
195impl FromStr for DebugBlocksStartingMode {
196 type Err = String;
197
198 fn from_str(input: &str) -> Result<DebugBlocksStartingMode, Self::Err> {
199 match input {
200 "all" => Ok(DebugBlocksStartingMode::All),
201 "first_block_miss" => Ok(DebugBlocksStartingMode::JumpToBlockMiss),
202 "first_chunk_miss" => Ok(DebugBlocksStartingMode::JumpToChunkMiss),
203 "first_block_produced" => Ok(DebugBlocksStartingMode::JumpToBlockProduced),
204 "all_chunks_included" => Ok(DebugBlocksStartingMode::JumpToAllChunksIncluded),
205 _ => Err(format!("Invalid input: {}", input)),
206 }
207 }
208}
209
210impl<'de> serde::Deserialize<'de> for DebugBlocksStartingMode {
211 fn deserialize<D>(deserializer: D) -> Result<DebugBlocksStartingMode, D::Error>
212 where
213 D: serde::Deserializer<'de>,
214 {
215 let s = String::deserialize(deserializer)?;
216 DebugBlocksStartingMode::from_str(&s).map_err(serde::de::Error::custom)
217 }
218}
219
220#[derive(serde::Deserialize, Debug)]
221pub struct DebugBlockStatusQuery {
222 pub starting_height: Option<u64>,
224 #[serde(default = "default_block_status_mode")]
226 pub mode: DebugBlocksStartingMode,
227 #[serde(default = "default_block_status_num_blocks")]
229 pub num_blocks: u64,
230}
231
232impl Default for DebugBlockStatusQuery {
233 fn default() -> Self {
234 Self {
235 starting_height: None,
236 mode: default_block_status_mode(),
237 num_blocks: default_block_status_num_blocks(),
238 }
239 }
240}
241
242fn default_block_status_mode() -> DebugBlocksStartingMode {
243 DebugBlocksStartingMode::All
244}
245
246fn default_block_status_num_blocks() -> u64 {
247 50
248}
249
250#[derive(Debug)]
252pub enum DebugStatus {
253 SyncStatus,
255 TrackedShards,
257 EpochInfo(Option<EpochId>),
259 EpochInfoLight(Option<EpochId>),
263 BlockStatus(DebugBlockStatusQuery),
265 ValidatorStatus,
267 CatchupStatus,
269 ChainProcessingStatus,
271 RequestedStateParts,
273}
274
275#[derive(serde::Serialize, Debug)]
276pub enum DebugStatusResponse {
277 SyncStatus(SyncStatusView),
278 CatchupStatus(Vec<CatchupStatusView>),
279 TrackedShards(TrackedShardsView),
280 EpochInfo(Vec<EpochInfoView>),
282 BlockStatus(DebugBlockStatusData),
284 ValidatorStatus(ValidatorStatus),
286 ChainProcessingStatus(ChainProcessingInfo),
288 RequestedStateParts(Vec<RequestedStatePartsView>),
290}