ibc_query/core/client/
service.rs

1//! [`ClientQueryService`](ClientQueryService) takes generics `I` and `U` to store `ibc_context` and `upgrade_context` that implement [`QueryContext`](QueryContext) and [`UpgradeValidationContext`](UpgradeValidationContext) respectively.
2//! `I` must be a type where writes from one thread are readable from another.
3//! This means using `Arc<Mutex<_>>` or `Arc<RwLock<_>>` in most cases.
4
5use ibc::core::host::ConsensusStateRef;
6use ibc::core::primitives::prelude::*;
7use ibc::cosmos_host::upgrade_proposal::{
8    UpgradeValidationContext, UpgradedClientStateRef, UpgradedConsensusStateRef,
9};
10use ibc_proto::google::protobuf::Any;
11use ibc_proto::ibc::core::client::v1::query_server::Query as ClientQuery;
12use ibc_proto::ibc::core::client::v1::{
13    QueryClientParamsRequest, QueryClientParamsResponse, QueryClientStateRequest,
14    QueryClientStateResponse, QueryClientStatesRequest, QueryClientStatesResponse,
15    QueryClientStatusRequest, QueryClientStatusResponse, QueryConsensusStateHeightsRequest,
16    QueryConsensusStateHeightsResponse, QueryConsensusStateRequest, QueryConsensusStateResponse,
17    QueryConsensusStatesRequest, QueryConsensusStatesResponse, QueryUpgradedClientStateRequest,
18    QueryUpgradedClientStateResponse, QueryUpgradedConsensusStateRequest,
19    QueryUpgradedConsensusStateResponse,
20};
21use tonic::{Request, Response, Status};
22
23use super::{
24    query_client_state, query_client_states, query_client_status, query_consensus_state,
25    query_consensus_state_heights, query_consensus_states, query_upgraded_client_state,
26    query_upgraded_consensus_state,
27};
28use crate::core::context::{ProvableContext, QueryContext};
29use crate::utils::{IntoDomain, IntoResponse, TryIntoDomain};
30
31// TODO(rano): currently the services don't support pagination, so we return all the results.
32
33/// Generics `I` and `U` must be a type where writes from one thread are readable from another.
34/// This means using `Arc<Mutex<_>>` or `Arc<RwLock<_>>` in most cases.
35pub struct ClientQueryService<I, U>
36where
37    I: QueryContext + Send + Sync + 'static,
38    U: UpgradeValidationContext + Send + Sync + 'static,
39    UpgradedClientStateRef<U>: Into<Any>,
40    UpgradedConsensusStateRef<U>: Into<Any>,
41{
42    ibc_context: I,
43    upgrade_context: U,
44}
45
46impl<I, U> ClientQueryService<I, U>
47where
48    I: QueryContext + Send + Sync + 'static,
49    U: UpgradeValidationContext + Send + Sync + 'static,
50    UpgradedClientStateRef<U>: Into<Any>,
51    UpgradedConsensusStateRef<U>: Into<Any>,
52{
53    /// Parameters `ibc_context` and `upgrade_context` must be a type where writes from one thread are readable from another.
54    /// This means using `Arc<Mutex<_>>` or `Arc<RwLock<_>>` in most cases.
55    pub fn new(ibc_context: I, upgrade_context: U) -> Self {
56        Self {
57            ibc_context,
58            upgrade_context,
59        }
60    }
61}
62
63#[tonic::async_trait]
64impl<I, U> ClientQuery for ClientQueryService<I, U>
65where
66    I: QueryContext + Send + Sync + 'static,
67    U: UpgradeValidationContext + ProvableContext + Send + Sync + 'static,
68    ConsensusStateRef<I>: Into<Any>,
69    UpgradedConsensusStateRef<U>: Into<Any>,
70{
71    async fn client_state(
72        &self,
73        request: Request<QueryClientStateRequest>,
74    ) -> Result<Response<QueryClientStateResponse>, Status> {
75        query_client_state(&self.ibc_context, &request.try_into_domain()?)?.into_response()
76    }
77
78    async fn client_states(
79        &self,
80        request: Request<QueryClientStatesRequest>,
81    ) -> Result<Response<QueryClientStatesResponse>, Status> {
82        query_client_states(&self.ibc_context, &request.into_domain())?.into_response()
83    }
84
85    async fn consensus_state(
86        &self,
87        request: Request<QueryConsensusStateRequest>,
88    ) -> Result<Response<QueryConsensusStateResponse>, Status> {
89        query_consensus_state(&self.ibc_context, &request.try_into_domain()?)?.into_response()
90    }
91
92    async fn consensus_states(
93        &self,
94        request: Request<QueryConsensusStatesRequest>,
95    ) -> Result<Response<QueryConsensusStatesResponse>, Status> {
96        query_consensus_states(&self.ibc_context, &request.try_into_domain()?)?.into_response()
97    }
98
99    async fn consensus_state_heights(
100        &self,
101        request: Request<QueryConsensusStateHeightsRequest>,
102    ) -> Result<Response<QueryConsensusStateHeightsResponse>, Status> {
103        query_consensus_state_heights(&self.ibc_context, &request.try_into_domain()?)?
104            .into_response()
105    }
106
107    async fn client_status(
108        &self,
109        request: Request<QueryClientStatusRequest>,
110    ) -> Result<Response<QueryClientStatusResponse>, Status> {
111        query_client_status(&self.ibc_context, &request.try_into_domain()?)?.into_response()
112    }
113
114    async fn client_params(
115        &self,
116        _request: Request<QueryClientParamsRequest>,
117    ) -> Result<Response<QueryClientParamsResponse>, Status> {
118        Err(Status::unimplemented(
119            "Querying ClientParams is not supported yet",
120        ))
121    }
122
123    async fn upgraded_client_state(
124        &self,
125        request: Request<QueryUpgradedClientStateRequest>,
126    ) -> Result<Response<QueryUpgradedClientStateResponse>, Status> {
127        query_upgraded_client_state(
128            &self.ibc_context,
129            &self.upgrade_context,
130            &request.into_domain(),
131        )?
132        .into_response()
133    }
134
135    async fn upgraded_consensus_state(
136        &self,
137        request: Request<QueryUpgradedConsensusStateRequest>,
138    ) -> Result<Response<QueryUpgradedConsensusStateResponse>, Status> {
139        query_upgraded_consensus_state(
140            &self.ibc_context,
141            &self.upgrade_context,
142            &request.into_domain(),
143        )?
144        .into_response()
145    }
146}