redgold_schema/
response.rs

1use 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    // TODO: Trait duplicate
80    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}