massa_models/
async_msg.rs

1//! Copyright (c) 2022 MASSA LABS <info@massa.net>
2
3//! This file defines the structure representing an asynchronous message
4#![allow(missing_docs)]
5use crate::address::{AddressDeserializer, AddressSerializer};
6use crate::amount::{AmountDeserializer, AmountSerializer};
7use crate::async_msg_id::AsyncMessageId;
8use crate::config::GENESIS_KEY;
9use crate::serialization::{StringDeserializer, StringSerializer};
10use crate::slot::{SlotDeserializer, SlotSerializer};
11use crate::types::{Applicable, SetOrKeep, SetOrKeepDeserializer, SetOrKeepSerializer};
12use crate::{
13    address::Address,
14    amount::Amount,
15    serialization::{VecU8Deserializer, VecU8Serializer},
16    slot::Slot,
17};
18use massa_serialization::{
19    BoolDeserializer, BoolSerializer, Deserializer, OptionDeserializer, OptionSerializer,
20    SerializeError, Serializer, U16VarIntDeserializer, U16VarIntSerializer, U64VarIntDeserializer,
21    U64VarIntSerializer,
22};
23use nom::error::{context, ContextError, ParseError};
24use nom::sequence::tuple;
25use nom::{IResult, Parser};
26use num::rational::Ratio;
27use serde::{Deserialize, Serialize};
28use std::ops::Bound::{Excluded, Included};
29
30/// Structure defining a trigger for an asynchronous message
31#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
32pub struct AsyncMessageTrigger {
33    /// Filter on the address
34    pub address: Address,
35
36    /// Filter on the datastore key
37    pub datastore_key: Option<Vec<u8>>,
38}
39
40#[derive(Clone)]
41/// Serializer for a trigger for an asynchronous message
42pub struct AsyncMessageTriggerSerializer {
43    address_serializer: AddressSerializer,
44    key_serializer: OptionSerializer<Vec<u8>, VecU8Serializer>,
45}
46
47impl AsyncMessageTriggerSerializer {
48    pub fn new() -> Self {
49        Self {
50            address_serializer: AddressSerializer::new(),
51            key_serializer: OptionSerializer::new(VecU8Serializer::new()),
52        }
53    }
54}
55
56impl Default for AsyncMessageTriggerSerializer {
57    fn default() -> Self {
58        Self::new()
59    }
60}
61
62impl Serializer<AsyncMessageTrigger> for AsyncMessageTriggerSerializer {
63    fn serialize(
64        &self,
65        value: &AsyncMessageTrigger,
66        buffer: &mut Vec<u8>,
67    ) -> Result<(), SerializeError> {
68        self.address_serializer.serialize(&value.address, buffer)?;
69        self.key_serializer
70            .serialize(&value.datastore_key, buffer)?;
71        Ok(())
72    }
73}
74
75#[derive(Clone)]
76/// Deserializer for a trigger for an asynchronous message
77pub struct AsyncMessageTriggerDeserializer {
78    address_deserializer: AddressDeserializer,
79    key_serializer: OptionDeserializer<Vec<u8>, VecU8Deserializer>,
80}
81
82impl AsyncMessageTriggerDeserializer {
83    pub fn new(max_key_length: u32) -> Self {
84        Self {
85            address_deserializer: AddressDeserializer::new(),
86            key_serializer: OptionDeserializer::new(VecU8Deserializer::new(
87                Included(0),
88                Included(max_key_length as u64),
89            )),
90        }
91    }
92}
93
94impl Deserializer<AsyncMessageTrigger> for AsyncMessageTriggerDeserializer {
95    fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
96        &self,
97        buffer: &'a [u8],
98    ) -> IResult<&'a [u8], AsyncMessageTrigger, E> {
99        context(
100            "Failed AsyncMessageTrigger deserialization",
101            tuple((
102                context("Failed address deserialization", |input| {
103                    self.address_deserializer.deserialize(input)
104                }),
105                context("Failed datastore_key deserialization", |input| {
106                    self.key_serializer.deserialize(input)
107                }),
108            )),
109        )
110        .map(|(address, datastore_key)| AsyncMessageTrigger {
111            address,
112            datastore_key,
113        })
114        .parse(buffer)
115    }
116}
117
118/// Structure defining an asynchronous smart contract message
119#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
120pub struct AsyncMessage {
121    /// Slot at which the message was emitted
122    pub emission_slot: Slot,
123
124    /// Index of the emitted message within the `emission_slot`.
125    /// This is used for disambiguate the emission of multiple messages at the same slot.
126    pub emission_index: u64,
127
128    /// The address that sent the message
129    pub sender: Address,
130
131    /// The address towards which the message is being sent
132    pub destination: Address,
133
134    /// the function function name within the destination address' bytecode
135    pub function: String,
136
137    /// Maximum gas to use when processing the message
138    pub max_gas: u64,
139
140    /// Fee paid by the sender when the message is processed.
141    pub fee: Amount,
142
143    /// Coins sent from the sender to the target address of the message.
144    /// Those coins are spent by the sender address when the message is sent,
145    /// and credited to the destination address when receiving the message.
146    /// In case of failure or discard, those coins are reimbursed to the sender.
147    pub coins: Amount,
148
149    /// Slot at which the message starts being valid (bound included in the validity range)
150    pub validity_start: Slot,
151
152    /// Slot at which the message stops being valid (bound included in the validity range)
153    pub validity_end: Slot,
154
155    /// Raw payload parameters to call the function with
156    pub function_params: Vec<u8>,
157
158    /// Trigger that define whenever a message can be executed
159    pub trigger: Option<AsyncMessageTrigger>,
160
161    /// Boolean that determine if the message can be executed. For messages without filter this boolean is always true.
162    /// For messages with filter, this boolean is true if the filter has been matched at any slot up to
163    /// the current one, including before `validity_start`: arming is not restricted to the validity
164    /// interval, which only bounds execution. Once true, this boolean is never set back to false.
165    pub can_be_executed: bool,
166}
167
168impl Default for AsyncMessage {
169    #[allow(unconditional_recursion)]
170    fn default() -> Self {
171        let genesis_address = Address::from_public_key(&(*GENESIS_KEY).get_public_key());
172        let slot_zero = Slot::new(0, 0);
173        Self {
174            emission_slot: slot_zero,
175            sender: genesis_address,
176            destination: genesis_address,
177            validity_start: slot_zero,
178            validity_end: slot_zero,
179            ..Default::default()
180        }
181    }
182}
183
184impl AsyncMessage {
185    #[allow(clippy::too_many_arguments)]
186    /// Take an `AsyncMessage` and return it
187    pub fn new(
188        emission_slot: Slot,
189        emission_index: u64,
190        sender: Address,
191        destination: Address,
192        function: String,
193        max_gas: u64,
194        fee: Amount,
195        coins: Amount,
196        validity_start: Slot,
197        validity_end: Slot,
198        function_params: Vec<u8>,
199        trigger: Option<AsyncMessageTrigger>,
200        can_be_executed: Option<bool>,
201    ) -> Self {
202        AsyncMessage {
203            emission_slot,
204            emission_index,
205            sender,
206            destination,
207            function,
208            max_gas,
209            fee,
210            coins,
211            validity_start,
212            validity_end,
213            function_params,
214            can_be_executed: can_be_executed.unwrap_or(trigger.is_none()),
215            trigger,
216        }
217    }
218
219    /// Compute the ID of the message for use when choosing which operations to keep in priority (highest score) on pool overflow.
220    pub fn compute_id(&self) -> AsyncMessageId {
221        let denom = if self.max_gas > 0 { self.max_gas } else { 1 };
222        (
223            std::cmp::Reverse(Ratio::new(self.fee.to_raw(), denom)),
224            self.emission_slot,
225            self.emission_index,
226        )
227    }
228}
229
230#[derive(Clone)]
231pub struct AsyncMessageSerializer {
232    pub slot_serializer: SlotSerializer,
233    pub function_serializer: StringSerializer<U16VarIntSerializer, u16>,
234    pub amount_serializer: AmountSerializer,
235    pub u64_serializer: U64VarIntSerializer,
236    pub function_params_serializer: VecU8Serializer,
237    pub address_serializer: AddressSerializer,
238    pub trigger_serializer: OptionSerializer<AsyncMessageTrigger, AsyncMessageTriggerSerializer>,
239    pub bool_serializer: BoolSerializer,
240    pub for_db: bool,
241}
242
243impl AsyncMessageSerializer {
244    pub fn new(for_db: bool) -> Self {
245        Self {
246            slot_serializer: SlotSerializer::new(),
247            amount_serializer: AmountSerializer::new(),
248            u64_serializer: U64VarIntSerializer::new(),
249            function_serializer: StringSerializer::new(U16VarIntSerializer::new()),
250            function_params_serializer: VecU8Serializer::new(),
251            address_serializer: AddressSerializer::new(),
252            trigger_serializer: OptionSerializer::new(AsyncMessageTriggerSerializer::new()),
253            bool_serializer: BoolSerializer::new(),
254            for_db,
255        }
256    }
257}
258
259impl Default for AsyncMessageSerializer {
260    fn default() -> Self {
261        Self::new(false)
262    }
263}
264
265impl Serializer<AsyncMessage> for AsyncMessageSerializer {
266    /// ## Example
267    /// ```
268    /// use massa_models::{address::Address, amount::Amount, slot::Slot, async_msg::{AsyncMessage, AsyncMessageSerializer, AsyncMessageTrigger}};
269    /// use massa_serialization::Serializer;
270    /// use std::str::FromStr;
271    ///
272    /// let message = AsyncMessage::new(
273    ///     Slot::new(1, 0),
274    ///     0,
275    ///     Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x").unwrap(),
276    ///     Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G").unwrap(),
277    ///     String::from("test"),
278    ///     10000000,
279    ///     Amount::from_str("1").unwrap(),
280    ///     Amount::from_str("1").unwrap(),
281    ///     Slot::new(2, 0),
282    ///     Slot::new(3, 0),
283    ///     vec![1, 2, 3, 4],
284    ///     Some(AsyncMessageTrigger {
285    ///         address: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x").unwrap(),
286    ///         datastore_key: Some(vec![1, 2, 3, 4])
287    ///     }),
288    ///     None,
289    /// );
290    /// let mut buffer = Vec::new();
291    /// let message_serializer = AsyncMessageSerializer::new(false);
292    /// message_serializer.serialize(&message, &mut buffer).unwrap();
293    /// ```
294    fn serialize(
295        &self,
296        value: &AsyncMessage,
297        buffer: &mut Vec<u8>,
298    ) -> Result<(), massa_serialization::SerializeError> {
299        self.slot_serializer
300            .serialize(&value.emission_slot, buffer)?;
301        self.u64_serializer
302            .serialize(&value.emission_index, buffer)?;
303        self.address_serializer.serialize(&value.sender, buffer)?;
304        self.address_serializer
305            .serialize(&value.destination, buffer)?;
306        self.function_serializer
307            .serialize(&value.function, buffer)?;
308        self.u64_serializer.serialize(&value.max_gas, buffer)?;
309        self.amount_serializer.serialize(&value.fee, buffer)?;
310        self.amount_serializer.serialize(&value.coins, buffer)?;
311        self.slot_serializer
312            .serialize(&value.validity_start, buffer)?;
313        self.slot_serializer
314            .serialize(&value.validity_end, buffer)?;
315        self.function_params_serializer
316            .serialize(&value.function_params, buffer)?;
317        self.trigger_serializer.serialize(&value.trigger, buffer)?;
318        if self.for_db {
319            self.bool_serializer
320                .serialize(&value.can_be_executed, buffer)?;
321        }
322        Ok(())
323    }
324}
325
326#[derive(Clone)]
327pub struct AsyncMessageDeserializer {
328    pub slot_deserializer: SlotDeserializer,
329    pub amount_deserializer: AmountDeserializer,
330    pub emission_index_deserializer: U64VarIntDeserializer,
331    pub max_gas_deserializer: U64VarIntDeserializer,
332    pub function_deserializer: StringDeserializer<U16VarIntDeserializer, u16>,
333    pub function_params_deserializer: VecU8Deserializer,
334    pub address_deserializer: AddressDeserializer,
335    pub trigger_deserializer:
336        OptionDeserializer<AsyncMessageTrigger, AsyncMessageTriggerDeserializer>,
337    pub bool_deserializer: BoolDeserializer,
338    pub for_db: bool,
339}
340
341impl AsyncMessageDeserializer {
342    pub fn new(
343        thread_count: u8,
344        max_function_length: u16,
345        max_function_params_length: u64,
346        max_key_length: u32,
347        for_db: bool,
348    ) -> Self {
349        Self {
350            slot_deserializer: SlotDeserializer::new(
351                (Included(0), Included(u64::MAX)),
352                (Included(0), Excluded(thread_count)),
353            ),
354            amount_deserializer: AmountDeserializer::new(
355                Included(Amount::MIN),
356                Included(Amount::MAX),
357            ),
358            emission_index_deserializer: U64VarIntDeserializer::new(
359                Included(0),
360                Included(u64::MAX),
361            ),
362            max_gas_deserializer: U64VarIntDeserializer::new(Included(0), Included(u64::MAX)),
363            function_deserializer: StringDeserializer::new(U16VarIntDeserializer::new(
364                Included(0),
365                Included(max_function_length),
366            )),
367            function_params_deserializer: VecU8Deserializer::new(
368                Included(0),
369                Included(max_function_params_length),
370            ),
371            address_deserializer: AddressDeserializer::new(),
372            trigger_deserializer: OptionDeserializer::new(AsyncMessageTriggerDeserializer::new(
373                max_key_length,
374            )),
375            bool_deserializer: BoolDeserializer::new(),
376            for_db,
377        }
378    }
379}
380
381impl Deserializer<AsyncMessage> for AsyncMessageDeserializer {
382    /// ## Example
383    /// ```
384    /// use massa_models::{address::Address, amount::Amount, slot::Slot, async_msg::{AsyncMessage, AsyncMessageSerializer, AsyncMessageDeserializer, AsyncMessageTrigger}};
385    /// use massa_serialization::{Serializer, Deserializer, DeserializeError};
386    /// use std::str::FromStr;
387    ///
388    /// let message = AsyncMessage::new(
389    ///     Slot::new(1, 0),
390    ///     0,
391    ///     Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x").unwrap(),
392    ///     Address::from_str("AS12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G").unwrap(),
393    ///     String::from("test"),
394    ///     10000000,
395    ///     Amount::from_str("1").unwrap(),
396    ///     Amount::from_str("1").unwrap(),
397    ///     Slot::new(2, 0),
398    ///     Slot::new(3, 0),
399    ///     vec![1, 2, 3, 4],
400    ///     Some(AsyncMessageTrigger {
401    ///        address: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x").unwrap(),
402    ///        datastore_key: Some(vec![1, 2, 3, 4]),
403    ///     }),
404    ///     None,
405    /// );
406    /// let message_serializer = AsyncMessageSerializer::new(false);
407    /// let mut serialized = Vec::new();
408    /// message_serializer.serialize(&message, &mut serialized).unwrap();
409    /// let message_deserializer = AsyncMessageDeserializer::new(32, 10000, 100000, 255, false);
410    /// // dbg!(&serialized);
411    /// let (rest, message_deserialized) = message_deserializer.deserialize::<DeserializeError>(&serialized).unwrap();
412    /// assert!(rest.is_empty());
413    /// assert_eq!(message, message_deserialized);
414    /// ```
415    fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
416        &self,
417        buffer: &'a [u8],
418    ) -> IResult<&'a [u8], AsyncMessage, E> {
419        context(
420            "Failed AsyncMessage deserialization",
421            tuple((
422                context("Failed emission_slot deserialization", |input| {
423                    self.slot_deserializer.deserialize(input)
424                }),
425                context("Failed emission_index deserialization", |input| {
426                    self.emission_index_deserializer.deserialize(input)
427                }),
428                context("Failed sender deserialization", |input| {
429                    self.address_deserializer.deserialize(input)
430                }),
431                context("Failed destination deserialization", |input| {
432                    self.address_deserializer.deserialize(input)
433                }),
434                context("Failed function deserialization", |input| {
435                    self.function_deserializer.deserialize(input)
436                }),
437                context("Failed max_gas deserialization", |input| {
438                    self.max_gas_deserializer.deserialize(input)
439                }),
440                context("Failed fee deserialization", |input| {
441                    self.amount_deserializer.deserialize(input)
442                }),
443                context("Failed coins deserialization", |input| {
444                    self.amount_deserializer.deserialize(input)
445                }),
446                context("Failed validity_start deserialization", |input| {
447                    self.slot_deserializer.deserialize(input)
448                }),
449                context("Failed validity_end deserialization", |input| {
450                    self.slot_deserializer.deserialize(input)
451                }),
452                context("Failed data deserialization", |input| {
453                    self.function_params_deserializer.deserialize(input)
454                }),
455                context("Failed filter deserialization", |input| {
456                    self.trigger_deserializer.deserialize(input)
457                }),
458                context("Failed can_be_executed deserialization", |input| {
459                    if self.for_db {
460                        self.bool_deserializer.deserialize(input)
461                    } else {
462                        Ok((input, false))
463                    }
464                }),
465            )),
466        )
467        .map(
468            |(
469                emission_slot,
470                emission_index,
471                sender,
472                destination,
473                function,
474                max_gas,
475                fee,
476                coins,
477                validity_start,
478                validity_end,
479                function_params,
480                filter,
481                can_be_executed,
482            )| {
483                AsyncMessage::new(
484                    emission_slot,
485                    emission_index,
486                    sender,
487                    destination,
488                    function,
489                    max_gas,
490                    fee,
491                    coins,
492                    validity_start,
493                    validity_end,
494                    function_params,
495                    filter,
496                    if self.for_db {
497                        Some(can_be_executed)
498                    } else {
499                        None
500                    },
501                )
502            },
503        )
504        .parse(buffer)
505    }
506}
507
508/// represents an update to one or more fields of a `AsyncMessage`
509#[derive(Default, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
510pub struct AsyncMessageUpdate {
511    /// Slot at which the message was emitted
512    pub emission_slot: SetOrKeep<Slot>,
513
514    /// Index of the emitted message within the `emission_slot`.
515    /// This is used for disambiguate the emission of multiple messages at the same slot.
516    pub emission_index: SetOrKeep<u64>,
517
518    /// The address that sent the message
519    pub sender: SetOrKeep<Address>,
520
521    /// The address towards which the message is being sent
522    pub destination: SetOrKeep<Address>,
523
524    /// the function function name within the destination address' bytecode
525    pub function: SetOrKeep<String>,
526
527    /// Maximum gas to use when processing the message
528    pub max_gas: SetOrKeep<u64>,
529
530    /// Fee paid by the sender when the message is processed.
531    pub fee: SetOrKeep<Amount>,
532
533    /// Coins sent from the sender to the target address of the message.
534    /// Those coins are spent by the sender address when the message is sent,
535    /// and credited to the destination address when receiving the message.
536    /// In case of failure or discard, those coins are reimbursed to the sender.
537    pub coins: SetOrKeep<Amount>,
538
539    /// Slot at which the message starts being valid (bound included in the validity range)
540    pub validity_start: SetOrKeep<Slot>,
541
542    /// Slot at which the message stops being valid (bound not included in the validity range)
543    pub validity_end: SetOrKeep<Slot>,
544
545    /// Raw payload parameters to call the function with
546    pub function_params: SetOrKeep<Vec<u8>>,
547
548    /// Trigger that define whenever a message can be executed
549    pub trigger: SetOrKeep<Option<AsyncMessageTrigger>>,
550
551    /// Boolean that determine if the message can be executed. For messages without filter this boolean is always true.
552    /// For messages with filter, this boolean is true if the filter has been matched at any slot up to
553    /// the current one, including before `validity_start`: arming is not restricted to the validity
554    /// interval, which only bounds execution. Once true, this boolean is never set back to false.
555    pub can_be_executed: SetOrKeep<bool>,
556}
557
558/// Serializer for `AsyncMessageUpdate`
559pub struct AsyncMessageUpdateSerializer {
560    slot_serializer: SetOrKeepSerializer<Slot, SlotSerializer>,
561    amount_serializer: SetOrKeepSerializer<Amount, AmountSerializer>,
562    u64_serializer: SetOrKeepSerializer<u64, U64VarIntSerializer>,
563    function_serializer: SetOrKeepSerializer<String, StringSerializer<U16VarIntSerializer, u16>>,
564    function_params_serializer: SetOrKeepSerializer<Vec<u8>, VecU8Serializer>,
565    address_serializer: SetOrKeepSerializer<Address, AddressSerializer>,
566    trigger_serializer: SetOrKeepSerializer<
567        Option<AsyncMessageTrigger>,
568        OptionSerializer<AsyncMessageTrigger, AsyncMessageTriggerSerializer>,
569    >,
570    bool_serializer: SetOrKeepSerializer<bool, BoolSerializer>,
571    for_db: bool,
572}
573
574impl AsyncMessageUpdateSerializer {
575    /// Creates a new `AsyncMessageUpdateSerializer`
576    pub fn new(for_db: bool) -> Self {
577        Self {
578            slot_serializer: SetOrKeepSerializer::new(SlotSerializer::new()),
579            amount_serializer: SetOrKeepSerializer::new(AmountSerializer::new()),
580            u64_serializer: SetOrKeepSerializer::new(U64VarIntSerializer::new()),
581            function_serializer: SetOrKeepSerializer::new(StringSerializer::new(
582                U16VarIntSerializer::new(),
583            )),
584            function_params_serializer: SetOrKeepSerializer::new(VecU8Serializer::new()),
585            address_serializer: SetOrKeepSerializer::new(AddressSerializer::new()),
586            trigger_serializer: SetOrKeepSerializer::new(OptionSerializer::new(
587                AsyncMessageTriggerSerializer::new(),
588            )),
589            bool_serializer: SetOrKeepSerializer::new(BoolSerializer::new()),
590            for_db,
591        }
592    }
593}
594
595impl Default for AsyncMessageUpdateSerializer {
596    fn default() -> Self {
597        Self::new(false)
598    }
599}
600
601impl Serializer<AsyncMessageUpdate> for AsyncMessageUpdateSerializer {
602    fn serialize(
603        &self,
604        value: &AsyncMessageUpdate,
605        buffer: &mut Vec<u8>,
606    ) -> Result<(), SerializeError> {
607        self.slot_serializer
608            .serialize(&value.emission_slot, buffer)?;
609        self.u64_serializer
610            .serialize(&value.emission_index, buffer)?;
611        self.address_serializer.serialize(&value.sender, buffer)?;
612        self.address_serializer
613            .serialize(&value.destination, buffer)?;
614        self.function_serializer
615            .serialize(&value.function, buffer)?;
616        self.u64_serializer.serialize(&value.max_gas, buffer)?;
617        self.amount_serializer.serialize(&value.fee, buffer)?;
618        self.amount_serializer.serialize(&value.coins, buffer)?;
619        self.slot_serializer
620            .serialize(&value.validity_start, buffer)?;
621        self.slot_serializer
622            .serialize(&value.validity_end, buffer)?;
623        self.function_params_serializer
624            .serialize(&value.function_params, buffer)?;
625        self.trigger_serializer.serialize(&value.trigger, buffer)?;
626        if self.for_db {
627            self.bool_serializer
628                .serialize(&value.can_be_executed, buffer)?;
629        }
630        Ok(())
631    }
632}
633
634/// Deserializer for `AsyncMessageUpdate`
635pub struct AsyncMessageUpdateDeserializer {
636    slot_deserializer: SetOrKeepDeserializer<Slot, SlotDeserializer>,
637    amount_deserializer: SetOrKeepDeserializer<Amount, AmountDeserializer>,
638    emission_index_deserializer: SetOrKeepDeserializer<u64, U64VarIntDeserializer>,
639    max_gas_deserializer: SetOrKeepDeserializer<u64, U64VarIntDeserializer>,
640    function_deserializer:
641        SetOrKeepDeserializer<String, StringDeserializer<U16VarIntDeserializer, u16>>,
642    function_params_deserializer: SetOrKeepDeserializer<Vec<u8>, VecU8Deserializer>,
643    address_deserializer: SetOrKeepDeserializer<Address, AddressDeserializer>,
644    trigger_deserializer: SetOrKeepDeserializer<
645        Option<AsyncMessageTrigger>,
646        OptionDeserializer<AsyncMessageTrigger, AsyncMessageTriggerDeserializer>,
647    >,
648    bool_deserializer: SetOrKeepDeserializer<bool, BoolDeserializer>,
649    for_db: bool,
650}
651
652impl AsyncMessageUpdateDeserializer {
653    /// Creates a new `AsyncMessageUpdateDeserializer`
654    pub fn new(
655        thread_count: u8,
656        max_function_length: u16,
657        max_function_params_length: u64,
658        max_key_length: u32,
659        for_db: bool,
660    ) -> Self {
661        Self {
662            slot_deserializer: SetOrKeepDeserializer::new(SlotDeserializer::new(
663                (Included(0), Included(u64::MAX)),
664                (Included(0), Excluded(thread_count)),
665            )),
666            amount_deserializer: SetOrKeepDeserializer::new(AmountDeserializer::new(
667                Included(Amount::MIN),
668                Included(Amount::MAX),
669            )),
670            emission_index_deserializer: SetOrKeepDeserializer::new(U64VarIntDeserializer::new(
671                Included(0),
672                Included(u64::MAX),
673            )),
674            max_gas_deserializer: SetOrKeepDeserializer::new(U64VarIntDeserializer::new(
675                Included(0),
676                Included(u64::MAX),
677            )),
678            function_deserializer: SetOrKeepDeserializer::new(StringDeserializer::new(
679                U16VarIntDeserializer::new(Included(0), Included(max_function_length)),
680            )),
681            function_params_deserializer: SetOrKeepDeserializer::new(VecU8Deserializer::new(
682                Included(0),
683                Included(max_function_params_length),
684            )),
685            address_deserializer: SetOrKeepDeserializer::new(AddressDeserializer::new()),
686            trigger_deserializer: SetOrKeepDeserializer::new(OptionDeserializer::new(
687                AsyncMessageTriggerDeserializer::new(max_key_length),
688            )),
689            bool_deserializer: SetOrKeepDeserializer::new(BoolDeserializer::new()),
690            for_db,
691        }
692    }
693}
694
695impl Deserializer<AsyncMessageUpdate> for AsyncMessageUpdateDeserializer {
696    fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
697        &self,
698        buffer: &'a [u8],
699    ) -> IResult<&'a [u8], AsyncMessageUpdate, E> {
700        context(
701            "Failed AsyncMessageUpdate deserialization",
702            tuple((
703                context("Failed emission_slot deserialization", |input| {
704                    self.slot_deserializer.deserialize(input)
705                }),
706                context("Failed emission_index deserialization", |input| {
707                    self.emission_index_deserializer.deserialize(input)
708                }),
709                context("Failed sender deserialization", |input| {
710                    self.address_deserializer.deserialize(input)
711                }),
712                context("Failed destination deserialization", |input| {
713                    self.address_deserializer.deserialize(input)
714                }),
715                context("Failed function deserialization", |input| {
716                    self.function_deserializer.deserialize(input)
717                }),
718                context("Failed max_gas deserialization", |input| {
719                    self.max_gas_deserializer.deserialize(input)
720                }),
721                context("Failed fee deserialization", |input| {
722                    self.amount_deserializer.deserialize(input)
723                }),
724                context("Failed coins deserialization", |input| {
725                    self.amount_deserializer.deserialize(input)
726                }),
727                context("Failed validity_start deserialization", |input| {
728                    self.slot_deserializer.deserialize(input)
729                }),
730                context("Failed validity_end deserialization", |input| {
731                    self.slot_deserializer.deserialize(input)
732                }),
733                context("Failed function_params deserialization", |input| {
734                    self.function_params_deserializer.deserialize(input)
735                }),
736                context("Failed filter deserialization", |input| {
737                    self.trigger_deserializer.deserialize(input)
738                }),
739                context("Failed can_be_executed deserialization", |input| {
740                    if self.for_db {
741                        self.bool_deserializer.deserialize(input)
742                    } else {
743                        Ok((input, SetOrKeep::Keep))
744                    }
745                }),
746            )),
747        )
748        .map(
749            |(
750                emission_slot,
751                emission_index,
752                sender,
753                destination,
754                function,
755                max_gas,
756                fee,
757                coins,
758                validity_start,
759                validity_end,
760                function_params,
761                trigger,
762                can_be_executed,
763            )| {
764                AsyncMessageUpdate {
765                    emission_slot,
766                    emission_index,
767                    sender,
768                    destination,
769                    function,
770                    max_gas,
771                    fee,
772                    coins,
773                    validity_start,
774                    validity_end,
775                    function_params,
776                    trigger,
777                    can_be_executed,
778                }
779            },
780        )
781        .parse(buffer)
782    }
783}
784
785impl Applicable<AsyncMessageUpdate> for AsyncMessageUpdate {
786    /// extends the `AsyncMessageUpdate` with another one
787    fn apply(&mut self, update: AsyncMessageUpdate) {
788        self.emission_slot.apply(update.emission_slot);
789        self.emission_index.apply(update.emission_index);
790        self.sender.apply(update.sender);
791        self.destination.apply(update.destination);
792        self.function.apply(update.function);
793        self.max_gas.apply(update.max_gas);
794        self.fee.apply(update.fee);
795        self.coins.apply(update.coins);
796        self.validity_start.apply(update.validity_start);
797        self.validity_end.apply(update.validity_end);
798        self.function_params.apply(update.function_params);
799        self.trigger.apply(update.trigger);
800        self.can_be_executed.apply(update.can_be_executed);
801    }
802}
803
804impl Applicable<AsyncMessageUpdate> for AsyncMessage {
805    /// extends the `AsyncMessage` with a `AsyncMessageUpdate`
806    fn apply(&mut self, update: AsyncMessageUpdate) {
807        update.emission_slot.apply_to(&mut self.emission_slot);
808        update.emission_index.apply_to(&mut self.emission_index);
809        update.sender.apply_to(&mut self.sender);
810        update.destination.apply_to(&mut self.destination);
811        update.function.apply_to(&mut self.function);
812        update.max_gas.apply_to(&mut self.max_gas);
813        update.fee.apply_to(&mut self.fee);
814        update.coins.apply_to(&mut self.coins);
815        update.validity_start.apply_to(&mut self.validity_start);
816        update.validity_end.apply_to(&mut self.validity_end);
817        update.function_params.apply_to(&mut self.function_params);
818        update.trigger.apply_to(&mut self.trigger);
819        update.can_be_executed.apply_to(&mut self.can_be_executed);
820    }
821}
822
823#[cfg(test)]
824mod tests {
825    use crate::{
826        async_msg::{
827            AsyncMessage, AsyncMessageDeserializer, AsyncMessageSerializer, AsyncMessageTrigger,
828            AsyncMessageUpdate, AsyncMessageUpdateDeserializer, AsyncMessageUpdateSerializer,
829        },
830        async_msg_id::{AsyncMessageId, AsyncMessageIdDeserializer, AsyncMessageIdSerializer},
831        types::{Applicable, SetOrKeep},
832    };
833    use massa_serialization::{DeserializeError, Deserializer, Serializer};
834    use num::rational::Ratio;
835
836    use crate::{
837        address::Address,
838        amount::Amount,
839        config::{
840            MAX_DATASTORE_KEY_LENGTH, MAX_FUNCTION_NAME_LENGTH, MAX_PARAMETERS_SIZE, THREAD_COUNT,
841        },
842        slot::Slot,
843    };
844    use std::str::FromStr;
845
846    #[test]
847    fn no_apply_update_message() {
848        // Init an AsyncMessage, try to apply an update (with no modifications at all)
849        // Original async message and 'updated' async message should be ==
850
851        let mut msg = AsyncMessage {
852            emission_slot: Slot::new(0, 0),
853            emission_index: 0,
854            sender: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
855                .unwrap(),
856            destination: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
857                .unwrap(),
858            function: String::from(""),
859            max_gas: 0,
860            fee: Amount::from_str("0").unwrap(),
861            coins: Amount::from_str("0").unwrap(),
862            validity_start: Slot::new(0, 0),
863            validity_end: Slot::new(0, 0),
864            function_params: vec![],
865            trigger: None,
866            can_be_executed: false,
867        };
868        let old_message = msg.clone();
869
870        let update = AsyncMessageUpdate {
871            emission_slot: SetOrKeep::Keep,
872            emission_index: SetOrKeep::Keep,
873            sender: SetOrKeep::Keep,
874            destination: SetOrKeep::Keep,
875            function: SetOrKeep::Keep,
876            max_gas: SetOrKeep::Keep,
877            fee: SetOrKeep::Keep,
878            coins: SetOrKeep::Keep,
879            validity_start: SetOrKeep::Keep,
880            validity_end: SetOrKeep::Keep,
881            function_params: SetOrKeep::Keep,
882            trigger: SetOrKeep::Keep,
883            can_be_executed: SetOrKeep::Keep,
884        };
885        msg.apply(update);
886        assert_eq!(old_message, msg);
887    }
888
889    #[test]
890    fn apply_update_message() {
891        // Init an AsyncMessage, try to apply an update (with modifications for all fields)
892        // Original async message and 'updated' async message should be !=
893
894        let mut msg = AsyncMessage {
895            emission_slot: Slot::new(0, 0),
896            emission_index: 0,
897            sender: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
898                .unwrap(),
899            destination: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
900                .unwrap(),
901            function: String::from(""),
902            max_gas: 0,
903            fee: Amount::from_str("0").unwrap(),
904            coins: Amount::from_str("0").unwrap(),
905            validity_start: Slot::new(0, 0),
906            validity_end: Slot::new(0, 0),
907            function_params: vec![],
908            trigger: None,
909            can_be_executed: false,
910        };
911        let old_message = msg.clone();
912
913        let update = AsyncMessageUpdate {
914            emission_slot: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
915            emission_index: SetOrKeep::Set(u64::MAX),
916            sender: SetOrKeep::Set(
917                Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x").unwrap(),
918            ),
919            destination: SetOrKeep::Set(
920                Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G").unwrap(),
921            ),
922            function: SetOrKeep::Set(
923                (0..MAX_FUNCTION_NAME_LENGTH)
924                    .map(|_| "X")
925                    .collect::<String>(),
926            ),
927            max_gas: SetOrKeep::Set(u64::MAX),
928            fee: SetOrKeep::Set(Amount::from_raw(u64::MAX)),
929            coins: SetOrKeep::Set(Amount::from_raw(u64::MAX)),
930            validity_start: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
931            validity_end: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
932            function_params: SetOrKeep::Set(vec![0; MAX_PARAMETERS_SIZE as usize]),
933            trigger: SetOrKeep::Set(Some(AsyncMessageTrigger {
934                address: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
935                    .unwrap(),
936                datastore_key: Some(vec![0; MAX_DATASTORE_KEY_LENGTH as usize]),
937            })),
938            can_be_executed: SetOrKeep::Set(true),
939        };
940        msg.apply(update);
941
942        assert_ne!(old_message, msg);
943
944        let new_msg = AsyncMessage {
945            emission_slot: Slot::new(u64::MAX, THREAD_COUNT - 1),
946            emission_index: u64::MAX,
947            sender: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
948                .unwrap(),
949            destination: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
950                .unwrap(),
951            function: (0..MAX_FUNCTION_NAME_LENGTH)
952                .map(|_| "X")
953                .collect::<String>(),
954            max_gas: u64::MAX,
955            fee: Amount::from_raw(u64::MAX),
956            coins: Amount::from_raw(u64::MAX),
957            validity_start: Slot::new(u64::MAX, THREAD_COUNT - 1),
958            validity_end: Slot::new(u64::MAX, THREAD_COUNT - 1),
959            function_params: vec![0; MAX_PARAMETERS_SIZE as usize],
960            trigger: Some(AsyncMessageTrigger {
961                address: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
962                    .unwrap(),
963                datastore_key: Some(vec![0; MAX_DATASTORE_KEY_LENGTH as usize]),
964            }),
965            can_be_executed: true,
966        };
967        assert_eq!(new_msg, msg);
968    }
969
970    #[test]
971    fn apply_update_on_update_message() {
972        // Apply AsyncMessageUpdate on a AsyncMessageUpdate then apply to an AsyncMessage
973
974        let mut msg = AsyncMessage {
975            emission_slot: Slot::new(0, 0),
976            emission_index: 0,
977            sender: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
978                .unwrap(),
979            destination: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
980                .unwrap(),
981            function: String::from(""),
982            max_gas: 0,
983            fee: Amount::from_str("0").unwrap(),
984            coins: Amount::from_str("0").unwrap(),
985            validity_start: Slot::new(0, 0),
986            validity_end: Slot::new(0, 0),
987            function_params: vec![],
988            trigger: None,
989            can_be_executed: false,
990        };
991
992        let mut update = AsyncMessageUpdate {
993            emission_slot: SetOrKeep::Keep,
994            emission_index: SetOrKeep::Keep,
995            sender: SetOrKeep::Keep,
996            destination: SetOrKeep::Keep,
997            function: SetOrKeep::Keep,
998            max_gas: SetOrKeep::Keep,
999            fee: SetOrKeep::Keep,
1000            coins: SetOrKeep::Keep,
1001            validity_start: SetOrKeep::Keep,
1002            validity_end: SetOrKeep::Keep,
1003            function_params: SetOrKeep::Keep,
1004            trigger: SetOrKeep::Keep,
1005            can_be_executed: SetOrKeep::Keep,
1006        };
1007
1008        let update_update = AsyncMessageUpdate {
1009            emission_slot: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
1010            emission_index: SetOrKeep::Set(u64::MAX),
1011            sender: SetOrKeep::Set(
1012                Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x").unwrap(),
1013            ),
1014            destination: SetOrKeep::Set(
1015                Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G").unwrap(),
1016            ),
1017            function: SetOrKeep::Set(
1018                (0..MAX_FUNCTION_NAME_LENGTH)
1019                    .map(|_| "X")
1020                    .collect::<String>(),
1021            ),
1022            max_gas: SetOrKeep::Set(u64::MAX),
1023            fee: SetOrKeep::Set(Amount::from_raw(u64::MAX)),
1024            coins: SetOrKeep::Set(Amount::from_raw(u64::MAX)),
1025            validity_start: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
1026            validity_end: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
1027            function_params: SetOrKeep::Set(vec![0; MAX_PARAMETERS_SIZE as usize]),
1028            trigger: SetOrKeep::Set(Some(AsyncMessageTrigger {
1029                address: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
1030                    .unwrap(),
1031                datastore_key: Some(vec![0; MAX_DATASTORE_KEY_LENGTH as usize]),
1032            })),
1033            can_be_executed: SetOrKeep::Set(true),
1034        };
1035
1036        update.apply(update_update);
1037
1038        msg.apply(update);
1039
1040        let new_msg = AsyncMessage {
1041            emission_slot: Slot::new(u64::MAX, THREAD_COUNT - 1),
1042            emission_index: u64::MAX,
1043            sender: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
1044                .unwrap(),
1045            destination: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
1046                .unwrap(),
1047            function: (0..MAX_FUNCTION_NAME_LENGTH)
1048                .map(|_| "X")
1049                .collect::<String>(),
1050            max_gas: u64::MAX,
1051            fee: Amount::from_raw(u64::MAX),
1052            coins: Amount::from_raw(u64::MAX),
1053            validity_start: Slot::new(u64::MAX, THREAD_COUNT - 1),
1054            validity_end: Slot::new(u64::MAX, THREAD_COUNT - 1),
1055            function_params: vec![0; MAX_PARAMETERS_SIZE as usize],
1056            trigger: Some(AsyncMessageTrigger {
1057                address: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
1058                    .unwrap(),
1059                datastore_key: Some(vec![0; MAX_DATASTORE_KEY_LENGTH as usize]),
1060            }),
1061            can_be_executed: true,
1062        };
1063
1064        assert_eq!(new_msg, msg);
1065    }
1066
1067    #[test]
1068    fn lower_limit_ser_deser_id() {
1069        // Serialize then Deserialize an AsyncMessageId (with lowest values)
1070
1071        let id: AsyncMessageId = (std::cmp::Reverse(Ratio::new(0, 1)), Slot::new(0, 0), 0);
1072
1073        let mut buffer = Vec::new();
1074        let serializer = AsyncMessageIdSerializer::new();
1075        serializer.serialize(&id, &mut buffer).unwrap();
1076        let deserializer = AsyncMessageIdDeserializer::new(32);
1077        let (rest, deserialized) = deserializer
1078            .deserialize::<DeserializeError>(&buffer)
1079            .unwrap();
1080        assert!(rest.is_empty());
1081        assert_eq!(id, deserialized);
1082    }
1083
1084    #[test]
1085    fn higher_limit_ser_deser_id() {
1086        // Serialize then Deserialize an AsyncMessageId (with highest values)
1087
1088        let id: AsyncMessageId = (
1089            std::cmp::Reverse(Ratio::new(u64::MAX, u64::MAX)),
1090            Slot::new(u64::MAX, THREAD_COUNT - 1),
1091            u64::MAX,
1092        );
1093
1094        let mut buffer = Vec::new();
1095        let serializer = AsyncMessageIdSerializer::new();
1096        serializer.serialize(&id, &mut buffer).unwrap();
1097        let deserializer = AsyncMessageIdDeserializer::new(32);
1098        let (rest, deserialized) = deserializer
1099            .deserialize::<DeserializeError>(&buffer)
1100            .unwrap();
1101        assert!(rest.is_empty());
1102        assert_eq!(id, deserialized);
1103    }
1104
1105    #[test]
1106    fn wrong_denom_ser_deser_id() {
1107        let id: AsyncMessageId = (
1108            // Ratio with 0 as a denominator -> will fail to deserialize
1109            std::cmp::Reverse(Ratio::new_raw(u64::MAX, 0)),
1110            Slot::new(u64::MAX, THREAD_COUNT - 1),
1111            u64::MAX,
1112        );
1113
1114        let mut buffer = Vec::new();
1115        let serializer = AsyncMessageIdSerializer::new();
1116        serializer.serialize(&id, &mut buffer).unwrap();
1117        let deserializer = AsyncMessageIdDeserializer::new(32);
1118        let _ = deserializer
1119            .deserialize::<DeserializeError>(&buffer)
1120            .expect_err("Failed to deserialize");
1121    }
1122
1123    #[test]
1124    fn lower_limit_ser_deser_message() {
1125        // Serialize then Deserialize an AsyncMessage (with lowest values)
1126
1127        let msg = AsyncMessage {
1128            emission_slot: Slot::new(0, 0),
1129            emission_index: 0,
1130            sender: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
1131                .unwrap(),
1132            destination: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
1133                .unwrap(),
1134            function: String::from(""),
1135            max_gas: 0,
1136            fee: Amount::from_str("0").unwrap(),
1137            coins: Amount::from_str("0").unwrap(),
1138            validity_start: Slot::new(0, 0),
1139            validity_end: Slot::new(0, 0),
1140            function_params: vec![],
1141            trigger: None,
1142            can_be_executed: false,
1143        };
1144
1145        let mut buffer = Vec::new();
1146        let serializer = AsyncMessageSerializer::new(true);
1147        serializer.serialize(&msg, &mut buffer).unwrap();
1148        let deserializer = AsyncMessageDeserializer::new(
1149            THREAD_COUNT,
1150            MAX_FUNCTION_NAME_LENGTH,
1151            MAX_PARAMETERS_SIZE as u64,
1152            MAX_DATASTORE_KEY_LENGTH as u32,
1153            true,
1154        );
1155        let (rest, deserialized) = deserializer
1156            .deserialize::<DeserializeError>(&buffer)
1157            .unwrap();
1158        assert!(rest.is_empty());
1159        assert_eq!(msg, deserialized);
1160    }
1161
1162    #[test]
1163    fn higher_limit_ser_deser_message() {
1164        // Serialize then Deserialize an AsyncMessage (with max values in most of its fields)
1165
1166        let msg = AsyncMessage {
1167            emission_slot: Slot::new(u64::MAX, THREAD_COUNT - 1),
1168            emission_index: u64::MAX,
1169            sender: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
1170                .unwrap(),
1171            destination: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
1172                .unwrap(),
1173            function: (0..MAX_FUNCTION_NAME_LENGTH)
1174                .map(|_| "X")
1175                .collect::<String>(),
1176            max_gas: u64::MAX,
1177            fee: Amount::from_raw(u64::MAX),
1178            coins: Amount::from_raw(u64::MAX),
1179            validity_start: Slot::new(u64::MAX, THREAD_COUNT - 1),
1180            validity_end: Slot::new(u64::MAX, THREAD_COUNT - 1),
1181            function_params: vec![0; MAX_PARAMETERS_SIZE as usize],
1182            trigger: Some(AsyncMessageTrigger {
1183                address: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
1184                    .unwrap(),
1185                datastore_key: Some(vec![0; MAX_DATASTORE_KEY_LENGTH as usize]),
1186            }),
1187            can_be_executed: true,
1188        };
1189
1190        let mut buffer = Vec::new();
1191        let serializer = AsyncMessageSerializer::new(true);
1192        serializer.serialize(&msg, &mut buffer).unwrap();
1193        let deserializer = AsyncMessageDeserializer::new(
1194            THREAD_COUNT,
1195            MAX_FUNCTION_NAME_LENGTH,
1196            MAX_PARAMETERS_SIZE as u64,
1197            MAX_DATASTORE_KEY_LENGTH as u32,
1198            true,
1199        );
1200        let (rest, deserialized) = deserializer
1201            .deserialize::<DeserializeError>(&buffer)
1202            .unwrap();
1203        assert!(rest.is_empty());
1204        assert_eq!(msg, deserialized);
1205    }
1206
1207    #[test]
1208    fn lower_limit_ser_deser_message_update() {
1209        let msg = AsyncMessageUpdate {
1210            emission_slot: SetOrKeep::Keep,
1211            emission_index: SetOrKeep::Keep,
1212            sender: SetOrKeep::Keep,
1213            destination: SetOrKeep::Keep,
1214            function: SetOrKeep::Keep,
1215            max_gas: SetOrKeep::Keep,
1216            fee: SetOrKeep::Keep,
1217            coins: SetOrKeep::Keep,
1218            validity_start: SetOrKeep::Keep,
1219            validity_end: SetOrKeep::Keep,
1220            function_params: SetOrKeep::Keep,
1221            trigger: SetOrKeep::Keep,
1222            can_be_executed: SetOrKeep::Keep,
1223        };
1224
1225        let mut buffer = Vec::new();
1226        let serializer = AsyncMessageUpdateSerializer::new(true);
1227        serializer.serialize(&msg, &mut buffer).unwrap();
1228        let deserializer = AsyncMessageUpdateDeserializer::new(
1229            THREAD_COUNT,
1230            MAX_FUNCTION_NAME_LENGTH,
1231            MAX_PARAMETERS_SIZE as u64,
1232            MAX_DATASTORE_KEY_LENGTH as u32,
1233            true,
1234        );
1235        let (rest, deserialized) = deserializer
1236            .deserialize::<DeserializeError>(&buffer)
1237            .unwrap();
1238        assert!(rest.is_empty());
1239        assert_eq!(msg, deserialized);
1240    }
1241
1242    #[test]
1243    fn higher_limit_ser_deser_message_update() {
1244        let msg = AsyncMessageUpdate {
1245            emission_slot: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
1246            emission_index: SetOrKeep::Set(u64::MAX),
1247            sender: SetOrKeep::Set(
1248                Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x").unwrap(),
1249            ),
1250            destination: SetOrKeep::Set(
1251                Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G").unwrap(),
1252            ),
1253            function: SetOrKeep::Set(
1254                (0..MAX_FUNCTION_NAME_LENGTH)
1255                    .map(|_| "X")
1256                    .collect::<String>(),
1257            ),
1258            max_gas: SetOrKeep::Set(u64::MAX),
1259            fee: SetOrKeep::Set(Amount::from_raw(u64::MAX)),
1260            coins: SetOrKeep::Set(Amount::from_raw(u64::MAX)),
1261            validity_start: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
1262            validity_end: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
1263            function_params: SetOrKeep::Set(vec![0; MAX_PARAMETERS_SIZE as usize]),
1264            trigger: SetOrKeep::Set(Some(AsyncMessageTrigger {
1265                address: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
1266                    .unwrap(),
1267                datastore_key: Some(vec![0; MAX_DATASTORE_KEY_LENGTH as usize]),
1268            })),
1269            can_be_executed: SetOrKeep::Set(true),
1270        };
1271
1272        let mut buffer = Vec::new();
1273        let serializer = AsyncMessageUpdateSerializer::new(true);
1274        serializer.serialize(&msg, &mut buffer).unwrap();
1275        let deserializer = AsyncMessageUpdateDeserializer::new(
1276            THREAD_COUNT,
1277            MAX_FUNCTION_NAME_LENGTH,
1278            MAX_PARAMETERS_SIZE as u64,
1279            MAX_DATASTORE_KEY_LENGTH as u32,
1280            true,
1281        );
1282        let (rest, deserialized) = deserializer
1283            .deserialize::<DeserializeError>(&buffer)
1284            .unwrap();
1285        assert!(rest.is_empty());
1286        assert_eq!(msg, deserialized);
1287    }
1288
1289    #[test]
1290    fn bad_serialization_message() {
1291        // Serialize an AsyncMessage, write some crap in the result and try to deserialize it
1292
1293        let message = AsyncMessage::new(
1294            Slot::new(1, 2),
1295            0,
1296            Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x").unwrap(),
1297            Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G").unwrap(),
1298            String::from("test"),
1299            10000000,
1300            Amount::from_str("1").unwrap(),
1301            Amount::from_str("1").unwrap(),
1302            Slot::new(2, 0),
1303            Slot::new(3, 0),
1304            vec![1, 2, 3, 4],
1305            Some(AsyncMessageTrigger {
1306                address: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
1307                    .unwrap(),
1308                datastore_key: None,
1309            }),
1310            None,
1311        );
1312        let message_serializer = AsyncMessageSerializer::new(false);
1313        let mut serialized = Vec::new();
1314        message_serializer
1315            .serialize(&message, &mut serialized)
1316            .unwrap();
1317        let message_deserializer = AsyncMessageDeserializer::new(
1318            THREAD_COUNT,
1319            MAX_FUNCTION_NAME_LENGTH,
1320            MAX_PARAMETERS_SIZE as u64,
1321            MAX_DATASTORE_KEY_LENGTH as u32,
1322            false,
1323        );
1324        // Will break the deserialization
1325        serialized[1] = 50;
1326        message_deserializer
1327            .deserialize::<DeserializeError>(&serialized)
1328            .unwrap_err();
1329    }
1330}