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