rialo_oracle_processor_interface/
state.rs1use rialo_cli_representable::Representable;
5use rialo_cli_representation::HumanReadable;
6use rialo_types::{AuthorityKeyBytes, OracleData, OracleId, OracleOutput};
7use serde::{Deserialize, Serialize};
8use serde_big_array::BigArray;
9
10use crate::errors::OracleProcessorError;
11
12#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Representable)]
14#[representable(human_readable = "oracle_update_human_readable")]
15pub struct OracleUpdate {
16 pub(crate) data: Vec<u8>,
18 #[serde(with = "BigArray")]
20 pub(crate) validator: AuthorityKeyBytes,
21}
22
23fn oracle_update_human_readable(update: &OracleUpdate) -> String {
24 let mut out = String::new();
25 let auth_key_hex = hex::encode(update.validator);
27 out.push_str(&format!("Validator (authority key): {}; ", auth_key_hex));
28 out.push_str("Data: ");
29 match update.try_data_as_output() {
31 Ok(oracle_output) => {
32 out.push_str(&format!("{oracle_output:?}"));
33 }
34 Err(_) => {
35 out.push_str("<Unable to decode>: \n");
36 }
37 }
38 out
39}
40
41impl OracleUpdate {
42 pub fn new(data: Vec<u8>, validator: AuthorityKeyBytes) -> Self {
43 Self { data, validator }
44 }
45
46 pub fn data(&self) -> &[u8] {
52 &self.data
53 }
54
55 pub fn validator(&self) -> AuthorityKeyBytes {
57 self.validator
58 }
59
60 pub fn try_data_as_output(&self) -> Result<OracleOutput, OracleProcessorError> {
66 borsh::from_slice(&self.data).map_err(|_| OracleProcessorError::ReportData)
67 }
68
69 pub fn success_payload(&self) -> Option<OracleData> {
76 match self.try_data_as_output() {
77 Ok(OracleOutput::Success(response)) => Some(response.response),
78 _ => None,
79 }
80 }
81
82 pub fn get_oracle_response_timestamp(&self) -> Option<String> {
83 if let Ok(OracleOutput::Success(response)) = self.try_data_as_output() {
84 Some(response.timestamp)
85 } else {
86 None
87 }
88 }
89}
90
91#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Representable)]
93#[representable(human_readable = "oracle_report_human_readable")]
94pub struct OracleReport {
95 pub oracle_id: OracleId, pub round: u64, pub updates: Vec<OracleUpdate>, }
99
100fn oracle_report_human_readable(report: &OracleReport) -> String {
101 let mut out = String::new();
102
103 out.push_str("Oracle Report\n");
104 out.push_str("=============\n\n");
105 out.push_str(&format!("Oracle ID: {}\n", report.oracle_id));
106 out.push_str(&format!("Round: {}\n", report.round));
107 out.push_str(&format!("Number of Updates: {}\n", report.updates.len()));
108
109 if !report.updates.is_empty() {
110 out.push_str("\nUpdates:\n");
111 for (i, update) in report.updates.iter().enumerate() {
112 out.push_str(&format!(" Update {}:\n", i + 1));
113 let auth_key_hex = hex::encode(update.validator());
114 out.push_str(&format!(" Validator: {}\n", auth_key_hex));
115 out.push_str(&format!(" Data Size: {} bytes\n", update.data().len()));
116
117 if let Ok(output) = update.try_data_as_output() {
119 match output {
120 OracleOutput::Success(response) => {
121 out.push_str(&format!(" Success: {:?}\n", response.human_readable()));
122 }
123 OracleOutput::OracleError(err) => {
124 out.push_str(&format!(" OracleError: {err:?}\n"));
125 }
126 OracleOutput::UnserializableResponse(err) => {
127 out.push_str(&format!(" UnserializableResponse: {err:?}\n"));
128 }
129 _ => {
130 out.push_str(&format!(" Unknown Output Type: {:?}\n", output));
131 }
132 }
133 } else {
134 out.push_str(&format!(" Output: {}\n", update.human_readable()));
135 }
136 }
137 }
138
139 out
140}
141
142impl OracleReport {
143 pub fn into_updates(self) -> Vec<OracleUpdate> {
151 self.updates
152 }
153
154 pub fn outputs(&self) -> impl Iterator<Item = OracleOutput> + '_ {
160 self.updates
161 .iter()
162 .filter_map(|update| update.try_data_as_output().ok())
163 }
164}
165
166pub fn extract_round_raw(bincode_data: &[u8]) -> Result<u64, OracleProcessorError> {
180 let report: OracleReport =
183 bincode::deserialize(bincode_data).map_err(|_| OracleProcessorError::ReportData)?;
184
185 Ok(report.round)
186}