canic_core/ops/runtime/
mod.rs

1pub mod cycles;
2pub mod log;
3pub mod metrics;
4
5use crate::{
6    VERSION,
7    cdk::{
8        api::{canister_self, trap},
9        println,
10    },
11    ids::{CanisterRole, SubnetRole},
12    log::Topic,
13    ops::{
14        service::TimerService,
15        storage::{
16            CanisterInitPayload,
17            directory::{AppDirectoryOps, SubnetDirectoryOps},
18            env::EnvOps,
19            memory::MemoryRegistryOps,
20            topology::{SubnetCanisterRegistryOps, SubnetIdentity},
21        },
22    },
23};
24use canic_memory::runtime::init_eager_tls;
25
26fn init_memory_or_trap(phase: &str) {
27    if let Err(err) = MemoryRegistryOps::init_memory() {
28        println!("[canic] FATAL: memory init failed during {phase}: {err}");
29        let msg = format!("canic init failed during {phase}: memory init failed: {err}");
30        trap(&msg);
31    }
32}
33
34/// root_init
35/// Bootstraps the root canister runtime and environment.
36pub fn root_init(identity: SubnetIdentity) {
37    // --- Phase 1: Init base systems ---
38
39    // log - clear some space
40    println!("");
41    println!("");
42    println!("");
43    crate::log!(
44        Topic::Init,
45        Info,
46        "🔧 --------------------- 'canic v{VERSION} -----------------------",
47    );
48    crate::log!(Topic::Init, Info, "🏁 init: root ({identity:?})");
49
50    // init
51    init_eager_tls();
52    init_memory_or_trap("root_init");
53
54    // --- Phase 2: Env registration ---
55    let self_pid = canister_self();
56    EnvOps::set_canister_role(CanisterRole::ROOT);
57    EnvOps::set_root_pid(self_pid);
58
59    match identity {
60        SubnetIdentity::Prime => {
61            EnvOps::set_prime_root_pid(self_pid);
62            EnvOps::set_subnet_role(SubnetRole::PRIME);
63            EnvOps::set_subnet_pid(self_pid);
64        }
65        SubnetIdentity::Standard(params) => {
66            EnvOps::set_prime_root_pid(params.prime_root_pid);
67            EnvOps::set_subnet_role(params.subnet_type);
68            EnvOps::set_subnet_pid(self_pid);
69        }
70        SubnetIdentity::Manual(subnet_pid) => {
71            EnvOps::set_prime_root_pid(self_pid);
72            EnvOps::set_subnet_role(SubnetRole::PRIME);
73            EnvOps::set_subnet_pid(subnet_pid);
74        }
75    }
76
77    SubnetCanisterRegistryOps::register_root(self_pid);
78
79    // --- Phase 3: Service startup ---
80    if let Err(err) = TimerService::start_all_root() {
81        crate::log!(Topic::Init, Warn, "timer startup failed (root): {err}");
82    }
83}
84
85/// root_post_upgrade
86pub fn root_post_upgrade() {
87    // --- Phase 1: Init base systems ---
88    crate::log!(Topic::Init, Info, "🏁 post_upgrade: root");
89    init_eager_tls();
90    init_memory_or_trap("root_post_upgrade");
91
92    // --- Phase 2: Env registration ---
93
94    // --- Phase 3: Service startup ---
95    if let Err(err) = TimerService::start_all_root() {
96        crate::log!(Topic::Init, Warn, "timer startup failed (root): {err}");
97    }
98}
99
100/// nonroot_init
101pub fn nonroot_init(canister_type: CanisterRole, payload: CanisterInitPayload) {
102    // --- Phase 1: Init base systems ---
103    crate::log!(Topic::Init, Info, "🏁 init: {}", canister_type);
104    init_eager_tls();
105    init_memory_or_trap("nonroot_init");
106
107    // --- Phase 2: Payload registration ---
108    EnvOps::import(payload.env);
109    AppDirectoryOps::import(payload.app_directory);
110    SubnetDirectoryOps::import(payload.subnet_directory);
111
112    // --- Phase 3: Service startup ---
113    if let Err(err) = TimerService::start_all() {
114        crate::log!(Topic::Init, Warn, "timer startup failed (nonroot): {err}");
115    }
116}
117
118/// nonroot_post_upgrade
119pub fn nonroot_post_upgrade(canister_type: CanisterRole) {
120    // --- Phase 1: Init base systems ---
121    crate::log!(Topic::Init, Info, "🏁 post_upgrade: {}", canister_type);
122    init_eager_tls();
123    init_memory_or_trap("nonroot_post_upgrade");
124
125    // --- Phase 2: Env registration ---
126
127    // --- Phase 3: Service startup ---
128    if let Err(err) = TimerService::start_all() {
129        crate::log!(Topic::Init, Warn, "timer startup failed (nonroot): {err}");
130    }
131}