rialo_rex_processor_interface/
state.rs1use rialo_cli_representable::Representable;
5use rialo_cli_representation::HumanReadable;
6use rialo_types::{AuthorityKeyBytes, RexData, RexId, RexOutput};
7use serde::{Deserialize, Serialize};
8use serde_big_array::BigArray;
9
10use crate::errors::RexProcessorError;
11
12#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Representable)]
14#[representable(human_readable = "rex_update_human_readable")]
15pub struct RexUpdate {
16 pub(crate) data: Vec<u8>,
18 #[serde(with = "BigArray")]
20 pub(crate) validator: AuthorityKeyBytes,
21}
22
23fn rex_update_human_readable(update: &RexUpdate) -> 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(rex_output) => {
32 out.push_str(&format!("{rex_output:?}"));
33 }
34 Err(_) => {
35 out.push_str("<Unable to decode>: \n");
36 }
37 }
38 out
39}
40
41impl RexUpdate {
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<RexOutput, RexProcessorError> {
66 borsh::from_slice(&self.data).map_err(|_| RexProcessorError::ReportData)
67 }
68
69 pub fn success_payload(&self) -> Option<RexData> {
76 match self.try_data_as_output() {
77 Ok(RexOutput::Success(response)) => Some(response.response),
78 _ => None,
79 }
80 }
81
82 pub fn get_rex_response_timestamp(&self) -> Option<String> {
83 if let Ok(RexOutput::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 = "rex_report_human_readable")]
94pub struct RexReport {
95 pub rex_id: RexId, pub round: u64, pub updates: Vec<RexUpdate>, }
99
100fn rex_report_human_readable(report: &RexReport) -> String {
101 let mut out = String::new();
102
103 out.push_str("REX Report\n");
104 out.push_str("=============\n\n");
105 out.push_str(&format!("REX ID: {}\n", report.rex_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 RexOutput::Success(response) => {
121 out.push_str(&format!(" Success: {:?}\n", response.human_readable()));
122 }
123 RexOutput::RexError(err) => {
124 out.push_str(&format!(" RexError: {err:?}\n"));
125 }
126 RexOutput::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 RexReport {
143 pub fn into_updates(self) -> Vec<RexUpdate> {
151 self.updates
152 }
153
154 pub fn outputs(&self) -> impl Iterator<Item = RexOutput> + '_ {
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, RexProcessorError> {
180 let report: RexReport =
183 bincode::deserialize(bincode_data).map_err(|_| RexProcessorError::ReportData)?;
184
185 Ok(report.round)
186}