ic-query 0.20.1

Internet Computer query library for NNS, SNS, ICRC, and related public network metadata
Documentation
use crate::{
    ic_registry::{
        MainnetNode, MainnetNodeList, MainnetRegistryFetchRequest, RegistryFetchError,
        projection::subnet_kind_from_registry,
        proto::SubnetRecord,
        relations::{
            RegistryRelationInventory, ResolvedNodeRelation, node_subnet_assignments_from_records,
            resolved_node_relations_from_records,
        },
    },
    subnet_catalog::{MAINNET_NETWORK, MAINNET_REGISTRY_CANISTER_ID},
};
use std::collections::BTreeMap;

pub(in crate::ic_registry) fn node_list_from_inventory(
    request: &MainnetRegistryFetchRequest,
    inventory: RegistryRelationInventory,
    registry_version: u64,
) -> Result<MainnetNodeList, RegistryFetchError> {
    let node_subnets = node_subnet_assignments_from_records(&inventory.subnet_records)?;
    let node_relations = resolved_node_relations_from_records(
        &inventory.node_principals,
        &inventory.node_records,
        &inventory.node_operator_records,
    )?;
    let mut nodes = node_relations
        .into_iter()
        .map(|(principal, relation)| {
            node_from_relation(
                principal,
                relation,
                &inventory.subnet_records,
                &node_subnets,
            )
        })
        .collect::<Result<Vec<_>, _>>()?;
    nodes.sort_by(|left, right| left.principal.cmp(&right.principal));
    Ok(MainnetNodeList {
        network: MAINNET_NETWORK.to_string(),
        registry_canister_id: MAINNET_REGISTRY_CANISTER_ID.to_string(),
        registry_version,
        fetched_at: request.fetched_at.clone(),
        fetched_by: request.fetched_by.clone(),
        source_endpoint: request.endpoint.clone(),
        nodes,
    })
}

fn node_from_relation(
    principal: String,
    relation: ResolvedNodeRelation,
    subnet_records: &BTreeMap<String, SubnetRecord>,
    node_subnets: &BTreeMap<String, String>,
) -> Result<MainnetNode, RegistryFetchError> {
    let subnet_principal =
        node_subnets
            .get(&principal)
            .ok_or(RegistryFetchError::MissingField {
                field: "node_subnet_assignment",
            })?;
    let subnet_record =
        subnet_records
            .get(subnet_principal)
            .ok_or(RegistryFetchError::MissingField {
                field: "subnet_record",
            })?;
    Ok(MainnetNode {
        principal,
        node_operator_principal: relation.node_operator_principal,
        node_provider_principal: relation.node_provider_principal,
        subnet_principal: subnet_principal.clone(),
        subnet_kind: subnet_kind_from_registry(subnet_record.subnet_type)
            .as_str()
            .to_string(),
        data_center_id: relation.data_center_id,
    })
}