1use std::collections::BTreeMap;
2use std::ops::Bound::{Excluded, Included};
3
4use nom::{
5 bytes::complete::take,
6 error::context,
7 error::{ContextError, ParseError},
8 multi::length_count,
9 sequence::tuple,
10 IResult, Parser,
11};
12use num::rational::Ratio;
13
14use crate::versioning::{
15 Active, AdvanceLW, ComponentState, ComponentStateTypeId, LockedIn, MipComponent, MipInfo,
16 MipState, MipStatsConfig, MipStoreRaw, MipStoreStats, Started,
17};
18
19use massa_models::config::MIP_STORE_STATS_BLOCK_CONSIDERED;
20use massa_serialization::{
21 Deserializer, RatioDeserializer, RatioSerializer, SerializeError, Serializer,
22 U32VarIntDeserializer, U32VarIntSerializer, U64VarIntDeserializer, U64VarIntSerializer,
23};
24use massa_time::{MassaTime, MassaTimeDeserializer, MassaTimeSerializer};
25
26const MIP_INFO_NAME_MAX_LEN: u32 = 255;
29const MIP_INFO_COMPONENTS_MAX_ENTRIES: u32 = 8;
30const COMPONENT_STATE_VARIANT_COUNT: u32 = ComponentStateTypeId::VARIANT_COUNT as u32;
31const COMPONENT_STATE_ID_VARIANT_COUNT: u32 = ComponentStateTypeId::VARIANT_COUNT as u32;
32const MIP_STORE_MAX_ENTRIES: u32 = 4096;
33#[allow(dead_code)]
34const MIP_STORE_MAX_SIZE: usize = 2097152;
35
36pub struct MipInfoSerializer {
38 u32_serializer: U32VarIntSerializer,
39 time_serializer: MassaTimeSerializer, }
41
42impl MipInfoSerializer {
43 pub fn new() -> Self {
45 MipInfoSerializer {
46 u32_serializer: U32VarIntSerializer::new(),
47 time_serializer: MassaTimeSerializer::new(),
48 }
49 }
50}
51
52impl Default for MipInfoSerializer {
53 fn default() -> Self {
54 Self::new()
55 }
56}
57
58impl Serializer<MipInfo> for MipInfoSerializer {
59 fn serialize(&self, value: &MipInfo, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
60 let name_len_ = value.name.len();
62 let name_len = u32::try_from(name_len_).map_err(|_| {
63 SerializeError::GeneralError(format!("Cannot convert name_len ({}) to u32", name_len_))
64 })?;
65 self.u32_serializer.serialize(&name_len, buffer)?;
66 buffer.extend(value.name.as_bytes());
67 self.u32_serializer.serialize(&value.version, buffer)?;
69
70 let components_len_ = value.components.len();
72 let components_len = u32::try_from(components_len_).map_err(|_| {
73 SerializeError::GeneralError(format!(
74 "Cannot convert component_len ({}) to u32",
75 components_len_
76 ))
77 })?;
78 self.u32_serializer.serialize(&components_len, buffer)?;
80 for (component, component_version) in value.components.iter() {
82 self.u32_serializer
84 .serialize(&component.clone().into(), buffer)?;
85 self.u32_serializer.serialize(component_version, buffer)?;
87 }
88
89 self.time_serializer.serialize(&value.start, buffer)?;
91 self.time_serializer.serialize(&value.timeout, buffer)?;
93 self.time_serializer
95 .serialize(&value.activation_delay, buffer)?;
96 Ok(())
97 }
98}
99
100pub struct MipInfoDeserializer {
102 u32_deserializer: U32VarIntDeserializer,
103 name_len_deserializer: U32VarIntDeserializer,
104 components_len_deserializer: U32VarIntDeserializer,
105 time_deserializer: MassaTimeDeserializer,
106}
107
108impl MipInfoDeserializer {
109 pub fn new() -> Self {
111 Self {
112 u32_deserializer: U32VarIntDeserializer::new(Included(0), Excluded(u32::MAX)),
113 name_len_deserializer: U32VarIntDeserializer::new(
114 Included(0),
115 Included(MIP_INFO_NAME_MAX_LEN),
116 ),
117 components_len_deserializer: U32VarIntDeserializer::new(
118 Included(0),
119 Included(MIP_INFO_COMPONENTS_MAX_ENTRIES),
120 ),
121 time_deserializer: MassaTimeDeserializer::new((
122 Included(MassaTime::from_millis(0)),
123 Included(MassaTime::from_millis(u64::MAX)),
124 )),
125 }
126 }
127}
128
129impl Default for MipInfoDeserializer {
131 fn default() -> Self {
132 Self::new()
133 }
134}
135
136impl Deserializer<MipInfo> for MipInfoDeserializer {
137 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
138 &self,
139 buffer: &'a [u8],
140 ) -> IResult<&'a [u8], MipInfo, E> {
141 context(
142 "Failed MipInfo deserialization",
143 tuple((
144 context("Failed name deserialization", |input| {
145 let (input_, len_) = self.name_len_deserializer.deserialize(input)?;
147 let len = usize::try_from(len_).unwrap();
149 let (rem, slice) = take(len)(input_)?;
150 let name = String::from_utf8(slice.to_vec()).map_err(|_| {
151 nom::Err::Error(ParseError::from_error_kind(
152 input_,
153 nom::error::ErrorKind::Fail,
154 ))
155 })?;
156 IResult::Ok((rem, name))
157 }),
158 context("Failed version deserialization", |input| {
159 self.u32_deserializer.deserialize(input)
160 }),
161 context(
162 "Failed components deserialization",
163 length_count(
164 context("Failed components length deserialization", |input| {
165 self.components_len_deserializer.deserialize(input)
167 }),
168 tuple((
169 context("Failed component deserialization", |input| {
170 let (rem, component_) = self.u32_deserializer.deserialize(input)?;
171 let component = MipComponent::from(component_);
172 IResult::Ok((rem, component))
173 }),
174 context("Failed component version deserialization", |input| {
175 self.u32_deserializer.deserialize(input)
176 }),
177 )),
178 ),
179 ),
180 context("Failed start deserialization", |input| {
181 self.time_deserializer.deserialize(input)
182 }),
183 context("Failed timeout deserialization", |input| {
184 self.time_deserializer.deserialize(input)
185 }),
186 context("Failed activation delay deserialization", |input| {
187 self.time_deserializer.deserialize(input)
188 }),
189 )),
190 )
191 .map(
192 |(name, version, components, start, timeout, activation_delay)| MipInfo {
193 name,
194 version,
195 components: components.into_iter().collect(),
196 start,
197 timeout,
198 activation_delay,
199 },
200 )
201 .parse(buffer)
202 }
203}
204
205pub struct ComponentStateSerializer {
211 u32_serializer: U32VarIntSerializer,
212 ratio_serializer: RatioSerializer<u64, U64VarIntSerializer>,
213 time_serializer: MassaTimeSerializer,
214}
215
216impl ComponentStateSerializer {
217 pub fn new() -> Self {
219 Self {
220 u32_serializer: U32VarIntSerializer::new(),
221 ratio_serializer: RatioSerializer::new(U64VarIntSerializer::new()),
222 time_serializer: MassaTimeSerializer::new(),
223 }
224 }
225}
226
227impl Default for ComponentStateSerializer {
228 fn default() -> Self {
229 Self::new()
230 }
231}
232
233impl Serializer<ComponentState> for ComponentStateSerializer {
234 fn serialize(
235 &self,
236 value: &ComponentState,
237 buffer: &mut Vec<u8>,
238 ) -> Result<(), SerializeError> {
239 let state_id = u32::from(ComponentStateTypeId::from(value));
240 self.u32_serializer.serialize(&state_id, buffer)?;
241 match value {
242 ComponentState::Started(Started {
243 vote_ratio: threshold,
244 }) => {
245 self.ratio_serializer.serialize(threshold, buffer)?;
247 }
248 ComponentState::LockedIn(LockedIn { at }) => {
249 self.time_serializer.serialize(at, buffer)?;
250 }
251 ComponentState::Active(Active { at }) => {
252 self.time_serializer.serialize(at, buffer)?;
253 }
254 _ => {}
255 }
256 Ok(())
257 }
258}
259
260pub struct ComponentStateDeserializer {
262 state_deserializer: U32VarIntDeserializer,
263 ratio_deserializer: RatioDeserializer<u64, U64VarIntDeserializer>,
264 time_deserializer: MassaTimeDeserializer,
265}
266
267impl ComponentStateDeserializer {
268 pub fn new() -> Self {
270 Self {
271 state_deserializer: U32VarIntDeserializer::new(
272 Included(0),
273 Excluded(COMPONENT_STATE_VARIANT_COUNT),
274 ),
275 ratio_deserializer: RatioDeserializer::new(U64VarIntDeserializer::new(
276 Included(0),
277 Included(u64::MAX),
278 )),
279 time_deserializer: MassaTimeDeserializer::new((
280 Included(MassaTime::from_millis(0)),
281 Included(MassaTime::from_millis(u64::MAX)),
282 )),
283 }
284 }
285}
286
287impl Default for ComponentStateDeserializer {
288 fn default() -> Self {
289 Self::new()
290 }
291}
292
293impl Deserializer<ComponentState> for ComponentStateDeserializer {
294 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
295 &self,
296 buffer: &'a [u8],
297 ) -> IResult<&'a [u8], ComponentState, E> {
298 let (rem, enum_value_) = context("Failed enum value der", |input| {
299 self.state_deserializer.deserialize(input)
300 })
301 .parse(buffer)?;
302
303 let enum_value = ComponentStateTypeId::try_from(enum_value_).map_err(|_| {
304 nom::Err::Error(ParseError::from_error_kind(
305 buffer,
306 nom::error::ErrorKind::Eof,
307 ))
308 })?;
309 let (rem2, state): (&[u8], ComponentState) = match enum_value {
310 ComponentStateTypeId::Defined => (rem, ComponentState::defined()),
311 ComponentStateTypeId::Started => {
312 let (rem2, threshold) = context("Failed threshold value der", |input| {
313 self.ratio_deserializer.deserialize(input)
314 })
315 .parse(rem)?;
316 (rem2, ComponentState::started(threshold))
317 }
318 ComponentStateTypeId::LockedIn => {
319 let (rem2, at) = context("Failed delay value der", |input| {
320 self.time_deserializer.deserialize(input)
321 })
322 .parse(rem)?;
323 (rem2, ComponentState::locked_in(at))
324 }
325 ComponentStateTypeId::Active => {
326 let (rem2, at) = context("Failed at value der", |input| {
327 self.time_deserializer.deserialize(input)
328 })
329 .parse(rem)?;
330 (rem2, ComponentState::active(at))
331 }
332 ComponentStateTypeId::Failed => (rem, ComponentState::failed()),
333 _ => (rem, ComponentState::Error),
334 };
335
336 IResult::Ok((rem2, state))
337 }
338}
339
340pub struct AdvanceLWSerializer {
346 ratio_serializer: RatioSerializer<u64, U64VarIntSerializer>,
347 time_serializer: MassaTimeSerializer,
348}
349
350impl AdvanceLWSerializer {
351 pub fn new() -> Self {
353 Self {
354 ratio_serializer: RatioSerializer::new(U64VarIntSerializer::new()),
355 time_serializer: MassaTimeSerializer::new(),
356 }
357 }
358}
359
360impl Default for AdvanceLWSerializer {
361 fn default() -> Self {
362 Self::new()
363 }
364}
365
366impl Serializer<AdvanceLW> for AdvanceLWSerializer {
367 fn serialize(&self, value: &AdvanceLW, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
368 self.ratio_serializer.serialize(&value.threshold, buffer)?;
370 self.time_serializer.serialize(&value.now, buffer)?;
372 Ok(())
373 }
374}
375
376pub struct AdvanceLWDeserializer {
378 ratio_deserializer: RatioDeserializer<u64, U64VarIntDeserializer>,
379 time_deserializer: MassaTimeDeserializer,
380}
381
382impl AdvanceLWDeserializer {
383 pub fn new() -> Self {
385 Self {
386 ratio_deserializer: RatioDeserializer::new(U64VarIntDeserializer::new(
387 Included(0),
388 Included(u64::MAX),
389 )),
390 time_deserializer: MassaTimeDeserializer::new((
391 Included(MassaTime::from_millis(0)),
392 Included(MassaTime::from_millis(u64::MAX)),
393 )),
394 }
395 }
396}
397
398impl Default for AdvanceLWDeserializer {
399 fn default() -> Self {
400 Self::new()
401 }
402}
403
404impl Deserializer<AdvanceLW> for AdvanceLWDeserializer {
405 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
406 &self,
407 buffer: &'a [u8],
408 ) -> IResult<&'a [u8], AdvanceLW, E> {
409 context(
410 "Failed Advance deserialization",
411 tuple((
412 context("Failed threshold deserialization", |input| {
413 self.ratio_deserializer.deserialize(input)
414 }),
415 context("Failed now deserialization", |input| {
416 self.time_deserializer.deserialize(input)
417 }),
418 )),
419 )
420 .map(|(threshold, now)| AdvanceLW { threshold, now })
421 .parse(buffer)
422 }
423}
424
425pub struct MipStateSerializer {
431 state_serializer: ComponentStateSerializer,
432 advance_serializer: AdvanceLWSerializer,
433 u32_serializer: U32VarIntSerializer,
434}
435
436impl MipStateSerializer {
437 pub fn new() -> Self {
439 Self {
440 state_serializer: Default::default(),
441 advance_serializer: Default::default(),
442 u32_serializer: U32VarIntSerializer,
443 }
444 }
445}
446
447impl Default for MipStateSerializer {
448 fn default() -> Self {
449 Self::new()
450 }
451}
452
453impl Serializer<MipState> for MipStateSerializer {
454 fn serialize(&self, value: &MipState, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
455 self.state_serializer.serialize(&value.state, buffer)?;
456 self.u32_serializer.serialize(
458 &value.history.len().try_into().map_err(|err| {
459 SerializeError::GeneralError(format!("too many history: {}", err))
460 })?,
461 buffer,
462 )?;
463 for (advance, state_id) in value.history.iter() {
465 self.advance_serializer.serialize(advance, buffer)?;
466 self.u32_serializer
467 .serialize(&u32::from(state_id.clone()), buffer)?;
468 }
469 Ok(())
470 }
471}
472
473pub struct MipStateDeserializer {
475 state_deserializer: ComponentStateDeserializer,
476 advance_deserializer: AdvanceLWDeserializer,
477 state_id_deserializer: U32VarIntDeserializer,
478 u32_deserializer: U32VarIntDeserializer,
479}
480
481impl MipStateDeserializer {
482 pub fn new() -> Self {
484 Self {
485 state_deserializer: ComponentStateDeserializer::new(),
486 advance_deserializer: AdvanceLWDeserializer::new(),
487 state_id_deserializer: U32VarIntDeserializer::new(
488 Included(0),
489 Excluded(COMPONENT_STATE_ID_VARIANT_COUNT),
490 ),
491 u32_deserializer: U32VarIntDeserializer::new(Included(0), Excluded(u32::MAX)),
492 }
493 }
494}
495
496impl Default for MipStateDeserializer {
497 fn default() -> Self {
498 Self::new()
499 }
500}
501
502impl Deserializer<MipState> for MipStateDeserializer {
503 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
504 &self,
505 buffer: &'a [u8],
506 ) -> IResult<&'a [u8], MipState, E> {
507 let (rem, component_state) = context("Failed component state deserialization", |input| {
509 self.state_deserializer.deserialize(input)
510 })
511 .parse(buffer)?;
512 let (rem2, history) = context(
514 "Failed history deserialization",
515 length_count(
516 context("Failed length deserialization", |input| {
517 self.u32_deserializer.deserialize(input)
518 }),
519 context(
520 "Failed history items deserialization",
521 tuple((
522 context("Failed advance deserialization", |input| {
523 self.advance_deserializer.deserialize(input)
524 }),
525 context("Failed state id deserialization", |input| {
526 let (res, state_id_) = self.state_id_deserializer.deserialize(input)?;
528
529 let state_id =
530 ComponentStateTypeId::try_from(state_id_).map_err(|_e| {
531 nom::Err::Error(ParseError::from_error_kind(
532 buffer,
533 nom::error::ErrorKind::Fail,
534 ))
535 })?;
536
537 IResult::Ok((res, state_id))
538 }),
539 )),
540 ),
541 ),
542 )
543 .map(|items| {
544 items
545 .into_iter()
546 .collect::<BTreeMap<AdvanceLW, ComponentStateTypeId>>()
547 })
548 .parse(rem)?;
549
550 IResult::Ok((
551 rem2,
552 MipState {
553 state: component_state,
554 history,
555 },
556 ))
557 }
558}
559
560pub struct MipStoreStatsSerializer {
566 u32_serializer: U32VarIntSerializer,
567 u64_serializer: U64VarIntSerializer,
568}
569
570impl MipStoreStatsSerializer {
571 pub fn new() -> Self {
573 Self {
574 u32_serializer: U32VarIntSerializer::new(),
575 u64_serializer: U64VarIntSerializer::new(),
576 }
577 }
578}
579
580impl Default for MipStoreStatsSerializer {
581 fn default() -> Self {
582 Self::new()
583 }
584}
585
586impl Serializer<MipStoreStats> for MipStoreStatsSerializer {
587 fn serialize(&self, value: &MipStoreStats, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
588 {
590 let entry_count_ = value.latest_announcements.len();
591 let entry_count = u32::try_from(entry_count_).map_err(|e| {
592 SerializeError::GeneralError(format!("Could not convert to u32: {}", e))
593 })?;
594 let entry_count_max = u32::try_from(MIP_STORE_STATS_BLOCK_CONSIDERED).map_err(|e| {
595 SerializeError::GeneralError(format!("Could not convert to u32: {}", e))
596 })?;
597
598 if entry_count > entry_count_max {
599 return Err(SerializeError::GeneralError(format!(
600 "Too many entries in MipStoreStats latest announcements, max: {}, received: {}",
601 entry_count_max, entry_count
602 )));
603 }
604 self.u32_serializer.serialize(&entry_count, buffer)?;
605 for v in value.latest_announcements.iter() {
606 self.u32_serializer.serialize(v, buffer)?;
607 }
608 }
609
610 {
611 let entry_count_2_ = value.network_version_counters.len();
612 let entry_count_2 = u32::try_from(entry_count_2_).map_err(|e| {
613 SerializeError::GeneralError(format!("Could not convert to u32: {}", e))
614 })?;
615 let entry_count_2_max =
616 u32::try_from(MIP_STORE_STATS_BLOCK_CONSIDERED).map_err(|e| {
617 SerializeError::GeneralError(format!("Could not convert to u32: {}", e))
618 })?;
619
620 if entry_count_2 > entry_count_2_max {
621 return Err(SerializeError::GeneralError(format!(
622 "Too many entries in MipStoreStats version counters, max: {}, received: {}",
623 entry_count_2_max, entry_count_2
624 )));
625 }
626 self.u32_serializer.serialize(&entry_count_2, buffer)?;
627 for (v, c) in value.network_version_counters.iter() {
628 self.u32_serializer.serialize(v, buffer)?;
629 self.u64_serializer.serialize(c, buffer)?;
630 }
631 }
632
633 Ok(())
634 }
635}
636
637pub struct MipStoreStatsDeserializer {
639 config: MipStatsConfig,
640 u32_deserializer: U32VarIntDeserializer,
641 u64_deserializer: U64VarIntDeserializer,
642}
643
644impl MipStoreStatsDeserializer {
645 pub fn new(block_count_considered: usize, warn_announced_version_ratio: Ratio<u64>) -> Self {
647 Self {
648 config: MipStatsConfig {
649 block_count_considered,
650 warn_announced_version_ratio,
651 },
652 u32_deserializer: U32VarIntDeserializer::new(Included(0), Included(u32::MAX)),
653 u64_deserializer: U64VarIntDeserializer::new(Included(0), Included(u64::MAX)),
654 }
655 }
656}
657
658impl Deserializer<MipStoreStats> for MipStoreStatsDeserializer {
659 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
660 &self,
661 buffer: &'a [u8],
662 ) -> IResult<&'a [u8], MipStoreStats, E> {
663 let cfg_block_considered: u32 =
664 u32::try_from(self.config.block_count_considered).map_err(|_e| {
665 nom::Err::Error(ParseError::from_error_kind(
666 buffer,
667 nom::error::ErrorKind::Fail,
668 ))
669 })?;
670
671 let (rem3, latest_announcements_) = context(
672 "Failed MipStoreStats latest announcements der",
673 length_count(
674 context("Failed latest announcements count der", |input| {
675 let (rem, count) = self.u32_deserializer.deserialize(input)?;
676 if count > cfg_block_considered {
677 return IResult::Err(nom::Err::Error(ParseError::from_error_kind(
678 input,
679 nom::error::ErrorKind::Fail,
680 )));
681 }
682 IResult::Ok((rem, count))
683 }),
684 context("Failed latest announcement data der", |input| {
685 self.u32_deserializer.deserialize(input)
686 }),
687 ),
688 )
689 .parse(buffer)?;
690
691 let (rem4, network_version_counters) = context(
692 "Failed MipStoreStats network version counters der",
693 length_count(
694 context("Failed counters len der", |input| {
695 let (rem, count) = self.u32_deserializer.deserialize(input)?;
696 if count > cfg_block_considered {
697 return IResult::Err(nom::Err::Error(ParseError::from_error_kind(
698 input,
699 nom::error::ErrorKind::Fail,
700 )));
701 }
702 IResult::Ok((rem, count))
703 }),
704 context("Failed counters data der", |input| {
705 let (rem, v) = self.u32_deserializer.deserialize(input)?;
706 let (rem2, c) = self.u64_deserializer.deserialize(rem)?;
707 IResult::Ok((rem2, (v, c)))
708 }),
709 ),
710 )
711 .parse(rem3)?;
712
713 IResult::Ok((
714 rem4,
715 MipStoreStats {
716 config: self.config.clone(),
717 latest_announcements: latest_announcements_.into_iter().collect(),
718 network_version_counters: network_version_counters.into_iter().collect(),
719 },
720 ))
721 }
722}
723
724pub struct MipStoreRawSerializer {
730 u32_serializer: U32VarIntSerializer,
731 info_serializer: MipInfoSerializer,
732 state_serializer: MipStateSerializer,
733 stats_serializer: MipStoreStatsSerializer,
734}
735
736impl MipStoreRawSerializer {
737 pub fn new() -> Self {
739 Self {
740 u32_serializer: U32VarIntSerializer::new(),
741 info_serializer: MipInfoSerializer::new(),
742 state_serializer: MipStateSerializer::new(),
743 stats_serializer: MipStoreStatsSerializer::new(),
744 }
745 }
746}
747
748impl Default for MipStoreRawSerializer {
749 fn default() -> Self {
750 Self::new()
751 }
752}
753
754impl Serializer<MipStoreRaw> for MipStoreRawSerializer {
755 fn serialize(&self, value: &MipStoreRaw, buffer: &mut Vec<u8>) -> Result<(), SerializeError> {
756 let entry_count_ = value.store.len();
757 let entry_count = u32::try_from(entry_count_).map_err(|e| {
758 SerializeError::GeneralError(format!("Could not convert to u32: {}", e))
759 })?;
760 if entry_count > MIP_STORE_MAX_ENTRIES {
761 return Err(SerializeError::GeneralError(format!(
762 "Too many entries in VersioningStoreRaw, max: {}, received: {}",
763 MIP_STORE_MAX_ENTRIES, entry_count
764 )));
765 }
766 self.u32_serializer.serialize(&entry_count, buffer)?;
767 for (key, value) in value.store.iter() {
768 self.info_serializer.serialize(key, buffer)?;
769 self.state_serializer.serialize(value, buffer)?;
770 }
771 self.stats_serializer.serialize(&value.stats, buffer)?;
772 Ok(())
773 }
774}
775
776pub struct MipStoreRawDeserializer {
778 entry_count_deserializer: U32VarIntDeserializer,
779 info_deserializer: MipInfoDeserializer,
780 state_deserializer: MipStateDeserializer,
781 stats_deserializer: MipStoreStatsDeserializer,
782}
783
784impl MipStoreRawDeserializer {
785 pub fn new(block_count_considered: usize, warn_announced_version_ratio: Ratio<u64>) -> Self {
787 Self {
788 entry_count_deserializer: U32VarIntDeserializer::new(
789 Included(0),
790 Included(MIP_STORE_MAX_ENTRIES),
791 ),
792 info_deserializer: MipInfoDeserializer::new(),
793 state_deserializer: MipStateDeserializer::new(),
794 stats_deserializer: MipStoreStatsDeserializer::new(
795 block_count_considered,
796 warn_announced_version_ratio,
797 ),
798 }
799 }
800}
801
802impl Deserializer<MipStoreRaw> for MipStoreRawDeserializer {
803 fn deserialize<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>(
804 &self,
805 buffer: &'a [u8],
806 ) -> IResult<&'a [u8], MipStoreRaw, E> {
807 context(
808 "Failed MipStoreRaw der",
809 tuple((
810 length_count(
811 context("Failed entry count der", |input| {
812 self.entry_count_deserializer.deserialize(input)
813 }),
814 context("Failed items der", |input| {
815 let (rem, vi) = self.info_deserializer.deserialize(input)?;
816 let (rem2, vs) = self.state_deserializer.deserialize(rem)?;
817 IResult::Ok((rem2, (vi, vs)))
818 }),
819 ),
820 context("Failed mip store stats der", |input| {
821 self.stats_deserializer.deserialize(input)
822 }),
823 )),
824 )
825 .map(|(items, stats)| MipStoreRaw {
826 store: items.into_iter().collect(),
827 stats,
828 })
829 .parse(buffer)
830 }
831}
832
833#[cfg(test)]
836mod test {
837 use super::*;
838
839 use assert_matches::assert_matches;
840 use std::mem::{size_of, size_of_val};
841
842 use more_asserts::assert_lt;
843 use num::rational::Ratio;
844 use num::FromPrimitive;
845
846 use crate::test_helpers::versioning_helpers::advance_state_until;
847
848 use massa_serialization::DeserializeError;
849 use massa_time::MassaTime;
850
851 #[test]
852 fn test_mip_component_non_exhaustive() {
853 let last_variant__ = MipComponent::VARIANT_COUNT - 2; let last_variant_ = u32::try_from(last_variant__).unwrap();
855 let last_variant = MipComponent::from(last_variant_);
856
857 match last_variant {
858 MipComponent::__Nonexhaustive => {
859 panic!("Should be a known enum value")
860 }
861 _ => {
862 println!("last variant of MipComponent is: {:?}", last_variant);
864 }
865 }
866
867 {
868 let variant__ = MipComponent::VARIANT_COUNT - 1;
869 let variant_ = u32::try_from(variant__).unwrap();
870 assert_matches!(MipComponent::from(variant_), MipComponent::__Nonexhaustive);
871 }
872
873 {
874 let variant__ = MipComponent::VARIANT_COUNT;
875 let variant_ = u32::try_from(variant__).unwrap();
876 assert_matches!(MipComponent::from(variant_), MipComponent::__Nonexhaustive);
877 }
878 }
879
880 #[test]
881 fn test_mip_info_ser_der() {
882 let mi_1 = MipInfo {
883 name: "MIP-0002".to_string(),
884 version: 2,
885 components: BTreeMap::from([(MipComponent::Address, 1)]),
886 start: MassaTime::from_millis(2),
887 timeout: MassaTime::from_millis(5),
888 activation_delay: MassaTime::from_millis(2),
889 };
890
891 let mut buf = Vec::new();
892 let mip_info_ser = MipInfoSerializer::new();
893 mip_info_ser.serialize(&mi_1, &mut buf).unwrap();
894
895 let mip_info_der = MipInfoDeserializer::new();
896
897 let (rem, mi_1_der) = mip_info_der.deserialize::<DeserializeError>(&buf).unwrap();
898
899 assert!(rem.is_empty());
900 assert_eq!(mi_1, mi_1_der);
901 }
902
903 #[test]
904 fn test_mip_info_ser_der_err() {
905 {
906 let mi_1 = MipInfo {
908 name: "MIP-0002".to_string(),
909 version: 2,
910 components: BTreeMap::from([
911 (MipComponent::Address, 1),
912 (MipComponent::KeyPair, 2),
913 (MipComponent::Block, 3),
914 (MipComponent::VM, 4),
915 (MipComponent::FinalStateHashKind, 5),
916 (MipComponent::__Nonexhaustive, 6),
917 ]),
918 start: MassaTime::from_millis(2),
919 timeout: MassaTime::from_millis(5),
920 activation_delay: MassaTime::from_millis(2),
921 };
922
923 {
924 let mut buf = Vec::new();
925 let mip_info_ser = MipInfoSerializer::new();
926 mip_info_ser.serialize(&mi_1, &mut buf).unwrap();
927
928 let mut mip_info_der = MipInfoDeserializer::new();
929 mip_info_der.components_len_deserializer =
931 U32VarIntDeserializer::new(Included(0), Included(2));
932
933 let res = mip_info_der.deserialize::<DeserializeError>(&buf);
934 assert!(res.is_err());
935 }
936 }
937
938 {
939 let mi_2 = MipInfo {
941 name: "a".repeat(MIP_INFO_NAME_MAX_LEN as usize + 1),
942 version: 2,
943 components: BTreeMap::from([(MipComponent::Address, 1)]),
944 start: MassaTime::from_millis(2),
945 timeout: MassaTime::from_millis(5),
946 activation_delay: MassaTime::from_millis(2),
947 };
948
949 {
950 let mut buf = Vec::new();
951 let mip_info_ser = MipInfoSerializer::new();
952 mip_info_ser.serialize(&mi_2, &mut buf).unwrap();
953
954 let mip_info_der = MipInfoDeserializer::new();
955
956 let res = mip_info_der.deserialize::<DeserializeError>(&buf);
957 assert!(res.is_err());
958 }
959 }
960
961 {
962 let mip_info_name = "MIP-0002".to_string();
965 let mi_1 = MipInfo {
966 name: mip_info_name.clone(),
967 version: 2,
968 components: BTreeMap::from([
969 (MipComponent::Address, 1),
970 (MipComponent::KeyPair, 2),
971 (MipComponent::Block, 3),
972 ]),
973 start: MassaTime::from_millis(2),
974 timeout: MassaTime::from_millis(5),
975 activation_delay: MassaTime::from_millis(2),
976 };
977
978 let mut buf = Vec::new();
979 let mip_info_ser = MipInfoSerializer::new();
980 mip_info_ser.serialize(&mi_1, &mut buf).unwrap();
981
982 assert_eq!(buf[0], mip_info_name.len() as u8);
983 buf[0] = buf.len() as u8 + 1;
985 let mip_info_der = MipInfoDeserializer::new();
986 let res = mip_info_der.deserialize::<DeserializeError>(&buf);
987 assert!(res.is_err());
988 }
989 }
990
991 #[test]
992 fn test_component_state_ser_der() {
993 let state_ser = ComponentStateSerializer::new();
994 let state_der = ComponentStateDeserializer::new();
995
996 {
997 let st_1 = ComponentState::failed();
998
999 let mut buf = Vec::new();
1000 state_ser.serialize(&st_1, &mut buf).unwrap();
1001
1002 let (rem, st_1_der) = state_der.deserialize::<DeserializeError>(&buf).unwrap();
1003
1004 assert!(rem.is_empty());
1005 assert_eq!(st_1, st_1_der);
1006 }
1007
1008 {
1009 let st_2 = ComponentState::Started(Started {
1010 vote_ratio: Ratio::from_f32(0.9842).unwrap(),
1011 });
1012
1013 let mut buf = Vec::new();
1014 state_ser.serialize(&st_2, &mut buf).unwrap();
1015 let (rem, st_2_der) = state_der.deserialize::<DeserializeError>(&buf).unwrap();
1016
1017 assert!(rem.is_empty());
1018 assert_eq!(st_2, st_2_der);
1019 }
1020 }
1021
1022 #[test]
1023 fn test_component_state_ser_der_err() {
1024 let state_ser = ComponentStateSerializer::new();
1025 let state_der = ComponentStateDeserializer::new();
1026
1027 let st_2 = ComponentState::Started(Started {
1028 vote_ratio: Ratio::from_f32(0.9842).unwrap(),
1029 });
1030
1031 let mut buf = Vec::new();
1032 state_ser.serialize(&st_2, &mut buf).unwrap();
1033 buf[0] = 99;
1037
1038 let res = state_der.deserialize::<DeserializeError>(&buf);
1039 assert!(res.is_err());
1040 }
1041
1042 #[test]
1043 fn test_advance_ser_der() {
1044 let now = MassaTime::from_utc_ymd_hms(2017, 5, 11, 11, 33, 44).unwrap();
1045
1046 let adv_lw = AdvanceLW {
1047 threshold: Default::default(),
1048 now,
1049 };
1050
1051 let mut buf = Vec::new();
1052 let adv_ser = AdvanceLWSerializer::new();
1053 adv_ser.serialize(&adv_lw, &mut buf).unwrap();
1054
1055 let state_der = AdvanceLWDeserializer::new();
1056
1057 let (rem, adv_der) = state_der.deserialize::<DeserializeError>(&buf).unwrap();
1058
1059 assert!(rem.is_empty());
1060 assert_eq!(adv_lw, adv_der);
1061 }
1062
1063 #[test]
1064 fn test_mip_state_ser_der() {
1065 let state_1 = MipState::new(MassaTime::from_millis(100));
1066
1067 let mut buf = Vec::new();
1068 let state_ser = MipStateSerializer::new();
1069 state_ser.serialize(&state_1, &mut buf).unwrap();
1070
1071 let state_der = MipStateDeserializer::new();
1072
1073 let (rem, state_der_res) = state_der.deserialize::<DeserializeError>(&buf).unwrap();
1074
1075 assert!(rem.is_empty());
1076 assert_eq!(state_1, state_der_res);
1077 buf.clear();
1078
1079 let mi_1 = MipInfo {
1080 name: "MIP-0002".to_string(),
1081 version: 2,
1082 components: BTreeMap::from([(MipComponent::Address, 1)]),
1083 start: MassaTime::from_millis(2),
1084 timeout: MassaTime::from_millis(5),
1085 activation_delay: MassaTime::from_millis(2),
1086 };
1087
1088 let state_2 =
1089 advance_state_until(ComponentState::locked_in(MassaTime::from_millis(3)), &mi_1);
1090 state_ser.serialize(&state_2, &mut buf).unwrap();
1091 let (rem2, state_der_res) = state_der.deserialize::<DeserializeError>(&buf).unwrap();
1092
1093 assert!(rem2.is_empty());
1094 assert_eq!(state_2, state_der_res);
1095 }
1096
1097 #[test]
1098 fn test_mip_store_stats_ser_der() {
1099 let mip_stats_cfg = MipStatsConfig {
1100 block_count_considered: 10,
1101 warn_announced_version_ratio: Ratio::new_raw(30, 100),
1102 };
1103
1104 let mip_stats = MipStoreStats {
1105 config: mip_stats_cfg.clone(),
1106 latest_announcements: Default::default(),
1107 network_version_counters: Default::default(),
1108 };
1109
1110 let mut buf = Vec::new();
1111 let store_stats_ser = MipStoreStatsSerializer::new();
1112 store_stats_ser.serialize(&mip_stats, &mut buf).unwrap();
1113
1114 let store_stats_der = MipStoreStatsDeserializer::new(
1115 mip_stats_cfg.block_count_considered,
1116 mip_stats_cfg.warn_announced_version_ratio,
1117 );
1118 let (rem, store_stats_der_res) = store_stats_der
1119 .deserialize::<DeserializeError>(&buf)
1120 .unwrap();
1121
1122 assert!(rem.is_empty());
1123 assert_eq!(mip_stats, store_stats_der_res);
1124 }
1125
1126 #[test]
1127 fn test_mip_store_raw_ser_der() {
1128 let mip_stats_cfg = MipStatsConfig {
1129 block_count_considered: 10,
1130 warn_announced_version_ratio: Ratio::new_raw(30, 100),
1131 };
1132
1133 let mi_2 = MipInfo {
1134 name: "MIP-0002".to_string(),
1135 version: 2,
1136 components: BTreeMap::from([(MipComponent::Address, 1)]),
1137 start: MassaTime::from_millis(2),
1138 timeout: MassaTime::from_millis(5),
1139 activation_delay: MassaTime::from_millis(2),
1140 };
1141
1142 let mi_3 = MipInfo {
1143 name: "MIP-0003".to_string(),
1144 version: 3,
1145 components: BTreeMap::from([(MipComponent::Block, 1)]),
1146 start: MassaTime::from_millis(12),
1147 timeout: MassaTime::from_millis(17),
1148 activation_delay: MassaTime::from_millis(2),
1149 };
1150
1151 let _time = MassaTime::now();
1152 let state_2 = advance_state_until(ComponentState::active(_time), &mi_2);
1153 let state_3 = advance_state_until(ComponentState::started(Ratio::new_raw(42, 100)), &mi_3);
1154
1155 let store_raw =
1156 MipStoreRaw::try_from(([(mi_2, state_2), (mi_3, state_3)], mip_stats_cfg.clone()))
1157 .unwrap();
1158
1159 let mut buf = Vec::new();
1160 let store_raw_ser = MipStoreRawSerializer::new();
1161 store_raw_ser.serialize(&store_raw, &mut buf).unwrap();
1162
1163 let store_raw_der = MipStoreRawDeserializer::new(
1164 mip_stats_cfg.block_count_considered,
1165 mip_stats_cfg.warn_announced_version_ratio,
1166 );
1167 let (rem, store_raw_der_res) = store_raw_der.deserialize::<DeserializeError>(&buf).unwrap();
1168
1169 assert!(rem.is_empty());
1170 assert_eq!(store_raw, store_raw_der_res);
1171 }
1172
1173 #[test]
1174 #[ignore]
1175 fn mip_store_raw_max_size() {
1176 let mut mi_base = MipInfo {
1177 name: "A".repeat(254),
1178 version: 0,
1179 components: BTreeMap::from([(MipComponent::Address, 0)]),
1180 start: MassaTime::from_millis(0),
1181 timeout: MassaTime::from_millis(2),
1182 activation_delay: MassaTime::from_millis(2),
1183 };
1184
1185 let mi_base_size = size_of_val(&mi_base.name[..])
1187 + size_of_val(&mi_base.version)
1188 + mi_base.components.len() * size_of::<u32>() * 2
1189 + size_of_val(&mi_base.start)
1190 + size_of_val(&mi_base.timeout);
1191
1192 let mut all_state_size = 0;
1193
1194 let _time = MassaTime::now();
1195 let store_raw_: Vec<(MipInfo, MipState)> = (0..MIP_STORE_MAX_ENTRIES)
1196 .map(|_i| {
1197 mi_base.version += 1;
1198 mi_base
1199 .components
1200 .entry(MipComponent::Address)
1201 .and_modify(|e| *e += 1);
1202 mi_base.start = mi_base.timeout.saturating_add(MassaTime::from_millis(1));
1203 mi_base.timeout = mi_base.start.saturating_add(MassaTime::from_millis(2));
1204
1205 let state = advance_state_until(ComponentState::active(_time), &mi_base);
1206
1207 all_state_size += size_of_val(&state.state);
1208 all_state_size += state.history.len() * (size_of::<AdvanceLW>() + size_of::<u32>());
1209
1210 (mi_base.clone(), state)
1211 })
1212 .collect();
1213
1214 let store_raw = MipStoreRaw {
1216 store: BTreeMap::from_iter(store_raw_),
1217 stats: MipStoreStats::new(MipStatsConfig {
1218 block_count_considered: 10,
1219 warn_announced_version_ratio: Ratio::new(30, 100),
1220 }),
1221 };
1222 assert_eq!(store_raw.store.len(), MIP_STORE_MAX_ENTRIES as usize);
1223
1224 let store_raw_size = (store_raw.store.len() * mi_base_size) + all_state_size;
1225 assert_lt!(store_raw_size, MIP_STORE_MAX_SIZE);
1226
1227 let mut buf = Vec::new();
1229 let store_raw_ser = MipStoreRawSerializer::new();
1230
1231 store_raw_ser
1232 .serialize(&store_raw, &mut buf)
1233 .expect("Unable to serialize");
1234
1235 let store_raw_der = MipStoreRawDeserializer::new(10, Ratio::new(30, 100));
1236 let (rem, store_raw_der_res) = store_raw_der.deserialize::<DeserializeError>(&buf).unwrap();
1237
1238 assert!(rem.is_empty());
1239 assert_eq!(store_raw, store_raw_der_res);
1240 }
1241}