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 {
229 self.compute_priority_id(0)
230 }
231
232 pub fn compute_priority_id(&self, extra_gas_cost: u64) -> AsyncMessageId {
238 let denom = match self.max_gas.saturating_add(extra_gas_cost) {
239 0 => 1,
240 d => d,
241 };
242 (
243 std::cmp::Reverse(Ratio::new(self.fee.to_raw(), denom)),
244 self.emission_slot,
245 self.emission_index,
246 )
247 }
248}
249
250#[derive(Clone)]
251pub struct AsyncMessageSerializer {
252 pub slot_serializer: SlotSerializer,
253 pub function_serializer: StringSerializer<U16VarIntSerializer, u16>,
254 pub amount_serializer: AmountSerializer,
255 pub u64_serializer: U64VarIntSerializer,
256 pub function_params_serializer: VecU8Serializer,
257 pub address_serializer: AddressSerializer,
258 pub trigger_serializer: OptionSerializer<AsyncMessageTrigger, AsyncMessageTriggerSerializer>,
259 pub bool_serializer: BoolSerializer,
260 pub for_db: bool,
261}
262
263impl AsyncMessageSerializer {
264 pub fn new(for_db: bool) -> Self {
265 Self {
266 slot_serializer: SlotSerializer::new(),
267 amount_serializer: AmountSerializer::new(),
268 u64_serializer: U64VarIntSerializer::new(),
269 function_serializer: StringSerializer::new(U16VarIntSerializer::new()),
270 function_params_serializer: VecU8Serializer::new(),
271 address_serializer: AddressSerializer::new(),
272 trigger_serializer: OptionSerializer::new(AsyncMessageTriggerSerializer::new()),
273 bool_serializer: BoolSerializer::new(),
274 for_db,
275 }
276 }
277}
278
279impl Default for AsyncMessageSerializer {
280 fn default() -> Self {
281 Self::new(false)
282 }
283}
284
285impl Serializer<AsyncMessage> for AsyncMessageSerializer {
286 fn serialize(
315 &self,
316 value: &AsyncMessage,
317 buffer: &mut Vec<u8>,
318 ) -> Result<(), massa_serialization::SerializeError> {
319 self.slot_serializer
320 .serialize(&value.emission_slot, buffer)?;
321 self.u64_serializer
322 .serialize(&value.emission_index, buffer)?;
323 self.address_serializer.serialize(&value.sender, buffer)?;
324 self.address_serializer
325 .serialize(&value.destination, buffer)?;
326 self.function_serializer
327 .serialize(&value.function, buffer)?;
328 self.u64_serializer.serialize(&value.max_gas, buffer)?;
329 self.amount_serializer.serialize(&value.fee, buffer)?;
330 self.amount_serializer.serialize(&value.coins, buffer)?;
331 self.slot_serializer
332 .serialize(&value.validity_start, buffer)?;
333 self.slot_serializer
334 .serialize(&value.validity_end, buffer)?;
335 self.function_params_serializer
336 .serialize(&value.function_params, buffer)?;
337 self.trigger_serializer.serialize(&value.trigger, buffer)?;
338 if self.for_db {
339 self.bool_serializer
340 .serialize(&value.can_be_executed, buffer)?;
341 }
342 Ok(())
343 }
344}
345
346#[derive(Clone)]
347pub struct AsyncMessageDeserializer {
348 pub slot_deserializer: SlotDeserializer,
349 pub amount_deserializer: AmountDeserializer,
350 pub emission_index_deserializer: U64VarIntDeserializer,
351 pub max_gas_deserializer: U64VarIntDeserializer,
352 pub function_deserializer: StringDeserializer<U16VarIntDeserializer, u16>,
353 pub function_params_deserializer: VecU8Deserializer,
354 pub address_deserializer: AddressDeserializer,
355 pub trigger_deserializer:
356 OptionDeserializer<AsyncMessageTrigger, AsyncMessageTriggerDeserializer>,
357 pub bool_deserializer: BoolDeserializer,
358 pub for_db: bool,
359}
360
361impl AsyncMessageDeserializer {
362 pub fn new(
363 thread_count: u8,
364 max_function_length: u16,
365 max_function_params_length: u64,
366 max_key_length: u32,
367 for_db: bool,
368 ) -> Self {
369 Self {
370 slot_deserializer: SlotDeserializer::new(
371 (Included(0), Included(u64::MAX)),
372 (Included(0), Excluded(thread_count)),
373 ),
374 amount_deserializer: AmountDeserializer::new(
375 Included(Amount::MIN),
376 Included(Amount::MAX),
377 ),
378 emission_index_deserializer: U64VarIntDeserializer::new(
379 Included(0),
380 Included(u64::MAX),
381 ),
382 max_gas_deserializer: U64VarIntDeserializer::new(Included(0), Included(u64::MAX)),
383 function_deserializer: StringDeserializer::new(U16VarIntDeserializer::new(
384 Included(0),
385 Included(max_function_length),
386 )),
387 function_params_deserializer: VecU8Deserializer::new(
388 Included(0),
389 Included(max_function_params_length),
390 ),
391 address_deserializer: AddressDeserializer::new(),
392 trigger_deserializer: OptionDeserializer::new(AsyncMessageTriggerDeserializer::new(
393 max_key_length,
394 )),
395 bool_deserializer: BoolDeserializer::new(),
396 for_db,
397 }
398 }
399}
400
401impl Deserializer<AsyncMessage> for AsyncMessageDeserializer {
402 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
436 &self,
437 buffer: &'a [u8],
438 ) -> IResult<&'a [u8], AsyncMessage, E> {
439 context(
440 "Failed AsyncMessage deserialization",
441 tuple((
442 context("Failed emission_slot deserialization", |input| {
443 self.slot_deserializer.deserialize(input)
444 }),
445 context("Failed emission_index deserialization", |input| {
446 self.emission_index_deserializer.deserialize(input)
447 }),
448 context("Failed sender deserialization", |input| {
449 self.address_deserializer.deserialize(input)
450 }),
451 context("Failed destination deserialization", |input| {
452 self.address_deserializer.deserialize(input)
453 }),
454 context("Failed function deserialization", |input| {
455 self.function_deserializer.deserialize(input)
456 }),
457 context("Failed max_gas deserialization", |input| {
458 self.max_gas_deserializer.deserialize(input)
459 }),
460 context("Failed fee deserialization", |input| {
461 self.amount_deserializer.deserialize(input)
462 }),
463 context("Failed coins deserialization", |input| {
464 self.amount_deserializer.deserialize(input)
465 }),
466 context("Failed validity_start deserialization", |input| {
467 self.slot_deserializer.deserialize(input)
468 }),
469 context("Failed validity_end deserialization", |input| {
470 self.slot_deserializer.deserialize(input)
471 }),
472 context("Failed data deserialization", |input| {
473 self.function_params_deserializer.deserialize(input)
474 }),
475 context("Failed filter deserialization", |input| {
476 self.trigger_deserializer.deserialize(input)
477 }),
478 context("Failed can_be_executed deserialization", |input| {
479 if self.for_db {
480 self.bool_deserializer.deserialize(input)
481 } else {
482 Ok((input, false))
483 }
484 }),
485 )),
486 )
487 .map(
488 |(
489 emission_slot,
490 emission_index,
491 sender,
492 destination,
493 function,
494 max_gas,
495 fee,
496 coins,
497 validity_start,
498 validity_end,
499 function_params,
500 filter,
501 can_be_executed,
502 )| {
503 AsyncMessage::new(
504 emission_slot,
505 emission_index,
506 sender,
507 destination,
508 function,
509 max_gas,
510 fee,
511 coins,
512 validity_start,
513 validity_end,
514 function_params,
515 filter,
516 if self.for_db {
517 Some(can_be_executed)
518 } else {
519 None
520 },
521 )
522 },
523 )
524 .parse(buffer)
525 }
526}
527
528#[derive(Default, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
530pub struct AsyncMessageUpdate {
531 pub emission_slot: SetOrKeep<Slot>,
533
534 pub emission_index: SetOrKeep<u64>,
537
538 pub sender: SetOrKeep<Address>,
540
541 pub destination: SetOrKeep<Address>,
543
544 pub function: SetOrKeep<String>,
546
547 pub max_gas: SetOrKeep<u64>,
549
550 pub fee: SetOrKeep<Amount>,
552
553 pub coins: SetOrKeep<Amount>,
558
559 pub validity_start: SetOrKeep<Slot>,
561
562 pub validity_end: SetOrKeep<Slot>,
564
565 pub function_params: SetOrKeep<Vec<u8>>,
567
568 pub trigger: SetOrKeep<Option<AsyncMessageTrigger>>,
570
571 pub can_be_executed: SetOrKeep<bool>,
576}
577
578pub struct AsyncMessageUpdateSerializer {
580 slot_serializer: SetOrKeepSerializer<Slot, SlotSerializer>,
581 amount_serializer: SetOrKeepSerializer<Amount, AmountSerializer>,
582 u64_serializer: SetOrKeepSerializer<u64, U64VarIntSerializer>,
583 function_serializer: SetOrKeepSerializer<String, StringSerializer<U16VarIntSerializer, u16>>,
584 function_params_serializer: SetOrKeepSerializer<Vec<u8>, VecU8Serializer>,
585 address_serializer: SetOrKeepSerializer<Address, AddressSerializer>,
586 trigger_serializer: SetOrKeepSerializer<
587 Option<AsyncMessageTrigger>,
588 OptionSerializer<AsyncMessageTrigger, AsyncMessageTriggerSerializer>,
589 >,
590 bool_serializer: SetOrKeepSerializer<bool, BoolSerializer>,
591 for_db: bool,
592}
593
594impl AsyncMessageUpdateSerializer {
595 pub fn new(for_db: bool) -> Self {
597 Self {
598 slot_serializer: SetOrKeepSerializer::new(SlotSerializer::new()),
599 amount_serializer: SetOrKeepSerializer::new(AmountSerializer::new()),
600 u64_serializer: SetOrKeepSerializer::new(U64VarIntSerializer::new()),
601 function_serializer: SetOrKeepSerializer::new(StringSerializer::new(
602 U16VarIntSerializer::new(),
603 )),
604 function_params_serializer: SetOrKeepSerializer::new(VecU8Serializer::new()),
605 address_serializer: SetOrKeepSerializer::new(AddressSerializer::new()),
606 trigger_serializer: SetOrKeepSerializer::new(OptionSerializer::new(
607 AsyncMessageTriggerSerializer::new(),
608 )),
609 bool_serializer: SetOrKeepSerializer::new(BoolSerializer::new()),
610 for_db,
611 }
612 }
613}
614
615impl Default for AsyncMessageUpdateSerializer {
616 fn default() -> Self {
617 Self::new(false)
618 }
619}
620
621impl Serializer<AsyncMessageUpdate> for AsyncMessageUpdateSerializer {
622 fn serialize(
623 &self,
624 value: &AsyncMessageUpdate,
625 buffer: &mut Vec<u8>,
626 ) -> Result<(), SerializeError> {
627 self.slot_serializer
628 .serialize(&value.emission_slot, buffer)?;
629 self.u64_serializer
630 .serialize(&value.emission_index, buffer)?;
631 self.address_serializer.serialize(&value.sender, buffer)?;
632 self.address_serializer
633 .serialize(&value.destination, buffer)?;
634 self.function_serializer
635 .serialize(&value.function, buffer)?;
636 self.u64_serializer.serialize(&value.max_gas, buffer)?;
637 self.amount_serializer.serialize(&value.fee, buffer)?;
638 self.amount_serializer.serialize(&value.coins, buffer)?;
639 self.slot_serializer
640 .serialize(&value.validity_start, buffer)?;
641 self.slot_serializer
642 .serialize(&value.validity_end, buffer)?;
643 self.function_params_serializer
644 .serialize(&value.function_params, buffer)?;
645 self.trigger_serializer.serialize(&value.trigger, buffer)?;
646 if self.for_db {
647 self.bool_serializer
648 .serialize(&value.can_be_executed, buffer)?;
649 }
650 Ok(())
651 }
652}
653
654pub struct AsyncMessageUpdateDeserializer {
656 slot_deserializer: SetOrKeepDeserializer<Slot, SlotDeserializer>,
657 amount_deserializer: SetOrKeepDeserializer<Amount, AmountDeserializer>,
658 emission_index_deserializer: SetOrKeepDeserializer<u64, U64VarIntDeserializer>,
659 max_gas_deserializer: SetOrKeepDeserializer<u64, U64VarIntDeserializer>,
660 function_deserializer:
661 SetOrKeepDeserializer<String, StringDeserializer<U16VarIntDeserializer, u16>>,
662 function_params_deserializer: SetOrKeepDeserializer<Vec<u8>, VecU8Deserializer>,
663 address_deserializer: SetOrKeepDeserializer<Address, AddressDeserializer>,
664 trigger_deserializer: SetOrKeepDeserializer<
665 Option<AsyncMessageTrigger>,
666 OptionDeserializer<AsyncMessageTrigger, AsyncMessageTriggerDeserializer>,
667 >,
668 bool_deserializer: SetOrKeepDeserializer<bool, BoolDeserializer>,
669 for_db: bool,
670}
671
672impl AsyncMessageUpdateDeserializer {
673 pub fn new(
675 thread_count: u8,
676 max_function_length: u16,
677 max_function_params_length: u64,
678 max_key_length: u32,
679 for_db: bool,
680 ) -> Self {
681 Self {
682 slot_deserializer: SetOrKeepDeserializer::new(SlotDeserializer::new(
683 (Included(0), Included(u64::MAX)),
684 (Included(0), Excluded(thread_count)),
685 )),
686 amount_deserializer: SetOrKeepDeserializer::new(AmountDeserializer::new(
687 Included(Amount::MIN),
688 Included(Amount::MAX),
689 )),
690 emission_index_deserializer: SetOrKeepDeserializer::new(U64VarIntDeserializer::new(
691 Included(0),
692 Included(u64::MAX),
693 )),
694 max_gas_deserializer: SetOrKeepDeserializer::new(U64VarIntDeserializer::new(
695 Included(0),
696 Included(u64::MAX),
697 )),
698 function_deserializer: SetOrKeepDeserializer::new(StringDeserializer::new(
699 U16VarIntDeserializer::new(Included(0), Included(max_function_length)),
700 )),
701 function_params_deserializer: SetOrKeepDeserializer::new(VecU8Deserializer::new(
702 Included(0),
703 Included(max_function_params_length),
704 )),
705 address_deserializer: SetOrKeepDeserializer::new(AddressDeserializer::new()),
706 trigger_deserializer: SetOrKeepDeserializer::new(OptionDeserializer::new(
707 AsyncMessageTriggerDeserializer::new(max_key_length),
708 )),
709 bool_deserializer: SetOrKeepDeserializer::new(BoolDeserializer::new()),
710 for_db,
711 }
712 }
713}
714
715impl Deserializer<AsyncMessageUpdate> for AsyncMessageUpdateDeserializer {
716 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
717 &self,
718 buffer: &'a [u8],
719 ) -> IResult<&'a [u8], AsyncMessageUpdate, E> {
720 context(
721 "Failed AsyncMessageUpdate deserialization",
722 tuple((
723 context("Failed emission_slot deserialization", |input| {
724 self.slot_deserializer.deserialize(input)
725 }),
726 context("Failed emission_index deserialization", |input| {
727 self.emission_index_deserializer.deserialize(input)
728 }),
729 context("Failed sender deserialization", |input| {
730 self.address_deserializer.deserialize(input)
731 }),
732 context("Failed destination deserialization", |input| {
733 self.address_deserializer.deserialize(input)
734 }),
735 context("Failed function deserialization", |input| {
736 self.function_deserializer.deserialize(input)
737 }),
738 context("Failed max_gas deserialization", |input| {
739 self.max_gas_deserializer.deserialize(input)
740 }),
741 context("Failed fee deserialization", |input| {
742 self.amount_deserializer.deserialize(input)
743 }),
744 context("Failed coins deserialization", |input| {
745 self.amount_deserializer.deserialize(input)
746 }),
747 context("Failed validity_start deserialization", |input| {
748 self.slot_deserializer.deserialize(input)
749 }),
750 context("Failed validity_end deserialization", |input| {
751 self.slot_deserializer.deserialize(input)
752 }),
753 context("Failed function_params deserialization", |input| {
754 self.function_params_deserializer.deserialize(input)
755 }),
756 context("Failed filter deserialization", |input| {
757 self.trigger_deserializer.deserialize(input)
758 }),
759 context("Failed can_be_executed deserialization", |input| {
760 if self.for_db {
761 self.bool_deserializer.deserialize(input)
762 } else {
763 Ok((input, SetOrKeep::Keep))
764 }
765 }),
766 )),
767 )
768 .map(
769 |(
770 emission_slot,
771 emission_index,
772 sender,
773 destination,
774 function,
775 max_gas,
776 fee,
777 coins,
778 validity_start,
779 validity_end,
780 function_params,
781 trigger,
782 can_be_executed,
783 )| {
784 AsyncMessageUpdate {
785 emission_slot,
786 emission_index,
787 sender,
788 destination,
789 function,
790 max_gas,
791 fee,
792 coins,
793 validity_start,
794 validity_end,
795 function_params,
796 trigger,
797 can_be_executed,
798 }
799 },
800 )
801 .parse(buffer)
802 }
803}
804
805impl Applicable<AsyncMessageUpdate> for AsyncMessageUpdate {
806 fn apply(&mut self, update: AsyncMessageUpdate) {
808 self.emission_slot.apply(update.emission_slot);
809 self.emission_index.apply(update.emission_index);
810 self.sender.apply(update.sender);
811 self.destination.apply(update.destination);
812 self.function.apply(update.function);
813 self.max_gas.apply(update.max_gas);
814 self.fee.apply(update.fee);
815 self.coins.apply(update.coins);
816 self.validity_start.apply(update.validity_start);
817 self.validity_end.apply(update.validity_end);
818 self.function_params.apply(update.function_params);
819 self.trigger.apply(update.trigger);
820 self.can_be_executed.apply(update.can_be_executed);
821 }
822}
823
824impl Applicable<AsyncMessageUpdate> for AsyncMessage {
825 fn apply(&mut self, update: AsyncMessageUpdate) {
827 update.emission_slot.apply_to(&mut self.emission_slot);
828 update.emission_index.apply_to(&mut self.emission_index);
829 update.sender.apply_to(&mut self.sender);
830 update.destination.apply_to(&mut self.destination);
831 update.function.apply_to(&mut self.function);
832 update.max_gas.apply_to(&mut self.max_gas);
833 update.fee.apply_to(&mut self.fee);
834 update.coins.apply_to(&mut self.coins);
835 update.validity_start.apply_to(&mut self.validity_start);
836 update.validity_end.apply_to(&mut self.validity_end);
837 update.function_params.apply_to(&mut self.function_params);
838 update.trigger.apply_to(&mut self.trigger);
839 update.can_be_executed.apply_to(&mut self.can_be_executed);
840 }
841}
842
843#[cfg(test)]
844mod tests {
845 use crate::{
846 async_msg::{
847 AsyncMessage, AsyncMessageDeserializer, AsyncMessageSerializer, AsyncMessageTrigger,
848 AsyncMessageUpdate, AsyncMessageUpdateDeserializer, AsyncMessageUpdateSerializer,
849 },
850 async_msg_id::{AsyncMessageId, AsyncMessageIdDeserializer, AsyncMessageIdSerializer},
851 types::{Applicable, SetOrKeep},
852 };
853 use massa_serialization::{DeserializeError, Deserializer, Serializer};
854 use num::rational::Ratio;
855
856 use crate::{
857 address::Address,
858 amount::Amount,
859 config::{
860 MAX_DATASTORE_KEY_LENGTH, MAX_FUNCTION_NAME_LENGTH, MAX_PARAMETERS_SIZE, THREAD_COUNT,
861 },
862 slot::Slot,
863 };
864 use std::str::FromStr;
865
866 #[test]
867 fn no_apply_update_message() {
868 let mut msg = AsyncMessage {
872 emission_slot: Slot::new(0, 0),
873 emission_index: 0,
874 sender: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
875 .unwrap(),
876 destination: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
877 .unwrap(),
878 function: String::from(""),
879 max_gas: 0,
880 fee: Amount::from_str("0").unwrap(),
881 coins: Amount::from_str("0").unwrap(),
882 validity_start: Slot::new(0, 0),
883 validity_end: Slot::new(0, 0),
884 function_params: vec![],
885 trigger: None,
886 can_be_executed: false,
887 };
888 let old_message = msg.clone();
889
890 let update = AsyncMessageUpdate {
891 emission_slot: SetOrKeep::Keep,
892 emission_index: SetOrKeep::Keep,
893 sender: SetOrKeep::Keep,
894 destination: SetOrKeep::Keep,
895 function: SetOrKeep::Keep,
896 max_gas: SetOrKeep::Keep,
897 fee: SetOrKeep::Keep,
898 coins: SetOrKeep::Keep,
899 validity_start: SetOrKeep::Keep,
900 validity_end: SetOrKeep::Keep,
901 function_params: SetOrKeep::Keep,
902 trigger: SetOrKeep::Keep,
903 can_be_executed: SetOrKeep::Keep,
904 };
905 msg.apply(update);
906 assert_eq!(old_message, msg);
907 }
908
909 #[test]
910 fn apply_update_message() {
911 let mut msg = AsyncMessage {
915 emission_slot: Slot::new(0, 0),
916 emission_index: 0,
917 sender: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
918 .unwrap(),
919 destination: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
920 .unwrap(),
921 function: String::from(""),
922 max_gas: 0,
923 fee: Amount::from_str("0").unwrap(),
924 coins: Amount::from_str("0").unwrap(),
925 validity_start: Slot::new(0, 0),
926 validity_end: Slot::new(0, 0),
927 function_params: vec![],
928 trigger: None,
929 can_be_executed: false,
930 };
931 let old_message = msg.clone();
932
933 let update = AsyncMessageUpdate {
934 emission_slot: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
935 emission_index: SetOrKeep::Set(u64::MAX),
936 sender: SetOrKeep::Set(
937 Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x").unwrap(),
938 ),
939 destination: SetOrKeep::Set(
940 Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G").unwrap(),
941 ),
942 function: SetOrKeep::Set(
943 (0..MAX_FUNCTION_NAME_LENGTH)
944 .map(|_| "X")
945 .collect::<String>(),
946 ),
947 max_gas: SetOrKeep::Set(u64::MAX),
948 fee: SetOrKeep::Set(Amount::from_raw(u64::MAX)),
949 coins: SetOrKeep::Set(Amount::from_raw(u64::MAX)),
950 validity_start: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
951 validity_end: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
952 function_params: SetOrKeep::Set(vec![0; MAX_PARAMETERS_SIZE as usize]),
953 trigger: SetOrKeep::Set(Some(AsyncMessageTrigger {
954 address: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
955 .unwrap(),
956 datastore_key: Some(vec![0; MAX_DATASTORE_KEY_LENGTH as usize]),
957 })),
958 can_be_executed: SetOrKeep::Set(true),
959 };
960 msg.apply(update);
961
962 assert_ne!(old_message, msg);
963
964 let new_msg = AsyncMessage {
965 emission_slot: Slot::new(u64::MAX, THREAD_COUNT - 1),
966 emission_index: u64::MAX,
967 sender: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
968 .unwrap(),
969 destination: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
970 .unwrap(),
971 function: (0..MAX_FUNCTION_NAME_LENGTH)
972 .map(|_| "X")
973 .collect::<String>(),
974 max_gas: u64::MAX,
975 fee: Amount::from_raw(u64::MAX),
976 coins: Amount::from_raw(u64::MAX),
977 validity_start: Slot::new(u64::MAX, THREAD_COUNT - 1),
978 validity_end: Slot::new(u64::MAX, THREAD_COUNT - 1),
979 function_params: vec![0; MAX_PARAMETERS_SIZE as usize],
980 trigger: Some(AsyncMessageTrigger {
981 address: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
982 .unwrap(),
983 datastore_key: Some(vec![0; MAX_DATASTORE_KEY_LENGTH as usize]),
984 }),
985 can_be_executed: true,
986 };
987 assert_eq!(new_msg, msg);
988 }
989
990 #[test]
991 fn apply_update_on_update_message() {
992 let mut msg = AsyncMessage {
995 emission_slot: Slot::new(0, 0),
996 emission_index: 0,
997 sender: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
998 .unwrap(),
999 destination: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
1000 .unwrap(),
1001 function: String::from(""),
1002 max_gas: 0,
1003 fee: Amount::from_str("0").unwrap(),
1004 coins: Amount::from_str("0").unwrap(),
1005 validity_start: Slot::new(0, 0),
1006 validity_end: Slot::new(0, 0),
1007 function_params: vec![],
1008 trigger: None,
1009 can_be_executed: false,
1010 };
1011
1012 let mut update = AsyncMessageUpdate {
1013 emission_slot: SetOrKeep::Keep,
1014 emission_index: SetOrKeep::Keep,
1015 sender: SetOrKeep::Keep,
1016 destination: SetOrKeep::Keep,
1017 function: SetOrKeep::Keep,
1018 max_gas: SetOrKeep::Keep,
1019 fee: SetOrKeep::Keep,
1020 coins: SetOrKeep::Keep,
1021 validity_start: SetOrKeep::Keep,
1022 validity_end: SetOrKeep::Keep,
1023 function_params: SetOrKeep::Keep,
1024 trigger: SetOrKeep::Keep,
1025 can_be_executed: SetOrKeep::Keep,
1026 };
1027
1028 let update_update = AsyncMessageUpdate {
1029 emission_slot: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
1030 emission_index: SetOrKeep::Set(u64::MAX),
1031 sender: SetOrKeep::Set(
1032 Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x").unwrap(),
1033 ),
1034 destination: SetOrKeep::Set(
1035 Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G").unwrap(),
1036 ),
1037 function: SetOrKeep::Set(
1038 (0..MAX_FUNCTION_NAME_LENGTH)
1039 .map(|_| "X")
1040 .collect::<String>(),
1041 ),
1042 max_gas: SetOrKeep::Set(u64::MAX),
1043 fee: SetOrKeep::Set(Amount::from_raw(u64::MAX)),
1044 coins: SetOrKeep::Set(Amount::from_raw(u64::MAX)),
1045 validity_start: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
1046 validity_end: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
1047 function_params: SetOrKeep::Set(vec![0; MAX_PARAMETERS_SIZE as usize]),
1048 trigger: SetOrKeep::Set(Some(AsyncMessageTrigger {
1049 address: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
1050 .unwrap(),
1051 datastore_key: Some(vec![0; MAX_DATASTORE_KEY_LENGTH as usize]),
1052 })),
1053 can_be_executed: SetOrKeep::Set(true),
1054 };
1055
1056 update.apply(update_update);
1057
1058 msg.apply(update);
1059
1060 let new_msg = AsyncMessage {
1061 emission_slot: Slot::new(u64::MAX, THREAD_COUNT - 1),
1062 emission_index: u64::MAX,
1063 sender: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
1064 .unwrap(),
1065 destination: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
1066 .unwrap(),
1067 function: (0..MAX_FUNCTION_NAME_LENGTH)
1068 .map(|_| "X")
1069 .collect::<String>(),
1070 max_gas: u64::MAX,
1071 fee: Amount::from_raw(u64::MAX),
1072 coins: Amount::from_raw(u64::MAX),
1073 validity_start: Slot::new(u64::MAX, THREAD_COUNT - 1),
1074 validity_end: Slot::new(u64::MAX, THREAD_COUNT - 1),
1075 function_params: vec![0; MAX_PARAMETERS_SIZE as usize],
1076 trigger: Some(AsyncMessageTrigger {
1077 address: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
1078 .unwrap(),
1079 datastore_key: Some(vec![0; MAX_DATASTORE_KEY_LENGTH as usize]),
1080 }),
1081 can_be_executed: true,
1082 };
1083
1084 assert_eq!(new_msg, msg);
1085 }
1086
1087 #[test]
1088 fn lower_limit_ser_deser_id() {
1089 let id: AsyncMessageId = (std::cmp::Reverse(Ratio::new(0, 1)), Slot::new(0, 0), 0);
1092
1093 let mut buffer = Vec::new();
1094 let serializer = AsyncMessageIdSerializer::new();
1095 serializer.serialize(&id, &mut buffer).unwrap();
1096 let deserializer = AsyncMessageIdDeserializer::new(32);
1097 let (rest, deserialized) = deserializer
1098 .deserialize::<DeserializeError>(&buffer)
1099 .unwrap();
1100 assert!(rest.is_empty());
1101 assert_eq!(id, deserialized);
1102 }
1103
1104 #[test]
1105 fn higher_limit_ser_deser_id() {
1106 let id: AsyncMessageId = (
1109 std::cmp::Reverse(Ratio::new(u64::MAX, u64::MAX)),
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 (rest, deserialized) = deserializer
1119 .deserialize::<DeserializeError>(&buffer)
1120 .unwrap();
1121 assert!(rest.is_empty());
1122 assert_eq!(id, deserialized);
1123 }
1124
1125 #[test]
1126 fn wrong_denom_ser_deser_id() {
1127 let id: AsyncMessageId = (
1128 std::cmp::Reverse(Ratio::new_raw(u64::MAX, 0)),
1130 Slot::new(u64::MAX, THREAD_COUNT - 1),
1131 u64::MAX,
1132 );
1133
1134 let mut buffer = Vec::new();
1135 let serializer = AsyncMessageIdSerializer::new();
1136 serializer.serialize(&id, &mut buffer).unwrap();
1137 let deserializer = AsyncMessageIdDeserializer::new(32);
1138 let _ = deserializer
1139 .deserialize::<DeserializeError>(&buffer)
1140 .expect_err("Failed to deserialize");
1141 }
1142
1143 #[test]
1144 fn lower_limit_ser_deser_message() {
1145 let msg = AsyncMessage {
1148 emission_slot: Slot::new(0, 0),
1149 emission_index: 0,
1150 sender: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
1151 .unwrap(),
1152 destination: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
1153 .unwrap(),
1154 function: String::from(""),
1155 max_gas: 0,
1156 fee: Amount::from_str("0").unwrap(),
1157 coins: Amount::from_str("0").unwrap(),
1158 validity_start: Slot::new(0, 0),
1159 validity_end: Slot::new(0, 0),
1160 function_params: vec![],
1161 trigger: None,
1162 can_be_executed: false,
1163 };
1164
1165 let mut buffer = Vec::new();
1166 let serializer = AsyncMessageSerializer::new(true);
1167 serializer.serialize(&msg, &mut buffer).unwrap();
1168 let deserializer = AsyncMessageDeserializer::new(
1169 THREAD_COUNT,
1170 MAX_FUNCTION_NAME_LENGTH,
1171 MAX_PARAMETERS_SIZE as u64,
1172 MAX_DATASTORE_KEY_LENGTH as u32,
1173 true,
1174 );
1175 let (rest, deserialized) = deserializer
1176 .deserialize::<DeserializeError>(&buffer)
1177 .unwrap();
1178 assert!(rest.is_empty());
1179 assert_eq!(msg, deserialized);
1180 }
1181
1182 #[test]
1183 fn higher_limit_ser_deser_message() {
1184 let msg = AsyncMessage {
1187 emission_slot: Slot::new(u64::MAX, THREAD_COUNT - 1),
1188 emission_index: u64::MAX,
1189 sender: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
1190 .unwrap(),
1191 destination: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
1192 .unwrap(),
1193 function: (0..MAX_FUNCTION_NAME_LENGTH)
1194 .map(|_| "X")
1195 .collect::<String>(),
1196 max_gas: u64::MAX,
1197 fee: Amount::from_raw(u64::MAX),
1198 coins: Amount::from_raw(u64::MAX),
1199 validity_start: Slot::new(u64::MAX, THREAD_COUNT - 1),
1200 validity_end: Slot::new(u64::MAX, THREAD_COUNT - 1),
1201 function_params: vec![0; MAX_PARAMETERS_SIZE as usize],
1202 trigger: Some(AsyncMessageTrigger {
1203 address: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
1204 .unwrap(),
1205 datastore_key: Some(vec![0; MAX_DATASTORE_KEY_LENGTH as usize]),
1206 }),
1207 can_be_executed: true,
1208 };
1209
1210 let mut buffer = Vec::new();
1211 let serializer = AsyncMessageSerializer::new(true);
1212 serializer.serialize(&msg, &mut buffer).unwrap();
1213 let deserializer = AsyncMessageDeserializer::new(
1214 THREAD_COUNT,
1215 MAX_FUNCTION_NAME_LENGTH,
1216 MAX_PARAMETERS_SIZE as u64,
1217 MAX_DATASTORE_KEY_LENGTH as u32,
1218 true,
1219 );
1220 let (rest, deserialized) = deserializer
1221 .deserialize::<DeserializeError>(&buffer)
1222 .unwrap();
1223 assert!(rest.is_empty());
1224 assert_eq!(msg, deserialized);
1225 }
1226
1227 #[test]
1228 fn lower_limit_ser_deser_message_update() {
1229 let msg = AsyncMessageUpdate {
1230 emission_slot: SetOrKeep::Keep,
1231 emission_index: SetOrKeep::Keep,
1232 sender: SetOrKeep::Keep,
1233 destination: SetOrKeep::Keep,
1234 function: SetOrKeep::Keep,
1235 max_gas: SetOrKeep::Keep,
1236 fee: SetOrKeep::Keep,
1237 coins: SetOrKeep::Keep,
1238 validity_start: SetOrKeep::Keep,
1239 validity_end: SetOrKeep::Keep,
1240 function_params: SetOrKeep::Keep,
1241 trigger: SetOrKeep::Keep,
1242 can_be_executed: SetOrKeep::Keep,
1243 };
1244
1245 let mut buffer = Vec::new();
1246 let serializer = AsyncMessageUpdateSerializer::new(true);
1247 serializer.serialize(&msg, &mut buffer).unwrap();
1248 let deserializer = AsyncMessageUpdateDeserializer::new(
1249 THREAD_COUNT,
1250 MAX_FUNCTION_NAME_LENGTH,
1251 MAX_PARAMETERS_SIZE as u64,
1252 MAX_DATASTORE_KEY_LENGTH as u32,
1253 true,
1254 );
1255 let (rest, deserialized) = deserializer
1256 .deserialize::<DeserializeError>(&buffer)
1257 .unwrap();
1258 assert!(rest.is_empty());
1259 assert_eq!(msg, deserialized);
1260 }
1261
1262 #[test]
1263 fn higher_limit_ser_deser_message_update() {
1264 let msg = AsyncMessageUpdate {
1265 emission_slot: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
1266 emission_index: SetOrKeep::Set(u64::MAX),
1267 sender: SetOrKeep::Set(
1268 Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x").unwrap(),
1269 ),
1270 destination: SetOrKeep::Set(
1271 Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G").unwrap(),
1272 ),
1273 function: SetOrKeep::Set(
1274 (0..MAX_FUNCTION_NAME_LENGTH)
1275 .map(|_| "X")
1276 .collect::<String>(),
1277 ),
1278 max_gas: SetOrKeep::Set(u64::MAX),
1279 fee: SetOrKeep::Set(Amount::from_raw(u64::MAX)),
1280 coins: SetOrKeep::Set(Amount::from_raw(u64::MAX)),
1281 validity_start: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
1282 validity_end: SetOrKeep::Set(Slot::new(u64::MAX, THREAD_COUNT - 1)),
1283 function_params: SetOrKeep::Set(vec![0; MAX_PARAMETERS_SIZE as usize]),
1284 trigger: SetOrKeep::Set(Some(AsyncMessageTrigger {
1285 address: Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x")
1286 .unwrap(),
1287 datastore_key: Some(vec![0; MAX_DATASTORE_KEY_LENGTH as usize]),
1288 })),
1289 can_be_executed: SetOrKeep::Set(true),
1290 };
1291
1292 let mut buffer = Vec::new();
1293 let serializer = AsyncMessageUpdateSerializer::new(true);
1294 serializer.serialize(&msg, &mut buffer).unwrap();
1295 let deserializer = AsyncMessageUpdateDeserializer::new(
1296 THREAD_COUNT,
1297 MAX_FUNCTION_NAME_LENGTH,
1298 MAX_PARAMETERS_SIZE as u64,
1299 MAX_DATASTORE_KEY_LENGTH as u32,
1300 true,
1301 );
1302 let (rest, deserialized) = deserializer
1303 .deserialize::<DeserializeError>(&buffer)
1304 .unwrap();
1305 assert!(rest.is_empty());
1306 assert_eq!(msg, deserialized);
1307 }
1308
1309 #[test]
1310 fn bad_serialization_message() {
1311 let message = AsyncMessage::new(
1314 Slot::new(1, 2),
1315 0,
1316 Address::from_str("AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x").unwrap(),
1317 Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G").unwrap(),
1318 String::from("test"),
1319 10000000,
1320 Amount::from_str("1").unwrap(),
1321 Amount::from_str("1").unwrap(),
1322 Slot::new(2, 0),
1323 Slot::new(3, 0),
1324 vec![1, 2, 3, 4],
1325 Some(AsyncMessageTrigger {
1326 address: Address::from_str("AU12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G")
1327 .unwrap(),
1328 datastore_key: None,
1329 }),
1330 None,
1331 );
1332 let message_serializer = AsyncMessageSerializer::new(false);
1333 let mut serialized = Vec::new();
1334 message_serializer
1335 .serialize(&message, &mut serialized)
1336 .unwrap();
1337 let message_deserializer = AsyncMessageDeserializer::new(
1338 THREAD_COUNT,
1339 MAX_FUNCTION_NAME_LENGTH,
1340 MAX_PARAMETERS_SIZE as u64,
1341 MAX_DATASTORE_KEY_LENGTH as u32,
1342 false,
1343 );
1344 serialized[1] = 50;
1346 message_deserializer
1347 .deserialize::<DeserializeError>(&serialized)
1348 .unwrap_err();
1349 }
1350}