dpp/data_contract/change_control_rules/
mod.rs1pub mod authorized_action_takers;
2pub mod v0;
3
4use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers;
5use crate::data_contract::change_control_rules::v0::ChangeControlRulesV0;
6use crate::data_contract::group::Group;
7use crate::data_contract::GroupContractPosition;
8use crate::group::action_taker::{ActionGoal, ActionTaker};
9#[cfg(feature = "json-conversion")]
10use crate::serialization::JsonConvertible;
11#[cfg(feature = "value-conversion")]
12use crate::serialization::ValueConvertible;
13use bincode::{Decode, DecodeUntrusted, Encode};
14use derive_more::From;
15use platform_value::Identifier;
16use serde::{Deserialize, Serialize};
17use std::collections::BTreeMap;
18use std::fmt;
19
20#[cfg_attr(feature = "json-conversion", derive(JsonConvertible))]
21#[cfg_attr(feature = "value-conversion", derive(ValueConvertible))]
22#[derive(
23 Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq, From, DecodeUntrusted,
24)]
25#[serde(tag = "$formatVersion")]
26pub enum ChangeControlRules {
27 #[serde(rename = "0")]
28 V0(ChangeControlRulesV0),
29}
30
31impl ChangeControlRules {
32 pub fn admin_action_takers(&self) -> &AuthorizedActionTakers {
33 match self {
34 ChangeControlRules::V0(v0) => &v0.admin_action_takers,
35 }
36 }
37 pub fn authorized_to_make_change_action_takers(&self) -> &AuthorizedActionTakers {
38 match self {
39 ChangeControlRules::V0(v0) => &v0.authorized_to_make_change,
40 }
41 }
42
43 pub fn set_admin_action_takers(&mut self, admin_action_takers: AuthorizedActionTakers) {
44 match self {
45 ChangeControlRules::V0(v0) => {
46 v0.admin_action_takers = admin_action_takers;
47 }
48 }
49 }
50
51 pub fn set_authorized_to_make_change_action_takers(
52 &mut self,
53 authorized_to_make_change: AuthorizedActionTakers,
54 ) {
55 match self {
56 ChangeControlRules::V0(v0) => {
57 v0.authorized_to_make_change = authorized_to_make_change;
58 }
59 }
60 }
61
62 pub fn can_make_change(
63 &self,
64 contract_owner_id: &Identifier,
65 main_group: Option<GroupContractPosition>,
66 groups: &BTreeMap<GroupContractPosition, Group>,
67 action_taker: &ActionTaker,
68 goal: ActionGoal,
69 ) -> bool {
70 match self {
71 ChangeControlRules::V0(v0) => {
72 v0.can_make_change(contract_owner_id, main_group, groups, action_taker, goal)
73 }
74 }
75 }
76
77 pub fn can_change_authorized_action_takers(
78 &self,
79 controlling_action_takers: &AuthorizedActionTakers,
80 contract_owner_id: &Identifier,
81 main_group: Option<GroupContractPosition>,
82 groups: &BTreeMap<GroupContractPosition, Group>,
83 action_taker: &ActionTaker,
84 goal: ActionGoal,
85 ) -> bool {
86 match self {
87 ChangeControlRules::V0(v0) => v0.can_change_authorized_action_takers(
88 controlling_action_takers,
89 contract_owner_id,
90 main_group,
91 groups,
92 action_taker,
93 goal,
94 ),
95 }
96 }
97
98 pub fn can_change_admin_action_takers(
99 &self,
100 admin_action_takers: &AuthorizedActionTakers,
101 contract_owner_id: &Identifier,
102 main_group: Option<GroupContractPosition>,
103 groups: &BTreeMap<GroupContractPosition, Group>,
104 action_taker: &ActionTaker,
105 goal: ActionGoal,
106 ) -> bool {
107 match self {
108 ChangeControlRules::V0(v0) => v0.can_change_admin_action_takers(
109 admin_action_takers,
110 contract_owner_id,
111 main_group,
112 groups,
113 action_taker,
114 goal,
115 ),
116 }
117 }
118 pub fn can_change_to(
119 &self,
120 other: &ChangeControlRules,
121 contract_owner_id: &Identifier,
122 main_group: Option<GroupContractPosition>,
123 groups: &BTreeMap<GroupContractPosition, Group>,
124 action_taker: &ActionTaker,
125 goal: ActionGoal,
126 ) -> bool {
127 match (self, other) {
128 (ChangeControlRules::V0(v0), ChangeControlRules::V0(v0_other)) => v0.can_change_to(
129 v0_other,
130 contract_owner_id,
131 main_group,
132 groups,
133 action_taker,
134 goal,
135 ),
136 }
137 }
138}
139
140impl fmt::Display for ChangeControlRules {
141 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142 match self {
143 ChangeControlRules::V0(v0) => {
144 write!(f, "{}", v0) }
146 }
147 }
148}
149
150#[cfg(all(test, feature = "json-conversion"))]
151mod tests {
152 use super::*;
153 use crate::serialization::JsonConvertible;
154
155 #[test]
156 fn change_control_rules_json_round_trip() {
157 let rules = ChangeControlRules::V0(ChangeControlRulesV0 {
158 authorized_to_make_change: AuthorizedActionTakers::ContractOwner,
159 admin_action_takers: AuthorizedActionTakers::NoOne,
160 changing_authorized_action_takers_to_no_one_allowed: true,
161 changing_admin_action_takers_to_no_one_allowed: false,
162 self_changing_admin_action_takers_allowed: true,
163 });
164
165 let json = rules.to_json().expect("to_json should succeed");
166
167 assert!(json["changingAuthorizedActionTakersToNoOneAllowed"]
169 .as_bool()
170 .unwrap());
171 assert!(!json["changingAdminActionTakersToNoOneAllowed"]
172 .as_bool()
173 .unwrap());
174 assert!(json["selfChangingAdminActionTakersAllowed"]
175 .as_bool()
176 .unwrap());
177
178 let restored = ChangeControlRules::from_json(json).expect("from_json should succeed");
180 assert_eq!(rules, restored);
181 }
182
183 #[test]
184 fn change_control_rules_with_group_json_round_trip() {
185 let rules = ChangeControlRules::V0(ChangeControlRulesV0 {
186 authorized_to_make_change: AuthorizedActionTakers::Group(3),
187 admin_action_takers: AuthorizedActionTakers::Identity(Identifier::from([0xFFu8; 32])),
188 changing_authorized_action_takers_to_no_one_allowed: false,
189 changing_admin_action_takers_to_no_one_allowed: false,
190 self_changing_admin_action_takers_allowed: false,
191 });
192
193 let json = rules.to_json().expect("to_json should succeed");
194 let restored = ChangeControlRules::from_json(json).expect("from_json should succeed");
195 assert_eq!(rules, restored);
196 }
197}
198
199#[cfg(all(
200 test,
201 feature = "json-conversion",
202 feature = "value-conversion",
203 feature = "serde-conversion"
204))]
205mod json_convertible_tests {
206 use super::*;
207 use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers;
208 use crate::data_contract::change_control_rules::v0::ChangeControlRulesV0;
209 use platform_value::platform_value;
210 use serde_json::json;
211
212 fn fixture() -> ChangeControlRules {
215 ChangeControlRules::V0(ChangeControlRulesV0 {
216 authorized_to_make_change: AuthorizedActionTakers::ContractOwner,
217 admin_action_takers: AuthorizedActionTakers::MainGroup,
218 changing_authorized_action_takers_to_no_one_allowed: true,
219 changing_admin_action_takers_to_no_one_allowed: false,
220 self_changing_admin_action_takers_allowed: true,
221 })
222 }
223
224 #[test]
225 fn json_round_trip_with_full_wire_shape() {
226 use crate::serialization::JsonConvertible;
227 let original = fixture();
228 let json = original.to_json().expect("to_json");
229 assert_eq!(
233 json,
234 json!({
235 "$formatVersion": "0",
236 "authorizedToMakeChange": {"$type": "contractOwner"},
237 "adminActionTakers": {"$type": "mainGroup"},
238 "changingAuthorizedActionTakersToNoOneAllowed": true,
239 "changingAdminActionTakersToNoOneAllowed": false,
240 "selfChangingAdminActionTakersAllowed": true,
241 })
242 );
243 let recovered = ChangeControlRules::from_json(json).expect("from_json");
244 assert_eq!(original, recovered);
245 }
246
247 #[test]
248 fn value_round_trip_with_full_wire_shape() {
249 use crate::serialization::ValueConvertible;
250 let original = fixture();
251 let value = original.to_object().expect("to_object");
252 assert_eq!(
256 value,
257 platform_value!({
258 "$formatVersion": "0",
259 "authorizedToMakeChange": {"$type": "contractOwner"},
260 "adminActionTakers": {"$type": "mainGroup"},
261 "changingAuthorizedActionTakersToNoOneAllowed": true,
262 "changingAdminActionTakersToNoOneAllowed": false,
263 "selfChangingAdminActionTakersAllowed": true,
264 })
265 );
266 let recovered = ChangeControlRules::from_object(value).expect("from_object");
267 assert_eq!(original, recovered);
268 }
269}