Skip to main content

ic_query/cloud_engine/
mod.rs

1//! Native CloudEngine control-plane report models, adapters, builders, and renderers.
2
3#[cfg(feature = "cloud-engine-host")]
4mod build;
5#[cfg(all(feature = "cloud-engine-host", feature = "subnet-catalog-host"))]
6mod list;
7mod model;
8#[cfg(feature = "cloud-engine-host")]
9mod source;
10mod text;
11#[cfg(feature = "cloud-engine-host")]
12mod wire;
13
14#[cfg(feature = "cloud-engine-host")]
15use crate::runtime::RuntimeError;
16#[cfg(feature = "cloud-engine-host")]
17use thiserror::Error as ThisError;
18
19#[cfg(feature = "cloud-engine-host")]
20pub use build::{
21    build_cloud_engine_operator_report, build_cloud_engine_operator_report_with_source,
22    build_cloud_engine_prices_report, build_cloud_engine_prices_report_with_source,
23};
24#[cfg(all(feature = "cloud-engine-host", feature = "subnet-catalog-host"))]
25pub use list::{build_cloud_engine_list_report, build_cloud_engine_list_report_with_sources};
26#[cfg(all(feature = "cloud-engine-host", feature = "subnet-catalog-host"))]
27pub use model::{CloudEngineListReport, CloudEngineListRow, CloudEngineOperatorLookupStatus};
28pub use model::{
29    CloudEngineNodeType, CloudEngineOperatorReport, CloudEnginePriceRow, CloudEnginePricesReport,
30    CloudEngineReportContext,
31};
32#[cfg(feature = "cloud-engine-host")]
33pub use model::{
34    CloudEngineOperatorBindingSourceData, CloudEngineOperatorSourceData,
35    CloudEnginePricesSourceData,
36};
37#[cfg(feature = "cloud-engine-host")]
38pub use source::{
39    CloudEngineOperatorBindingSource, CloudEngineSource, CloudEngineSourceRequest,
40    LiveCloudEngineSource,
41};
42#[cfg(all(feature = "cloud-engine-host", feature = "subnet-catalog-host"))]
43pub use text::cloud_engine_list_report_text;
44pub use text::{cloud_engine_operator_report_text, cloud_engine_prices_report_text};
45
46/// Mainnet CloudEngine control-plane registry canister principal.
47pub const MAINNET_CLOUD_ENGINE_CANISTER_ID: &str = "q6cfj-fyaaa-aaaar-qb77q-cai";
48
49/// Default replica endpoint used for live CloudEngine control-plane queries.
50pub const DEFAULT_CLOUD_ENGINE_SOURCE_ENDPOINT: &str = "https://icp-api.io";
51
52/// Maximum marketplace rows accepted from one live response.
53pub const MAX_CLOUD_ENGINE_PRICE_ROWS: usize = 1_000;
54
55/// Maximum Registry CloudEngine Subnets followed by one list invocation.
56pub const MAX_CLOUD_ENGINE_LIST_ROWS: usize = 100;
57
58/// Maximum claimed domains accepted from one engine operator.
59pub const MAX_CLOUD_ENGINE_DOMAINS: usize = 100;
60
61/// Maximum decimal digits accepted for one marketplace cycle amount.
62pub const MAX_CLOUD_ENGINE_CYCLE_DECIMAL_DIGITS: usize = 256;
63
64#[cfg(feature = "cloud-engine-host")]
65const CLOUD_ENGINE_REPORT_SCHEMA_VERSION: u32 = 1;
66#[cfg(feature = "cloud-engine-host")]
67const CLOUD_ENGINE_AUTHORITY: &str = "cloud_engine_control_plane_canister";
68
69///
70/// CloudEngineHostError
71///
72/// Failure while collecting or validating one live CloudEngine report.
73///
74
75#[cfg(feature = "cloud-engine-host")]
76#[derive(Debug, ThisError)]
77pub enum CloudEngineHostError {
78    /// The requested network is not the supported mainnet identity.
79    #[error(
80        "`icq cloud-engine` supports only the mainnet `ic` network\n\nThese reports query the mainnet CloudEngine control-plane canister.\n\nTry:\n  icq --network ic cloud-engine prices"
81    )]
82    UnsupportedNetwork {
83        /// Rejected network identity.
84        network: String,
85    },
86
87    /// A requested principal is invalid.
88    #[error("invalid {field}: {reason}")]
89    InvalidPrincipal {
90        /// Principal field being parsed.
91        field: &'static str,
92        /// Principal parsing failure.
93        reason: String,
94    },
95
96    /// The IC agent could not be constructed for the requested endpoint.
97    #[error("failed to build IC agent for {endpoint}: {reason}")]
98    AgentBuild {
99        /// Endpoint used to build the agent.
100        endpoint: String,
101        /// Agent construction failure.
102        reason: String,
103    },
104
105    /// The built-in CloudEngine control-plane principal could not be parsed.
106    #[error("invalid built-in CloudEngine canister principal: {reason}")]
107    CanisterId {
108        /// Principal parsing failure.
109        reason: String,
110    },
111
112    /// A CloudEngine control-plane query failed.
113    #[error("CloudEngine agent call {method} failed: {reason}")]
114    AgentCall {
115        /// Canister method being queried.
116        method: &'static str,
117        /// Agent call failure.
118        reason: String,
119    },
120
121    /// A CloudEngine query argument could not be Candid encoded.
122    #[error("failed to encode Candid {message}: {reason}")]
123    CandidEncode {
124        /// Candid request type.
125        message: &'static str,
126        /// Encoding failure.
127        reason: String,
128    },
129
130    /// A CloudEngine response could not be Candid decoded.
131    #[error("failed to decode Candid {message}: {reason}")]
132    CandidDecode {
133        /// Candid response type.
134        message: &'static str,
135        /// Decoding failure.
136        reason: String,
137    },
138
139    /// A custom CloudEngine source returned inconsistent or excessive data.
140    #[error("invalid CloudEngine source data: {reason}")]
141    InvalidSourceData {
142        /// Deterministic source-contract failure.
143        reason: String,
144    },
145
146    /// The Registry-backed Subnet Catalog could not supply the list inventory.
147    #[cfg(feature = "subnet-catalog-host")]
148    #[error(transparent)]
149    SubnetCatalog(#[from] crate::subnet_catalog::SubnetCatalogHostError),
150
151    /// The synchronous host runtime could not execute the live query.
152    #[error(transparent)]
153    Runtime(#[from] RuntimeError),
154}
155
156#[cfg(feature = "cloud-engine-host")]
157fn enforce_mainnet_network(network: &str) -> Result<(), CloudEngineHostError> {
158    crate::network::enforce_mainnet_network_with(network, |network| {
159        CloudEngineHostError::UnsupportedNetwork { network }
160    })
161}
162
163#[cfg(all(test, feature = "cloud-engine-host"))]
164mod tests;