1use crate::{FromBytes, ToBytes, io_error};
17
18use enum_iterator::{Sequence, last};
19use snarkvm_algorithms::snark::varuna::VarunaVersion;
20use std::io;
21
22#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Sequence)]
25#[repr(u16)]
26pub enum ConsensusVersion {
27 V1 = 1,
29 V2 = 2,
31 V3 = 3,
33 V4 = 4,
35 V5 = 5,
37 V6 = 6,
39 V7 = 7,
41 V8 = 8,
43 V9 = 9,
45 V10 = 10,
47 V11 = 11,
49 V12 = 12,
51 V13 = 13,
53 V14 = 14,
58 V15 = 15,
61 V16 = 16,
66 V17 = 17,
69 V18 = 18,
72}
73
74impl ToBytes for ConsensusVersion {
75 fn write_le<W: io::Write>(&self, writer: W) -> io::Result<()> {
76 (*self as u16).write_le(writer)
77 }
78}
79
80impl FromBytes for ConsensusVersion {
81 fn read_le<R: io::Read>(reader: R) -> io::Result<Self> {
82 match u16::read_le(reader)? {
83 0 => Err(io_error("Zero is not a valid consensus version")),
84 1 => Ok(Self::V1),
85 2 => Ok(Self::V2),
86 3 => Ok(Self::V3),
87 4 => Ok(Self::V4),
88 5 => Ok(Self::V5),
89 6 => Ok(Self::V6),
90 7 => Ok(Self::V7),
91 8 => Ok(Self::V8),
92 9 => Ok(Self::V9),
93 10 => Ok(Self::V10),
94 11 => Ok(Self::V11),
95 12 => Ok(Self::V12),
96 13 => Ok(Self::V13),
97 14 => Ok(Self::V14),
98 15 => Ok(Self::V15),
99 16 => Ok(Self::V16),
100 17 => Ok(Self::V17),
101 18 => Ok(Self::V18),
102 _ => Err(io_error("Invalid consensus version")),
103 }
104 }
105}
106
107impl ConsensusVersion {
108 pub fn latest() -> Self {
109 last::<ConsensusVersion>().expect("At least one ConsensusVersion should be defined.")
110 }
111}
112
113impl std::fmt::Display for ConsensusVersion {
114 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115 write!(f, "{self:?}")
117 }
118}
119
120pub(crate) const NUM_CONSENSUS_VERSIONS: usize = enum_iterator::cardinality::<ConsensusVersion>();
122
123pub const CANARY_V0_CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS] = [
125 (ConsensusVersion::V1, 0),
126 (ConsensusVersion::V2, 2_900_000),
127 (ConsensusVersion::V3, 4_560_000),
128 (ConsensusVersion::V4, 5_730_000),
129 (ConsensusVersion::V5, 5_780_000),
130 (ConsensusVersion::V6, 6_240_000),
131 (ConsensusVersion::V7, 6_880_000),
132 (ConsensusVersion::V8, 7_565_000),
133 (ConsensusVersion::V9, 8_028_000),
134 (ConsensusVersion::V10, 8_600_000),
135 (ConsensusVersion::V11, 9_510_000),
136 (ConsensusVersion::V12, 10_030_000),
137 (ConsensusVersion::V13, 10_881_000),
138 (ConsensusVersion::V14, 11_960_000),
139 (ConsensusVersion::V15, u32::MAX),
140 (ConsensusVersion::V16, u32::MAX),
141 (ConsensusVersion::V17, u32::MAX),
142 (ConsensusVersion::V18, u32::MAX),
143];
144
145pub const MAINNET_V0_CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS] = [
147 (ConsensusVersion::V1, 0),
148 (ConsensusVersion::V2, 2_800_000),
149 (ConsensusVersion::V3, 4_900_000),
150 (ConsensusVersion::V4, 6_135_000),
151 (ConsensusVersion::V5, 7_060_000),
152 (ConsensusVersion::V6, 7_560_000),
153 (ConsensusVersion::V7, 7_570_000),
154 (ConsensusVersion::V8, 9_430_000),
155 (ConsensusVersion::V9, 10_272_000),
156 (ConsensusVersion::V10, 11_205_000),
157 (ConsensusVersion::V11, 12_870_000),
158 (ConsensusVersion::V12, 13_815_000),
159 (ConsensusVersion::V13, 16_850_000),
160 (ConsensusVersion::V14, 17_700_000),
161 (ConsensusVersion::V15, 19_264_000),
162 (ConsensusVersion::V16, 19_860_000),
163 (ConsensusVersion::V17, 19_860_001),
164 (ConsensusVersion::V18, 20_794_000),
165];
166
167pub const TESTNET_V0_CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS] = [
169 (ConsensusVersion::V1, 0),
170 (ConsensusVersion::V2, 2_950_000),
171 (ConsensusVersion::V3, 4_800_000),
172 (ConsensusVersion::V4, 6_625_000),
173 (ConsensusVersion::V5, 6_765_000),
174 (ConsensusVersion::V6, 7_600_000),
175 (ConsensusVersion::V7, 8_365_000),
176 (ConsensusVersion::V8, 9_173_000),
177 (ConsensusVersion::V9, 9_800_000),
178 (ConsensusVersion::V10, 10_525_000),
179 (ConsensusVersion::V11, 11_952_000),
180 (ConsensusVersion::V12, 12_669_000),
181 (ConsensusVersion::V13, 14_906_000),
182 (ConsensusVersion::V14, 15_370_000),
183 (ConsensusVersion::V15, 16_886_000),
184 (ConsensusVersion::V16, 17_319_000),
185 (ConsensusVersion::V17, 18_295_000),
186 (ConsensusVersion::V18, 18_296_000),
187];
188
189pub const TEST_CONSENSUS_VERSION_HEIGHTS: [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS] = [
194 (ConsensusVersion::V1, 0),
195 (ConsensusVersion::V2, 5),
196 (ConsensusVersion::V3, 6),
197 (ConsensusVersion::V4, 7),
198 (ConsensusVersion::V5, 8),
199 (ConsensusVersion::V6, 9),
200 (ConsensusVersion::V7, 10),
201 (ConsensusVersion::V8, 11),
202 (ConsensusVersion::V9, 12),
203 (ConsensusVersion::V10, 13),
204 (ConsensusVersion::V11, 14),
205 (ConsensusVersion::V12, 15),
206 (ConsensusVersion::V13, 16),
207 (ConsensusVersion::V14, 17),
208 (ConsensusVersion::V15, 18),
209 (ConsensusVersion::V16, 19),
210 (ConsensusVersion::V17, 20),
211 (ConsensusVersion::V18, 21),
212];
213
214#[cfg(any(test, feature = "test", feature = "test_consensus_heights"))]
215pub fn load_test_consensus_heights() -> [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS] {
216 load_test_consensus_heights_inner(std::env::var("CONSENSUS_VERSION_HEIGHTS").ok())
218}
219
220#[cfg(any(test, feature = "test", feature = "test_consensus_heights", feature = "wasm"))]
221pub(crate) fn load_test_consensus_heights_inner(
222 consensus_version_heights: Option<String>,
223) -> [(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS] {
224 let verify_consensus_heights = |heights: &[(ConsensusVersion, u32); NUM_CONSENSUS_VERSIONS]| {
226 assert_eq!(heights[0].1, 0, "Genesis height must be 0.");
228 for window in heights.windows(2) {
230 if window[0] >= window[1] {
231 panic!("Heights must be strictly increasing, but found: {window:?}");
232 }
233 }
234 };
235
236 let mut test_consensus_heights = TEST_CONSENSUS_VERSION_HEIGHTS;
238
239 match consensus_version_heights {
241 Some(height_string) => {
242 let parsing_error = format!("Expected exactly {NUM_CONSENSUS_VERSIONS} ConsensusVersion heights.");
243 let parsed_test_consensus_heights: [u32; NUM_CONSENSUS_VERSIONS] = height_string
245 .replace(" ", "")
246 .split(",")
247 .map(|height| height.parse::<u32>().expect("Heights should be valid u32 values."))
248 .collect::<Vec<u32>>()
249 .try_into()
250 .expect(&parsing_error);
251 for (i, height) in parsed_test_consensus_heights.into_iter().enumerate() {
253 test_consensus_heights[i] = (TEST_CONSENSUS_VERSION_HEIGHTS[i].0, height);
254 }
255 verify_consensus_heights(&test_consensus_heights);
257 test_consensus_heights
258 }
259 None => {
260 verify_consensus_heights(&test_consensus_heights);
262 test_consensus_heights
263 }
264 }
265}
266
267#[macro_export]
274macro_rules! consensus_config_value {
275 ($network:ident, $constant:ident, $seek_height:expr) => {
276 $network::CONSENSUS_VERSION($seek_height).map_or(None, |seek_version| {
278 match $network::$constant.binary_search_by(|(version, _)| version.cmp(&seek_version)) {
281 Ok(index) => Some($network::$constant[index].1),
283 Err(index) => {
285 if index == 0 {
287 None
288 } else {
290 Some($network::$constant[index - 1].1)
291 }
292 }
293 }
294 })
295 };
296}
297
298#[macro_export]
305macro_rules! consensus_config_value_by_version {
306 ($network:ident, $constant:ident, $seek_version:expr) => {
307 match $network::$constant.binary_search_by(|(version, _)| version.cmp(&$seek_version)) {
309 Ok(index) => Some($network::$constant[index].1),
311 Err(index) => {
313 if index == 0 {
315 None
316 } else {
318 Some($network::$constant[index - 1].1)
319 }
320 }
321 }
322 };
323}
324
325pub fn varuna_version_from_consensus(consensus_version: ConsensusVersion) -> VarunaVersion {
327 if consensus_version >= ConsensusVersion::V4 { VarunaVersion::V2 } else { VarunaVersion::V1 }
329}
330
331#[cfg(test)]
332mod tests {
333 use super::*;
334 use crate::{CanaryV0, MainnetV0, Network, TestnetV0};
335
336 fn consensus_constants_at_genesis<N: Network>() {
339 let height = N::_CONSENSUS_VERSION_HEIGHTS.first().unwrap().1;
340 assert_eq!(height, 0);
341 let consensus_version = N::_CONSENSUS_VERSION_HEIGHTS.first().unwrap().0;
342 assert_eq!(consensus_version, ConsensusVersion::V1);
343 assert_eq!(consensus_version as usize, 1);
344 }
345
346 fn consensus_versions<N: Network>() {
348 let mut previous_version = N::_CONSENSUS_VERSION_HEIGHTS.first().unwrap().0;
349 assert_eq!(previous_version as usize, 1);
351 for (version, _) in N::_CONSENSUS_VERSION_HEIGHTS.iter().skip(1) {
353 assert_eq!(*version as usize, previous_version as usize + 1);
354 previous_version = *version;
355 }
356 let mut previous_version = N::MAX_CERTIFICATES.first().unwrap().0;
358 for (version, _) in N::MAX_CERTIFICATES.iter().skip(1) {
359 assert!(*version > previous_version);
360 previous_version = *version;
361 }
362 let mut previous_version = N::TRANSACTION_SPEND_LIMIT.first().unwrap().0;
363 for (version, _) in N::TRANSACTION_SPEND_LIMIT.iter().skip(1) {
364 assert!(*version > previous_version);
365 previous_version = *version;
366 }
367 let mut previous_version = N::CREDITS_PER_SECOND_OF_RUNTIME.first().unwrap().0;
368 for (version, _) in N::CREDITS_PER_SECOND_OF_RUNTIME.iter().skip(1) {
369 assert!(*version > previous_version);
370 previous_version = *version;
371 }
372 let mut previous_version = N::MAX_ARRAY_ELEMENTS.first().unwrap().0;
373 for (version, _) in N::MAX_ARRAY_ELEMENTS.iter().skip(1) {
374 assert!(*version > previous_version);
375 previous_version = *version;
376 }
377 let mut previous_version = N::MAX_PROGRAM_SIZE.first().unwrap().0;
378 for (version, _) in N::MAX_PROGRAM_SIZE.iter().skip(1) {
379 assert!(*version > previous_version);
380 previous_version = *version;
381 }
382 let mut previous_version = N::MAX_TRANSACTION_SIZE.first().unwrap().0;
383 for (version, _) in N::MAX_TRANSACTION_SIZE.iter().skip(1) {
384 assert!(*version > previous_version);
385 previous_version = *version;
386 }
387 let mut previous_version = N::MAX_WRITES.first().unwrap().0;
388 for (version, _) in N::MAX_WRITES.iter().skip(1) {
389 assert!(*version > previous_version);
390 previous_version = *version;
391 }
392 let mut previous_version = N::ANCHOR_TIMES.first().unwrap().0;
393 for (version, _) in N::ANCHOR_TIMES.iter().skip(1) {
394 assert!(*version > previous_version);
395 previous_version = *version;
396 }
397 }
398
399 fn consensus_constants_increasing_heights<N: Network>() {
401 let mut previous_height = N::CONSENSUS_VERSION_HEIGHTS().first().unwrap().1;
402 for (version, height) in N::CONSENSUS_VERSION_HEIGHTS().iter().skip(1) {
403 assert!(*height > previous_height);
404 previous_height = *height;
405 assert_eq!(N::CONSENSUS_VERSION(*height).unwrap(), *version);
407 assert_eq!(N::CONSENSUS_HEIGHT(*version).unwrap(), *height);
409 }
410 }
411
412 fn consensus_constants_valid_heights<N: Network>() {
414 for (version, value) in N::MAX_CERTIFICATES.iter() {
415 let height = N::CONSENSUS_VERSION_HEIGHTS().iter().find(|(c_version, _)| *c_version == *version).unwrap().1;
417 assert_eq!(consensus_config_value!(N, MAX_CERTIFICATES, height).unwrap(), *value);
419 }
420 for (version, value) in N::TRANSACTION_SPEND_LIMIT.iter() {
421 let height = N::CONSENSUS_VERSION_HEIGHTS().iter().find(|(c_version, _)| *c_version == *version).unwrap().1;
423 assert_eq!(consensus_config_value!(N, TRANSACTION_SPEND_LIMIT, height).unwrap(), *value);
425 }
426 for (version, value) in N::CREDITS_PER_SECOND_OF_RUNTIME.iter() {
427 let height = N::CONSENSUS_VERSION_HEIGHTS().iter().find(|(c_version, _)| *c_version == *version).unwrap().1;
429 assert_eq!(consensus_config_value!(N, CREDITS_PER_SECOND_OF_RUNTIME, height).unwrap(), *value);
431 }
432 for (version, value) in N::MAX_ARRAY_ELEMENTS.iter() {
433 let height = N::CONSENSUS_VERSION_HEIGHTS().iter().find(|(c_version, _)| *c_version == *version).unwrap().1;
435 assert_eq!(consensus_config_value!(N, MAX_ARRAY_ELEMENTS, height).unwrap(), *value);
437 }
438 for (version, value) in N::MAX_PROGRAM_SIZE.iter() {
439 let height = N::CONSENSUS_VERSION_HEIGHTS().iter().find(|(c_version, _)| *c_version == *version).unwrap().1;
441 assert_eq!(consensus_config_value!(N, MAX_PROGRAM_SIZE, height).unwrap(), *value);
443 }
444 for (version, value) in N::MAX_TRANSACTION_SIZE.iter() {
445 let height = N::CONSENSUS_VERSION_HEIGHTS().iter().find(|(c_version, _)| *c_version == *version).unwrap().1;
447 assert_eq!(consensus_config_value!(N, MAX_TRANSACTION_SIZE, height).unwrap(), *value);
449 }
450 for (version, value) in N::MAX_WRITES.iter() {
451 let height = N::CONSENSUS_VERSION_HEIGHTS().iter().find(|(c_version, _)| *c_version == *version).unwrap().1;
453 assert_eq!(consensus_config_value!(N, MAX_WRITES, height).unwrap(), *value);
455 }
456 for (version, value) in N::ANCHOR_TIMES.iter() {
457 let height = N::CONSENSUS_VERSION_HEIGHTS().iter().find(|(c_version, _)| c_version == version).unwrap().1;
458 assert_eq!(consensus_config_value!(N, ANCHOR_TIMES, height).unwrap(), *value);
459 }
460 }
461
462 fn consensus_config_returns_some<N: Network>() {
464 for (_, height) in N::CONSENSUS_VERSION_HEIGHTS().iter() {
465 assert!(consensus_config_value!(N, MAX_CERTIFICATES, *height).is_some());
466 assert!(consensus_config_value!(N, TRANSACTION_SPEND_LIMIT, *height).is_some());
467 assert!(consensus_config_value!(N, CREDITS_PER_SECOND_OF_RUNTIME, *height).is_some());
468 assert!(consensus_config_value!(N, MAX_ARRAY_ELEMENTS, *height).is_some());
469 assert!(consensus_config_value!(N, MAX_PROGRAM_SIZE, *height).is_some());
470 assert!(consensus_config_value!(N, MAX_TRANSACTION_SIZE, *height).is_some());
471 assert!(consensus_config_value!(N, MAX_WRITES, *height).is_some());
472 assert!(consensus_config_value!(N, ANCHOR_TIMES, *height).is_some());
473 }
474 }
475
476 fn max_certificates_increasing<N: Network>() {
479 let mut previous_value = N::MAX_CERTIFICATES.first().unwrap().1;
480 for (_, value) in N::MAX_CERTIFICATES.iter().skip(1) {
481 assert!(*value >= previous_value);
482 previous_value = *value;
483 }
484 }
485
486 fn max_array_elements_increasing<N: Network>() {
489 let mut previous_value = N::MAX_ARRAY_ELEMENTS.first().unwrap().1;
490 for (_, value) in N::MAX_ARRAY_ELEMENTS.iter().skip(1) {
491 assert!(*value >= previous_value);
492 previous_value = *value;
493 }
494 }
495
496 fn transaction_size_exceeds_program_size<N: Network>() {
499 const MIN_OVERHEAD: usize = 28_000; for (_, height) in N::CONSENSUS_VERSION_HEIGHTS().iter() {
502 let max_program_size = consensus_config_value!(N, MAX_PROGRAM_SIZE, *height).unwrap();
503 let max_transaction_size = consensus_config_value!(N, MAX_TRANSACTION_SIZE, *height).unwrap();
504
505 assert!(
506 max_transaction_size >= max_program_size + MIN_OVERHEAD,
507 "At height {height}: MAX_TRANSACTION_SIZE ({max_transaction_size}) must be at least {MIN_OVERHEAD} bytes greater than MAX_PROGRAM_SIZE ({max_program_size})"
508 );
509 }
510 }
511
512 fn program_and_transaction_size_aligned<N: Network>() {
518 assert_eq!(
520 N::MAX_PROGRAM_SIZE.len(),
521 N::MAX_TRANSACTION_SIZE.len(),
522 "MAX_PROGRAM_SIZE and MAX_TRANSACTION_SIZE must define the same number of entries"
523 );
524 for (index, (program_version, program_size)) in N::MAX_PROGRAM_SIZE.iter().enumerate() {
527 let (transaction_version, transaction_size) = &N::MAX_TRANSACTION_SIZE[index];
528 assert_eq!(
529 program_version, transaction_version,
530 "MAX_PROGRAM_SIZE and MAX_TRANSACTION_SIZE must be keyed by the same consensus version at index {index}, but found {program_version} and {transaction_version}"
531 );
532 assert!(
533 transaction_size > program_size,
534 "At consensus version {program_version}: MAX_TRANSACTION_SIZE ({transaction_size}) must be greater than MAX_PROGRAM_SIZE ({program_size})"
535 );
536 }
537 assert!(
539 N::LATEST_MAX_TRANSACTION_SIZE() > N::LATEST_MAX_PROGRAM_SIZE(),
540 "LATEST_MAX_TRANSACTION_SIZE ({}) must be greater than LATEST_MAX_PROGRAM_SIZE ({})",
541 N::LATEST_MAX_TRANSACTION_SIZE(),
542 N::LATEST_MAX_PROGRAM_SIZE()
543 );
544 }
545
546 fn constants_equal_length<N1: Network, N2: Network, N3: Network>() {
548 let _ = [N1::CONSENSUS_VERSION_HEIGHTS, N2::CONSENSUS_VERSION_HEIGHTS, N3::CONSENSUS_VERSION_HEIGHTS];
550 let _ = [N1::MAX_CERTIFICATES, N2::MAX_CERTIFICATES, N3::MAX_CERTIFICATES];
551 let _ = [N1::TRANSACTION_SPEND_LIMIT, N2::TRANSACTION_SPEND_LIMIT, N3::TRANSACTION_SPEND_LIMIT];
552 let _ =
553 [N1::CREDITS_PER_SECOND_OF_RUNTIME, N2::CREDITS_PER_SECOND_OF_RUNTIME, N3::CREDITS_PER_SECOND_OF_RUNTIME];
554 let _ = [N1::MAX_ARRAY_ELEMENTS, N2::MAX_ARRAY_ELEMENTS, N3::MAX_ARRAY_ELEMENTS];
555 let _ = [N1::MAX_PROGRAM_SIZE, N2::MAX_PROGRAM_SIZE, N3::MAX_PROGRAM_SIZE];
556 let _ = [N1::MAX_TRANSACTION_SIZE, N2::MAX_TRANSACTION_SIZE, N3::MAX_TRANSACTION_SIZE];
557 let _ = [N1::MAX_WRITES, N2::MAX_WRITES, N3::MAX_WRITES];
558 let _ = [N1::ANCHOR_TIMES, N2::ANCHOR_TIMES, N3::ANCHOR_TIMES];
559 }
560
561 fn latest_max_functions_are_safe<N: Network>() {
564 assert!(N::LATEST_MAX_CERTIFICATES() > 0, "LATEST_MAX_CERTIFICATES must be positive");
566 assert!(N::LATEST_MAX_PROGRAM_SIZE() > 0, "LATEST_MAX_PROGRAM_SIZE must be positive");
568 assert!(N::LATEST_MAX_TRANSACTION_SIZE() > 0, "LATEST_MAX_TRANSACTION_SIZE must be positive");
570 assert!(N::LATEST_MAX_WRITES() > 0, "LATEST_MAX_WRITES must be positive");
572 }
573
574 #[test]
575 #[allow(clippy::assertions_on_constants)]
576 fn test_consensus_constants() {
577 consensus_constants_at_genesis::<MainnetV0>();
578 consensus_constants_at_genesis::<TestnetV0>();
579 consensus_constants_at_genesis::<CanaryV0>();
580
581 consensus_versions::<MainnetV0>();
582 consensus_versions::<TestnetV0>();
583 consensus_versions::<CanaryV0>();
584
585 consensus_constants_increasing_heights::<MainnetV0>();
586 consensus_constants_increasing_heights::<TestnetV0>();
587 consensus_constants_increasing_heights::<CanaryV0>();
588
589 consensus_constants_valid_heights::<MainnetV0>();
590 consensus_constants_valid_heights::<TestnetV0>();
591 consensus_constants_valid_heights::<CanaryV0>();
592
593 consensus_config_returns_some::<MainnetV0>();
594 consensus_config_returns_some::<TestnetV0>();
595 consensus_config_returns_some::<CanaryV0>();
596
597 max_certificates_increasing::<MainnetV0>();
598 max_certificates_increasing::<TestnetV0>();
599 max_certificates_increasing::<CanaryV0>();
600
601 max_array_elements_increasing::<MainnetV0>();
602 max_array_elements_increasing::<TestnetV0>();
603 max_array_elements_increasing::<CanaryV0>();
604
605 transaction_size_exceeds_program_size::<MainnetV0>();
606 transaction_size_exceeds_program_size::<TestnetV0>();
607 transaction_size_exceeds_program_size::<CanaryV0>();
608
609 program_and_transaction_size_aligned::<MainnetV0>();
610 program_and_transaction_size_aligned::<TestnetV0>();
611 program_and_transaction_size_aligned::<CanaryV0>();
612
613 latest_max_functions_are_safe::<MainnetV0>();
614 latest_max_functions_are_safe::<TestnetV0>();
615 latest_max_functions_are_safe::<CanaryV0>();
616
617 constants_equal_length::<MainnetV0, TestnetV0, CanaryV0>();
618 }
619
620 #[test]
622 fn test_to_bytes() {
623 let version = ConsensusVersion::V8;
624 let bytes = version.to_bytes_le().unwrap();
625 let result = ConsensusVersion::from_bytes_le(&bytes).unwrap();
626 assert_eq!(result, version);
627
628 let version = ConsensusVersion::latest();
629 let bytes = version.to_bytes_le().unwrap();
630 let result = ConsensusVersion::from_bytes_le(&bytes).unwrap();
631 assert_eq!(result, version);
632
633 let invalid_bytes = u16::MAX.to_bytes_le().unwrap();
634 let result = ConsensusVersion::from_bytes_le(&invalid_bytes);
635 assert!(result.is_err());
636 }
637
638 #[test]
639 fn test_reward_anchor_time() {
640 assert_eq!(MainnetV0::REWARD_ANCHOR_TIME, MainnetV0::ANCHOR_TIMES.first().unwrap().1);
641 assert_eq!(TestnetV0::REWARD_ANCHOR_TIME, TestnetV0::ANCHOR_TIMES.first().unwrap().1);
642 assert_eq!(CanaryV0::REWARD_ANCHOR_TIME, CanaryV0::ANCHOR_TIMES.first().unwrap().1);
643 }
644
645 #[test]
646 fn test_varuna_version_from_consensus() {
647 assert_eq!(varuna_version_from_consensus(ConsensusVersion::V3), VarunaVersion::V1);
649 assert_eq!(varuna_version_from_consensus(ConsensusVersion::V4), VarunaVersion::V2);
650 }
651}