ic-query 0.90.0

Internet Computer query library for CloudEngine, NNS, SNS, ICRC, system canisters, and public network metadata
Documentation
use crate::nns::inventory::{NnsInventoryInputKind, resolve_nns_inventory_row};

use super::{
    NNS_NODE_INFO_REPORT_SCHEMA_VERSION, NnsInventoryError, NnsInventoryInfoRequest,
    NnsNodeInfoReport, NnsNodeListReport, NnsNodeListRequest,
    cache::{load_cached_nns_node_report, nns_node_cache_path},
    filters::filter_node_list_report,
    refresh::refresh_nns_node_report_with_source,
    source::NnsNodeSource,
};
use crate::nns::{LiveNnsSource, inventory::load_or_refresh_nns_inventory_report};
use crate::{QueryProgress, progress::IgnoreQueryProgress};

pub async fn build_nns_node_list_report(
    request: &NnsNodeListRequest,
) -> Result<NnsNodeListReport, NnsInventoryError> {
    build_nns_node_list_report_with_source_and_progress(
        request,
        &LiveNnsSource::default(),
        &mut IgnoreQueryProgress,
    )
    .await
}

pub async fn build_nns_node_info_report(
    request: &NnsInventoryInfoRequest,
) -> Result<NnsNodeInfoReport, NnsInventoryError> {
    build_nns_node_info_report_with_source_and_progress(
        request,
        &LiveNnsSource::default(),
        &mut IgnoreQueryProgress,
    )
    .await
}

/// Build the report with a caller-owned source and progress sink.
pub async fn build_nns_node_list_report_with_source_and_progress(
    request: &NnsNodeListRequest,
    source: &dyn NnsNodeSource,
    progress: &mut dyn QueryProgress,
) -> Result<NnsNodeListReport, NnsInventoryError> {
    let report = load_or_refresh_nns_inventory_report(
        &request.inventory,
        nns_node_cache_path(
            &request.inventory.cache.cache_root,
            &request.inventory.cache.network,
        ),
        progress,
        |cache| load_cached_nns_node_report(cache).map(|cached| cached.report),
        async |refresh_request| {
            refresh_nns_node_report_with_source(refresh_request, source)
                .await
                .map(|_| ())
        },
    )
    .await?;
    Ok(filter_node_list_report(report, &request.filters))
}

/// Build the report with a caller-owned source and progress sink.
pub async fn build_nns_node_info_report_with_source_and_progress(
    request: &NnsInventoryInfoRequest,
    source: &dyn NnsNodeSource,
    progress: &mut dyn QueryProgress,
) -> Result<NnsNodeInfoReport, NnsInventoryError> {
    let list_request = NnsNodeListRequest::new(
        request.cache.clone(),
        request.source_endpoint.clone(),
        request.now_unix_secs,
    );
    let mut report =
        build_nns_node_list_report_with_source_and_progress(&list_request, source, progress)
            .await?;
    let (index, resolved_from) = resolve_node(&report, &request.input)?;
    let node = report.nodes.swap_remove(index);
    Ok(NnsNodeInfoReport {
        schema_version: NNS_NODE_INFO_REPORT_SCHEMA_VERSION,
        input: request.input.clone(),
        resolved_from,
        provenance: report.provenance,
        node,
    })
}

pub(super) fn resolve_node(
    report: &NnsNodeListReport,
    input: &str,
) -> Result<(usize, String), NnsInventoryError> {
    resolve_nns_inventory_row(
        &report.nodes,
        |row| row.node_principal.as_str(),
        input,
        NnsInventoryInputKind::Principal,
        "node_principal",
    )
    .map_err(|error| error.for_collection(super::COLLECTION))
}