redgold_schema/
response.rs1use crate::helpers::easy_json::EasyJson;
2use crate::structs::{AboutNodeResponse, ControlResponse, ErrorInfo, NodeMetadata, PublicKey, QueryTransactionResponse, State, SubmitTransactionResponse};
3use crate::{error_info, response_metadata, HashClear, Response, ResponseMetadata, SafeOption};
4use itertools::Itertools;
5use prost::{DecodeError, Message};
6use std::collections::{HashMap, HashSet};
7
8impl AboutNodeResponse {
9 pub fn empty() -> Self {
10 AboutNodeResponse::default()
11 }
12}
13
14impl HashClear for Response {
15 fn hash_clear(&mut self) {
16 self.proof = None;
17 }
18}
19
20impl Response {
21 pub fn serialize(&self) -> Vec<u8> {
22 return self.encode_to_vec();
23 }
24
25 pub fn deserialize(bytes: Vec<u8>) -> Result<Self, DecodeError> {
26 return Response::decode(&*bytes);
27 }
28
29 pub fn empty_success() -> Response {
30 let mut response = Response::default();
31 response.response_metadata = response_metadata();
32 response
33 }
34
35 pub fn from_error_info(error_info: ErrorInfo) -> Response {
36 let mut r = Response::empty_success();
37 let mut rm = response_metadata().expect("m");
38 rm.success = false;
39 rm.error_info = Some(error_info);
40 r.response_metadata = Some(rm);
41 return r.clone();
42 }
43
44 pub fn with_metadata(mut self, node_metadata: NodeMetadata) -> Response {
45 self.node_metadata = Some(node_metadata);
46 self
47 }
48
49
50 pub fn as_error_info(&self) -> Result<(), ErrorInfo> {
51 let res = self.response_metadata.safe_get()?;
52 if let Some(e) = &res.error_info {
53 return Err(e.clone());
54 }
55 Ok(())
56 }
57
58 pub fn with_error_info(self) -> Result<Self, ErrorInfo> {
59 let res = self.response_metadata.safe_get()?;
60 if let Some(e) = &res.error_info {
61 return Err(e.clone());
62 }
63 Ok(self)
64 }
65
66
67}
68
69
70impl ControlResponse {
71 pub fn empty() -> Self {
72 Self {
73 response_metadata: response_metadata(),
74 control_multiparty_keygen_response: None,
75 control_multiparty_signing_response: None,
76 }
77 }
78
79 pub fn as_error_info(&self) -> Result<(), ErrorInfo> {
81 let res = self.response_metadata.safe_get()?;
82 if let Some(e) = &res.error_info {
83 return Err(e.clone());
84 }
85 Ok(())
86 }
87}
88
89
90impl QueryTransactionResponse {
91
92}
93
94impl SubmitTransactionResponse {
95 pub fn accepted(&self, expected_count: usize) -> Result<(), ErrorInfo> {
96 self.check_by_state(expected_count, State::Accepted)
97 }
98 pub fn pending(&self, expected_count: usize) -> Result<(), ErrorInfo> {
99 self.check_by_state(expected_count, State::Pending)
100 }
101 pub fn check_by_state(&self, expected_count: usize, state: State) -> Result<(), ErrorInfo> {
102 let accepted_count = self.unique_by_state()?.iter().filter(|(_, s)| *s == state as i32).count();
103 if accepted_count >= expected_count {
104 Ok(())
105 } else {
106 Err(error_info(format!("not enough {} observations, expected {}, got {}",
107 state.json_or(), expected_count, accepted_count)))
108 }
109 }
110 pub fn unique_by_state(&self) -> Result<HashSet<(&PublicKey, i32)>, ErrorInfo> {
111 let mut results = HashSet::new();
112 for p in &self.query_transaction_response
113 .safe_get()?
114 .observation_proofs {
115 let state = p.metadata.safe_get()?.state;
116 let pk = p.proof.safe_get()?.public_key.safe_get()?;
117 results.insert((pk, state));
118 }
119 Ok(results)
120 }
121
122 pub fn count_unique_by_state(&self) -> Result<HashMap<i32, usize>, ErrorInfo> {
123 let map: HashMap<i32, usize> = self.unique_by_state()?.iter().map(|(_, y)| y.clone()).counts();
124 Ok(map)
125 }
126
127
128 pub fn at_least_1(&self) -> Result<(), ErrorInfo> {
129 self.at_least_n(1)
130 }
131
132 pub fn at_least_n(&self, n: usize) -> Result<(), ErrorInfo> {
133 self.accepted(n)?;
134 self.pending(n)
135 }
136}
137
138impl ResponseMetadata {
139 pub fn from_error(error: ErrorInfo) -> Self {
140 let mut rm = response_metadata().expect("m");
141 rm.success = false;
142 rm.error_info = Some(error);
143 rm
144 }
145}