1use std::{marker::PhantomData, sync::Arc};
3
4use futures::future::join_all;
5use near_jsonrpc_client::methods::{
6 block::{RpcBlockError, RpcBlockRequest},
7 query::{RpcQueryError, RpcQueryRequest, RpcQueryResponse},
8 validators::{RpcValidatorError, RpcValidatorRequest},
9 RpcMethod,
10};
11use near_primitives::{
12 types::{BlockReference, EpochReference},
13 views::{
14 AccessKeyList, AccessKeyView, AccountView, BlockView, ContractCodeView, EpochValidatorInfo,
15 QueryRequest, ViewStateResult,
16 },
17};
18use serde::de::DeserializeOwned;
19use tracing::{debug, error, info, instrument, trace, warn};
20
21use crate::{
22 config::{retry, NetworkConfig, RetryResponse},
23 errors::QueryError,
24 types::Data,
25};
26
27use super::utils::{
28 is_critical_blocks_error, is_critical_query_error, is_critical_validator_error,
29};
30
31const QUERY_EXECUTOR_TARGET: &str = "near_api::query::executor";
32
33type ResultWithMethod<T, Method> = core::result::Result<T, QueryError<Method>>;
34
35pub trait ResponseHandler
36where
37 <Self::Method as RpcMethod>::Error: std::fmt::Display + std::fmt::Debug,
38{
39 type QueryResponse;
40 type Response;
41 type Method: RpcMethod;
42
43 fn process_response(
47 &self,
48 responses: Vec<Self::QueryResponse>,
49 ) -> ResultWithMethod<Self::Response, Self::Method>;
50 fn request_amount(&self) -> usize {
51 1
52 }
53}
54
55pub trait QueryCreator<Method: RpcMethod>
56where
57 Method::Error: std::fmt::Display + std::fmt::Debug + Sync + Send,
58{
59 type RpcReference;
60 fn create_query(
61 &self,
62 network: &NetworkConfig,
63 reference: Self::RpcReference,
64 ) -> ResultWithMethod<Method, Method>;
65
66 fn is_critical_error(
67 &self,
68 error: &near_jsonrpc_client::errors::JsonRpcError<Method::Error>,
69 ) -> bool;
70}
71
72#[derive(Clone, Debug)]
73pub struct SimpleQuery {
74 pub request: QueryRequest,
75}
76
77impl QueryCreator<RpcQueryRequest> for SimpleQuery {
78 type RpcReference = BlockReference;
79 fn create_query(
80 &self,
81 _network: &NetworkConfig,
82 reference: BlockReference,
83 ) -> ResultWithMethod<RpcQueryRequest, RpcQueryRequest> {
84 Ok(RpcQueryRequest {
85 block_reference: reference,
86 request: self.request.clone(),
87 })
88 }
89
90 fn is_critical_error(
91 &self,
92 error: &near_jsonrpc_client::errors::JsonRpcError<RpcQueryError>,
93 ) -> bool {
94 is_critical_query_error(error)
95 }
96}
97
98#[derive(Clone, Debug)]
99pub struct SimpleValidatorRpc;
100
101impl QueryCreator<RpcValidatorRequest> for SimpleValidatorRpc {
102 type RpcReference = EpochReference;
103 fn create_query(
104 &self,
105 _network: &NetworkConfig,
106 reference: EpochReference,
107 ) -> ResultWithMethod<RpcValidatorRequest, RpcValidatorRequest> {
108 Ok(RpcValidatorRequest {
109 epoch_reference: reference,
110 })
111 }
112
113 fn is_critical_error(
114 &self,
115 error: &near_jsonrpc_client::errors::JsonRpcError<RpcValidatorError>,
116 ) -> bool {
117 is_critical_validator_error(error)
118 }
119}
120
121#[derive(Clone, Debug)]
122pub struct SimpleBlockRpc;
123
124impl QueryCreator<RpcBlockRequest> for SimpleBlockRpc {
125 type RpcReference = BlockReference;
126 fn create_query(
127 &self,
128 _network: &NetworkConfig,
129 reference: BlockReference,
130 ) -> ResultWithMethod<RpcBlockRequest, RpcBlockRequest> {
131 Ok(RpcBlockRequest {
132 block_reference: reference,
133 })
134 }
135
136 fn is_critical_error(
137 &self,
138 error: &near_jsonrpc_client::errors::JsonRpcError<RpcBlockError>,
139 ) -> bool {
140 is_critical_blocks_error(error)
141 }
142}
143
144pub type QueryBuilder<T> = RpcBuilder<T, RpcQueryRequest, BlockReference>;
145pub type MultiQueryBuilder<T> = MultiRpcBuilder<T, RpcQueryRequest, BlockReference>;
146
147pub type ValidatorQueryBuilder<T> = RpcBuilder<T, RpcValidatorRequest, EpochReference>;
148pub type BlockQueryBuilder<T> = RpcBuilder<T, RpcBlockRequest, BlockReference>;
149
150pub struct MultiRpcBuilder<Handler, Method, Reference>
162where
163 Reference: Send + Sync,
164 Handler: Send + Sync,
165{
166 reference: Reference,
167 requests: Vec<Arc<dyn QueryCreator<Method, RpcReference = Reference> + Send + Sync>>,
168 handler: Handler,
169}
170
171impl<Handler, Method, Reference> MultiRpcBuilder<Handler, Method, Reference>
172where
173 Reference: Send + Sync,
174 Handler: Default + Send + Sync,
175{
176 pub fn with_reference(reference: impl Into<Reference>) -> Self {
177 Self {
178 reference: reference.into(),
179 requests: vec![],
180 handler: Default::default(),
181 }
182 }
183}
184
185impl<Handler, Method, Reference> MultiRpcBuilder<Handler, Method, Reference>
186where
187 Handler: ResponseHandler<QueryResponse = Method::Response, Method = Method> + Send + Sync,
188 Method: RpcMethod + std::fmt::Debug + Send + Sync + 'static,
189 Method::Response: std::fmt::Debug + Send + Sync,
190 Method::Error: std::fmt::Display + std::fmt::Debug + Sync + Send,
191 Reference: Clone + Send + Sync,
192{
193 pub fn new(handler: Handler, reference: Reference) -> Self {
194 Self {
195 reference,
196 requests: vec![],
197 handler,
198 }
199 }
200
201 pub fn map<MappedType>(
235 self,
236 map: impl Fn(Handler::Response) -> MappedType + Send + Sync + 'static,
237 ) -> MultiRpcBuilder<PostprocessHandler<MappedType, Handler>, Method, Reference> {
238 MultiRpcBuilder {
239 handler: PostprocessHandler::new(self.handler, map),
240 requests: self.requests,
241 reference: self.reference,
242 }
243 }
244
245 pub fn add_query(
248 mut self,
249 request: Arc<dyn QueryCreator<Method, RpcReference = Reference> + Send + Sync>,
250 ) -> Self {
251 self.requests.push(request);
252 self
253 }
254
255 pub fn add_query_builder<T>(mut self, query_builder: RpcBuilder<T, Method, Reference>) -> Self {
257 self.requests.push(query_builder.request);
258 self
259 }
260
261 pub fn at(self, reference: impl Into<Reference>) -> Self {
263 Self {
264 reference: reference.into(),
265 ..self
266 }
267 }
268
269 #[instrument(skip(self, network), fields(request_count = self.requests.len()))]
271 pub async fn fetch_from(
272 self,
273 network: &NetworkConfig,
274 ) -> ResultWithMethod<Handler::Response, Method> {
275 debug!(target: QUERY_EXECUTOR_TARGET, "Preparing queries");
276 let requests: Vec<_> = self
277 .requests
278 .into_iter()
279 .map(|request| {
280 request
281 .create_query(network, self.reference.clone())
282 .map(|query| (query, request))
283 })
284 .collect::<Result<_, _>>()?;
285
286 info!(target: QUERY_EXECUTOR_TARGET, "Sending {} queries", requests.len());
287 let requests = requests.into_iter().map(|(query, request)| async move {
288 retry(network.clone(), |json_rpc_client| {
289 let query = &query;
290 let request = &request;
291
292 async move {
293 let result = match json_rpc_client.call(&query).await {
294 Ok(result) => RetryResponse::Ok(result),
295 Err(err) if request.is_critical_error(&err) => RetryResponse::Critical(err),
296 Err(err) => RetryResponse::Retry(err),
297 };
298 tracing::debug!(
299 target: QUERY_EXECUTOR_TARGET,
300 "Querying RPC with {:?} resulted in {:?}",
301 query,
302 result
303 );
304 result
305 }
306 })
307 .await
308 });
309
310 let requests: Vec<_> = join_all(requests)
311 .await
312 .into_iter()
313 .collect::<Result<_, _>>()?;
314 if requests.is_empty() {
315 error!(target: QUERY_EXECUTOR_TARGET, "No responses received");
316 return Err(QueryError::InternalErrorNoResponse);
317 }
318
319 debug!(target: QUERY_EXECUTOR_TARGET, "Processing {} responses", requests.len());
320 self.handler.process_response(requests)
321 }
322
323 pub async fn fetch_from_mainnet(self) -> ResultWithMethod<Handler::Response, Method> {
325 let network = NetworkConfig::mainnet();
326 self.fetch_from(&network).await
327 }
328
329 pub async fn fetch_from_testnet(self) -> ResultWithMethod<Handler::Response, Method> {
331 let network = NetworkConfig::testnet();
332 self.fetch_from(&network).await
333 }
334}
335
336pub struct RpcBuilder<Handler, Method, Reference> {
337 reference: Reference,
338 request: Arc<dyn QueryCreator<Method, RpcReference = Reference> + Send + Sync>,
339 handler: Handler,
340}
341
342impl<Handler, Method, Reference> RpcBuilder<Handler, Method, Reference>
343where
344 Handler: ResponseHandler<QueryResponse = Method::Response, Method = Method> + Send + Sync,
345 Method: RpcMethod + std::fmt::Debug + Send + Sync + 'static,
346 Method::Response: std::fmt::Debug + Send + Sync,
347 Method::Error: std::fmt::Display + std::fmt::Debug + Sync + Send,
348 Reference: Send + Sync,
349{
350 pub fn new(
351 request: impl QueryCreator<Method, RpcReference = Reference> + 'static + Send + Sync,
352 reference: Reference,
353 handler: Handler,
354 ) -> Self {
355 Self {
356 reference,
357 request: Arc::new(request),
358 handler,
359 }
360 }
361
362 pub fn at(self, reference: impl Into<Reference>) -> Self {
364 Self {
365 reference: reference.into(),
366 ..self
367 }
368 }
369
370 pub fn map<MappedType>(
390 self,
391 map: impl Fn(Handler::Response) -> MappedType + Send + Sync + 'static,
392 ) -> RpcBuilder<PostprocessHandler<MappedType, Handler>, Method, Reference> {
393 RpcBuilder {
394 handler: PostprocessHandler::new(self.handler, map),
395 request: self.request,
396 reference: self.reference,
397 }
398 }
399
400 #[instrument(skip(self, network))]
402 pub async fn fetch_from(
403 self,
404 network: &NetworkConfig,
405 ) -> ResultWithMethod<Handler::Response, Method> {
406 debug!(target: QUERY_EXECUTOR_TARGET, "Preparing query");
407 let query = self.request.create_query(network, self.reference)?;
408
409 let query_response = retry(network.clone(), |json_rpc_client| {
410 let query = &query;
411 let request = &self.request;
412 async move {
413 let result = match json_rpc_client.call(&query).await {
414 Ok(result) => RetryResponse::Ok(result),
415 Err(err) if request.is_critical_error(&err) => RetryResponse::Critical(err),
416 Err(err) => RetryResponse::Retry(err),
417 };
418 tracing::debug!(
419 target: QUERY_EXECUTOR_TARGET,
420 "Querying RPC with {:?} resulted in {:?}",
421 query,
422 result
423 );
424 result
425 }
426 })
427 .await?;
428
429 debug!(target: QUERY_EXECUTOR_TARGET, "Processing query response");
430 self.handler.process_response(vec![query_response])
431 }
432
433 pub async fn fetch_from_mainnet(self) -> ResultWithMethod<Handler::Response, Method> {
435 let network = NetworkConfig::mainnet();
436 self.fetch_from(&network).await
437 }
438
439 pub async fn fetch_from_testnet(self) -> ResultWithMethod<Handler::Response, Method> {
441 let network = NetworkConfig::testnet();
442 self.fetch_from(&network).await
443 }
444}
445
446#[derive(Clone, Debug)]
447pub struct MultiQueryHandler<Handlers> {
448 handlers: Handlers,
449}
450
451impl<QR, Method, H1, H2, R1, R2> ResponseHandler for MultiQueryHandler<(H1, H2)>
452where
453 Method: RpcMethod,
454 H1: ResponseHandler<QueryResponse = QR, Response = R1, Method = Method>,
455 H2: ResponseHandler<QueryResponse = QR, Response = R2, Method = Method>,
456 Method::Error: std::fmt::Display + std::fmt::Debug,
457{
458 type Response = (R1, R2);
459 type QueryResponse = QR;
460 type Method = Method;
461
462 fn process_response(&self, mut responses: Vec<QR>) -> ResultWithMethod<Self::Response, Method> {
463 let (h1, h2) = &self.handlers;
464
465 let first_response =
466 h1.process_response(responses.drain(0..h1.request_amount()).collect())?;
467 let second_response = h2.process_response(responses)?;
468
469 Ok((first_response, second_response))
470 }
471
472 fn request_amount(&self) -> usize {
473 self.handlers.0.request_amount() + self.handlers.1.request_amount()
474 }
475}
476
477impl<QR, Method, H1, H2, H3, R1, R2, R3> ResponseHandler for MultiQueryHandler<(H1, H2, H3)>
478where
479 Method: RpcMethod,
480 Method::Error: std::fmt::Display + std::fmt::Debug,
481 H1: ResponseHandler<QueryResponse = QR, Response = R1, Method = Method>,
482 H2: ResponseHandler<QueryResponse = QR, Response = R2, Method = Method>,
483 H3: ResponseHandler<QueryResponse = QR, Response = R3, Method = Method>,
484{
485 type Response = (R1, R2, R3);
486 type QueryResponse = QR;
487 type Method = Method;
488
489 fn process_response(&self, mut responses: Vec<QR>) -> ResultWithMethod<Self::Response, Method> {
490 let (h1, h2, h3) = &self.handlers;
491
492 let first_response =
493 h1.process_response(responses.drain(0..h1.request_amount()).collect())?;
494 let second_response = h2.process_response(
495 responses
496 .drain(h1.request_amount()..h2.request_amount())
497 .collect(),
498 )?;
499 let third_response = h3.process_response(responses)?;
500
501 Ok((first_response, second_response, third_response))
502 }
503
504 fn request_amount(&self) -> usize {
505 self.handlers.0.request_amount() + self.handlers.1.request_amount()
506 }
507}
508
509impl<Handlers> MultiQueryHandler<Handlers> {
510 pub const fn new(handlers: Handlers) -> Self {
511 Self { handlers }
512 }
513}
514
515impl<Handlers: Default> Default for MultiQueryHandler<Handlers> {
516 fn default() -> Self {
517 Self::new(Default::default())
518 }
519}
520
521pub struct PostprocessHandler<PostProcessed, Handler: ResponseHandler>
522where
523 <Handler::Method as RpcMethod>::Error: std::fmt::Display + std::fmt::Debug,
524{
525 post_process: Box<dyn Fn(Handler::Response) -> PostProcessed + Send + Sync>,
526 handler: Handler,
527}
528
529impl<PostProcessed, Handler: ResponseHandler> PostprocessHandler<PostProcessed, Handler>
530where
531 <Handler::Method as RpcMethod>::Error: std::fmt::Display + std::fmt::Debug,
532{
533 pub fn new<F>(handler: Handler, post_process: F) -> Self
534 where
535 F: Fn(Handler::Response) -> PostProcessed + Send + Sync + 'static,
536 {
537 Self {
538 post_process: Box::new(post_process),
539 handler,
540 }
541 }
542}
543
544impl<PostProcessed, Handler> ResponseHandler for PostprocessHandler<PostProcessed, Handler>
545where
546 Handler: ResponseHandler,
547 <Handler::Method as RpcMethod>::Error: std::fmt::Display + std::fmt::Debug,
548{
549 type Response = PostProcessed;
550 type QueryResponse = Handler::QueryResponse;
551 type Method = Handler::Method;
552
553 fn process_response(
554 &self,
555 response: Vec<Self::QueryResponse>,
556 ) -> ResultWithMethod<Self::Response, Self::Method> {
557 trace!(target: QUERY_EXECUTOR_TARGET, "Processing response with postprocessing, response count: {}", response.len());
558 Handler::process_response(&self.handler, response).map(|data| {
559 trace!(target: QUERY_EXECUTOR_TARGET, "Applying postprocessing");
560 (self.post_process)(data)
561 })
562 }
563
564 fn request_amount(&self) -> usize {
565 self.handler.request_amount()
566 }
567}
568
569#[derive(Default, Debug, Clone)]
570pub struct CallResultHandler<Response: Send + Sync>(PhantomData<Response>);
571
572impl<Response: Send + Sync> CallResultHandler<Response> {
573 pub const fn new() -> Self {
574 Self(PhantomData::<Response>)
575 }
576}
577
578impl<Response> ResponseHandler for CallResultHandler<Response>
579where
580 Response: DeserializeOwned + Send + Sync,
581{
582 type Response = Data<Response>;
583 type QueryResponse = RpcQueryResponse;
584 type Method = RpcQueryRequest;
585
586 fn process_response(
587 &self,
588 response: Vec<RpcQueryResponse>,
589 ) -> ResultWithMethod<Self::Response, Self::Method> {
590 let response = response
591 .into_iter()
592 .next()
593 .ok_or(QueryError::InternalErrorNoResponse)?;
594
595 if let near_jsonrpc_primitives::types::query::QueryResponseKind::CallResult(result) =
596 response.kind
597 {
598 trace!(target: QUERY_EXECUTOR_TARGET, "Deserializing CallResult, result size: {} bytes", result.result.len());
599 let data: Response = serde_json::from_slice(&result.result)?;
600 Ok(Data {
601 data,
602 block_height: response.block_height,
603 block_hash: response.block_hash.into(),
604 })
605 } else {
606 warn!(target: QUERY_EXECUTOR_TARGET, "Unexpected response kind: {:?}", response.kind);
607 Err(QueryError::UnexpectedResponse {
608 expected: "CallResult",
609 got: Box::new(response.kind),
610 })
611 }
612 }
613}
614
615#[derive(Default, Debug, Clone)]
616pub struct AccountViewHandler;
617
618impl ResponseHandler for AccountViewHandler {
619 type QueryResponse = RpcQueryResponse;
620 type Response = Data<AccountView>;
621 type Method = RpcQueryRequest;
622
623 fn process_response(
624 &self,
625 response: Vec<RpcQueryResponse>,
626 ) -> ResultWithMethod<Self::Response, Self::Method> {
627 let response = response
628 .into_iter()
629 .next()
630 .ok_or(QueryError::InternalErrorNoResponse)?;
631
632 if let near_jsonrpc_primitives::types::query::QueryResponseKind::ViewAccount(account) =
633 response.kind
634 {
635 info!(
636 target: QUERY_EXECUTOR_TARGET,
637 "Processed ViewAccount response: balance: {}, locked: {}",
638 account.amount, account.locked
639 );
640 Ok(Data {
641 data: account,
642 block_height: response.block_height,
643 block_hash: response.block_hash.into(),
644 })
645 } else {
646 warn!(target: QUERY_EXECUTOR_TARGET, "Unexpected response kind: {:?}", response.kind);
647 Err(QueryError::UnexpectedResponse {
648 expected: "ViewAccount",
649 got: Box::new(response.kind),
650 })
651 }
652 }
653}
654
655#[derive(Default, Debug, Clone)]
656pub struct AccessKeyListHandler;
657
658impl ResponseHandler for AccessKeyListHandler {
659 type Response = AccessKeyList;
660 type QueryResponse = RpcQueryResponse;
661 type Method = RpcQueryRequest;
662
663 fn process_response(
664 &self,
665 response: Vec<RpcQueryResponse>,
666 ) -> ResultWithMethod<Self::Response, Self::Method> {
667 let response = response
668 .into_iter()
669 .next()
670 .ok_or(QueryError::InternalErrorNoResponse)?;
671 if let near_jsonrpc_primitives::types::query::QueryResponseKind::AccessKeyList(
672 access_key_list,
673 ) = response.kind
674 {
675 info!(
676 target: QUERY_EXECUTOR_TARGET,
677 "Processed AccessKeyList response, keys count: {}",
678 access_key_list.keys.len()
679 );
680 Ok(access_key_list)
681 } else {
682 warn!(target: QUERY_EXECUTOR_TARGET, "Unexpected response kind: {:?}", response.kind);
683 Err(QueryError::UnexpectedResponse {
684 expected: "AccessKeyList",
685 got: Box::new(response.kind),
686 })
687 }
688 }
689}
690
691#[derive(Default, Debug, Clone)]
692pub struct AccessKeyHandler;
693
694impl ResponseHandler for AccessKeyHandler {
695 type Response = Data<AccessKeyView>;
696 type QueryResponse = RpcQueryResponse;
697 type Method = RpcQueryRequest;
698
699 fn process_response(
700 &self,
701 response: Vec<RpcQueryResponse>,
702 ) -> ResultWithMethod<Self::Response, Self::Method> {
703 let response = response
704 .into_iter()
705 .next()
706 .ok_or(QueryError::InternalErrorNoResponse)?;
707 if let near_jsonrpc_primitives::types::query::QueryResponseKind::AccessKey(key) =
708 response.kind
709 {
710 info!(
711 target: QUERY_EXECUTOR_TARGET,
712 "Processed AccessKey response, nonce: {}, permission: {:?}",
713 key.nonce,
714 key.permission
715 );
716 Ok(Data {
717 data: key,
718 block_height: response.block_height,
719 block_hash: response.block_hash.into(),
720 })
721 } else {
722 warn!(target: QUERY_EXECUTOR_TARGET, "Unexpected response kind: {:?}", response.kind);
723 Err(QueryError::UnexpectedResponse {
724 expected: "AccessKey",
725 got: Box::new(response.kind),
726 })
727 }
728 }
729}
730
731#[derive(Default, Debug, Clone)]
732pub struct ViewStateHandler;
733
734impl ResponseHandler for ViewStateHandler {
735 type Response = Data<ViewStateResult>;
736 type QueryResponse = RpcQueryResponse;
737 type Method = RpcQueryRequest;
738
739 fn process_response(
740 &self,
741 response: Vec<RpcQueryResponse>,
742 ) -> ResultWithMethod<Self::Response, Self::Method> {
743 let response = response
744 .into_iter()
745 .next()
746 .ok_or(QueryError::InternalErrorNoResponse)?;
747 if let near_jsonrpc_primitives::types::query::QueryResponseKind::ViewState(data) =
748 response.kind
749 {
750 info!(
751 target: QUERY_EXECUTOR_TARGET,
752 "Processed ViewState response, values count: {}, proof nodes: {}",
753 data.values.len(),
754 data.proof.len()
755 );
756 Ok(Data {
757 data,
758 block_height: response.block_height,
759 block_hash: response.block_hash.into(),
760 })
761 } else {
762 warn!(target: QUERY_EXECUTOR_TARGET, "Unexpected response kind: {:?}", response.kind);
763 Err(QueryError::UnexpectedResponse {
764 expected: "ViewState",
765 got: Box::new(response.kind),
766 })
767 }
768 }
769}
770
771#[derive(Default, Debug, Clone)]
772pub struct ViewCodeHandler;
773
774impl ResponseHandler for ViewCodeHandler {
775 type Response = Data<ContractCodeView>;
776 type QueryResponse = RpcQueryResponse;
777 type Method = RpcQueryRequest;
778
779 fn process_response(
780 &self,
781 response: Vec<RpcQueryResponse>,
782 ) -> ResultWithMethod<Self::Response, Self::Method> {
783 let response = response
784 .into_iter()
785 .next()
786 .ok_or(QueryError::InternalErrorNoResponse)?;
787 if let near_jsonrpc_primitives::types::query::QueryResponseKind::ViewCode(code) =
788 response.kind
789 {
790 info!(
791 target: QUERY_EXECUTOR_TARGET,
792 "Processed ViewCode response, code size: {} bytes, hash: {:?}",
793 code.code.len(),
794 code.hash
795 );
796 Ok(Data {
797 data: code,
798 block_height: response.block_height,
799 block_hash: response.block_hash.into(),
800 })
801 } else {
802 warn!(target: QUERY_EXECUTOR_TARGET, "Unexpected response kind: {:?}", response.kind);
803 Err(QueryError::UnexpectedResponse {
804 expected: "ViewCode",
805 got: Box::new(response.kind),
806 })
807 }
808 }
809}
810
811#[derive(Clone, Debug)]
812pub struct RpcValidatorHandler;
813
814impl ResponseHandler for RpcValidatorHandler {
815 type Response = EpochValidatorInfo;
816 type QueryResponse = EpochValidatorInfo;
817 type Method = RpcValidatorRequest;
818
819 fn process_response(
820 &self,
821 response: Vec<EpochValidatorInfo>,
822 ) -> ResultWithMethod<Self::Response, Self::Method> {
823 let response = response
824 .into_iter()
825 .next()
826 .ok_or(QueryError::InternalErrorNoResponse)?;
827
828 info!(
829 target: QUERY_EXECUTOR_TARGET,
830 "Processed EpochValidatorInfo response, epoch height: {}, validators count: {}",
831 response.epoch_height,
832 response.current_validators.len()
833 );
834 Ok(response)
835 }
836}
837
838#[derive(Clone, Debug)]
839pub struct RpcBlockHandler;
840
841impl ResponseHandler for RpcBlockHandler {
842 type Response = BlockView;
843 type QueryResponse = BlockView;
844 type Method = RpcBlockRequest;
845
846 fn process_response(
847 &self,
848 response: Vec<BlockView>,
849 ) -> ResultWithMethod<Self::Response, Self::Method> {
850 let response = response
851 .into_iter()
852 .next()
853 .ok_or(QueryError::InternalErrorNoResponse)?;
854
855 info!(
856 target: QUERY_EXECUTOR_TARGET,
857 "Processed Block response, height: {}, hash: {:?}",
858 response.header.height,
859 response.header.hash
860 );
861 Ok(response)
862 }
863}
864
865impl ResponseHandler for () {
866 type Response = ();
867 type QueryResponse = RpcQueryResponse;
868 type Method = RpcQueryRequest;
869
870 fn process_response(
871 &self,
872 _response: Vec<RpcQueryResponse>,
873 ) -> ResultWithMethod<Self::Response, Self::Method> {
874 trace!(target: QUERY_EXECUTOR_TARGET, "Processed empty response handler");
875 Ok(())
876 }
877}