1use 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}