1#![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#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
32pub struct AsyncMessageTrigger {
33 pub address: Address,
35
36 pub datastore_key: Option<Vec<u8>>,
38}
39
40#[derive(Clone)]
41pub 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)]
76pub 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#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
120pub struct AsyncMessage {
121 pub emission_slot: Slot,
123
124 pub emission_index: u64,
127
128 pub sender: Address,
130
131 pub destination: Address,
133
134 pub function: String,
136
137 pub max_gas: u64,
139
140 pub fee: Amount,
142
143 pub coins: Amount,
148
149 pub validity_start: Slot,
151
152 pub validity_end: Slot,
154
155 pub function_params: Vec<u8>,
157
158 pub trigger: Option<AsyncMessageTrigger>,
160
161 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 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 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 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 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#[derive(Default, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
510pub struct AsyncMessageUpdate {
511 pub emission_slot: SetOrKeep<Slot>,
513
514 pub emission_index: SetOrKeep<u64>,
517
518 pub sender: SetOrKeep<Address>,
520
521 pub destination: SetOrKeep<Address>,
523
524 pub function: SetOrKeep<String>,
526
527 pub max_gas: SetOrKeep<u64>,
529
530 pub fee: SetOrKeep<Amount>,
532
533 pub coins: SetOrKeep<Amount>,
538
539 pub validity_start: SetOrKeep<Slot>,
541
542 pub validity_end: SetOrKeep<Slot>,
544
545 pub function_params: SetOrKeep<Vec<u8>>,
547
548 pub trigger: SetOrKeep<Option<AsyncMessageTrigger>>,
550
551 pub can_be_executed: SetOrKeep<bool>,
556}
557
558pub 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 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
634pub 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 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 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 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 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 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 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 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 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 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 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 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 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 serialized[1] = 50;
1326 message_deserializer
1327 .deserialize::<DeserializeError>(&serialized)
1328 .unwrap_err();
1329 }
1330}