1use hedera_proto::services;
4use tonic::transport::Channel;
5
6use super::ToQueryProtobuf;
7use crate::account::{
8 AccountBalanceQueryData,
9 AccountInfoQueryData,
10 AccountRecordsQueryData,
11};
12use crate::contract::{
13 ContractBytecodeQueryData,
14 ContractCallQueryData,
15 ContractInfoQueryData,
16};
17use crate::entity_id::ValidateChecksums;
18use crate::file::{
19 FileContentsQueryData,
20 FileInfoQueryData,
21};
22use crate::ledger_id::RefLedgerId;
23use crate::query::QueryExecute;
24use crate::schedule::ScheduleInfoQueryData;
25use crate::token::{
26 TokenInfoQueryData,
27 TokenNftInfoQueryData,
28};
29use crate::topic::TopicInfoQueryData;
30use crate::transaction_receipt_query::TransactionReceiptQueryData;
31use crate::{
32 AccountBalance,
33 AccountInfo,
34 AllProxyStakers,
35 BoxGrpcFuture,
36 ContractFunctionResult,
37 ContractInfo,
38 Error,
39 FileContentsResponse,
40 FileInfo,
41 FromProtobuf,
42 Hbar,
43 NetworkVersionInfo,
44 NetworkVersionInfoQueryData,
45 Query,
46 ScheduleInfo,
47 TokenInfo,
48 TokenNftInfo,
49 TopicInfo,
50 TransactionReceipt,
51 TransactionRecord,
52 TransactionRecordQueryData,
53};
54
55pub type AnyQuery = Query<AnyQueryData>;
57
58#[derive(Debug, Clone)]
59pub enum AnyQueryData {
60 AccountBalance(AccountBalanceQueryData),
61 AccountInfo(AccountInfoQueryData),
62 AccountRecords(AccountRecordsQueryData),
63 TransactionReceipt(TransactionReceiptQueryData),
64 TransactionRecord(TransactionRecordQueryData),
65 FileContents(FileContentsQueryData),
66 FileInfo(FileInfoQueryData),
67 ContractBytecode(ContractBytecodeQueryData),
68 ContractCall(ContractCallQueryData),
69 TokenInfo(TokenInfoQueryData),
70 ContractInfo(ContractInfoQueryData),
71 TokenNftInfo(TokenNftInfoQueryData),
72 TopicInfo(TopicInfoQueryData),
73 ScheduleInfo(ScheduleInfoQueryData),
74 NetworkVersionInfo(NetworkVersionInfoQueryData),
75}
76
77#[derive(Debug, Clone)]
80pub enum AnyQueryResponse {
81 AccountBalance(AccountBalance),
83
84 AccountInfo(AccountInfo),
86
87 AccountStakers(AllProxyStakers),
89
90 AccountRecords(Vec<TransactionRecord>),
92
93 TransactionReceipt(TransactionReceipt),
95
96 TransactionRecord(Box<TransactionRecord>),
98
99 FileContents(FileContentsResponse),
101
102 FileInfo(FileInfo),
104
105 ContractBytecode(Vec<u8>),
107
108 ContractCall(ContractFunctionResult),
110
111 TokenInfo(Box<TokenInfo>),
113
114 TopicInfo(TopicInfo),
116
117 ContractInfo(ContractInfo),
119
120 TokenNftInfo(TokenNftInfo),
122
123 ScheduleInfo(ScheduleInfo),
125
126 NetworkVersionInfo(NetworkVersionInfo),
128}
129
130impl ToQueryProtobuf for AnyQueryData {
131 fn to_query_protobuf(&self, header: services::QueryHeader) -> services::Query {
132 match self {
133 Self::AccountBalance(data) => data.to_query_protobuf(header),
134 Self::AccountInfo(data) => data.to_query_protobuf(header),
135 Self::AccountRecords(data) => data.to_query_protobuf(header),
136 Self::TransactionReceipt(data) => data.to_query_protobuf(header),
137 Self::TransactionRecord(data) => data.to_query_protobuf(header),
138 Self::FileContents(data) => data.to_query_protobuf(header),
139 Self::FileInfo(data) => data.to_query_protobuf(header),
140 Self::ContractBytecode(data) => data.to_query_protobuf(header),
141 Self::ContractCall(data) => data.to_query_protobuf(header),
142 Self::ContractInfo(data) => data.to_query_protobuf(header),
143 Self::TokenNftInfo(data) => data.to_query_protobuf(header),
144 Self::TokenInfo(data) => data.to_query_protobuf(header),
145 Self::TopicInfo(data) => data.to_query_protobuf(header),
146 Self::ScheduleInfo(data) => data.to_query_protobuf(header),
147 Self::NetworkVersionInfo(data) => data.to_query_protobuf(header),
148 }
149 }
150}
151
152impl QueryExecute for AnyQueryData {
153 type Response = AnyQueryResponse;
154
155 fn is_payment_required(&self) -> bool {
156 match self {
157 Self::AccountInfo(query) => query.is_payment_required(),
158 Self::AccountBalance(query) => query.is_payment_required(),
159 Self::AccountRecords(query) => query.is_payment_required(),
160 Self::TransactionReceipt(query) => query.is_payment_required(),
161 Self::TransactionRecord(query) => query.is_payment_required(),
162 Self::FileContents(query) => query.is_payment_required(),
163 Self::FileInfo(query) => query.is_payment_required(),
164 Self::ContractBytecode(query) => query.is_payment_required(),
165 Self::ContractCall(query) => query.is_payment_required(),
166 Self::ContractInfo(query) => query.is_payment_required(),
167 Self::TokenNftInfo(query) => query.is_payment_required(),
168 Self::TokenInfo(query) => query.is_payment_required(),
169 Self::TopicInfo(query) => query.is_payment_required(),
170 Self::ScheduleInfo(query) => query.is_payment_required(),
171 Self::NetworkVersionInfo(query) => query.is_payment_required(),
172 }
173 }
174
175 fn map_cost(&self, cost: Hbar) -> Hbar {
176 match self {
177 Self::AccountInfo(query) => query.map_cost(cost),
178 Self::AccountBalance(query) => query.map_cost(cost),
179 Self::AccountRecords(query) => query.map_cost(cost),
180 Self::TransactionReceipt(query) => query.map_cost(cost),
181 Self::TransactionRecord(query) => query.map_cost(cost),
182 Self::FileContents(query) => query.map_cost(cost),
183 Self::FileInfo(query) => query.map_cost(cost),
184 Self::ContractBytecode(query) => query.map_cost(cost),
185 Self::ContractCall(query) => query.map_cost(cost),
186 Self::ContractInfo(query) => query.map_cost(cost),
187 Self::TokenNftInfo(query) => query.map_cost(cost),
188 Self::TokenInfo(query) => query.map_cost(cost),
189 Self::TopicInfo(query) => query.map_cost(cost),
190 Self::ScheduleInfo(query) => query.map_cost(cost),
191 Self::NetworkVersionInfo(query) => query.map_cost(cost),
192 }
193 }
194
195 fn execute(
196 &self,
197 channel: Channel,
198 request: services::Query,
199 ) -> BoxGrpcFuture<'_, services::Response> {
200 match self {
201 Self::AccountInfo(query) => query.execute(channel, request),
202 Self::AccountBalance(query) => query.execute(channel, request),
203 Self::AccountRecords(query) => query.execute(channel, request),
204 Self::TransactionReceipt(query) => query.execute(channel, request),
205 Self::TransactionRecord(query) => query.execute(channel, request),
206 Self::FileContents(query) => query.execute(channel, request),
207 Self::FileInfo(query) => query.execute(channel, request),
208 Self::ContractBytecode(query) => query.execute(channel, request),
209 Self::ContractCall(query) => query.execute(channel, request),
210 Self::ContractInfo(query) => query.execute(channel, request),
211 Self::TokenNftInfo(query) => query.execute(channel, request),
212 Self::TokenInfo(query) => query.execute(channel, request),
213 Self::TopicInfo(query) => query.execute(channel, request),
214 Self::ScheduleInfo(query) => query.execute(channel, request),
215 Self::NetworkVersionInfo(query) => query.execute(channel, request),
216 }
217 }
218
219 fn should_retry_pre_check(&self, status: crate::Status) -> bool {
220 match self {
221 Self::AccountInfo(query) => query.should_retry_pre_check(status),
222 Self::AccountBalance(query) => query.should_retry_pre_check(status),
223 Self::AccountRecords(query) => query.should_retry_pre_check(status),
224 Self::TransactionReceipt(query) => query.should_retry_pre_check(status),
225 Self::TransactionRecord(query) => query.should_retry_pre_check(status),
226 Self::FileContents(query) => query.should_retry_pre_check(status),
227 Self::FileInfo(query) => query.should_retry_pre_check(status),
228 Self::ContractBytecode(query) => query.should_retry_pre_check(status),
229 Self::ContractCall(query) => query.should_retry_pre_check(status),
230 Self::ContractInfo(query) => query.should_retry_pre_check(status),
231 Self::TokenNftInfo(query) => query.should_retry_pre_check(status),
232 Self::TokenInfo(query) => query.should_retry_pre_check(status),
233 Self::TopicInfo(query) => query.should_retry_pre_check(status),
234 Self::ScheduleInfo(query) => query.should_retry_pre_check(status),
235 Self::NetworkVersionInfo(query) => query.should_retry_pre_check(status),
236 }
237 }
238
239 fn should_retry(&self, response: &services::Response) -> bool {
240 match self {
241 Self::AccountInfo(query) => query.should_retry(response),
242 Self::AccountBalance(query) => query.should_retry(response),
243 Self::AccountRecords(query) => query.should_retry(response),
244 Self::TransactionReceipt(query) => query.should_retry(response),
245 Self::TransactionRecord(query) => query.should_retry(response),
246 Self::FileContents(query) => query.should_retry(response),
247 Self::FileInfo(query) => query.should_retry(response),
248 Self::ContractBytecode(query) => query.should_retry(response),
249 Self::ContractCall(query) => query.should_retry(response),
250 Self::ContractInfo(query) => query.should_retry(response),
251 Self::TokenNftInfo(query) => query.should_retry(response),
252 Self::TokenInfo(query) => query.should_retry(response),
253 Self::TopicInfo(query) => query.should_retry(response),
254 Self::ScheduleInfo(query) => query.should_retry(response),
255 Self::NetworkVersionInfo(query) => query.should_retry(response),
256 }
257 }
258
259 fn transaction_id(&self) -> Option<crate::TransactionId> {
260 match self {
261 Self::AccountBalance(query) => query.transaction_id(),
262 Self::AccountInfo(query) => query.transaction_id(),
263 Self::AccountRecords(query) => query.transaction_id(),
264 Self::TransactionReceipt(query) => query.transaction_id(),
265 Self::TransactionRecord(query) => query.transaction_id(),
266 Self::FileContents(query) => query.transaction_id(),
267 Self::FileInfo(query) => query.transaction_id(),
268 Self::ContractBytecode(query) => query.transaction_id(),
269 Self::ContractCall(query) => query.transaction_id(),
270 Self::TokenInfo(query) => query.transaction_id(),
271 Self::ContractInfo(query) => query.transaction_id(),
272 Self::TokenNftInfo(query) => query.transaction_id(),
273 Self::TopicInfo(query) => query.transaction_id(),
274 Self::ScheduleInfo(query) => query.transaction_id(),
275 Self::NetworkVersionInfo(query) => query.transaction_id(),
276 }
277 }
278
279 fn make_response(
280 &self,
281 response: services::response::Response,
282 ) -> crate::Result<Self::Response> {
283 match self {
284 Self::AccountBalance(query) => {
285 query.make_response(response).map(AnyQueryResponse::AccountBalance)
286 }
287 Self::AccountInfo(query) => {
288 query.make_response(response).map(AnyQueryResponse::AccountInfo)
289 }
290 Self::AccountRecords(query) => {
291 query.make_response(response).map(AnyQueryResponse::AccountRecords)
292 }
293 Self::TransactionReceipt(query) => {
294 query.make_response(response).map(AnyQueryResponse::TransactionReceipt)
295 }
296 Self::TransactionRecord(query) => {
297 query.make_response(response).map(Box::new).map(AnyQueryResponse::TransactionRecord)
298 }
299 Self::FileContents(query) => {
300 query.make_response(response).map(AnyQueryResponse::FileContents)
301 }
302 Self::FileInfo(query) => query.make_response(response).map(AnyQueryResponse::FileInfo),
303 Self::ContractBytecode(query) => {
304 query.make_response(response).map(AnyQueryResponse::ContractBytecode)
305 }
306 Self::ContractCall(query) => {
307 query.make_response(response).map(AnyQueryResponse::ContractCall)
308 }
309 Self::TokenInfo(query) => {
310 query.make_response(response).map(Box::new).map(AnyQueryResponse::TokenInfo)
311 }
312 Self::ContractInfo(query) => {
313 query.make_response(response).map(AnyQueryResponse::ContractInfo)
314 }
315 Self::TokenNftInfo(query) => {
316 query.make_response(response).map(AnyQueryResponse::TokenNftInfo)
317 }
318 Self::TopicInfo(query) => {
319 query.make_response(response).map(AnyQueryResponse::TopicInfo)
320 }
321 Self::ScheduleInfo(query) => {
322 query.make_response(response).map(AnyQueryResponse::ScheduleInfo)
323 }
324 Self::NetworkVersionInfo(query) => {
325 query.make_response(response).map(AnyQueryResponse::NetworkVersionInfo)
326 }
327 }
328 }
329}
330
331impl ValidateChecksums for AnyQueryData {
332 fn validate_checksums(&self, ledger_id: &RefLedgerId) -> Result<(), Error> {
333 match self {
334 Self::AccountBalance(query) => query.validate_checksums(ledger_id),
335 Self::AccountInfo(query) => query.validate_checksums(ledger_id),
336 Self::AccountRecords(query) => query.validate_checksums(ledger_id),
337 Self::TransactionReceipt(query) => query.validate_checksums(ledger_id),
338 Self::TransactionRecord(query) => query.validate_checksums(ledger_id),
339 Self::FileContents(query) => query.validate_checksums(ledger_id),
340 Self::FileInfo(query) => query.validate_checksums(ledger_id),
341 Self::ContractBytecode(query) => query.validate_checksums(ledger_id),
342 Self::ContractCall(query) => query.validate_checksums(ledger_id),
343 Self::TokenInfo(query) => query.validate_checksums(ledger_id),
344 Self::ContractInfo(query) => query.validate_checksums(ledger_id),
345 Self::TokenNftInfo(query) => query.validate_checksums(ledger_id),
346 Self::TopicInfo(query) => query.validate_checksums(ledger_id),
347 Self::ScheduleInfo(query) => query.validate_checksums(ledger_id),
348 Self::NetworkVersionInfo(query) => query.validate_checksums(ledger_id),
349 }
350 }
351}
352
353impl FromProtobuf<services::response::Response> for AnyQueryResponse {
354 fn from_protobuf(response: services::response::Response) -> crate::Result<Self>
355 where
356 Self: Sized,
357 {
358 use services::response::Response::*;
359
360 Ok(match response {
361 TransactionGetReceipt(_) => {
362 Self::TransactionReceipt(TransactionReceipt::from_protobuf(response)?)
363 }
364 CryptoGetInfo(_) => Self::AccountInfo(AccountInfo::from_protobuf(response)?),
365 CryptogetAccountBalance(_) => {
366 Self::AccountBalance(AccountBalance::from_protobuf(response)?)
367 }
368 FileGetContents(_) => {
369 Self::FileContents(FileContentsResponse::from_protobuf(response)?)
370 }
371 ContractGetBytecodeResponse(_) => {
372 Self::ContractBytecode(Vec::<u8>::from_protobuf(response)?)
373 }
374 ContractCallLocal(_) => {
375 Self::ContractCall(ContractFunctionResult::from_protobuf(response)?)
376 }
377 ContractGetInfo(_) => Self::ContractInfo(ContractInfo::from_protobuf(response)?),
378 ConsensusGetTopicInfo(_) => Self::TopicInfo(TopicInfo::from_protobuf(response)?),
379 ScheduleGetInfo(_) => Self::ScheduleInfo(ScheduleInfo::from_protobuf(response)?),
380 CryptoGetProxyStakers(_) => {
381 Self::AccountStakers(AllProxyStakers::from_protobuf(response)?)
382 }
383 CryptoGetAccountRecords(_) => {
384 Self::AccountRecords(Vec::<TransactionRecord>::from_protobuf(response)?)
385 }
386 TransactionGetRecord(_) => {
387 Self::TransactionRecord(Box::new(TransactionRecord::from_protobuf(response)?))
388 }
389 NetworkGetVersionInfo(_) => {
390 Self::NetworkVersionInfo(NetworkVersionInfo::from_protobuf(response)?)
391 }
392 FileGetInfo(_) => Self::FileInfo(FileInfo::from_protobuf(response)?),
393 TokenGetInfo(_) => Self::TokenInfo(Box::new(TokenInfo::from_protobuf(response)?)),
394 TokenGetNftInfo(_) | TokenGetNftInfos(_) => {
395 Self::TokenNftInfo(TokenNftInfo::from_protobuf(response)?)
396 }
397 TransactionGetFastRecord(_)
399 | CryptoGetLiveHash(_)
400 | GetBySolidityId(_)
401 | TokenGetAccountNftInfos(_)
402 | NetworkGetExecutionTime(_)
403 | ContractGetRecordsResponse(_)
404 | AccountDetails(_)
405 | GetByKey(_) => unreachable!(),
406 })
407 }
408}