canic_core/ops/
mod.rs

1//! Business-logic helpers that sit between endpoint handlers and the state
2//! layer.
3//!
4//! The ops layer orchestrates multi-step workflows such as provisioning new
5//! canisters,  running scaling/sharding policies, and
6//! synchronizing topology snapshots. Endpoint macros call into these modules so
7//! the public surface remains thin while policy, logging, and validation live
8//! here.
9
10pub mod config;
11pub mod icrc;
12pub mod metrics;
13pub mod mgmt;
14pub mod model;
15pub mod orchestration;
16pub mod request;
17pub mod root;
18pub mod runtime;
19pub mod service;
20pub mod signature;
21pub mod sync;
22pub mod types;
23pub mod wasm;
24
25pub use types::*;
26
27/// Common imports for ops submodules and consumers.
28pub mod prelude {
29    pub use crate::{
30        cdk::{
31            api::{canister_self, msg_caller},
32            candid::CandidType,
33        },
34        ids::CanisterRole,
35        interface::{
36            InterfaceError,
37            ic::{call::Call, call_and_decode},
38        },
39        log,
40        log::Level,
41        ops::OpsError,
42        types::{Cycles, Int, Nat, Principal, Subaccount},
43    };
44    pub use serde::{Deserialize, Serialize};
45}
46
47use crate::{ThisError, ops::model::memory::EnvOps};
48
49///
50/// OpsError
51/// Error envelope shared across operations submodules
52///
53
54#[derive(Debug, ThisError)]
55pub enum OpsError {
56    /// Raised when a function requires root context, but was called from a child.
57    #[error("operation must be called from the root canister")]
58    NotRoot,
59
60    /// Raised when a function must not be called from root.
61    #[error("operation cannot be called from the root canister")]
62    IsRoot,
63
64    #[error(transparent)]
65    ConfigOpsError(#[from] config::ConfigOpsError),
66
67    #[error(transparent)]
68    ModelOpsError(#[from] model::ModelOpsError),
69
70    #[error(transparent)]
71    RequestOpsError(#[from] request::RequestOpsError),
72
73    #[error(transparent)]
74    SignatureOpsError(#[from] signature::SignatureOpsError),
75
76    #[error(transparent)]
77    SyncOpsError(#[from] sync::SyncOpsError),
78}
79
80impl OpsError {
81    /// Ensure the caller is the root canister.
82    pub fn require_root() -> Result<(), Self> {
83        if EnvOps::is_root() {
84            Ok(())
85        } else {
86            Err(Self::NotRoot)
87        }
88    }
89
90    /// Ensure the caller is not the root canister.
91    pub fn deny_root() -> Result<(), Self> {
92        if EnvOps::is_root() {
93            Err(Self::IsRoot)
94        } else {
95            Ok(())
96        }
97    }
98}