massa_event_cache/
ser_deser.rs

1use massa_models::async_msg_id::{
2    AsyncMessageId, AsyncMessageIdDeserializer, AsyncMessageIdSerializer,
3};
4use massa_models::deferred_calls::{
5    DeferredCallId, DeferredCallIdDeserializer, DeferredCallIdSerializer,
6};
7use std::collections::Bound::{Excluded, Included};
8use std::collections::VecDeque;
9// third-party
10use nom::{
11    bytes::complete::take,
12    error::{context, ContextError, ParseError},
13    multi::length_count,
14    sequence::tuple,
15    IResult, Parser,
16};
17// internal
18use massa_models::address::{AddressDeserializer, AddressSerializer};
19use massa_models::block_id::{BlockId, BlockIdDeserializer, BlockIdSerializer};
20use massa_models::operation::{OperationId, OperationIdDeserializer, OperationIdSerializer};
21use massa_models::output_event::{EventExecutionContext, SCOutputEvent};
22use massa_models::serialization::{StringDeserializer, StringSerializer};
23use massa_models::slot::{SlotDeserializer, SlotSerializer};
24use massa_serialization::{
25    Deserializer, OptionDeserializer, OptionSerializer, SerializeError, Serializer,
26    U32VarIntDeserializer, U32VarIntSerializer, U64VarIntDeserializer, U64VarIntSerializer,
27};
28
29/// Metadata serializer
30pub struct SCOutputEventSerializer {
31    index_in_slot_ser: U64VarIntSerializer,
32    addr_len_ser: U32VarIntSerializer,
33    slot_ser: SlotSerializer,
34    addr_ser: AddressSerializer,
35    block_id_ser: OptionSerializer<BlockId, BlockIdSerializer>,
36    op_id_ser: OptionSerializer<OperationId, OperationIdSerializer>,
37    data_ser: StringSerializer<U64VarIntSerializer, u64>,
38    deferred_call_id_ser: OptionSerializer<DeferredCallId, DeferredCallIdSerializer>,
39    async_msg_id_ser: OptionSerializer<AsyncMessageId, AsyncMessageIdSerializer>,
40}
41
42impl SCOutputEventSerializer {
43    pub fn new() -> Self {
44        Self {
45            index_in_slot_ser: U64VarIntSerializer::new(),
46            addr_len_ser: U32VarIntSerializer::new(),
47            slot_ser: SlotSerializer::new(),
48            addr_ser: AddressSerializer::new(),
49            block_id_ser: OptionSerializer::new(BlockIdSerializer::new()),
50            op_id_ser: OptionSerializer::new(OperationIdSerializer::new()),
51            data_ser: StringSerializer::new(U64VarIntSerializer::new()),
52            deferred_call_id_ser: OptionSerializer::new(DeferredCallIdSerializer::new()),
53            async_msg_id_ser: OptionSerializer::new(AsyncMessageIdSerializer::new()),
54        }
55    }
56}
57
58impl Default for SCOutputEventSerializer {
59    fn default() -> Self {
60        Self::new()
61    }
62}
63
64impl Serializer<SCOutputEvent> for SCOutputEventSerializer {
65    fn serialize(&self, value: &SCOutputEvent, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
66        // context
67        self.slot_ser.serialize(&value.context.slot, buffer)?;
68        self.block_id_ser.serialize(&value.context.block, buffer)?;
69        buffer.push(u8::from(value.context.read_only));
70        self.index_in_slot_ser
71            .serialize(&value.context.index_in_slot, buffer)?;
72        // Components
73        let call_stack_len_ = value.context.call_stack.len();
74        let call_stack_len = u32::try_from(call_stack_len_).map_err(|_| {
75            SerializeError::GeneralError(format!(
76                "Cannot convert component_len ({}) to u32",
77                call_stack_len_
78            ))
79        })?;
80        // ser vec len
81        self.addr_len_ser.serialize(&call_stack_len, buffer)?;
82        for address in value.context.call_stack.iter() {
83            self.addr_ser.serialize(address, buffer)?;
84        }
85        self.op_id_ser
86            .serialize(&value.context.origin_operation_id, buffer)?;
87        buffer.push(u8::from(value.context.is_final));
88        buffer.push(u8::from(value.context.is_error));
89
90        // data
91        self.data_ser.serialize(&value.data, buffer)?;
92
93        self.deferred_call_id_ser
94            .serialize(&value.context.deferred_call_id, buffer)?;
95        self.async_msg_id_ser
96            .serialize(&value.context.async_msg_id, buffer)?;
97
98        Ok(())
99    }
100}
101
102/// SCOutputEvent deserializer
103pub struct SCOutputEventDeserializer {
104    index_in_slot_deser: U64VarIntDeserializer,
105    addr_len_deser: U32VarIntDeserializer,
106    slot_deser: SlotDeserializer,
107    addr_deser: AddressDeserializer,
108    block_id_deser: OptionDeserializer<BlockId, BlockIdDeserializer>,
109    op_id_deser: OptionDeserializer<OperationId, OperationIdDeserializer>,
110    data_deser: StringDeserializer<U64VarIntDeserializer, u64>,
111    deferred_call_id_deser: OptionDeserializer<DeferredCallId, DeferredCallIdDeserializer>,
112    async_msg_id_deser: OptionDeserializer<AsyncMessageId, AsyncMessageIdDeserializer>,
113}
114
115impl SCOutputEventDeserializer {
116    pub fn new(args: SCOutputEventDeserializerArgs) -> Self {
117        Self {
118            index_in_slot_deser: U64VarIntDeserializer::new(Included(0), Included(u64::MAX)),
119            addr_len_deser: U32VarIntDeserializer::new(
120                Included(0),
121                Included(u32::from(args.max_call_stack_length)),
122            ),
123            slot_deser: SlotDeserializer::new(
124                (Included(0), Included(u64::MAX)),
125                (Included(0), Excluded(args.thread_count)),
126            ),
127            addr_deser: Default::default(),
128            block_id_deser: OptionDeserializer::new(BlockIdDeserializer::new()),
129            op_id_deser: OptionDeserializer::new(OperationIdDeserializer::new()),
130            data_deser: StringDeserializer::new(U64VarIntDeserializer::new(
131                Included(0),
132                Included(args.max_event_data_length),
133            )),
134            deferred_call_id_deser: OptionDeserializer::new(DeferredCallIdDeserializer::new()),
135            async_msg_id_deser: OptionDeserializer::new(AsyncMessageIdDeserializer::new(
136                args.thread_count,
137            )),
138        }
139    }
140}
141
142impl Deserializer<SCOutputEvent> for SCOutputEventDeserializer {
143    fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
144        &self,
145        buffer: &'a [u8],
146    ) -> IResult<&'a [u8], SCOutputEvent, E> {
147        context(
148            "Failed ScOutputEvent deserialization",
149            tuple((
150                context("Failed slot deserialization", |input| {
151                    self.slot_deser.deserialize(input)
152                }),
153                context("Failed BlockId deserialization", |input| {
154                    self.block_id_deser.deserialize(input)
155                }),
156                context("Failed read_only deserialization", |input: &'a [u8]| {
157                    let (rem, read_only) = take(1usize)(input)?;
158                    let read_only = match read_only.first() {
159                        None => {
160                            return IResult::Err(nom::Err::Error(ParseError::from_error_kind(
161                                input,
162                                nom::error::ErrorKind::Fail,
163                            )));
164                        }
165                        Some(0) => false,
166                        _ => true,
167                    };
168                    IResult::Ok((rem, read_only))
169                }),
170                context("Failed index_in_slot deser", |input| {
171                    self.index_in_slot_deser.deserialize(input)
172                }),
173                length_count(
174                    context("Failed call stack entry count deser", |input| {
175                        self.addr_len_deser.deserialize(input)
176                    }),
177                    context("Failed call stack items deser", |input| {
178                        self.addr_deser.deserialize(input)
179                    }),
180                ),
181                context("Failed OperationId deserialization", |input| {
182                    self.op_id_deser.deserialize(input)
183                }),
184                context("Failed is_final deserialization", |input: &'a [u8]| {
185                    let (rem, read_only) = take(1usize)(input)?;
186                    let read_only = match read_only.first() {
187                        None => {
188                            return IResult::Err(nom::Err::Error(ParseError::from_error_kind(
189                                input,
190                                nom::error::ErrorKind::Fail,
191                            )));
192                        }
193                        Some(0) => false,
194                        _ => true,
195                    };
196                    IResult::Ok((rem, read_only))
197                }),
198                context("Failed is_error deserialization", |input: &'a [u8]| {
199                    let (rem, read_only) = take(1usize)(input)?;
200                    let read_only = match read_only.first() {
201                        None => {
202                            return IResult::Err(nom::Err::Error(ParseError::from_error_kind(
203                                input,
204                                nom::error::ErrorKind::Fail,
205                            )));
206                        }
207                        Some(0) => false,
208                        _ => true,
209                    };
210                    IResult::Ok((rem, read_only))
211                }),
212                context("Failed data deserialization", |input| {
213                    self.data_deser.deserialize(input)
214                }),
215                context("Failed deferred call id deserialization", |input| {
216                    self.deferred_call_id_deser.deserialize(input)
217                }),
218                context("Failed async msg id deserialization", |input| {
219                    self.async_msg_id_deser.deserialize(input)
220                }),
221            )),
222        )
223        .map(
224            |(
225                slot,
226                bid,
227                read_only,
228                idx,
229                call_stack,
230                oid,
231                is_final,
232                is_error,
233                data,
234                deferred_call_id,
235                async_msg_id,
236            )| {
237                SCOutputEvent {
238                    context: EventExecutionContext {
239                        slot,
240                        block: bid,
241                        read_only,
242                        index_in_slot: idx,
243                        call_stack: VecDeque::from(call_stack),
244                        origin_operation_id: oid,
245                        is_final,
246                        is_error,
247                        deferred_call_id,
248                        async_msg_id,
249                    },
250                    data,
251                }
252            },
253        )
254        .parse(buffer)
255    }
256}
257
258/// SCOutputEvent deserializer args
259#[allow(missing_docs)]
260pub struct SCOutputEventDeserializerArgs {
261    pub thread_count: u8,
262    pub max_call_stack_length: u16,
263    pub max_event_data_length: u64,
264}
265
266#[cfg(test)]
267mod test {
268    use super::*;
269    use massa_models::slot::Slot;
270    use massa_serialization::DeserializeError;
271    use serial_test::serial;
272
273    #[test]
274    #[serial]
275    fn test_sc_output_event_ser_der() {
276        let slot_1 = Slot::new(1, 0);
277        let index_1_0 = 0;
278        let event = SCOutputEvent {
279            context: EventExecutionContext {
280                slot: slot_1,
281                block: None,
282                read_only: false,
283                index_in_slot: index_1_0,
284                call_stack: Default::default(),
285                origin_operation_id: None,
286                is_final: true,
287                is_error: false,
288                deferred_call_id: Some(
289                    massa_models::deferred_calls::DeferredCallId::new(0, Slot::new(1, 0), 1, &[])
290                        .unwrap(),
291                ),
292                async_msg_id: None,
293            },
294            data: "message foo bar".to_string(),
295        };
296
297        let event_ser = SCOutputEventSerializer::new();
298        let event_deser = SCOutputEventDeserializer::new(SCOutputEventDeserializerArgs {
299            thread_count: 16,
300            max_call_stack_length: 25,
301            max_event_data_length: 512,
302        });
303
304        let mut buffer = Vec::new();
305        event_ser.serialize(&event, &mut buffer).unwrap();
306
307        let (rem, event_new) = event_deser
308            .deserialize::<DeserializeError>(&buffer)
309            .unwrap();
310
311        assert_eq!(event.context, event_new.context);
312        assert_eq!(event.data, event_new.data);
313        assert_eq!(
314            event.context.deferred_call_id.unwrap().get_slot().unwrap(),
315            Slot::new(1, 0)
316        );
317        assert!(rem.is_empty());
318    }
319
320    #[test]
321    #[serial]
322    fn test_sc_output_event_ser_der_err() {
323        // Test serialization / deserialization with a slot with thread too high
324
325        let slot_1 = Slot::new(1, 99);
326        let index_1_0 = 0;
327        let event = SCOutputEvent {
328            context: EventExecutionContext {
329                slot: slot_1,
330                block: None,
331                read_only: false,
332                index_in_slot: index_1_0,
333                call_stack: Default::default(),
334                origin_operation_id: None,
335                is_final: true,
336                is_error: false,
337                deferred_call_id: None,
338                async_msg_id: None,
339            },
340            data: "message foo bar".to_string(),
341        };
342
343        let event_ser = SCOutputEventSerializer::new();
344        let event_deser = SCOutputEventDeserializer::new(SCOutputEventDeserializerArgs {
345            thread_count: 16,
346            max_call_stack_length: 25,
347            max_event_data_length: 512,
348        });
349
350        let mut buffer = Vec::new();
351        event_ser.serialize(&event, &mut buffer).unwrap();
352
353        let res = event_deser.deserialize::<DeserializeError>(&buffer);
354        // Expect deserialization to fail (slot thread too high)
355        assert!(res.is_err());
356    }
357}