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;
9use nom::{
11 bytes::complete::take,
12 error::{context, ContextError, ParseError},
13 multi::length_count,
14 sequence::tuple,
15 IResult, Parser,
16};
17use 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
29pub 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 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 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 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 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
102pub 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#[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 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 assert!(res.is_err());
356 }
357}