Skip to main content

canic_core/ids/fleet_topology/
mod.rs

1//! Module: ids::fleet_topology
2//!
3//! Responsibility: define protected Fleet topology, admission, limit, and binding facts.
4//! Does not own: configuration compilation, placement decisions, Registry mutation, or storage.
5//! Boundary: these passive cross-layer contracts are validated before authoritative use.
6
7use crate::{
8    cdk::types::Cycles,
9    ids::{CanisterRole, ComponentInstanceId, ComponentSpecId, FleetBinding, SubnetId},
10};
11use candid::{CandidType, Principal};
12use serde::{Deserialize, Serialize};
13use std::fmt;
14
15///
16/// ComponentTopologyDigest
17///
18/// SHA-256 identity of one canonical root-local Component Topology projection.
19///
20
21#[derive(
22    CandidType, Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize,
23)]
24#[serde(transparent)]
25pub struct ComponentTopologyDigest([u8; 32]);
26
27impl ComponentTopologyDigest {
28    #[must_use]
29    pub const fn from_bytes(bytes: [u8; 32]) -> Self {
30        Self(bytes)
31    }
32
33    #[must_use]
34    pub const fn as_bytes(&self) -> &[u8; 32] {
35        &self.0
36    }
37
38    #[must_use]
39    pub const fn into_bytes(self) -> [u8; 32] {
40        self.0
41    }
42}
43
44impl fmt::Display for ComponentTopologyDigest {
45    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
46        for byte in self.0 {
47            write!(formatter, "{byte:02x}")?;
48        }
49        Ok(())
50    }
51}
52
53///
54/// CyclesFundingBudget
55///
56/// Positive aggregate cycles-funding ceiling applied over one bounded window.
57///
58
59#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
60#[serde(deny_unknown_fields)]
61pub struct CyclesFundingBudget {
62    pub window_secs: u64,
63    pub maximum_cycles: Cycles,
64}
65
66///
67/// ComponentSpecAdmission
68///
69/// Immutable permission and concrete-instance ceiling for one Spec on one Fleet Subnet Root.
70///
71
72#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
73#[serde(deny_unknown_fields)]
74pub struct ComponentSpecAdmission {
75    pub component_spec: ComponentSpecId,
76    pub spec_hash: [u8; 32],
77    pub maximum_root_instances: u32,
78}
79
80///
81/// FleetSubnetRootLimits
82///
83/// Immutable aggregate policy ceilings for one Fleet Subnet Root.
84///
85
86#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
87#[serde(deny_unknown_fields)]
88pub struct FleetSubnetRootLimits {
89    pub maximum_component_instances: u32,
90    pub maximum_managed_canisters: u32,
91    pub maximum_registry_bytes: u64,
92    pub maximum_wasm_store_bytes: u64,
93    pub cycles_funding: CyclesFundingBudget,
94}
95
96///
97/// FleetCoordinatorBinding
98///
99/// Immutable identity and exact physical placement of one Fleet Coordinator.
100///
101
102#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
103#[serde(deny_unknown_fields)]
104pub struct FleetCoordinatorBinding {
105    pub fleet: FleetBinding,
106    pub coordinator_subnet: SubnetId,
107    pub coordinator: Principal,
108}
109
110///
111/// FleetRegistryAuthority
112///
113/// Exact Coordinator binding and reinstall-local authority epoch for one Fleet Registry.
114///
115
116#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
117#[serde(deny_unknown_fields)]
118pub struct FleetRegistryAuthority {
119    pub binding: FleetCoordinatorBinding,
120    pub epoch: u64,
121}
122
123///
124/// FleetSubnetRootBinding
125///
126/// Complete immutable identity, placement, admissions, and limits of one Fleet Subnet Root.
127///
128
129#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
130#[serde(deny_unknown_fields)]
131pub struct FleetSubnetRootBinding {
132    pub authority: FleetRegistryAuthority,
133    pub placement_subnet: SubnetId,
134    pub fleet_subnet_root: Principal,
135    pub component_admissions: Vec<ComponentSpecAdmission>,
136    pub component_topology_digest: ComponentTopologyDigest,
137    pub limits: FleetSubnetRootLimits,
138}
139
140///
141/// ComponentBinding
142///
143/// Complete immutable identity and placement of one concrete Component.
144///
145
146#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
147#[serde(deny_unknown_fields)]
148pub struct ComponentBinding {
149    pub authority: FleetRegistryAuthority,
150    pub component: ComponentInstanceId,
151    pub component_spec: ComponentSpecId,
152    pub spec_hash: [u8; 32],
153    pub role: CanisterRole,
154    pub placement_subnet: SubnetId,
155    pub fleet_subnet_root: Principal,
156    pub canister_id: Principal,
157}
158
159///
160/// ComponentChildBinding
161///
162/// Complete immutable identity of one direct child owned by one exact Component.
163///
164
165#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
166#[serde(deny_unknown_fields)]
167pub struct ComponentChildBinding {
168    pub component: ComponentBinding,
169    pub role: CanisterRole,
170    pub canister_id: Principal,
171}