Skip to main content

linera_rpc/
client.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use linera_base::{
5    crypto::CryptoHash,
6    data_types::{BlobContent, BlockHeight, NetworkDescription},
7    identifiers::{BlobId, ChainId, EventId},
8};
9use linera_chain::{
10    data_types::BlockProposal,
11    types::{
12        ConfirmedBlockCertificate, LiteCertificate, TimeoutCertificate, ValidatedBlockCertificate,
13    },
14};
15use linera_core::{
16    data_types::{ChainInfoQuery, ChainInfoResponse},
17    node::{BlobStream, CrossChainMessageDelivery, NodeError, NotificationStream, ValidatorNode},
18};
19use linera_storage::Arc as CacheArc;
20
21use crate::grpc::GrpcClient;
22#[cfg(with_simple_network)]
23use crate::simple::SimpleClient;
24
25#[derive(Clone)]
26pub enum Client {
27    Grpc(Box<GrpcClient>),
28    #[cfg(with_simple_network)]
29    Simple(SimpleClient),
30}
31
32impl From<GrpcClient> for Client {
33    fn from(client: GrpcClient) -> Self {
34        Self::Grpc(Box::new(client))
35    }
36}
37
38#[cfg(with_simple_network)]
39impl From<SimpleClient> for Client {
40    fn from(client: SimpleClient) -> Self {
41        Self::Simple(client)
42    }
43}
44
45impl ValidatorNode for Client {
46    type NotificationStream = NotificationStream;
47
48    fn address(&self) -> String {
49        match self {
50            Client::Grpc(grpc_client) => grpc_client.address().to_string(),
51            #[cfg(with_simple_network)]
52            Client::Simple(simple_client) => simple_client.address(),
53        }
54    }
55
56    async fn handle_block_proposal(
57        &self,
58        proposal: BlockProposal,
59    ) -> Result<ChainInfoResponse, NodeError> {
60        match self {
61            Client::Grpc(grpc_client) => grpc_client.handle_block_proposal(proposal).await,
62
63            #[cfg(with_simple_network)]
64            Client::Simple(simple_client) => simple_client.handle_block_proposal(proposal).await,
65        }
66    }
67
68    async fn handle_lite_certificate(
69        &self,
70        certificate: LiteCertificate<'_>,
71        delivery: CrossChainMessageDelivery,
72    ) -> Result<ChainInfoResponse, NodeError> {
73        match self {
74            Client::Grpc(grpc_client) => {
75                grpc_client
76                    .handle_lite_certificate(certificate, delivery)
77                    .await
78            }
79
80            #[cfg(with_simple_network)]
81            Client::Simple(simple_client) => {
82                simple_client
83                    .handle_lite_certificate(certificate, delivery)
84                    .await
85            }
86        }
87    }
88
89    async fn handle_timeout_certificate(
90        &self,
91        certificate: TimeoutCertificate,
92    ) -> Result<ChainInfoResponse, NodeError> {
93        match self {
94            Client::Grpc(grpc_client) => grpc_client.handle_timeout_certificate(certificate).await,
95
96            #[cfg(with_simple_network)]
97            Client::Simple(simple_client) => {
98                simple_client.handle_timeout_certificate(certificate).await
99            }
100        }
101    }
102
103    async fn handle_confirmed_certificate(
104        &self,
105        certificate: CacheArc<ConfirmedBlockCertificate>,
106        delivery: CrossChainMessageDelivery,
107    ) -> Result<ChainInfoResponse, NodeError> {
108        match self {
109            Client::Grpc(grpc_client) => {
110                grpc_client
111                    .handle_confirmed_certificate(certificate, delivery)
112                    .await
113            }
114
115            #[cfg(with_simple_network)]
116            Client::Simple(simple_client) => {
117                simple_client
118                    .handle_confirmed_certificate(certificate, delivery)
119                    .await
120            }
121        }
122    }
123
124    async fn handle_validated_certificate(
125        &self,
126        certificate: ValidatedBlockCertificate,
127    ) -> Result<ChainInfoResponse, NodeError> {
128        match self {
129            Client::Grpc(grpc_client) => {
130                grpc_client.handle_validated_certificate(certificate).await
131            }
132
133            #[cfg(with_simple_network)]
134            Client::Simple(simple_client) => {
135                simple_client
136                    .handle_validated_certificate(certificate)
137                    .await
138            }
139        }
140    }
141
142    async fn handle_chain_info_query(
143        &self,
144        query: ChainInfoQuery,
145    ) -> Result<ChainInfoResponse, NodeError> {
146        match self {
147            Client::Grpc(grpc_client) => grpc_client.handle_chain_info_query(query).await,
148
149            #[cfg(with_simple_network)]
150            Client::Simple(simple_client) => simple_client.handle_chain_info_query(query).await,
151        }
152    }
153
154    async fn subscribe(&self, chains: Vec<ChainId>) -> Result<Self::NotificationStream, NodeError> {
155        Ok(match self {
156            Client::Grpc(grpc_client) => Box::pin(grpc_client.subscribe(chains).await?),
157
158            #[cfg(with_simple_network)]
159            Client::Simple(simple_client) => Box::pin(simple_client.subscribe(chains).await?),
160        })
161    }
162
163    async fn get_version_info(&self) -> Result<linera_version::VersionInfo, NodeError> {
164        Ok(match self {
165            Client::Grpc(grpc_client) => grpc_client.get_version_info().await?,
166
167            #[cfg(with_simple_network)]
168            Client::Simple(simple_client) => simple_client.get_version_info().await?,
169        })
170    }
171
172    async fn get_network_description(&self) -> Result<NetworkDescription, NodeError> {
173        Ok(match self {
174            Client::Grpc(grpc_client) => grpc_client.get_network_description().await?,
175
176            #[cfg(with_simple_network)]
177            Client::Simple(simple_client) => simple_client.get_network_description().await?,
178        })
179    }
180
181    async fn upload_blob(&self, content: BlobContent) -> Result<BlobId, NodeError> {
182        Ok(match self {
183            Client::Grpc(grpc_client) => grpc_client.upload_blob(content).await?,
184
185            #[cfg(with_simple_network)]
186            Client::Simple(simple_client) => simple_client.upload_blob(content).await?,
187        })
188    }
189
190    async fn download_blob(&self, blob_id: BlobId) -> Result<BlobContent, NodeError> {
191        Ok(match self {
192            Client::Grpc(grpc_client) => grpc_client.download_blob(blob_id).await?,
193
194            #[cfg(with_simple_network)]
195            Client::Simple(simple_client) => simple_client.download_blob(blob_id).await?,
196        })
197    }
198
199    async fn download_blobs(&self, blob_ids: Vec<BlobId>) -> Result<BlobStream, NodeError> {
200        Ok(match self {
201            Client::Grpc(grpc_client) => grpc_client.download_blobs(blob_ids).await?,
202
203            #[cfg(with_simple_network)]
204            Client::Simple(simple_client) => simple_client.download_blobs(blob_ids).await?,
205        })
206    }
207
208    async fn download_pending_blob(
209        &self,
210        chain_id: ChainId,
211        blob_id: BlobId,
212    ) -> Result<BlobContent, NodeError> {
213        Ok(match self {
214            Client::Grpc(grpc_client) => {
215                grpc_client.download_pending_blob(chain_id, blob_id).await?
216            }
217
218            #[cfg(with_simple_network)]
219            Client::Simple(simple_client) => {
220                simple_client
221                    .download_pending_blob(chain_id, blob_id)
222                    .await?
223            }
224        })
225    }
226
227    async fn handle_pending_blob(
228        &self,
229        chain_id: ChainId,
230        blob: BlobContent,
231    ) -> Result<ChainInfoResponse, NodeError> {
232        Ok(match self {
233            Client::Grpc(grpc_client) => grpc_client.handle_pending_blob(chain_id, blob).await?,
234
235            #[cfg(with_simple_network)]
236            Client::Simple(simple_client) => {
237                simple_client.handle_pending_blob(chain_id, blob).await?
238            }
239        })
240    }
241
242    async fn download_certificate(
243        &self,
244        hash: CryptoHash,
245    ) -> Result<ConfirmedBlockCertificate, NodeError> {
246        Ok(match self {
247            Client::Grpc(grpc_client) => grpc_client.download_certificate(hash).await?,
248
249            #[cfg(with_simple_network)]
250            Client::Simple(simple_client) => simple_client.download_certificate(hash).await?,
251        })
252    }
253
254    async fn download_certificates(
255        &self,
256        hashes: Vec<CryptoHash>,
257    ) -> Result<Vec<ConfirmedBlockCertificate>, NodeError> {
258        Ok(match self {
259            Client::Grpc(grpc_client) => grpc_client.download_certificates(hashes).await?,
260
261            #[cfg(with_simple_network)]
262            Client::Simple(simple_client) => simple_client.download_certificates(hashes).await?,
263        })
264    }
265
266    async fn download_certificates_by_heights(
267        &self,
268        chain_id: ChainId,
269        mut heights: Vec<BlockHeight>,
270    ) -> Result<Vec<ConfirmedBlockCertificate>, NodeError> {
271        heights.sort();
272        Ok(match self {
273            Client::Grpc(grpc_client) => {
274                grpc_client
275                    .download_certificates_by_heights(chain_id, heights)
276                    .await?
277            }
278
279            #[cfg(with_simple_network)]
280            Client::Simple(simple_client) => {
281                simple_client
282                    .download_certificates_by_heights(chain_id, heights)
283                    .await?
284            }
285        })
286    }
287
288    async fn event_block_heights(
289        &self,
290        event_ids: Vec<EventId>,
291    ) -> Result<Vec<Option<BlockHeight>>, NodeError> {
292        Ok(match self {
293            Client::Grpc(grpc_client) => grpc_client.event_block_heights(event_ids).await?,
294
295            #[cfg(with_simple_network)]
296            Client::Simple(simple_client) => simple_client.event_block_heights(event_ids).await?,
297        })
298    }
299
300    async fn blob_last_used_by(&self, blob_id: BlobId) -> Result<CryptoHash, NodeError> {
301        Ok(match self {
302            Client::Grpc(grpc_client) => grpc_client.blob_last_used_by(blob_id).await?,
303
304            #[cfg(with_simple_network)]
305            Client::Simple(simple_client) => simple_client.blob_last_used_by(blob_id).await?,
306        })
307    }
308
309    async fn blob_last_used_by_certificate(
310        &self,
311        blob_id: BlobId,
312    ) -> Result<ConfirmedBlockCertificate, NodeError> {
313        Ok(match self {
314            Client::Grpc(grpc_client) => grpc_client.blob_last_used_by_certificate(blob_id).await?,
315
316            #[cfg(with_simple_network)]
317            Client::Simple(simple_client) => {
318                simple_client.blob_last_used_by_certificate(blob_id).await?
319            }
320        })
321    }
322
323    async fn missing_blob_ids(&self, blob_ids: Vec<BlobId>) -> Result<Vec<BlobId>, NodeError> {
324        Ok(match self {
325            Client::Grpc(grpc_client) => grpc_client.missing_blob_ids(blob_ids).await?,
326
327            #[cfg(with_simple_network)]
328            Client::Simple(simple_client) => simple_client.missing_blob_ids(blob_ids).await?,
329        })
330    }
331
332    async fn get_shard_info(
333        &self,
334        chain_id: ChainId,
335    ) -> Result<linera_core::data_types::ShardInfo, NodeError> {
336        Ok(match self {
337            Client::Grpc(grpc_client) => grpc_client.get_shard_info(chain_id).await?,
338
339            #[cfg(with_simple_network)]
340            Client::Simple(simple_client) => simple_client.get_shard_info(chain_id).await?,
341        })
342    }
343}