ic_query/ic/api_boundary_node/model.rs
1//! Module: ic::api_boundary_node::model
2//!
3//! Responsibility: certified API boundary-node requests, evidence, reports, and host errors.
4//! Does not own: state-tree collection, validation, command parsing, or text rendering.
5//! Boundary: preserves authenticated node identities, domains, addresses, and certificate time.
6
7use serde::Serialize;
8#[cfg(feature = "ic-state-host")]
9use thiserror::Error as ThisError;
10
11///
12/// IcApiBoundaryNodeRequest
13///
14/// Caller request for the complete certified API boundary-node state-tree collection.
15///
16
17#[derive(Clone, Debug, Eq, PartialEq)]
18pub struct IcApiBoundaryNodeRequest {
19 /// Mainnet IC API endpoint used for the certified `read_state` request.
20 pub source_endpoint: String,
21 /// Caller observation time as Unix seconds.
22 pub now_unix_secs: u64,
23}
24
25impl IcApiBoundaryNodeRequest {
26 /// Construct one live certified API boundary-node request.
27 #[must_use]
28 pub fn new(source_endpoint: impl Into<String>, now_unix_secs: u64) -> Self {
29 Self {
30 source_endpoint: source_endpoint.into(),
31 now_unix_secs,
32 }
33 }
34}
35
36///
37/// IcCertifiedStateProvenance
38///
39/// Certificate and retrieval provenance for one authenticated IC state-tree report.
40///
41
42#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
43pub struct IcCertifiedStateProvenance {
44 /// Emitted report schema version.
45 pub schema_version: u32,
46 /// Network identity authenticated by the built-in mainnet root key.
47 pub network: String,
48 /// Stable authority label for certified IC state-tree evidence.
49 pub authority: String,
50 /// IC API endpoint that returned the certificate.
51 pub source_endpoint: String,
52 /// Canister principal used only to route the `read_state` request.
53 pub effective_canister_id: String,
54 /// Caller observation time as Unix seconds.
55 pub fetched_at_unix_seconds: u64,
56 /// Caller observation time formatted in UTC.
57 pub fetched_at: String,
58 /// Collector identity.
59 pub fetched_by: String,
60 /// Raw certified state-tree time as Unix nanoseconds.
61 pub certificate_time_unix_nanos: u64,
62 /// Certified state-tree time rounded down to Unix seconds.
63 pub certificate_time_unix_seconds: u64,
64 /// Certified state-tree time formatted in UTC at second precision.
65 pub certificate_time: String,
66 /// Whether the report rows are authenticated by an IC certificate.
67 pub certified: bool,
68 /// Whether the returned rows belong to one certified state-tree time.
69 pub point_in_time_guaranteed: bool,
70}
71
72///
73/// IcApiBoundaryNodeRow
74///
75/// One API boundary node authenticated by the certified IC state tree.
76///
77
78#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
79pub struct IcApiBoundaryNodeRow {
80 /// Canonical API boundary-node principal.
81 pub node_id: String,
82 /// Certified DNS domain.
83 pub domain: String,
84 /// Optional certified IPv4 address.
85 pub ipv4_address: Option<String>,
86 /// Certified IPv6 address.
87 pub ipv6_address: String,
88}
89
90///
91/// IcApiBoundaryNodeReport
92///
93/// Complete API boundary-node collection from one authenticated IC state tree.
94///
95
96#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
97pub struct IcApiBoundaryNodeReport {
98 /// Certificate and retrieval provenance, flattened in serialized report JSON.
99 #[serde(flatten)]
100 pub provenance: IcCertifiedStateProvenance,
101 /// Number of authenticated API boundary-node rows.
102 pub node_count: usize,
103 /// Rows in canonical node-principal order.
104 pub rows: Vec<IcApiBoundaryNodeRow>,
105}
106
107///
108/// IcApiBoundaryNodeSourceRequest
109///
110/// Exact state-tree request and collection provenance supplied to a host source.
111///
112
113#[cfg(feature = "ic-state-host")]
114#[derive(Clone, Debug, Eq, PartialEq)]
115pub struct IcApiBoundaryNodeSourceRequest {
116 /// Fixed mainnet network identity.
117 pub network: String,
118 /// IC API endpoint used for `read_state`.
119 pub endpoint: String,
120 /// Canister principal used only to route the request.
121 pub effective_canister_id: String,
122 /// Caller observation time as Unix seconds.
123 pub observed_at_unix_seconds: u64,
124 /// Caller observation time formatted in UTC.
125 pub fetched_at: String,
126 /// Collector identity.
127 pub fetched_by: String,
128}
129
130///
131/// IcApiBoundaryNodeSourceData
132///
133/// Authenticated state-tree evidence returned by an API boundary-node source.
134///
135
136#[cfg(feature = "ic-state-host")]
137#[derive(Clone, Debug, Eq, PartialEq)]
138pub struct IcApiBoundaryNodeSourceData {
139 /// Exact source request echoed by the source.
140 pub source: IcApiBoundaryNodeSourceRequest,
141 /// Raw certified state-tree time as Unix nanoseconds.
142 pub certificate_time_unix_nanos: u64,
143 /// Authenticated API boundary-node rows.
144 pub rows: Vec<IcApiBoundaryNodeRow>,
145}
146
147///
148/// IcApiBoundaryNodeHostError
149///
150/// Failure while collecting or projecting certified API boundary-node evidence.
151///
152
153#[cfg(feature = "ic-state-host")]
154#[derive(Debug, ThisError)]
155pub enum IcApiBoundaryNodeHostError {
156 /// The response-bounded IC agent could not be constructed.
157 #[error("failed to build IC state agent for {endpoint}: {reason}")]
158 AgentBuild {
159 /// Rejected endpoint.
160 endpoint: String,
161 /// Agent or endpoint diagnostic.
162 reason: String,
163 },
164
165 /// The certified `read_state` request or certificate authentication failed.
166 #[error("certified IC state read through {endpoint} failed: {reason}")]
167 CertifiedReadState {
168 /// Endpoint used for the request.
169 endpoint: String,
170 /// Transport, decoding, delegation, signature, or age diagnostic.
171 reason: String,
172 },
173
174 /// The authenticated state tree did not match the specified boundary-node contract.
175 #[error("invalid certified IC state-tree data: {reason}")]
176 InvalidCertifiedState {
177 /// Deterministic state-tree validation diagnostic.
178 reason: String,
179 },
180
181 /// A source capability returned inconsistent request or report data.
182 #[error("invalid API boundary-node source data: {reason}")]
183 InvalidSourceData {
184 /// Deterministic source-contract diagnostic.
185 reason: String,
186 },
187}