1use linera_base::{
6 crypto::CryptoHash,
7 data_types::{BlobContent, BlockHeight, NetworkDescription},
8 identifiers::{BlobId, ChainId},
9};
10use linera_chain::{
11 data_types::{BlockProposal, LiteVote},
12 types::{ConfirmedBlock, ConfirmedBlockCertificate},
13};
14use linera_core::{
15 data_types::{ChainInfoQuery, ChainInfoResponse, CrossChainRequest},
16 node::NodeError,
17};
18use linera_version::VersionInfo;
19use serde::{Deserialize, Serialize};
20
21use crate::{
22 HandleConfirmedCertificateRequest, HandleLiteCertRequest, HandleTimeoutCertificateRequest,
23 HandleValidatedCertificateRequest,
24};
25
26#[derive(Clone, Serialize, Deserialize, Debug)]
27#[cfg_attr(with_testing, derive(Eq, PartialEq))]
28pub enum RpcMessage {
29 BlockProposal(Box<BlockProposal>),
31 TimeoutCertificate(Box<HandleTimeoutCertificateRequest>),
32 ValidatedCertificate(Box<HandleValidatedCertificateRequest>),
33 ConfirmedCertificate(Box<HandleConfirmedCertificateRequest>),
34 LiteCertificate(Box<HandleLiteCertRequest<'static>>),
35 ChainInfoQuery(Box<ChainInfoQuery>),
36 UploadBlob(Box<BlobContent>),
37 DownloadBlob(Box<BlobId>),
38 DownloadPendingBlob(Box<(ChainId, BlobId)>),
39 HandlePendingBlob(Box<(ChainId, BlobContent)>),
40 DownloadConfirmedBlock(Box<CryptoHash>),
41 DownloadCertificates(Vec<CryptoHash>),
42 DownloadCertificatesByHeights(ChainId, Vec<BlockHeight>),
43 BlobLastUsedBy(Box<BlobId>),
44 MissingBlobIds(Vec<BlobId>),
45 VersionInfoQuery,
46 NetworkDescriptionQuery,
47
48 Vote(Box<LiteVote>),
50 ChainInfoResponse(Box<ChainInfoResponse>),
51 Error(Box<NodeError>),
52 VersionInfoResponse(Box<VersionInfo>),
53 NetworkDescriptionResponse(Box<NetworkDescription>),
54 UploadBlobResponse(Box<BlobId>),
55 DownloadBlobResponse(Box<BlobContent>),
56 DownloadPendingBlobResponse(Box<BlobContent>),
57 DownloadConfirmedBlockResponse(Box<ConfirmedBlock>),
58 DownloadCertificatesResponse(Vec<ConfirmedBlockCertificate>),
59 DownloadCertificatesByHeightsResponse(Vec<ConfirmedBlockCertificate>),
60 BlobLastUsedByResponse(Box<CryptoHash>),
61 MissingBlobIdsResponse(Vec<BlobId>),
62
63 CrossChainRequest(Box<CrossChainRequest>),
65
66 BlobLastUsedByCertificate(Box<BlobId>),
67 BlobLastUsedByCertificateResponse(Box<ConfirmedBlockCertificate>),
68}
69
70impl RpcMessage {
71 pub fn target_chain_id(&self) -> Option<ChainId> {
75 use RpcMessage::*;
76
77 let chain_id = match self {
78 BlockProposal(proposal) => proposal.content.block.chain_id,
79 LiteCertificate(request) => request.certificate.value.chain_id,
80 TimeoutCertificate(request) => request.certificate.inner().chain_id(),
81 ValidatedCertificate(request) => request.certificate.inner().chain_id(),
82 ConfirmedCertificate(request) => request.certificate.inner().chain_id(),
83 ChainInfoQuery(query) => query.chain_id,
84 CrossChainRequest(request) => request.target_chain_id(),
85 DownloadPendingBlob(request) => request.0,
86 DownloadCertificatesByHeights(chain_id, _) => *chain_id,
87 HandlePendingBlob(request) => request.0,
88 Vote(_)
89 | Error(_)
90 | ChainInfoResponse(_)
91 | VersionInfoQuery
92 | VersionInfoResponse(_)
93 | NetworkDescriptionQuery
94 | NetworkDescriptionResponse(_)
95 | UploadBlob(_)
96 | UploadBlobResponse(_)
97 | DownloadBlob(_)
98 | DownloadBlobResponse(_)
99 | DownloadPendingBlobResponse(_)
100 | DownloadConfirmedBlock(_)
101 | DownloadConfirmedBlockResponse(_)
102 | DownloadCertificatesByHeightsResponse(_)
103 | DownloadCertificates(_)
104 | BlobLastUsedBy(_)
105 | BlobLastUsedByResponse(_)
106 | BlobLastUsedByCertificate(_)
107 | BlobLastUsedByCertificateResponse(_)
108 | MissingBlobIds(_)
109 | MissingBlobIdsResponse(_)
110 | DownloadCertificatesResponse(_) => {
111 return None;
112 }
113 };
114
115 Some(chain_id)
116 }
117
118 pub fn is_local_message(&self) -> bool {
121 use RpcMessage::*;
122
123 match self {
124 VersionInfoQuery
125 | NetworkDescriptionQuery
126 | UploadBlob(_)
127 | DownloadBlob(_)
128 | DownloadConfirmedBlock(_)
129 | BlobLastUsedBy(_)
130 | BlobLastUsedByCertificate(_)
131 | MissingBlobIds(_)
132 | DownloadCertificates(_)
133 | DownloadCertificatesByHeights(_, _) => true,
134 BlockProposal(_)
135 | LiteCertificate(_)
136 | TimeoutCertificate(_)
137 | ValidatedCertificate(_)
138 | ConfirmedCertificate(_)
139 | ChainInfoQuery(_)
140 | CrossChainRequest(_)
141 | Vote(_)
142 | Error(_)
143 | ChainInfoResponse(_)
144 | VersionInfoResponse(_)
145 | NetworkDescriptionResponse(_)
146 | UploadBlobResponse(_)
147 | DownloadPendingBlob(_)
148 | DownloadPendingBlobResponse(_)
149 | HandlePendingBlob(_)
150 | DownloadBlobResponse(_)
151 | DownloadConfirmedBlockResponse(_)
152 | BlobLastUsedByResponse(_)
153 | BlobLastUsedByCertificateResponse(_)
154 | MissingBlobIdsResponse(_)
155 | DownloadCertificatesResponse(_)
156 | DownloadCertificatesByHeightsResponse(_) => false,
157 }
158 }
159}
160
161impl TryFrom<RpcMessage> for ChainInfoResponse {
162 type Error = NodeError;
163 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
164 match message {
165 RpcMessage::ChainInfoResponse(response) => Ok(*response),
166 RpcMessage::Error(error) => Err(*error),
167 _ => Err(NodeError::UnexpectedMessage),
168 }
169 }
170}
171
172impl TryFrom<RpcMessage> for VersionInfo {
173 type Error = NodeError;
174 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
175 match message {
176 RpcMessage::VersionInfoResponse(version_info) => Ok(*version_info),
177 RpcMessage::Error(error) => Err(*error),
178 _ => Err(NodeError::UnexpectedMessage),
179 }
180 }
181}
182
183impl TryFrom<RpcMessage> for BlobContent {
184 type Error = NodeError;
185 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
186 match message {
187 RpcMessage::DownloadBlobResponse(blob)
188 | RpcMessage::DownloadPendingBlobResponse(blob) => Ok(*blob),
189 RpcMessage::Error(error) => Err(*error),
190 _ => Err(NodeError::UnexpectedMessage),
191 }
192 }
193}
194
195impl TryFrom<RpcMessage> for ConfirmedBlock {
196 type Error = NodeError;
197 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
198 match message {
199 RpcMessage::DownloadConfirmedBlockResponse(certificate) => Ok(*certificate),
200 RpcMessage::Error(error) => Err(*error),
201 _ => Err(NodeError::UnexpectedMessage),
202 }
203 }
204}
205
206impl TryFrom<RpcMessage> for ConfirmedBlockCertificate {
207 type Error = NodeError;
208 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
209 match message {
210 RpcMessage::BlobLastUsedByCertificateResponse(certificate) => Ok(*certificate),
211 RpcMessage::Error(error) => Err(*error),
212 _ => Err(NodeError::UnexpectedMessage),
213 }
214 }
215}
216
217impl TryFrom<RpcMessage> for Vec<ConfirmedBlockCertificate> {
218 type Error = NodeError;
219 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
220 match message {
221 RpcMessage::DownloadCertificatesResponse(certificates) => Ok(certificates),
222 RpcMessage::DownloadCertificatesByHeightsResponse(certificates) => Ok(certificates),
223 RpcMessage::Error(error) => Err(*error),
224 _ => Err(NodeError::UnexpectedMessage),
225 }
226 }
227}
228
229impl TryFrom<RpcMessage> for CryptoHash {
230 type Error = NodeError;
231 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
232 match message {
233 RpcMessage::BlobLastUsedByResponse(hash) => Ok(*hash),
234 RpcMessage::Error(error) => Err(*error),
235 _ => Err(NodeError::UnexpectedMessage),
236 }
237 }
238}
239
240impl TryFrom<RpcMessage> for NetworkDescription {
241 type Error = NodeError;
242 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
243 match message {
244 RpcMessage::NetworkDescriptionResponse(description) => Ok(*description),
245 _ => Err(NodeError::UnexpectedMessage),
246 }
247 }
248}
249
250impl TryFrom<RpcMessage> for Vec<BlobId> {
251 type Error = NodeError;
252 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
253 match message {
254 RpcMessage::MissingBlobIdsResponse(blob_ids) => Ok(blob_ids),
255 RpcMessage::Error(error) => Err(*error),
256 _ => Err(NodeError::UnexpectedMessage),
257 }
258 }
259}
260
261impl TryFrom<RpcMessage> for BlobId {
262 type Error = NodeError;
263 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
264 match message {
265 RpcMessage::UploadBlobResponse(blob_id) => Ok(*blob_id),
266 RpcMessage::Error(error) => Err(*error),
267 _ => Err(NodeError::UnexpectedMessage),
268 }
269 }
270}
271
272impl From<NodeError> for RpcMessage {
273 fn from(error: NodeError) -> Self {
274 RpcMessage::Error(Box::new(error))
275 }
276}