Skip to main content

linera_rpc/
client.rs

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