use chrono::{DateTime, Utc};
use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
use super::snarkos_status::SnarkOSStatus;
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum NodeStatus {
#[default]
Unknown,
Standby,
PendingStart,
Running(SnarkOSStatus),
Exited(u8),
Stopping,
LedgerWriting,
}
impl From<SnarkOSStatus> for NodeStatus {
fn from(status: SnarkOSStatus) -> Self {
NodeStatus::Running(status)
}
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct LatestBlockInfo {
pub height: u32,
pub state_root: String,
pub block_hash: String,
pub previous_hash: String,
pub block_timestamp: i64,
pub update_time: DateTime<Utc>,
}
const MAX_BLOCK_AGE: u32 = 3600;
const MAX_UPDATE_AGE: u32 = 60;
const UPDATE_AGE_INDIFFERENCE: u32 = 5;
impl LatestBlockInfo {
pub fn score(&self, now: &DateTime<Utc>) -> u32 {
let block_age_score =
if let Some(block_time) = DateTime::from_timestamp(self.block_timestamp, 0) {
let block_age = now
.signed_duration_since(block_time)
.num_seconds()
.clamp(0, MAX_BLOCK_AGE as i64);
MAX_BLOCK_AGE.saturating_sub(block_age as u32)
} else {
0
};
let update_age = now
.signed_duration_since(self.update_time)
.num_seconds()
.clamp(0, MAX_UPDATE_AGE as i64);
let update_age_score = MAX_UPDATE_AGE
.saturating_sub(update_age as u32)
.clamp(0, MAX_UPDATE_AGE - UPDATE_AGE_INDIFFERENCE);
(block_age_score * (MAX_UPDATE_AGE >> 1) + update_age_score)
.saturating_sub(MAX_UPDATE_AGE >> 1)
}
}
pub type TransferId = u32;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TransferStatusUpdate {
Start {
desc: String,
total: u64,
time: DateTime<Utc>,
},
Progress {
downloaded: u64,
},
End {
interruption: Option<String>,
},
Cleanup,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct TransferStatus {
pub desc: String,
pub started_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub downloaded_bytes: u64,
pub total_bytes: u64,
pub interruption: Option<String>,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct AgentStatus {
pub agent_version: Option<String>,
pub block_info: Option<LatestBlockInfo>,
pub node_status: NodeStatus,
pub start_time: Option<DateTime<Utc>>,
pub connected_time: Option<DateTime<Utc>>,
pub transfers: IndexMap<TransferId, TransferStatus>,
}