1use linera_base::{
6 crypto::CryptoHash,
7 data_types::{BlobContent, 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 BlobLastUsedBy(Box<BlobId>),
43 MissingBlobIds(Vec<BlobId>),
44 VersionInfoQuery,
45 NetworkDescriptionQuery,
46
47 Vote(Box<LiteVote>),
49 ChainInfoResponse(Box<ChainInfoResponse>),
50 Error(Box<NodeError>),
51 VersionInfoResponse(Box<VersionInfo>),
52 NetworkDescriptionResponse(Box<NetworkDescription>),
53 UploadBlobResponse(Box<BlobId>),
54 DownloadBlobResponse(Box<BlobContent>),
55 DownloadPendingBlobResponse(Box<BlobContent>),
56 DownloadConfirmedBlockResponse(Box<ConfirmedBlock>),
57 DownloadCertificatesResponse(Vec<ConfirmedBlockCertificate>),
58 BlobLastUsedByResponse(Box<CryptoHash>),
59 MissingBlobIdsResponse(Vec<BlobId>),
60
61 CrossChainRequest(Box<CrossChainRequest>),
63}
64
65impl RpcMessage {
66 pub fn target_chain_id(&self) -> Option<ChainId> {
70 use RpcMessage::*;
71
72 let chain_id = match self {
73 BlockProposal(proposal) => proposal.content.block.chain_id,
74 LiteCertificate(request) => request.certificate.value.chain_id,
75 TimeoutCertificate(request) => request.certificate.inner().chain_id(),
76 ValidatedCertificate(request) => request.certificate.inner().chain_id(),
77 ConfirmedCertificate(request) => request.certificate.inner().chain_id(),
78 ChainInfoQuery(query) => query.chain_id,
79 CrossChainRequest(request) => request.target_chain_id(),
80 DownloadPendingBlob(request) => request.0,
81 HandlePendingBlob(request) => request.0,
82 Vote(_)
83 | Error(_)
84 | ChainInfoResponse(_)
85 | VersionInfoQuery
86 | VersionInfoResponse(_)
87 | NetworkDescriptionQuery
88 | NetworkDescriptionResponse(_)
89 | UploadBlob(_)
90 | UploadBlobResponse(_)
91 | DownloadBlob(_)
92 | DownloadBlobResponse(_)
93 | DownloadPendingBlobResponse(_)
94 | DownloadConfirmedBlock(_)
95 | DownloadConfirmedBlockResponse(_)
96 | DownloadCertificates(_)
97 | BlobLastUsedBy(_)
98 | BlobLastUsedByResponse(_)
99 | MissingBlobIds(_)
100 | MissingBlobIdsResponse(_)
101 | DownloadCertificatesResponse(_) => {
102 return None;
103 }
104 };
105
106 Some(chain_id)
107 }
108
109 pub fn is_local_message(&self) -> bool {
112 use RpcMessage::*;
113
114 match self {
115 VersionInfoQuery
116 | NetworkDescriptionQuery
117 | UploadBlob(_)
118 | DownloadBlob(_)
119 | DownloadConfirmedBlock(_)
120 | BlobLastUsedBy(_)
121 | MissingBlobIds(_)
122 | DownloadCertificates(_) => true,
123 BlockProposal(_)
124 | LiteCertificate(_)
125 | TimeoutCertificate(_)
126 | ValidatedCertificate(_)
127 | ConfirmedCertificate(_)
128 | ChainInfoQuery(_)
129 | CrossChainRequest(_)
130 | Vote(_)
131 | Error(_)
132 | ChainInfoResponse(_)
133 | VersionInfoResponse(_)
134 | NetworkDescriptionResponse(_)
135 | UploadBlobResponse(_)
136 | DownloadPendingBlob(_)
137 | DownloadPendingBlobResponse(_)
138 | HandlePendingBlob(_)
139 | DownloadBlobResponse(_)
140 | DownloadConfirmedBlockResponse(_)
141 | BlobLastUsedByResponse(_)
142 | MissingBlobIdsResponse(_)
143 | DownloadCertificatesResponse(_) => false,
144 }
145 }
146}
147
148impl TryFrom<RpcMessage> for ChainInfoResponse {
149 type Error = NodeError;
150 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
151 match message {
152 RpcMessage::ChainInfoResponse(response) => Ok(*response),
153 RpcMessage::Error(error) => Err(*error),
154 _ => Err(NodeError::UnexpectedMessage),
155 }
156 }
157}
158
159impl TryFrom<RpcMessage> for VersionInfo {
160 type Error = NodeError;
161 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
162 match message {
163 RpcMessage::VersionInfoResponse(version_info) => Ok(*version_info),
164 RpcMessage::Error(error) => Err(*error),
165 _ => Err(NodeError::UnexpectedMessage),
166 }
167 }
168}
169
170impl TryFrom<RpcMessage> for BlobContent {
171 type Error = NodeError;
172 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
173 match message {
174 RpcMessage::DownloadBlobResponse(blob)
175 | RpcMessage::DownloadPendingBlobResponse(blob) => Ok(*blob),
176 RpcMessage::Error(error) => Err(*error),
177 _ => Err(NodeError::UnexpectedMessage),
178 }
179 }
180}
181
182impl TryFrom<RpcMessage> for ConfirmedBlock {
183 type Error = NodeError;
184 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
185 match message {
186 RpcMessage::DownloadConfirmedBlockResponse(certificate) => Ok(*certificate),
187 RpcMessage::Error(error) => Err(*error),
188 _ => Err(NodeError::UnexpectedMessage),
189 }
190 }
191}
192
193impl TryFrom<RpcMessage> for Vec<ConfirmedBlockCertificate> {
194 type Error = NodeError;
195 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
196 match message {
197 RpcMessage::DownloadCertificatesResponse(certificates) => Ok(certificates),
198 RpcMessage::Error(error) => Err(*error),
199 _ => Err(NodeError::UnexpectedMessage),
200 }
201 }
202}
203
204impl TryFrom<RpcMessage> for CryptoHash {
205 type Error = NodeError;
206 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
207 match message {
208 RpcMessage::BlobLastUsedByResponse(hash) => Ok(*hash),
209 RpcMessage::Error(error) => Err(*error),
210 _ => Err(NodeError::UnexpectedMessage),
211 }
212 }
213}
214
215impl TryFrom<RpcMessage> for NetworkDescription {
216 type Error = NodeError;
217 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
218 match message {
219 RpcMessage::NetworkDescriptionResponse(description) => Ok(*description),
220 _ => Err(NodeError::UnexpectedMessage),
221 }
222 }
223}
224
225impl TryFrom<RpcMessage> for Vec<BlobId> {
226 type Error = NodeError;
227 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
228 match message {
229 RpcMessage::MissingBlobIdsResponse(blob_ids) => Ok(blob_ids),
230 RpcMessage::Error(error) => Err(*error),
231 _ => Err(NodeError::UnexpectedMessage),
232 }
233 }
234}
235
236impl TryFrom<RpcMessage> for BlobId {
237 type Error = NodeError;
238 fn try_from(message: RpcMessage) -> Result<Self, Self::Error> {
239 match message {
240 RpcMessage::UploadBlobResponse(blob_id) => Ok(*blob_id),
241 RpcMessage::Error(error) => Err(*error),
242 _ => Err(NodeError::UnexpectedMessage),
243 }
244 }
245}
246
247impl From<NodeError> for RpcMessage {
248 fn from(error: NodeError) -> Self {
249 RpcMessage::Error(Box::new(error))
250 }
251}