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/// SubnetRegistryQueryError
20///
21
22#[derive(Debug, ThisError)]
23pub enum SubnetRegistryQueryError {
24    #[error(transparent)]
25    Icp(#[from] IcpCommandError),
26
27    #[error(transparent)]
28    Registry(#[from] RegistryParseError),
29
30    #[error(transparent)]
31    Replica(#[from] ReplicaQueryError),
32}
33
34/// Query `canic_subnet_registry`, using the local replica API for local targets.
35pub fn query_subnet_registry(
36    icp: &IcpCli,
37    root: &str,
38    environment: &str,
39    icp_root: Option<&Path>,
40    candid_path: Option<&Path>,
41) -> Result<Vec<RegistryEntry>, SubnetRegistryQueryError> {
42    if replica_query::should_use_local_replica_query(Some(environment)) {
43        return query_local_subnet_registry(root, environment, icp_root);
44    }
45
46    let output = icp.canister_query_output_with_candid(
47        root,
48        CANIC_SUBNET_REGISTRY_METHOD,
49        Some(ICP_JSON_OUTPUT),
50        candid_path,
51    )?;
52    Ok(parse_registry_entries(&output)?)
53}
54
55fn query_local_subnet_registry(
56    root: &str,
57    environment: &str,
58    icp_root: Option<&Path>,
59) -> Result<Vec<RegistryEntry>, SubnetRegistryQueryError> {
60    Ok(replica_query::query_subnet_registry_entries(
61        Some(environment),
62        root,
63        icp_root,
64    )?)
65}