canic_core/ops/runtime/
mod.rs

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