eth_state_server_common/
conversions.rs

1// (c) Cartesi and individual authors (see AUTHORS)
2// SPDX-License-Identifier: Apache-2.0 (see LICENSE)
3
4use crate::grpc_interface::state_fold_server::{
5    block_stream_response::Response as GrpcBlockStreamResponse,
6    blocks_since_response::Response as GrpcBlocksSince, query_block::Id,
7    state_stream_response::Response as GrpcStateStreamResponse,
8    states_since_response::Response as GrpcStatesSince, Block as GrpcBlock,
9    BlockState as GrpcBlockState, BlockStreamResponse, Blocks as GrpcBlocks, BlocksSinceResponse,
10    Bloom as GrpcBloom, Hash, QueryBlock as GrpcQueryBlock, State as GrpcState,
11    StateStreamResponse, States as GrpcStates, StatesSinceResponse,
12};
13
14use eth_state_fold_types::{
15    ethereum_types::{Bloom, H256},
16    Block,
17};
18
19use eth_state_fold_types::{
20    BlockState, BlockStreamItem, BlocksSince, QueryBlock, StateStreamItem, StatesSince,
21};
22
23use serde::{de::DeserializeOwned, Serialize};
24use serde_json;
25
26use std::convert::{TryFrom, TryInto};
27use std::sync::Arc;
28
29use snafu::{ResultExt, Snafu};
30
31#[derive(Debug, Snafu)]
32#[snafu(display("message `{}` field `{}` is nil", message, field))]
33pub struct MessageNilError {
34    message: String,
35    field: String,
36}
37
38#[derive(Debug, Snafu)]
39#[snafu(display("message `{}` field `{}` malformed: {}", message, field, reason))]
40pub struct MessageMalformedError {
41    message: String,
42    field: String,
43    reason: String,
44}
45
46#[derive(Debug, Snafu)]
47pub enum MessageConversionError {
48    #[snafu(display("NilError error: {}", source,))]
49    NilError { source: MessageNilError },
50
51    #[snafu(display("MalformedError error: {}", source,))]
52    MalformedError { source: MessageMalformedError },
53}
54
55#[derive(Debug, Snafu)]
56pub enum StateConversionError {
57    #[snafu(display("NilError error: {}", source,))]
58    MessageError { source: MessageConversionError },
59
60    #[snafu(display("Deserialize error: {}", source))]
61    DeserializeError { source: serde_json::Error },
62}
63
64impl<T: Serialize> TryFrom<BlockState<T>> for GrpcBlockState {
65    type Error = serde_json::Error;
66
67    fn try_from(bs: BlockState<T>) -> Result<Self, Self::Error> {
68        Ok(Self {
69            block: Some(bs.block.into()),
70            state: Some(GrpcState {
71                json_data: serde_json::to_string(bs.state.as_ref())?,
72            }),
73        })
74    }
75}
76
77impl<T: DeserializeOwned> TryFrom<GrpcBlockState> for BlockState<T> {
78    type Error = StateConversionError;
79
80    fn try_from(sr: GrpcBlockState) -> Result<Self, Self::Error> {
81        let block = sr
82            .block
83            .ok_or(MessageNilError {
84                message: "GrpcBlockState".to_owned(),
85                field: "block".to_owned(),
86            })
87            .context(NilSnafu)
88            .context(MessageSnafu)?
89            .try_into()
90            .context(MessageSnafu)?;
91
92        let state = serde_json::from_str(
93            &sr.state
94                .ok_or(MessageNilError {
95                    message: "GrpcBlockState".to_owned(),
96                    field: "state".to_owned(),
97                })
98                .context(NilSnafu)
99                .context(MessageSnafu)?
100                .json_data,
101        )
102        .context(DeserializeSnafu)?;
103
104        Ok(Self {
105            block,
106            state: Arc::new(state),
107        })
108    }
109}
110
111impl<T: DeserializeOwned> TryFrom<StatesSinceResponse> for StatesSince<T> {
112    type Error = StateConversionError;
113
114    fn try_from(sd: StatesSinceResponse) -> Result<Self, Self::Error> {
115        sd.response
116            .ok_or(MessageNilError {
117                message: "StatesSinceResponse".to_owned(),
118                field: "response".to_owned(),
119            })
120            .context(NilSnafu)
121            .context(MessageSnafu)?
122            .try_into()
123    }
124}
125
126impl<T: DeserializeOwned> TryFrom<GrpcStatesSince> for StatesSince<T> {
127    type Error = StateConversionError;
128
129    fn try_from(sd: GrpcStatesSince) -> Result<Self, Self::Error> {
130        Ok(match sd {
131            GrpcStatesSince::NewStates(ss) => StatesSince::Normal(ss.try_into()?),
132            GrpcStatesSince::ReorganizedStates(ss) => StatesSince::Reorg(ss.try_into()?),
133        })
134    }
135}
136
137impl<T: DeserializeOwned> TryFrom<StateStreamResponse> for StateStreamItem<T> {
138    type Error = StateConversionError;
139
140    fn try_from(b: StateStreamResponse) -> Result<Self, Self::Error> {
141        b.response
142            .ok_or(MessageNilError {
143                message: "StateStreamResponse".to_owned(),
144                field: "response".to_owned(),
145            })
146            .context(NilSnafu)
147            .context(MessageSnafu)?
148            .try_into()
149    }
150}
151
152impl<T: Serialize> TryFrom<StateStreamItem<T>> for StateStreamResponse {
153    type Error = serde_json::Error;
154
155    fn try_from(i: StateStreamItem<T>) -> Result<Self, Self::Error> {
156        Ok(Self {
157            response: Some(i.try_into()?),
158        })
159    }
160}
161
162impl<T: Serialize> TryFrom<StateStreamItem<T>> for GrpcStateStreamResponse {
163    type Error = serde_json::Error;
164
165    fn try_from(i: StateStreamItem<T>) -> Result<Self, Self::Error> {
166        Ok(match i {
167            StateStreamItem::NewState(s) => GrpcStateStreamResponse::NewState(s.try_into()?),
168            StateStreamItem::Reorg(ss) => {
169                GrpcStateStreamResponse::ReorganizedStates(ss.try_into()?)
170            }
171        })
172    }
173}
174impl<T: DeserializeOwned> TryFrom<GrpcStateStreamResponse> for StateStreamItem<T> {
175    type Error = StateConversionError;
176
177    fn try_from(ssr: GrpcStateStreamResponse) -> Result<Self, Self::Error> {
178        Ok(match ssr {
179            GrpcStateStreamResponse::NewState(s) => StateStreamItem::NewState(s.try_into()?),
180            GrpcStateStreamResponse::ReorganizedStates(ss) => {
181                StateStreamItem::Reorg(ss.try_into()?)
182            }
183        })
184    }
185}
186
187impl From<BlocksSince> for BlocksSinceResponse {
188    fn from(d: BlocksSince) -> Self {
189        Self {
190            response: Some(d.into()),
191        }
192    }
193}
194
195impl TryFrom<BlocksSinceResponse> for BlocksSince {
196    type Error = MessageConversionError;
197
198    fn try_from(d: BlocksSinceResponse) -> Result<Self, Self::Error> {
199        d.response
200            .ok_or(MessageNilError {
201                message: "BlocksSinceResponse".to_owned(),
202                field: "response".to_owned(),
203            })
204            .context(NilSnafu)?
205            .try_into()
206    }
207}
208
209impl From<BlocksSince> for GrpcBlocksSince {
210    fn from(d: BlocksSince) -> Self {
211        match d {
212            BlocksSince::Normal(bs) => GrpcBlocksSince::NewBlocks(bs.into()),
213            BlocksSince::Reorg(bs) => GrpcBlocksSince::ReorganizedBlocks(bs.into()),
214        }
215    }
216}
217
218impl TryFrom<GrpcBlocksSince> for BlocksSince {
219    type Error = MessageConversionError;
220
221    fn try_from(d: GrpcBlocksSince) -> Result<Self, Self::Error> {
222        Ok(match d {
223            GrpcBlocksSince::NewBlocks(bs) => BlocksSince::Normal(bs.try_into()?),
224
225            GrpcBlocksSince::ReorganizedBlocks(bs) => BlocksSince::Reorg(bs.try_into()?),
226        })
227    }
228}
229
230impl TryFrom<BlockStreamResponse> for BlockStreamItem {
231    type Error = MessageConversionError;
232
233    fn try_from(b: BlockStreamResponse) -> Result<Self, Self::Error> {
234        b.response
235            .ok_or(MessageNilError {
236                message: "BlockStreamResponse".to_owned(),
237                field: "response".to_owned(),
238            })
239            .context(NilSnafu)?
240            .try_into()
241    }
242}
243
244impl From<BlockStreamItem> for BlockStreamResponse {
245    fn from(i: BlockStreamItem) -> Self {
246        Self {
247            response: Some(i.into()),
248        }
249    }
250}
251
252impl From<BlockStreamItem> for GrpcBlockStreamResponse {
253    fn from(i: BlockStreamItem) -> Self {
254        match i {
255            BlockStreamItem::NewBlock(b) => GrpcBlockStreamResponse::NewBlock(b.into()),
256            BlockStreamItem::Reorg(bs) => GrpcBlockStreamResponse::ReorganizedBlocks(bs.into()),
257        }
258    }
259}
260
261impl TryFrom<GrpcBlockStreamResponse> for BlockStreamItem {
262    type Error = MessageConversionError;
263
264    fn try_from(s: GrpcBlockStreamResponse) -> Result<Self, Self::Error> {
265        Ok(match s {
266            GrpcBlockStreamResponse::NewBlock(b) => BlockStreamItem::NewBlock(b.try_into()?),
267
268            GrpcBlockStreamResponse::ReorganizedBlocks(bs) => {
269                BlockStreamItem::Reorg(bs.try_into()?)
270            }
271        })
272    }
273}
274
275impl<T: Serialize> TryFrom<Vec<BlockState<T>>> for GrpcStates {
276    type Error = serde_json::Error;
277
278    fn try_from(bs: Vec<BlockState<T>>) -> Result<Self, Self::Error> {
279        let states: Result<_, _> = bs.into_iter().map(|x| x.try_into()).collect();
280        let states = states?;
281        Ok(GrpcStates { states })
282    }
283}
284
285impl<T: DeserializeOwned> TryFrom<GrpcStates> for Vec<BlockState<T>> {
286    type Error = StateConversionError;
287
288    fn try_from(bs: GrpcStates) -> Result<Self, Self::Error> {
289        let blocks_result: Vec<Result<BlockState<T>, _>> =
290            bs.states.into_iter().map(|x| x.try_into()).collect();
291
292        blocks_result.into_iter().collect()
293    }
294}
295
296impl From<Vec<Arc<Block>>> for GrpcBlocks {
297    fn from(bs: Vec<Arc<Block>>) -> Self {
298        let blocks: Vec<GrpcBlock> = bs.into_iter().map(|x| x.into()).collect();
299        GrpcBlocks { blocks }
300    }
301}
302
303impl TryFrom<GrpcBlocks> for Vec<Arc<Block>> {
304    type Error = MessageConversionError;
305
306    fn try_from(bs: GrpcBlocks) -> Result<Self, Self::Error> {
307        let blocks_result: Vec<Result<Arc<Block>, _>> =
308            bs.blocks.into_iter().map(|x| x.try_into()).collect();
309
310        blocks_result.into_iter().collect()
311    }
312}
313
314impl TryFrom<Id> for QueryBlock {
315    type Error = MessageConversionError;
316
317    fn try_from(i: Id) -> Result<Self, Self::Error> {
318        Ok(match i {
319            Id::Depth(d) => QueryBlock::BlockDepth(d as usize),
320
321            Id::BlockHash(h) => QueryBlock::BlockHash(h.try_into().context(MalformedSnafu)?),
322
323            Id::BlockNumber(n) => QueryBlock::BlockNumber(n.into()),
324        })
325    }
326}
327
328impl From<QueryBlock> for GrpcQueryBlock {
329    fn from(b: QueryBlock) -> Self {
330        let id = match b {
331            QueryBlock::BlockDepth(d) => Some(Id::Depth(d as u64)),
332
333            QueryBlock::BlockHash(h) => Some(Id::BlockHash(h.into())),
334
335            QueryBlock::BlockNumber(n) => Some(Id::BlockNumber(n.as_u64())),
336
337            QueryBlock::Block(b) => Some(Id::BlockHash(b.hash.into())),
338
339            QueryBlock::Latest => None,
340        };
341
342        Self { id }
343    }
344}
345
346impl TryFrom<GrpcQueryBlock> for QueryBlock {
347    type Error = MessageConversionError;
348
349    fn try_from(b: GrpcQueryBlock) -> Result<Self, Self::Error> {
350        Ok(match b.id {
351            Some(i) => i.try_into()?,
352            None => QueryBlock::Latest,
353        })
354    }
355}
356
357impl TryFrom<GrpcBlock> for Arc<Block> {
358    type Error = MessageConversionError;
359
360    fn try_from(b: GrpcBlock) -> Result<Self, Self::Error> {
361        let ret = Block {
362            hash: b
363                .hash
364                .ok_or(MessageNilError {
365                    message: "Block".to_owned(),
366                    field: "hash".to_owned(),
367                })
368                .context(NilSnafu)?
369                .try_into()
370                .context(MalformedSnafu)?,
371
372            number: b.number.into(),
373
374            parent_hash: b
375                .parent_hash
376                .ok_or(MessageNilError {
377                    message: "Block".to_owned(),
378                    field: "parent_hash".to_owned(),
379                })
380                .context(NilSnafu)?
381                .try_into()
382                .context(MalformedSnafu)?,
383
384            timestamp: b.timestamp.into(),
385
386            logs_bloom: b
387                .logs_bloom
388                .ok_or(MessageNilError {
389                    message: "Block".to_owned(),
390                    field: "logs_bloom".to_owned(),
391                })
392                .context(NilSnafu)?
393                .try_into()
394                .context(MalformedSnafu)?,
395        };
396
397        Ok(Arc::new(ret))
398    }
399}
400
401impl From<Arc<Block>> for GrpcBlock {
402    fn from(b: Arc<Block>) -> Self {
403        Self {
404            hash: Some(b.hash.into()),
405            number: b.number.as_u64(),
406            parent_hash: Some(b.parent_hash.into()),
407            timestamp: b.timestamp.as_u64(),
408            logs_bloom: Some(b.logs_bloom.into()),
409        }
410    }
411}
412
413impl TryFrom<Hash> for H256 {
414    type Error = MessageMalformedError;
415
416    fn try_from(h: Hash) -> Result<Self, Self::Error> {
417        let data = h.data;
418        let len = data.len();
419
420        if len != 32 {
421            return Err(MessageMalformedError {
422                message: "Block".to_owned(),
423                field: "data".to_owned(),
424                reason: format!("length of `{}` is different than 32", len),
425            });
426        }
427
428        Ok(H256::from_slice(&data))
429    }
430}
431
432impl From<H256> for Hash {
433    fn from(h: H256) -> Self {
434        Self {
435            data: h.to_fixed_bytes().into(),
436        }
437    }
438}
439
440impl TryFrom<GrpcBloom> for Bloom {
441    type Error = MessageMalformedError;
442
443    fn try_from(b: GrpcBloom) -> Result<Self, Self::Error> {
444        let data = b.data;
445        let len = data.len();
446
447        if len != 256 {
448            return Err(MessageMalformedError {
449                message: "Bloom".to_owned(),
450                field: "data".to_owned(),
451                reason: format!("length of `{}` is different than 256", len),
452            });
453        }
454
455        Ok(Bloom::from_slice(&data))
456    }
457}
458
459impl From<Bloom> for GrpcBloom {
460    fn from(b: Bloom) -> Self {
461        Self {
462            data: b.to_fixed_bytes().into(),
463        }
464    }
465}