casper_types/account/
action_thresholds.rs1use alloc::vec::Vec;
4
5#[cfg(feature = "datasize")]
6use datasize::DataSize;
7#[cfg(feature = "json-schema")]
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10
11use crate::{
12 account::{ActionType, SetThresholdFailure, Weight},
13 addressable_entity::WEIGHT_SERIALIZED_LENGTH,
14 bytesrepr::{self, Error, FromBytes, ToBytes},
15};
16
17#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
19#[cfg_attr(feature = "datasize", derive(DataSize))]
20#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
21#[cfg_attr(feature = "json-schema", schemars(rename = "AccountActionThresholds"))]
22pub struct ActionThresholds {
23 pub deployment: Weight,
25 pub key_management: Weight,
27}
28
29impl ActionThresholds {
30 pub fn new(
35 deployment: Weight,
36 key_management: Weight,
37 ) -> Result<ActionThresholds, SetThresholdFailure> {
38 if deployment > key_management {
39 return Err(SetThresholdFailure::DeploymentThreshold);
40 }
41 Ok(ActionThresholds {
42 deployment,
43 key_management,
44 })
45 }
46 pub fn set_deployment_threshold(
53 &mut self,
54 new_threshold: Weight,
55 ) -> Result<(), SetThresholdFailure> {
56 if new_threshold > self.key_management {
57 Err(SetThresholdFailure::DeploymentThreshold)
58 } else {
59 self.deployment = new_threshold;
60 Ok(())
61 }
62 }
63
64 pub fn set_key_management_threshold(
66 &mut self,
67 new_threshold: Weight,
68 ) -> Result<(), SetThresholdFailure> {
69 if self.deployment > new_threshold {
70 Err(SetThresholdFailure::KeyManagementThreshold)
71 } else {
72 self.key_management = new_threshold;
73 Ok(())
74 }
75 }
76
77 pub fn deployment(&self) -> &Weight {
79 &self.deployment
80 }
81
82 pub fn key_management(&self) -> &Weight {
84 &self.key_management
85 }
86
87 pub fn set_threshold(
90 &mut self,
91 action_type: ActionType,
92 new_threshold: Weight,
93 ) -> Result<(), SetThresholdFailure> {
94 match action_type {
95 ActionType::Deployment => self.set_deployment_threshold(new_threshold),
96 ActionType::KeyManagement => self.set_key_management_threshold(new_threshold),
97 }
98 }
99}
100
101impl Default for ActionThresholds {
102 fn default() -> Self {
103 ActionThresholds {
104 deployment: Weight::new(1),
105 key_management: Weight::new(1),
106 }
107 }
108}
109
110impl ToBytes for ActionThresholds {
111 fn to_bytes(&self) -> Result<Vec<u8>, Error> {
112 let mut result = bytesrepr::unchecked_allocate_buffer(self);
113 result.append(&mut self.deployment.to_bytes()?);
114 result.append(&mut self.key_management.to_bytes()?);
115 Ok(result)
116 }
117
118 fn serialized_length(&self) -> usize {
119 2 * WEIGHT_SERIALIZED_LENGTH
120 }
121
122 fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
123 self.deployment().write_bytes(writer)?;
124 self.key_management().write_bytes(writer)?;
125 Ok(())
126 }
127}
128
129impl FromBytes for ActionThresholds {
130 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> {
131 let (deployment, rem) = Weight::from_bytes(bytes)?;
132 let (key_management, rem) = Weight::from_bytes(rem)?;
133 let ret = ActionThresholds {
134 deployment,
135 key_management,
136 };
137 Ok((ret, rem))
138 }
139}
140
141#[doc(hidden)]
142#[cfg(any(feature = "testing", feature = "gens", test))]
143pub mod gens {
144 use proptest::prelude::*;
145
146 use super::ActionThresholds;
147
148 pub fn account_action_thresholds_arb() -> impl Strategy<Value = ActionThresholds> {
149 Just(Default::default())
150 }
151}
152
153#[cfg(test)]
154mod tests {
155 use super::*;
156
157 #[test]
158 fn should_create_new_action_thresholds() {
159 let action_thresholds = ActionThresholds::new(Weight::new(1), Weight::new(42)).unwrap();
160 assert_eq!(*action_thresholds.deployment(), Weight::new(1));
161 assert_eq!(*action_thresholds.key_management(), Weight::new(42));
162 }
163
164 #[test]
165 fn should_not_create_action_thresholds_with_invalid_deployment_threshold() {
166 assert!(ActionThresholds::new(Weight::new(5), Weight::new(1)).is_err());
168 }
169
170 #[test]
171 fn serialization_roundtrip() {
172 let action_thresholds = ActionThresholds::new(Weight::new(1), Weight::new(42)).unwrap();
173 bytesrepr::test_serialization_roundtrip(&action_thresholds);
174 }
175}