ic-query 0.25.6

Internet Computer query library for NNS, SNS, ICRC, system canisters, and public network metadata
Documentation
use super::{
    error::NnsRegistryHostError,
    model::{
        NNS_REGISTRY_VERSION_REPORT_SCHEMA_VERSION, NnsRegistryVersionReport,
        NnsRegistryVersionRequest,
    },
    source::{NnsRegistrySource, NnsRegistryVersionData},
};
use crate::{
    nns::{LiveNnsSource, NnsSourceRequest},
    subnet_catalog::{MAINNET_NETWORK, MAINNET_REGISTRY_CANISTER_ID, format_utc_timestamp_secs},
};

impl_nns_mainnet_network_enforcer!(NnsRegistryHostError);

pub fn build_nns_registry_version_report(
    request: &NnsRegistryVersionRequest,
) -> Result<NnsRegistryVersionReport, NnsRegistryHostError> {
    build_nns_registry_version_report_with_source(request, &LiveNnsSource)
}

pub fn build_nns_registry_version_report_with_source(
    request: &NnsRegistryVersionRequest,
    source: &dyn NnsRegistrySource,
) -> Result<NnsRegistryVersionReport, NnsRegistryHostError> {
    enforce_mainnet_network(&request.network)?;
    let fetched_at = format_utc_timestamp_secs(request.now_unix_secs);
    let fetch_request = NnsSourceRequest::new(
        MAINNET_NETWORK,
        &request.source_endpoint,
        fetched_at,
        "ic-query",
    );
    let version = source.fetch_registry_version(&fetch_request)?;
    validate_source_result(&fetch_request, &version)?;
    Ok(registry_version_report_from_version(version))
}

fn validate_source_result(
    request: &NnsSourceRequest,
    version: &NnsRegistryVersionData,
) -> Result<(), NnsRegistryHostError> {
    for (field, expected, actual) in [
        (
            "network",
            request.network.as_str(),
            version.network.as_str(),
        ),
        (
            "registry_canister_id",
            MAINNET_REGISTRY_CANISTER_ID,
            version.registry_canister_id.as_str(),
        ),
        (
            "fetched_at",
            request.fetched_at.as_str(),
            version.fetched_at.as_str(),
        ),
        (
            "source_endpoint",
            request.endpoint.as_str(),
            version.source_endpoint.as_str(),
        ),
        (
            "fetched_by",
            request.fetched_by.as_str(),
            version.fetched_by.as_str(),
        ),
    ] {
        if expected != actual {
            return Err(NnsRegistryHostError::SourceMismatch {
                field,
                expected: expected.to_string(),
                actual: actual.to_string(),
            });
        }
    }
    Ok(())
}

fn registry_version_report_from_version(
    version: NnsRegistryVersionData,
) -> NnsRegistryVersionReport {
    NnsRegistryVersionReport {
        schema_version: NNS_REGISTRY_VERSION_REPORT_SCHEMA_VERSION,
        network: version.network,
        registry_canister_id: version.registry_canister_id,
        registry_version: version.registry_version,
        fetched_at: version.fetched_at,
        source_endpoint: version.source_endpoint,
        fetched_by: version.fetched_by,
    }
}