use super::{
NnsGovernanceCacheMetadata, NnsGovernanceCacheRequest, NnsGovernanceRefreshAttemptStatus,
};
use crate::{
cache::CacheValidationStatus,
nns::MAINNET_GOVERNANCE_CANISTER_ID,
snapshot_cache::{SnapshotEnvelope, SnapshotJsonPaths},
};
use serde::Serialize;
use std::path::Path;
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct NnsGovernanceCacheSummary {
pub governance_canister_id: String,
pub cache_status: CacheValidationStatus,
pub cache_error: Option<String>,
pub complete: bool,
pub point_in_time_guaranteed: bool,
pub row_count: usize,
pub page_count: u32,
pub page_size: u32,
pub fetched_at: String,
pub source_endpoint: String,
pub cache_path: String,
}
impl NnsGovernanceCacheSummary {
pub(in crate::nns) fn from_snapshot<Rows>(
path: &Path,
cache: &SnapshotEnvelope<NnsGovernanceCacheMetadata, Rows>,
) -> Self {
Self {
governance_canister_id: cache.metadata.governance_canister_id.clone(),
cache_status: CacheValidationStatus::Valid,
cache_error: None,
complete: cache.completeness.is_api_exhausted(),
point_in_time_guaranteed: cache.completeness.point_in_time_guaranteed,
row_count: cache.completeness.row_count,
page_count: cache.completeness.page_count,
page_size: cache.completeness.page_size,
fetched_at: cache.fetched_at.clone(),
source_endpoint: cache.source_endpoint.clone(),
cache_path: path.display().to_string(),
}
}
pub(in crate::nns) fn invalid(path: &Path, reason: String) -> Self {
Self {
governance_canister_id: MAINNET_GOVERNANCE_CANISTER_ID.to_string(),
cache_status: CacheValidationStatus::Invalid,
cache_error: Some(reason),
complete: false,
point_in_time_guaranteed: false,
row_count: 0,
page_count: 0,
page_size: 0,
fetched_at: String::new(),
source_endpoint: String::new(),
cache_path: path.display().to_string(),
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct NnsGovernanceCacheStatusReport {
pub schema_version: u32,
pub network: String,
pub collection: String,
pub cache_root: String,
pub found: bool,
pub cache: Option<NnsGovernanceCacheSummary>,
pub expected_cache_path: String,
pub refresh_attempt_path: String,
pub latest_attempt: Option<NnsGovernanceRefreshAttemptStatus>,
}
impl NnsGovernanceCacheStatusReport {
pub(in crate::nns) fn from_cache(
request: &NnsGovernanceCacheRequest,
collection: &str,
paths: &SnapshotJsonPaths,
cache: Option<NnsGovernanceCacheSummary>,
latest_attempt: Option<NnsGovernanceRefreshAttemptStatus>,
) -> Self {
Self {
schema_version: 1,
network: request.network.clone(),
collection: collection.to_string(),
cache_root: paths
.snapshot_path
.parent()
.unwrap_or(&request.cache_root)
.display()
.to_string(),
found: cache.is_some(),
cache,
expected_cache_path: paths.snapshot_path.display().to_string(),
refresh_attempt_path: paths.refresh_attempt_path.display().to_string(),
latest_attempt,
}
}
}
macro_rules! governance_snapshot_matches {
($cache:expr, $state:expr, $rows:ident) => {{
let cache = $cache;
let state = $state;
let source = $crate::nns::governance::NnsGovernanceSourceProvenance::ReplicaQuery {
endpoint: cache.source_endpoint.clone(),
fetched_by: cache.fetched_by.clone(),
};
state.is_complete()
&& state.network() == cache.network
&& state.governance_canister_id() == cache.metadata.governance_canister_id
&& state.source() == Some(&source)
&& state.updated_at() == cache.fetched_at
&& state.pages_fetched() == cache.completeness.page_count
&& state.page_size() == cache.completeness.page_size
&& state.$rows() == cache.completeness.row_count as u64
}};
}
pub(in crate::nns) use governance_snapshot_matches;