Skip to main content

canic_core/dto/
fleet_registry.rs

1//! Module: dto::fleet_registry
2//!
3//! Responsibility: carry canonical Fleet Registry snapshots and versions across boundaries.
4//! Does not own: validation, canonical encoding, persistence, or lifecycle transitions.
5//! Boundary: Coordinator and Fleet Subnet Root workflows validate these passive shapes.
6
7use crate::{
8    config::{FleetServiceMemberPurpose, FleetServicePlacementPolicy},
9    dto::{
10        fleet_subnet_root::{
11            FleetSubnetRootDrainingResponse, FleetSubnetRootFinalInventoryResponse,
12        },
13        root_store::RootStoreBootstrapRequest,
14    },
15    ids::{
16        CanisterRole, ComponentGroupMemberPath, ComponentGroupPlacementId, ComponentInstanceId,
17        ComponentSpecAdmission, ComponentSpecId, ComponentTopologyDigest, FleetRegistryAuthority,
18        FleetServiceId, FleetSubnetRootLimits, FleetSubnetRootReleaseSet, SubnetId,
19    },
20};
21use candid::{CandidType, Principal};
22use serde::{Deserialize, Serialize};
23
24///
25/// FleetSubnetRootStatus
26///
27/// Lifecycle state of one Fleet Subnet Root in the Fleet Registry snapshot.
28///
29
30#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
31pub enum FleetSubnetRootStatus {
32    Joining,
33    Active,
34    Draining,
35    Removed,
36}
37
38///
39/// FleetComponentSpecEntry
40///
41/// Fleet-wide immutable Component Spec declaration projected into the Registry.
42///
43
44#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
45pub struct FleetComponentSpecEntry {
46    pub component_spec: ComponentSpecId,
47    pub spec_hash: [u8; 32],
48    pub component_role: CanisterRole,
49    pub maximum_fleet_instances: u32,
50}
51
52///
53/// FleetSubnetRootEntry
54///
55/// One Fleet Subnet Root's immutable placement and admission facts plus lifecycle state.
56///
57
58#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
59pub struct FleetSubnetRootEntry {
60    pub placement_subnet: SubnetId,
61    pub fleet_subnet_root: Principal,
62    pub component_admissions: Vec<ComponentSpecAdmission>,
63    pub component_topology_digest: ComponentTopologyDigest,
64    pub active_release_set: FleetSubnetRootReleaseSet,
65    pub limits: FleetSubnetRootLimits,
66    pub status: FleetSubnetRootStatus,
67}
68
69/// Published service mode after configuration-only Authority selectors have been resolved.
70#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
71pub enum FleetServiceMode {
72    AuthorityReplica,
73    ActivePool,
74}
75
76/// One exact configured Component member of a published Fleet service.
77#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
78#[serde(deny_unknown_fields)]
79pub struct FleetServiceComponentBinding {
80    pub member_purpose: FleetServiceMemberPurpose,
81    pub component: ComponentInstanceId,
82    pub fleet_subnet_root: Principal,
83    pub canister_id: Principal,
84    pub group_placement: ComponentGroupPlacementId,
85    pub member_path: ComponentGroupMemberPath,
86}
87
88/// Complete configured member set for one logical Fleet service.
89#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
90#[serde(deny_unknown_fields)]
91pub struct FleetServiceBinding {
92    pub service: FleetServiceId,
93    pub role: CanisterRole,
94    pub component_spec: ComponentSpecId,
95    pub mode: FleetServiceMode,
96    pub placement: FleetServicePlacementPolicy,
97    pub members: Vec<FleetServiceComponentBinding>,
98}
99
100///
101/// FleetRegistry
102///
103/// Complete canonical Fleet Registry snapshot distributed by one Coordinator.
104///
105
106#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
107pub struct FleetRegistry {
108    pub authority: FleetRegistryAuthority,
109    pub revision: u64,
110    pub component_specs: Vec<FleetComponentSpecEntry>,
111    pub fleet_subnet_roots: Vec<FleetSubnetRootEntry>,
112    pub services: Vec<FleetServiceBinding>,
113}
114
115///
116/// FleetRegistryManifest
117///
118/// Compact current-head evidence for one complete canonical Registry snapshot.
119///
120
121#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
122pub struct FleetRegistryManifest {
123    pub authority: FleetRegistryAuthority,
124    pub revision: u64,
125    pub byte_length: u64,
126    pub content_hash: [u8; 32],
127}
128
129///
130/// FleetRegistryVersion
131///
132/// Compact immutable identity used by mirrors, acknowledgements, and journals.
133///
134
135#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
136pub struct FleetRegistryVersion {
137    pub authority: FleetRegistryAuthority,
138    pub revision: u64,
139    pub content_hash: [u8; 32],
140}
141
142///
143/// FleetSubnetRootJoinRequest
144///
145/// Controller command that compare-and-commits one exact root as Registry `Joining`.
146///
147
148#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
149pub struct FleetSubnetRootJoinRequest {
150    pub expected_registry: FleetRegistryVersion,
151    pub entry: FleetSubnetRootEntry,
152}
153
154///
155/// FleetSubnetRootJoinResponse
156///
157/// Durable response receipt for one exact root's original `Joining` commit.
158///
159
160#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
161pub struct FleetSubnetRootJoinResponse {
162    pub entry: FleetSubnetRootEntry,
163    pub version: FleetRegistryVersion,
164}
165
166///
167/// FleetRegistryActivationRequest
168///
169/// Controller compare-and-commit command for the complete acknowledged `Joining` root set.
170///
171
172#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
173pub struct FleetRegistryActivationRequest {
174    pub expected_registry: FleetRegistryVersion,
175}
176
177///
178/// FleetRegistryActivationResponse
179///
180/// Durable response authority for one atomic all-`Active` Registry transition.
181///
182
183#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
184pub struct FleetRegistryActivationResponse {
185    pub previous_version: FleetRegistryVersion,
186    pub version: FleetRegistryVersion,
187}
188
189///
190/// FleetSubnetRootDrainingPublicationRequest
191///
192/// Controller command publishing one root's exact local draining fence to the Coordinator.
193///
194
195#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
196pub struct FleetSubnetRootDrainingPublicationRequest {
197    pub expected_registry: FleetRegistryVersion,
198    pub root_draining: FleetSubnetRootDrainingResponse,
199}
200
201///
202/// FleetSubnetRootDrainingPublicationResponse
203///
204/// Durable response authority for one root's canonical `Active -> Draining` transition.
205///
206
207#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
208pub struct FleetSubnetRootDrainingPublicationResponse {
209    pub root_draining: FleetSubnetRootDrainingResponse,
210    pub previous_version: FleetRegistryVersion,
211    pub version: FleetRegistryVersion,
212}
213
214///
215/// FleetSubnetRootRemovalPublicationRequest
216///
217/// Root-authenticated command publishing one exact terminal inventory to the Coordinator.
218///
219
220#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
221pub struct FleetSubnetRootRemovalPublicationRequest {
222    pub expected_registry: FleetRegistryVersion,
223    pub final_inventory: FleetSubnetRootFinalInventoryResponse,
224}
225
226///
227/// FleetSubnetRootRemovalPublicationResponse
228///
229/// Durable response authority for one root's canonical `Draining -> Removed` transition.
230///
231
232#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
233pub struct FleetSubnetRootRemovalPublicationResponse {
234    pub final_inventory: FleetSubnetRootFinalInventoryResponse,
235    pub previous_version: FleetRegistryVersion,
236    pub version: FleetRegistryVersion,
237}
238
239/// Root-authenticated command freezing its pre-transfer physical-deletion readiness authority.
240#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
241pub struct FleetSubnetRootDeletionReadinessIntentRequest {
242    pub operation_id: [u8; 32],
243    pub fleet_subnet_root: Principal,
244    pub final_inventory_hash: [u8; 32],
245    pub store_deletion_hash: [u8; 32],
246    pub observed_cycles_before_reclamation: u128,
247    pub retained_cycles_target: u128,
248    pub observed_reserved_cycles: u128,
249    pub observed_idle_cycles_burned_per_day: u128,
250    pub observed_freezing_threshold_seconds: u128,
251    pub prepared_at_ns: u64,
252}
253
254/// Coordinator receipt proving root-deletion readiness intent is durable before cycle transfer.
255#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
256pub struct FleetSubnetRootDeletionReadinessIntentResponse {
257    pub request: FleetSubnetRootDeletionReadinessIntentRequest,
258    pub coordinator: Principal,
259    pub recorded_at_ns: u64,
260    pub intent_hash: [u8; 32],
261}
262
263/// Root-authenticated command recording its converged post-transfer cycle balance.
264#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
265pub struct FleetSubnetRootDeletionReadinessRequest {
266    pub operation_id: [u8; 32],
267    pub fleet_subnet_root: Principal,
268    pub expected_intent_hash: [u8; 32],
269    pub observed_cycles_after_reclamation: u128,
270    pub cycles_reclaimed_at_ns: u64,
271}
272
273/// Coordinator receipt proving one removed root is ready for an external executor.
274#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
275pub struct FleetSubnetRootDeletionReadinessResponse {
276    pub request: FleetSubnetRootDeletionReadinessRequest,
277    pub coordinator: Principal,
278    pub final_inventory_hash: [u8; 32],
279    pub store_deletion_hash: [u8; 32],
280    pub observed_cycles_before_reclamation: u128,
281    pub retained_cycles_target: u128,
282    pub observed_reserved_cycles: u128,
283    pub observed_idle_cycles_burned_per_day: u128,
284    pub observed_freezing_threshold_seconds: u128,
285    pub prepared_at_ns: u64,
286    pub recorded_at_ns: u64,
287    pub readiness_hash: [u8; 32],
288}
289
290/// Controller command freezing independently observed root authority before stop/delete.
291#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
292pub struct FleetSubnetRootDeletionExecutionRequest {
293    pub operation_id: [u8; 32],
294    pub fleet_subnet_root: Principal,
295    pub expected_readiness_hash: [u8; 32],
296    pub observed_module_hash: [u8; 32],
297    pub observed_controllers: Vec<Principal>,
298    pub observed_cycles_after_reclamation: u128,
299    pub observed_reserved_cycles: u128,
300    pub observed_idle_cycles_burned_per_day: u128,
301    pub observed_freezing_threshold_seconds: u128,
302}
303
304/// Durable Coordinator intent binding one authenticated external root-deletion executor.
305#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
306pub struct FleetSubnetRootDeletionExecutionResponse {
307    pub request: FleetSubnetRootDeletionExecutionRequest,
308    pub executor: Principal,
309    pub prepared_at_ns: u64,
310    pub execution_hash: [u8; 32],
311}
312
313/// Controller request confirming typed root absence under one durable execution intent.
314#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
315pub struct FleetSubnetRootDeletionCompletionRequest {
316    pub operation_id: [u8; 32],
317    pub fleet_subnet_root: Principal,
318    pub expected_execution_hash: [u8; 32],
319    pub observed_absent_at_ns: u64,
320}
321
322/// Read-only lookup key for one durable root-deletion execution intent or receipt.
323#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
324pub struct FleetSubnetRootDeletionStatusRequest {
325    pub operation_id: [u8; 32],
326    pub fleet_subnet_root: Principal,
327}
328
329/// Terminal Coordinator receipt for externally observed Fleet Subnet Root absence.
330#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
331pub struct FleetSubnetRootDeletionResponse {
332    pub operation_id: [u8; 32],
333    pub fleet_subnet_root: Principal,
334    pub coordinator: Principal,
335    pub executor: Principal,
336    pub readiness_hash: [u8; 32],
337    pub execution_hash: [u8; 32],
338    pub observed_module_hash: [u8; 32],
339    pub observed_controllers: Vec<Principal>,
340    pub observed_cycles_after_reclamation: u128,
341    pub observed_absent_at_ns: u64,
342    pub completed_at_ns: u64,
343    pub deletion_hash: [u8; 32],
344}
345
346///
347/// FleetRegistrySnapshotResponse
348///
349/// Complete current Coordinator snapshot supplied only to one registered root.
350///
351
352#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
353pub struct FleetRegistrySnapshotResponse {
354    pub registry: FleetRegistry,
355    pub manifest: FleetRegistryManifest,
356    pub version: FleetRegistryVersion,
357}
358
359///
360/// FleetSubnetRootSnapshotAcknowledgementRequest
361///
362/// Root-authenticated acknowledgement of one exact durably staged snapshot.
363///
364
365#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
366pub struct FleetSubnetRootSnapshotAcknowledgementRequest {
367    pub version: FleetRegistryVersion,
368}
369
370///
371/// FleetSubnetRootSnapshotAcknowledgement
372///
373/// Durable Coordinator receipt proving which root acknowledged which version.
374///
375
376#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
377pub struct FleetSubnetRootSnapshotAcknowledgement {
378    pub fleet_subnet_root: Principal,
379    pub version: FleetRegistryVersion,
380}
381
382/// Controller command asking a Prepared root to synchronize and acknowledge its Registry.
383#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
384pub struct FleetSubnetRootRegistrySyncRequest {
385    pub expected_registry: FleetRegistryVersion,
386    pub store_bootstrap: RootStoreBootstrapRequest,
387}
388
389/// Exact root-local candidate and Coordinator acknowledgement evidence.
390#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
391pub struct FleetSubnetRootRegistrySyncResponse {
392    pub fleet_subnet_root: Principal,
393    pub version: FleetRegistryVersion,
394    pub acknowledgement: FleetSubnetRootSnapshotAcknowledgement,
395}
396
397///
398/// FleetDirectoryProvenance
399///
400/// Exact Registry authority and root that published one local Fleet Directory projection.
401///
402
403#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
404pub struct FleetDirectoryProvenance {
405    pub registry: FleetRegistryVersion,
406    pub source_fleet_subnet_root: Principal,
407}
408
409///
410/// FleetSubnetRootDirectoryEntry
411///
412/// One root placement and lifecycle status projected from the complete Fleet Registry.
413///
414
415#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
416pub struct FleetSubnetRootDirectoryEntry {
417    pub placement_subnet: SubnetId,
418    pub fleet_subnet_root: Principal,
419    pub status: FleetSubnetRootStatus,
420}
421
422/// One exact configured Component projected into a Fleet Directory service.
423#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
424#[serde(deny_unknown_fields)]
425pub struct FleetDirectoryServiceComponent {
426    pub member_purpose: FleetServiceMemberPurpose,
427    pub component: ComponentInstanceId,
428    pub fleet_subnet_root: Principal,
429    pub canister_id: Principal,
430    pub group_placement: ComponentGroupPlacementId,
431    pub member_path: ComponentGroupMemberPath,
432}
433
434/// One complete configured service projected from the canonical Fleet Registry.
435#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
436#[serde(deny_unknown_fields)]
437pub struct FleetDirectoryService {
438    pub service: FleetServiceId,
439    pub role: CanisterRole,
440    pub component_spec: ComponentSpecId,
441    pub mode: FleetServiceMode,
442    pub placement: FleetServicePlacementPolicy,
443    pub members: Vec<FleetDirectoryServiceComponent>,
444}
445
446///
447/// FleetDirectorySnapshot
448///
449/// Root-local read-only discovery projection derived from one exact published Registry.
450///
451
452#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
453pub struct FleetDirectorySnapshot {
454    pub provenance: FleetDirectoryProvenance,
455    pub fleet_subnet_roots: Vec<FleetSubnetRootDirectoryEntry>,
456    pub services: Vec<FleetDirectoryService>,
457}
458
459///
460/// FleetSubnetRootRegistryMirrorActivationRequest
461///
462/// Controller command that atomically activates a newer complete Registry mirror and Directory.
463///
464
465#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
466pub struct FleetSubnetRootRegistryMirrorActivationRequest {
467    pub previous_registry: FleetRegistryVersion,
468    pub expected_registry: FleetRegistryVersion,
469    pub expected_directory: FleetDirectorySnapshot,
470    pub store_bootstrap: RootStoreBootstrapRequest,
471}
472
473///
474/// FleetSubnetRootRegistryMirrorActivationResponse
475///
476/// Exact durable evidence for one root's current Registry mirror and Fleet Directory.
477///
478
479#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
480pub struct FleetSubnetRootRegistryMirrorActivationResponse {
481    pub fleet_subnet_root: Principal,
482    pub previous_registry: FleetRegistryVersion,
483    pub version: FleetRegistryVersion,
484    pub directory: FleetDirectorySnapshot,
485}