rialo_oracle_processor_interface/
state.rs1use rialo_cli_representable::Representable;
5use rialo_cli_representation::HumanReadable;
6use rialo_s_pubkey::Pubkey;
7use rialo_types::{OracleData, OracleId, OracleOutput};
8use serde::{Deserialize, Serialize};
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 pub(crate) validator: Pubkey,
20}
21fn oracle_update_human_readable(update: &OracleUpdate) -> String {
22 let mut out = String::new();
23 out.push_str(&format!("Validator: {:?}; ", update.validator));
24 out.push_str("Data: ");
25 match update.try_data_as_output() {
27 Ok(oracle_output) => {
28 out.push_str(&format!("{oracle_output:?}"));
29 }
30 Err(_) => {
31 out.push_str("<Unable to decode>: \n");
32 }
33 }
34 out
35}
36
37impl OracleUpdate {
38 pub fn new(data: Vec<u8>, validator: Pubkey) -> Self {
39 Self { data, validator }
40 }
41
42 pub fn data(&self) -> &[u8] {
48 &self.data
49 }
50
51 pub fn validator(&self) -> Pubkey {
53 self.validator
54 }
55
56 pub fn try_data_as_output(&self) -> Result<OracleOutput, OracleProcessorError> {
62 borsh::from_slice(&self.data).map_err(|_| OracleProcessorError::ReportData)
63 }
64
65 pub fn success_payload(&self) -> Option<OracleData> {
72 match self.try_data_as_output() {
73 Ok(OracleOutput::Success(response)) => Some(response.response),
74 _ => None,
75 }
76 }
77
78 pub fn get_oracle_response_timestamp(&self) -> Option<String> {
79 if let Ok(OracleOutput::Success(response)) = self.try_data_as_output() {
80 Some(response.timestamp)
81 } else {
82 None
83 }
84 }
85}
86
87#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Representable)]
89#[representable(human_readable = "oracle_report_human_readable")]
90pub struct OracleReport {
91 pub oracle_id: OracleId, pub round: u64, pub updates: Vec<OracleUpdate>, }
95
96fn oracle_report_human_readable(report: &OracleReport) -> String {
97 let mut out = String::new();
98
99 out.push_str("Oracle Report\n");
100 out.push_str("=============\n\n");
101 out.push_str(&format!("Oracle ID: {}\n", report.oracle_id));
102 out.push_str(&format!("Round: {}\n", report.round));
103 out.push_str(&format!("Number of Updates: {}\n", report.updates.len()));
104
105 if !report.updates.is_empty() {
106 out.push_str("\nUpdates:\n");
107 for (i, update) in report.updates.iter().enumerate() {
108 out.push_str(&format!(" Update {}:\n", i + 1));
109 out.push_str(&format!(" Validator: {}\n", update.validator()));
110 out.push_str(&format!(" Data Size: {} bytes\n", update.data().len()));
111
112 if let Ok(output) = update.try_data_as_output() {
114 match output {
115 OracleOutput::Success(response) => {
116 out.push_str(&format!(" Success: {:?}\n", response.human_readable()));
117 }
118 OracleOutput::OracleError(err) => {
119 out.push_str(&format!(" OracleError: {err:?}\n"));
120 }
121 OracleOutput::UnserializableResponse(err) => {
122 out.push_str(&format!(" UnserializableResponse: {err:?}\n"));
123 }
124 _ => {
125 out.push_str(&format!(" Unknown Output Type: {:?}\n", output));
126 }
127 }
128 } else {
129 out.push_str(&format!(" Output: {}\n", update.human_readable()));
130 }
131 }
132 }
133
134 out
135}
136
137impl OracleReport {
138 pub fn into_updates(self) -> Vec<OracleUpdate> {
146 self.updates
147 }
148
149 pub fn outputs_with_validators(&self) -> impl Iterator<Item = (Pubkey, OracleOutput)> + '_ {
151 self.updates
152 .iter()
153 .filter_map(|update| match update.try_data_as_output() {
154 Ok(output) => Some((update.validator, output)),
155 Err(_) => None,
156 })
157 }
158
159 pub fn outputs(&self) -> impl Iterator<Item = OracleOutput> + '_ {
165 self.updates
166 .iter()
167 .filter_map(|update| update.try_data_as_output().ok())
168 }
169
170 pub fn validators(&self) -> impl Iterator<Item = Pubkey> + '_ {
176 self.updates.iter().map(|update| update.validator)
177 }
178}
179
180pub fn extract_round_raw(bincode_data: &[u8]) -> Result<u64, OracleProcessorError> {
194 let report: OracleReport =
197 bincode::deserialize(bincode_data).map_err(|_| OracleProcessorError::ReportData)?;
198
199 Ok(report.round)
200}