Skip to main content

canic_host/subnet_registry/
mod.rs

1//! Module: subnet_registry
2//!
3//! Responsibility: query one root canister's maintained subnet registry.
4//! Does not own: registry state, endpoint DTOs, or deployment discovery policy.
5//! Boundary: selects one transport and returns validated canonical host entries.
6
7use crate::{
8    icp::{IcpCli, IcpCommandError},
9    registry::{RegistryEntry, RegistryParseError, parse_registry_entries},
10    replica_query::{self, ReplicaQueryError},
11};
12use std::path::Path;
13use thiserror::Error as ThisError;
14
15const CANIC_SUBNET_REGISTRY_METHOD: &str = "canic_subnet_registry";
16const ICP_JSON_OUTPUT: &str = "json";
17
18///
19/// SubnetRegistryQuery
20///
21
22#[derive(Clone, Debug, Eq, PartialEq)]
23pub struct SubnetRegistryQuery {
24    pub entries: Vec<RegistryEntry>,
25}
26
27///
28/// SubnetRegistryQueryError
29///
30
31#[derive(Debug, ThisError)]
32pub enum SubnetRegistryQueryError {
33    #[error(transparent)]
34    Icp(#[from] IcpCommandError),
35
36    #[error(transparent)]
37    Registry(#[from] RegistryParseError),
38
39    #[error(transparent)]
40    Replica(#[from] ReplicaQueryError),
41}
42
43/// Query `canic_subnet_registry`, using the local replica API for local targets.
44pub fn query_subnet_registry(
45    icp: &IcpCli,
46    root: &str,
47    environment: &str,
48    icp_root: Option<&Path>,
49    candid_path: Option<&Path>,
50) -> Result<SubnetRegistryQuery, SubnetRegistryQueryError> {
51    if replica_query::should_use_local_replica_query(Some(environment)) {
52        return query_local_subnet_registry(root, environment, icp_root);
53    }
54
55    let output = icp.canister_query_output_with_candid(
56        root,
57        CANIC_SUBNET_REGISTRY_METHOD,
58        Some(ICP_JSON_OUTPUT),
59        candid_path,
60    )?;
61    Ok(SubnetRegistryQuery {
62        entries: parse_registry_entries(&output)?,
63    })
64}
65
66fn query_local_subnet_registry(
67    root: &str,
68    environment: &str,
69    icp_root: Option<&Path>,
70) -> Result<SubnetRegistryQuery, SubnetRegistryQueryError> {
71    let entries = replica_query::query_subnet_registry_entries(Some(environment), root, icp_root)?;
72    Ok(SubnetRegistryQuery { entries })
73}