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::{
10        CanisterRole, ComponentInstanceId, ComponentSpecId, FleetBinding, ReleaseBuildId, SubnetId,
11    },
12};
13use candid::{CandidType, Principal};
14use serde::{Deserialize, Serialize};
15use std::fmt;
16
17///
18/// ComponentTopologyDigest
19///
20/// SHA-256 identity of one canonical root-local Component Topology projection.
21///
22
23#[derive(
24    CandidType, Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize,
25)]
26#[serde(transparent)]
27pub struct ComponentTopologyDigest([u8; 32]);
28
29impl ComponentTopologyDigest {
30    #[must_use]
31    pub const fn from_bytes(bytes: [u8; 32]) -> Self {
32        Self(bytes)
33    }
34
35    #[must_use]
36    pub const fn as_bytes(&self) -> &[u8; 32] {
37        &self.0
38    }
39
40    #[must_use]
41    pub const fn into_bytes(self) -> [u8; 32] {
42        self.0
43    }
44}
45
46impl fmt::Display for ComponentTopologyDigest {
47    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
48        for byte in self.0 {
49            write!(formatter, "{byte:02x}")?;
50        }
51        Ok(())
52    }
53}
54
55///
56/// CyclesFundingBudget
57///
58/// Positive aggregate cycles-funding ceiling applied over one bounded window.
59///
60
61#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
62#[serde(deny_unknown_fields)]
63pub struct CyclesFundingBudget {
64    pub window_secs: u64,
65    pub maximum_cycles: Cycles,
66}
67
68///
69/// FleetSubnetCanisterPoolConfig
70///
71/// Immutable prepaid empty-Canister inventory policy for one Fleet Subnet Root.
72///
73
74#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
75#[serde(deny_unknown_fields)]
76pub struct FleetSubnetCanisterPoolConfig {
77    /// Ready empty Canisters the root continuously attempts to retain.
78    pub minimum_size: u32,
79    /// Ceiling for configured imports and proactive refill inventory.
80    ///
81    /// Recycled assets remain tracked even when their return temporarily exceeds this target.
82    pub maximum_size: u32,
83    /// Cycles placed on each Canister created by the root for this pool.
84    pub canister_cycles: Cycles,
85}
86
87///
88/// ComponentSpecAdmission
89///
90/// Immutable permission and concrete-instance ceiling for one Spec on one Fleet Subnet Root.
91///
92
93#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
94#[serde(deny_unknown_fields)]
95pub struct ComponentSpecAdmission {
96    pub component_spec: ComponentSpecId,
97    pub spec_hash: [u8; 32],
98    pub maximum_root_instances: u32,
99}
100
101///
102/// FleetSubnetRootLimits
103///
104/// Immutable aggregate policy ceilings for one Fleet Subnet Root.
105///
106
107#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
108#[serde(deny_unknown_fields)]
109pub struct FleetSubnetRootLimits {
110    pub maximum_component_instances: u32,
111    pub maximum_managed_canisters: u32,
112    pub maximum_registry_bytes: u64,
113    pub maximum_wasm_store_bytes: u64,
114    pub canister_pool: FleetSubnetCanisterPoolConfig,
115    pub cycles_funding: CyclesFundingBudget,
116}
117
118///
119/// FleetCoordinatorBinding
120///
121/// Immutable identity and exact physical placement of one Fleet Coordinator.
122///
123
124#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
125#[serde(deny_unknown_fields)]
126pub struct FleetCoordinatorBinding {
127    pub fleet: FleetBinding,
128    pub coordinator_subnet: SubnetId,
129    pub coordinator: Principal,
130}
131
132///
133/// FleetRegistryAuthority
134///
135/// Exact Coordinator binding and reinstall-local authority epoch for one Fleet Registry.
136///
137
138#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
139#[serde(deny_unknown_fields)]
140pub struct FleetRegistryAuthority {
141    pub binding: FleetCoordinatorBinding,
142    pub epoch: u64,
143}
144
145///
146/// FleetSubnetRootBinding
147///
148/// Complete immutable identity, placement, admissions, and limits of one Fleet Subnet Root.
149///
150
151#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
152#[serde(deny_unknown_fields)]
153pub struct FleetSubnetRootBinding {
154    pub authority: FleetRegistryAuthority,
155    pub placement_subnet: SubnetId,
156    pub fleet_subnet_root: Principal,
157    pub component_admissions: Vec<ComponentSpecAdmission>,
158    pub component_topology_digest: ComponentTopologyDigest,
159    pub limits: FleetSubnetRootLimits,
160}
161
162///
163/// FleetSubnetWasmStoreAuthority
164///
165/// Exact reciprocal authority retained by one root and its host-installed sibling Store.
166///
167
168#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
169#[serde(deny_unknown_fields)]
170pub struct FleetSubnetWasmStoreAuthority {
171    pub authority: FleetRegistryAuthority,
172    pub placement_subnet: SubnetId,
173    pub fleet_subnet_root: Principal,
174    pub wasm_store: Principal,
175    pub installation_controller: Principal,
176    pub release_build_id: ReleaseBuildId,
177    pub wasm_module_hash: [u8; 32],
178}
179
180///
181/// ComponentBinding
182///
183/// Complete immutable identity and placement of one concrete Component.
184///
185
186#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
187#[serde(deny_unknown_fields)]
188pub struct ComponentBinding {
189    pub authority: FleetRegistryAuthority,
190    pub component: ComponentInstanceId,
191    pub component_spec: ComponentSpecId,
192    pub spec_hash: [u8; 32],
193    pub role: CanisterRole,
194    pub placement_subnet: SubnetId,
195    pub fleet_subnet_root: Principal,
196    pub canister_id: Principal,
197}
198
199///
200/// ComponentChildBinding
201///
202/// Complete immutable identity of one child at any depth in one exact Component tree.
203///
204
205#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
206#[serde(deny_unknown_fields)]
207pub struct ComponentChildBinding {
208    pub component: ComponentBinding,
209    pub parent_canister_id: Principal,
210    pub role: CanisterRole,
211    pub canister_id: Principal,
212}
213
214///
215/// ManagedCanisterBinding
216///
217/// Immutable Registry-issued identity retained by one managed application Canister.
218///
219
220#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
221#[serde(deny_unknown_fields)]
222pub enum ManagedCanisterBinding {
223    Component(ComponentBinding),
224    ComponentChild(ComponentChildBinding),
225}