pclientd/
proxy.rs

1use futures::FutureExt;
2use std::convert::Infallible;
3use std::pin::Pin;
4use std::{
5    future::Future,
6    task::{Context, Poll},
7};
8use tonic::server::NamedService;
9use tonic::{body::BoxBody, transport::Channel};
10use tower::ServiceExt;
11
12fn proxy(
13    channel: Channel,
14    req: http::Request<BoxBody>,
15) -> Pin<Box<dyn Future<Output = Result<http::Response<BoxBody>, Infallible>> + Send + 'static>> {
16    tracing::debug!(headers = ?req.headers(), "proxying request");
17
18    let rsp = channel.oneshot(req);
19
20    async move {
21        // Once we get the response, we need to convert any transport errors into
22        // an Ok(HTTP response reporting an internal error), so we can have Error = Infallible
23        let rsp = match rsp.await {
24            Ok(rsp) => rsp,
25            Err(e) => tonic::Status::internal(format!("grpc proxy error: {e}")).into_http(),
26        };
27        Ok::<_, Infallible>(rsp)
28    }
29    .boxed()
30}
31
32#[derive(Clone)]
33pub struct AppQueryProxy(pub Channel);
34
35impl NamedService for AppQueryProxy {
36    const NAME: &'static str = "penumbra.core.app.v1.QueryService";
37}
38
39impl tower::Service<http::Request<BoxBody>> for AppQueryProxy {
40    type Response = http::Response<BoxBody>;
41    type Error = Infallible;
42    type Future =
43        Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
44
45    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
46        Poll::Ready(Ok(()))
47    }
48
49    fn call(&mut self, req: http::Request<BoxBody>) -> Self::Future {
50        proxy(self.0.clone(), req)
51    }
52}
53
54#[derive(Clone)]
55pub struct GovernanceQueryProxy(pub Channel);
56
57impl NamedService for GovernanceQueryProxy {
58    const NAME: &'static str = "penumbra.core.component.governance.v1.QueryService";
59}
60
61impl tower::Service<http::Request<BoxBody>> for GovernanceQueryProxy {
62    type Response = http::Response<BoxBody>;
63    type Error = Infallible;
64    type Future =
65        Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
66
67    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
68        Poll::Ready(Ok(()))
69    }
70
71    fn call(&mut self, req: http::Request<BoxBody>) -> Self::Future {
72        proxy(self.0.clone(), req)
73    }
74}
75
76#[derive(Clone)]
77pub struct DexQueryProxy(pub Channel);
78
79impl NamedService for DexQueryProxy {
80    const NAME: &'static str = "penumbra.core.component.dex.v1.QueryService";
81}
82
83impl tower::Service<http::Request<BoxBody>> for DexQueryProxy {
84    type Response = http::Response<BoxBody>;
85    type Error = Infallible;
86    type Future =
87        Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
88
89    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
90        Poll::Ready(Ok(()))
91    }
92
93    fn call(&mut self, req: http::Request<BoxBody>) -> Self::Future {
94        proxy(self.0.clone(), req)
95    }
96}
97
98#[derive(Clone)]
99pub struct DexSimulationProxy(pub Channel);
100
101impl NamedService for DexSimulationProxy {
102    const NAME: &'static str = "penumbra.core.component.dex.v1.SimulationService";
103}
104
105impl tower::Service<http::Request<BoxBody>> for DexSimulationProxy {
106    type Response = http::Response<BoxBody>;
107    type Error = Infallible;
108    type Future =
109        Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
110
111    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
112        Poll::Ready(Ok(()))
113    }
114
115    fn call(&mut self, req: http::Request<BoxBody>) -> Self::Future {
116        proxy(self.0.clone(), req)
117    }
118}
119
120#[derive(Clone)]
121pub struct FeeQueryProxy(pub Channel);
122
123impl NamedService for FeeQueryProxy {
124    const NAME: &'static str = "penumbra.core.component.fee.v1.QueryService";
125}
126
127impl tower::Service<http::Request<BoxBody>> for FeeQueryProxy {
128    type Response = http::Response<BoxBody>;
129    type Error = Infallible;
130    type Future =
131        Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
132
133    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
134        Poll::Ready(Ok(()))
135    }
136
137    fn call(&mut self, req: http::Request<BoxBody>) -> Self::Future {
138        proxy(self.0.clone(), req)
139    }
140}
141
142#[derive(Clone)]
143pub struct SctQueryProxy(pub Channel);
144
145impl NamedService for SctQueryProxy {
146    const NAME: &'static str = "penumbra.core.component.sct.v1.QueryService";
147}
148
149impl tower::Service<http::Request<BoxBody>> for SctQueryProxy {
150    type Response = http::Response<BoxBody>;
151    type Error = Infallible;
152    type Future =
153        Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
154
155    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
156        Poll::Ready(Ok(()))
157    }
158
159    fn call(&mut self, req: http::Request<BoxBody>) -> Self::Future {
160        proxy(self.0.clone(), req)
161    }
162}
163
164#[derive(Clone)]
165pub struct ShieldedPoolQueryProxy(pub Channel);
166
167impl NamedService for ShieldedPoolQueryProxy {
168    const NAME: &'static str = "penumbra.core.component.shielded_pool.v1.QueryService";
169}
170
171impl tower::Service<http::Request<BoxBody>> for ShieldedPoolQueryProxy {
172    type Response = http::Response<BoxBody>;
173    type Error = Infallible;
174    type Future =
175        Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
176
177    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
178        Poll::Ready(Ok(()))
179    }
180
181    fn call(&mut self, req: http::Request<BoxBody>) -> Self::Future {
182        proxy(self.0.clone(), req)
183    }
184}
185
186#[derive(Clone)]
187pub struct ChainQueryProxy(pub Channel);
188
189impl NamedService for ChainQueryProxy {
190    const NAME: &'static str = "penumbra.core.component.chain.v1.QueryService";
191}
192
193impl tower::Service<http::Request<BoxBody>> for ChainQueryProxy {
194    type Response = http::Response<BoxBody>;
195    type Error = Infallible;
196    type Future =
197        Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
198
199    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
200        Poll::Ready(Ok(()))
201    }
202
203    fn call(&mut self, req: http::Request<BoxBody>) -> Self::Future {
204        proxy(self.0.clone(), req)
205    }
206}
207
208#[derive(Clone)]
209pub struct StakeQueryProxy(pub Channel);
210
211impl NamedService for StakeQueryProxy {
212    const NAME: &'static str = "penumbra.core.component.stake.v1.QueryService";
213}
214
215impl tower::Service<http::Request<BoxBody>> for StakeQueryProxy {
216    type Response = http::Response<BoxBody>;
217    type Error = Infallible;
218    type Future =
219        Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
220
221    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
222        Poll::Ready(Ok(()))
223    }
224
225    fn call(&mut self, req: http::Request<BoxBody>) -> Self::Future {
226        proxy(self.0.clone(), req)
227    }
228}
229
230#[derive(Clone)]
231pub struct CompactBlockQueryProxy(pub Channel);
232
233impl NamedService for CompactBlockQueryProxy {
234    const NAME: &'static str = "penumbra.core.component.compact_block.v1.QueryService";
235}
236
237impl tower::Service<http::Request<BoxBody>> for CompactBlockQueryProxy {
238    type Response = http::Response<BoxBody>;
239    type Error = Infallible;
240    type Future =
241        Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
242
243    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
244        Poll::Ready(Ok(()))
245    }
246
247    fn call(&mut self, req: http::Request<BoxBody>) -> Self::Future {
248        proxy(self.0.clone(), req)
249    }
250}
251
252#[derive(Clone)]
253pub struct TendermintProxyProxy(pub Channel);
254
255impl NamedService for TendermintProxyProxy {
256    const NAME: &'static str = "penumbra.util.tendermint_proxy.v1.TendermintProxyService";
257}
258
259impl tower::Service<http::Request<BoxBody>> for TendermintProxyProxy {
260    type Response = http::Response<BoxBody>;
261    type Error = Infallible;
262    type Future =
263        Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
264
265    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
266        Poll::Ready(Ok(()))
267    }
268
269    fn call(&mut self, req: http::Request<BoxBody>) -> Self::Future {
270        proxy(self.0.clone(), req)
271    }
272}