casper_types/transaction/
transaction_scheduling.rs1use super::serialization::CalltableSerializationEnvelope;
2#[cfg(any(feature = "testing", test))]
3use crate::testing::TestRng;
4use crate::{
5 bytesrepr::{
6 Error::{self, Formatting},
7 FromBytes, ToBytes,
8 },
9 transaction::serialization::CalltableSerializationEnvelopeBuilder,
10};
11use alloc::vec::Vec;
12use core::fmt::{self, Display, Formatter};
13#[cfg(feature = "datasize")]
14use datasize::DataSize;
15#[cfg(any(feature = "testing", test))]
16use rand::Rng;
17#[cfg(feature = "json-schema")]
18use schemars::JsonSchema;
19#[cfg(any(feature = "std", test))]
20use serde::{Deserialize, Serialize};
21
22#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
24#[cfg_attr(
25 any(feature = "std", test),
26 derive(Serialize, Deserialize),
27 serde(deny_unknown_fields)
28)]
29#[cfg_attr(feature = "datasize", derive(DataSize))]
30#[cfg_attr(
31 feature = "json-schema",
32 derive(JsonSchema),
33 schemars(description = "Scheduling mode of a Transaction.")
34)]
35pub enum TransactionScheduling {
36 Standard,
38}
39
40impl TransactionScheduling {
41 fn serialized_field_lengths(&self) -> Vec<usize> {
42 match self {
43 TransactionScheduling::Standard => {
44 vec![crate::bytesrepr::U8_SERIALIZED_LENGTH]
45 }
46 }
47 }
48
49 #[cfg(any(feature = "testing", test))]
51 pub fn random(rng: &mut TestRng) -> Self {
52 match rng.gen_range(0..1) {
53 0 => TransactionScheduling::Standard,
54 _ => unreachable!(),
55 }
56 }
57}
58
59const TAG_FIELD_INDEX: u16 = 0;
60
61const STANDARD_VARIANT: u8 = 0;
62
63impl ToBytes for TransactionScheduling {
64 fn to_bytes(&self) -> Result<Vec<u8>, Error> {
65 match self {
66 TransactionScheduling::Standard => {
67 CalltableSerializationEnvelopeBuilder::new(self.serialized_field_lengths())?
68 .add_field(TAG_FIELD_INDEX, &STANDARD_VARIANT)?
69 .binary_payload_bytes()
70 }
71 }
72 }
73 fn serialized_length(&self) -> usize {
74 CalltableSerializationEnvelope::estimate_size(self.serialized_field_lengths())
75 }
76}
77
78impl FromBytes for TransactionScheduling {
79 fn from_bytes(bytes: &[u8]) -> Result<(TransactionScheduling, &[u8]), Error> {
80 let (binary_payload, remainder) = CalltableSerializationEnvelope::from_bytes(2, bytes)?;
81 let window = binary_payload.start_consuming()?.ok_or(Formatting)?;
82 window.verify_index(0)?;
83 let (tag, window) = window.deserialize_and_maybe_next::<u8>()?;
84 let to_ret = match tag {
85 STANDARD_VARIANT => {
86 if window.is_some() {
87 return Err(Formatting);
88 }
89 Ok(TransactionScheduling::Standard)
90 }
91 _ => Err(Formatting),
92 };
93 to_ret.map(|endpoint| (endpoint, remainder))
94 }
95}
96
97impl Display for TransactionScheduling {
98 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
99 match self {
100 TransactionScheduling::Standard => write!(formatter, "schedule(standard)"),
101 }
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108 use crate::{bytesrepr, gens::transaction_scheduling_arb};
109 use proptest::prelude::*;
110
111 #[test]
112 fn bytesrepr_roundtrip() {
113 let rng = &mut TestRng::new();
114 for _ in 0..10 {
115 bytesrepr::test_serialization_roundtrip(&TransactionScheduling::random(rng));
116 }
117 }
118
119 proptest! {
120 #[test]
121 fn generative_bytesrepr_roundtrip(val in transaction_scheduling_arb()) {
122 bytesrepr::test_serialization_roundtrip(&val);
123 }
124 }
125}