1use std::collections::BTreeMap;
3
4use thiserror::Error;
5
6use crate::{
7 common::{
8 crypto::{
9 hash::Hash,
10 signature::{self, Signature},
11 x25519,
12 },
13 namespace::Namespace,
14 sgx::{ias::AVR, Quote, QuotePolicy},
15 version::Version,
16 },
17 consensus::{
18 self,
19 beacon::EpochTime,
20 registry::EndorsedCapabilityTEE,
21 roothash::{self, Block, ComputeResultsHeader, Header},
22 state::keymanager::Status as KeyManagerStatus,
23 transaction::{Proof, SignedTransaction},
24 LightBlock,
25 },
26 enclave_rpc,
27 storage::mkvs::{sync, WriteLog},
28 transaction::types::TxnBatch,
29};
30
31#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
33pub struct ComputedBatch {
34 pub header: ComputeResultsHeader,
36 pub io_write_log: WriteLog,
38 pub state_write_log: WriteLog,
40 pub rak_sig: Signature,
43 pub messages: Vec<roothash::Message>,
45}
46
47#[derive(Debug, cbor::Encode, cbor::Decode)]
49pub enum StorageSyncRequest {
50 SyncGet(sync::GetRequest),
51 SyncGetPrefixes(sync::GetPrefixesRequest),
52 SyncIterate(sync::IterateRequest),
53}
54
55#[derive(Debug)]
56pub struct StorageSyncRequestWithEndpoint {
57 pub endpoint: HostStorageEndpoint,
58 pub request: StorageSyncRequest,
59}
60
61impl cbor::Encode for StorageSyncRequestWithEndpoint {
62 fn into_cbor_value(self) -> cbor::Value {
63 let mut request = cbor::EncodeAsMap::into_cbor_map(self.request);
64 let key = cbor::values::IntoCborValue::into_cbor_value("endpoint");
66 request.push((key, self.endpoint.into_cbor_value()));
67 cbor::Value::Map(request)
68 }
69}
70
71impl cbor::Decode for StorageSyncRequestWithEndpoint {
72 fn try_from_cbor_value(value: cbor::Value) -> Result<Self, cbor::DecodeError> {
73 match value {
74 cbor::Value::Map(mut items) => {
75 let key = cbor::values::IntoCborValue::into_cbor_value("endpoint");
77 let (index, _) = items
78 .iter()
79 .enumerate()
80 .find(|(_, v)| v.0 == key)
81 .ok_or(cbor::DecodeError::MissingField)?;
82 let endpoint = items.remove(index).1;
83
84 Ok(Self {
85 endpoint: cbor::Decode::try_from_cbor_value(endpoint)?,
86 request: cbor::Decode::try_from_cbor_value(cbor::Value::Map(items))?,
87 })
88 }
89 _ => Err(cbor::DecodeError::UnexpectedType),
90 }
91 }
92}
93
94#[derive(Debug, cbor::Encode, cbor::Decode)]
96pub enum StorageSyncResponse {
97 ProofResponse(sync::ProofResponse),
98}
99
100#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)]
102#[repr(u8)]
103pub enum HostStorageEndpoint {
104 Runtime = 0,
105 Consensus = 1,
106}
107
108#[derive(Debug, cbor::Encode, cbor::Decode)]
110pub enum Body {
111 Empty {},
113
114 Error(Error),
116
117 RuntimeInfoRequest(RuntimeInfoRequest),
119 RuntimeInfoResponse(RuntimeInfoResponse),
120 RuntimePingRequest {},
121 RuntimeShutdownRequest {},
122 RuntimeAbortRequest {},
123 RuntimeAbortResponse {},
124 RuntimeCapabilityTEERakInitRequest {
125 target_info: Vec<u8>,
126 },
127 RuntimeCapabilityTEERakInitResponse {},
128 RuntimeCapabilityTEERakReportRequest {},
129 RuntimeCapabilityTEERakReportResponse {
130 rak_pub: signature::PublicKey,
131 rek_pub: x25519::PublicKey,
132 report: Vec<u8>,
133 nonce: String,
134 },
135 RuntimeCapabilityTEERakAvrRequest {
136 avr: AVR,
137 },
138 RuntimeCapabilityTEERakAvrResponse {},
139 RuntimeCapabilityTEERakQuoteRequest {
140 quote: Quote,
141 },
142 RuntimeCapabilityTEERakQuoteResponse {
143 height: u64,
144 signature: Signature,
145 },
146 RuntimeCapabilityTEEUpdateEndorsementRequest {
147 ect: EndorsedCapabilityTEE,
148 },
149 RuntimeCapabilityTEEUpdateEndorsementResponse {},
150 RuntimeRPCCallRequest {
151 request: Vec<u8>,
152 kind: enclave_rpc::types::Kind,
153 peer_id: Vec<u8>,
154 },
155 RuntimeRPCCallResponse {
156 response: Vec<u8>,
157 },
158 RuntimeLocalRPCCallRequest {
159 request: Vec<u8>,
160 },
161 RuntimeLocalRPCCallResponse {
162 response: Vec<u8>,
163 },
164 RuntimeCheckTxBatchRequest {
165 consensus_block: LightBlock,
166 inputs: TxnBatch,
167 block: Block,
168 epoch: EpochTime,
169 max_messages: u32,
170 },
171 RuntimeCheckTxBatchResponse {
172 results: Vec<CheckTxResult>,
173 },
174 RuntimeExecuteTxBatchRequest {
175 #[cbor(optional)]
176 mode: ExecutionMode,
177 consensus_block: LightBlock,
178 round_results: roothash::RoundResults,
179 io_root: Hash,
180 #[cbor(optional)]
181 inputs: Option<TxnBatch>,
182 #[cbor(optional)]
183 in_msgs: Vec<roothash::IncomingMessage>,
184 block: Block,
185 epoch: EpochTime,
186 max_messages: u32,
187 },
188 RuntimeExecuteTxBatchResponse {
189 batch: ComputedBatch,
190
191 tx_hashes: Vec<Hash>,
192 tx_reject_hashes: Vec<Hash>,
193 tx_input_root: Hash,
194 tx_input_write_log: WriteLog,
195 },
196 RuntimeKeyManagerStatusUpdateRequest {
197 status: KeyManagerStatus,
198 },
199 RuntimeKeyManagerStatusUpdateResponse {},
200 RuntimeKeyManagerQuotePolicyUpdateRequest {
201 policy: QuotePolicy,
202 },
203 RuntimeKeyManagerQuotePolicyUpdateResponse {},
204 RuntimeQueryRequest {
205 consensus_block: LightBlock,
206 header: Header,
207 epoch: EpochTime,
208 max_messages: u32,
209 method: String,
210 #[cbor(optional)]
211 args: Vec<u8>,
212 },
213 RuntimeQueryResponse {
214 #[cbor(optional)]
215 data: Vec<u8>,
216 },
217 RuntimeConsensusSyncRequest {
218 height: u64,
219 },
220 RuntimeConsensusSyncResponse {},
221 RuntimeNotifyRequest {
222 #[cbor(optional)]
223 runtime_block: Option<roothash::AnnotatedBlock>,
224 #[cbor(optional)]
225 runtime_event: Option<RuntimeNotifyEvent>,
226 },
227 RuntimeNotifyResponse {},
228
229 HostRPCCallRequest {
231 endpoint: String,
232 request_id: u64,
233 request: Vec<u8>,
234 kind: enclave_rpc::types::Kind,
235 nodes: Vec<signature::PublicKey>,
236 },
237 HostRPCCallResponse {
238 response: Vec<u8>,
239 node: signature::PublicKey,
240 },
241 HostSubmitPeerFeedbackRequest {
242 endpoint: String,
243 request_id: u64,
244 peer_feedback: enclave_rpc::types::PeerFeedback,
245 },
246 HostSubmitPeerFeedbackResponse {},
247 HostStorageSyncRequest(StorageSyncRequestWithEndpoint),
248 HostStorageSyncResponse(StorageSyncResponse),
249 HostLocalStorageGetRequest {
250 key: Vec<u8>,
251 },
252 HostLocalStorageGetResponse {
253 value: Vec<u8>,
254 },
255 HostLocalStorageSetRequest {
256 key: Vec<u8>,
257 value: Vec<u8>,
258 },
259 HostLocalStorageSetResponse {},
260 HostFetchConsensusBlockRequest {
261 height: u64,
262 },
263 HostFetchConsensusBlockResponse {
264 block: LightBlock,
265 },
266 HostFetchConsensusEventsRequest(HostFetchConsensusEventsRequest),
267 HostFetchConsensusEventsResponse(HostFetchConsensusEventsResponse),
268 HostFetchTxBatchRequest {
269 #[cbor(optional)]
270 offset: Option<Hash>,
271 limit: u32,
272 },
273 HostFetchTxBatchResponse {
274 #[cbor(optional)]
275 batch: Option<TxnBatch>,
276 },
277 HostFetchBlockMetadataTxRequest {
278 height: u64,
279 },
280 HostFetchBlockMetadataTxResponse {
281 signed_tx: SignedTransaction,
282 proof: Proof,
283 },
284 HostFetchGenesisHeightRequest {},
285 HostFetchGenesisHeightResponse {
286 height: u64,
287 },
288 HostProveFreshnessRequest {
289 blob: Vec<u8>,
290 },
291 HostProveFreshnessResponse {
292 signed_tx: SignedTransaction,
293 proof: Proof,
294 },
295 HostIdentityRequest {},
296 HostIdentityResponse {
297 node_id: signature::PublicKey,
298 },
299 HostSubmitTxRequest {
300 runtime_id: Namespace,
301 data: Vec<u8>,
302 wait: bool,
303 prove: bool,
304 },
305 HostSubmitTxResponse {
306 output: Vec<u8>,
307 round: u64,
308 batch_order: u32,
309 proof: Option<sync::Proof>,
310 },
311 HostRegisterNotifyRequest {
312 #[cbor(optional)]
313 runtime_block: bool,
314 #[cbor(optional)]
315 runtime_event: Option<RegisterNotifyRuntimeEvent>,
316 },
317 HostRegisterNotifyResponse {},
318}
319
320impl Default for Body {
321 fn default() -> Self {
322 Self::Empty {}
323 }
324}
325
326#[derive(Clone, Debug, Default, Error, cbor::Encode, cbor::Decode)]
328#[error("module: {module} code: {code} message: {message}")]
329pub struct Error {
330 #[cbor(optional)]
331 pub module: String,
332
333 #[cbor(optional)]
334 pub code: u32,
335
336 #[cbor(optional)]
337 pub message: String,
338}
339
340impl Error {
341 pub fn new(module: &str, code: u32, msg: &str) -> Self {
343 Self {
344 module: module.to_owned(),
345 code,
346 message: msg.to_owned(),
347 }
348 }
349}
350
351impl From<anyhow::Error> for Error {
352 fn from(err: anyhow::Error) -> Self {
353 Self {
354 module: "unknown".to_string(),
355 code: 1,
356 message: err.to_string(),
357 }
358 }
359}
360
361#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
363pub struct RuntimeInfoRequest {
364 pub runtime_id: Namespace,
365 pub consensus_backend: String,
366 pub consensus_protocol_version: Version,
367 pub consensus_chain_context: String,
368
369 #[cbor(optional)]
370 pub local_config: BTreeMap<String, cbor::Value>,
371}
372
373#[derive(Clone, Debug, cbor::Encode, cbor::Decode)]
375pub struct Features {
376 #[cbor(optional)]
378 pub schedule_control: Option<FeatureScheduleControl>,
379 #[cbor(optional)]
381 pub key_manager_quote_policy_updates: bool,
382 #[cbor(optional)]
384 pub key_manager_status_updates: bool,
385 #[cbor(optional)]
387 pub endorsed_capability_tee: bool,
388}
389
390impl Default for Features {
391 fn default() -> Self {
392 Self {
393 schedule_control: None,
394 key_manager_quote_policy_updates: true,
395 key_manager_status_updates: true,
396 endorsed_capability_tee: true,
397 }
398 }
399}
400
401#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
405pub struct FeatureScheduleControl {
406 pub initial_batch_size: u32,
408}
409
410#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
412pub struct RuntimeInfoResponse {
413 pub protocol_version: Version,
415
416 pub runtime_version: Version,
418
419 pub features: Features,
421}
422
423#[derive(Clone, Debug, PartialEq, Eq, cbor::Encode, cbor::Decode)]
425#[cbor(with_default)]
426pub enum ExecutionMode {
427 Execute = 0,
430 Schedule = 1,
437}
438
439impl Default for ExecutionMode {
440 fn default() -> Self {
441 Self::Execute
442 }
443}
444
445#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
447pub struct CheckTxResult {
448 pub error: Error,
449 pub meta: Option<CheckTxMetadata>,
450}
451
452#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
454pub struct CheckTxMetadata {
455 #[cbor(optional)]
456 pub priority: u64,
457
458 #[cbor(optional)]
459 pub sender: Vec<u8>,
460 #[cbor(optional)]
461 pub sender_seq: u64,
462 #[cbor(optional)]
463 pub sender_state_seq: u64,
464}
465
466#[derive(Clone, Copy, Debug, cbor::Encode, cbor::Decode)]
468#[repr(u8)]
469pub enum EventKind {
470 Staking = 1,
471 Registry = 2,
472 RootHash = 3,
473 Governance = 4,
474}
475
476#[derive(Clone, Debug, cbor::Encode, cbor::Decode)]
478#[cbor(no_default)]
479pub struct HostFetchConsensusEventsRequest {
480 pub height: u64,
481 pub kind: EventKind,
482}
483
484#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
486pub struct HostFetchConsensusEventsResponse {
487 pub events: Vec<consensus::Event>,
488}
489
490#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
492pub struct RegisterNotifyRuntimeEvent {
493 pub tags: Vec<Vec<u8>>,
495}
496
497#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)]
499pub struct RuntimeNotifyEvent {
500 pub block: roothash::AnnotatedBlock,
502 pub tags: Vec<Vec<u8>>,
504}
505
506#[derive(Clone, Copy, Debug, cbor::Encode, cbor::Decode)]
507#[repr(u8)]
508pub enum MessageType {
509 Invalid = 0,
511 Request = 1,
513 Response = 2,
515}
516
517impl Default for MessageType {
518 fn default() -> Self {
519 Self::Invalid
520 }
521}
522
523#[derive(Debug, Default, cbor::Encode, cbor::Decode)]
525pub struct Message {
526 pub id: u64,
528 pub message_type: MessageType,
530 pub body: Body,
532}