Skip to main content

ave_core/governance/
model.rs

1//! # Governance model.
2//!
3
4use ave_common::{
5    Namespace, SchemaType, ValueWrapper, identity::PublicKey,
6    schematype::ReservedWords,
7};
8use borsh::{BorshDeserialize, BorshSerialize};
9use serde::{Deserialize, Serialize, Serializer};
10
11use std::{
12    collections::{BTreeSet, HashSet},
13    fmt::{self},
14    hash::Hash,
15    vec,
16};
17
18pub type MemberName = String;
19
20/// Governance schema.
21#[derive(
22    Serialize,
23    Deserialize,
24    Clone,
25    Debug,
26    Hash,
27    PartialEq,
28    Eq,
29    BorshDeserialize,
30    BorshSerialize,
31)]
32pub struct Schema {
33    pub initial_value: ValueWrapper,
34    pub contract: String,
35}
36
37pub struct NameCreators {
38    pub validation: Option<HashSet<String>>,
39    pub evaluation: Option<HashSet<String>>,
40}
41
42impl NameCreators {
43    pub const fn is_empty(&self) -> bool {
44        self.validation.is_none() && self.evaluation.is_none()
45    }
46}
47
48pub struct SchemaKeyCreators {
49    pub schema_id: SchemaType,
50    pub validation: Option<HashSet<PublicKey>>,
51    pub evaluation: Option<HashSet<PublicKey>>,
52}
53
54#[derive(
55    Serialize,
56    Deserialize,
57    Clone,
58    Debug,
59    PartialEq,
60    Eq,
61    Default,
62    BorshDeserialize,
63    BorshSerialize,
64)]
65pub struct RolesGov {
66    pub approver: BTreeSet<MemberName>,
67    pub evaluator: BTreeSet<MemberName>,
68    pub validator: BTreeSet<MemberName>,
69    pub witness: BTreeSet<MemberName>,
70    pub issuer: RoleGovIssuer,
71}
72
73impl RolesGov {
74    pub fn check_basic_gov(&self) -> bool {
75        self.approver.contains(&ReservedWords::Owner.to_string())
76            && self.evaluator.contains(&ReservedWords::Owner.to_string())
77            && self.validator.contains(&ReservedWords::Owner.to_string())
78            && self
79                .issuer
80                .signers
81                .contains(&ReservedWords::Owner.to_string())
82    }
83
84    pub fn remove_member_role(&mut self, remove_members: &Vec<String>) {
85        for remove in remove_members {
86            self.approver.remove(remove);
87            self.evaluator.remove(remove);
88            self.validator.remove(remove);
89            self.witness.remove(remove);
90            self.issuer.signers.remove(remove);
91        }
92    }
93
94    pub fn change_name_role(
95        &mut self,
96        chang_name_members: &Vec<(String, String)>,
97    ) {
98        for (old_name, new_name) in chang_name_members {
99            if self.approver.remove(old_name) {
100                self.approver.insert(new_name.clone());
101            };
102            if self.evaluator.remove(old_name) {
103                self.evaluator.insert(new_name.clone());
104            };
105            if self.validator.remove(old_name) {
106                self.validator.insert(new_name.clone());
107            };
108            if self.witness.remove(old_name) {
109                self.witness.insert(new_name.clone());
110            };
111            if self.issuer.signers.remove(old_name) {
112                self.issuer.signers.insert(new_name.clone());
113            };
114        }
115    }
116
117    pub fn hash_this_rol(&self, role: RoleTypes, name: &str) -> bool {
118        match role {
119            RoleTypes::Approver => self.approver.contains(name),
120            RoleTypes::Evaluator => self.evaluator.contains(name),
121            RoleTypes::Validator => self.validator.contains(name),
122            RoleTypes::Issuer => {
123                self.issuer.signers.contains(name) || self.issuer.any
124            }
125            RoleTypes::Creator => false,
126            RoleTypes::Witness => self.witness.contains(name),
127        }
128    }
129
130    pub fn get_signers(&self, role: RoleTypes) -> (Vec<String>, bool) {
131        match role {
132            RoleTypes::Evaluator => (
133                self.evaluator.iter().cloned().collect::<Vec<String>>(),
134                false,
135            ),
136            RoleTypes::Validator => (
137                self.validator.iter().cloned().collect::<Vec<String>>(),
138                false,
139            ),
140            RoleTypes::Approver => (
141                self.approver.iter().cloned().collect::<Vec<String>>(),
142                false,
143            ),
144            RoleTypes::Issuer => (
145                self.issuer.signers.iter().cloned().collect::<Vec<String>>(),
146                self.issuer.any,
147            ),
148            RoleTypes::Witness => {
149                (self.witness.iter().cloned().collect::<Vec<String>>(), false)
150            }
151            RoleTypes::Creator => (vec![], false),
152        }
153    }
154}
155
156#[derive(
157    Serialize,
158    Deserialize,
159    Clone,
160    Debug,
161    PartialEq,
162    Eq,
163    Default,
164    BorshDeserialize,
165    BorshSerialize,
166)]
167pub struct RolesTrackerSchemas {
168    pub evaluator: BTreeSet<Role>,
169    pub validator: BTreeSet<Role>,
170    pub witness: BTreeSet<Role>,
171    pub issuer: RoleSchemaIssuer,
172}
173
174impl From<RolesTrackerSchemas> for RolesSchema {
175    fn from(value: RolesTrackerSchemas) -> Self {
176        Self {
177            evaluator: value.evaluator,
178            validator: value.validator,
179            witness: value.witness,
180            creator: BTreeSet::new(),
181            issuer: value.issuer,
182        }
183    }
184}
185
186impl From<RolesSchema> for RolesTrackerSchemas {
187    fn from(value: RolesSchema) -> Self {
188        Self {
189            evaluator: value.evaluator,
190            validator: value.validator,
191            witness: value.witness,
192            issuer: value.issuer,
193        }
194    }
195}
196
197impl RolesTrackerSchemas {
198    pub fn role_namespace(
199        &self,
200        role: ProtocolTypes,
201        name: &str,
202    ) -> Vec<Namespace> {
203        let role = RoleTypes::from(role);
204        match role {
205            RoleTypes::Evaluator => self
206                .evaluator
207                .iter()
208                .filter(|x| x.name == name)
209                .map(|x| x.namespace.clone())
210                .collect(),
211            RoleTypes::Validator => self
212                .validator
213                .iter()
214                .filter(|x| x.name == name)
215                .map(|x| x.namespace.clone())
216                .collect(),
217            RoleTypes::Approver => {
218                vec![]
219            }
220            _ => unreachable!("The role is obtained from ProtocolTypes"),
221        }
222    }
223
224    pub fn hash_this_rol_not_namespace(
225        &self,
226        role: ProtocolTypes,
227        name: &str,
228    ) -> bool {
229        let role = RoleTypes::from(role);
230        match role {
231            RoleTypes::Evaluator => {
232                self.evaluator.iter().any(|x| x.name == name)
233            }
234            RoleTypes::Validator => {
235                self.validator.iter().any(|x| x.name == name)
236            }
237            RoleTypes::Approver => false,
238            _ => unreachable!("The role is obtained from ProtocolTypes"),
239        }
240    }
241
242    pub fn roles_namespace(
243        &self,
244        name: &str,
245    ) -> (Option<Vec<Namespace>>, Option<Vec<Namespace>>) {
246        let val_namespace = self
247            .validator
248            .iter()
249            .filter(|x| x.name == name)
250            .map(|x| x.namespace.clone())
251            .collect::<Vec<Namespace>>();
252        let eval_namespace = self
253            .evaluator
254            .iter()
255            .filter(|x| x.name == name)
256            .map(|x| x.namespace.clone())
257            .collect::<Vec<Namespace>>();
258
259        let val_namespace = if val_namespace.is_empty() {
260            None
261        } else {
262            Some(val_namespace)
263        };
264
265        let eval_namespace = if eval_namespace.is_empty() {
266            None
267        } else {
268            Some(eval_namespace)
269        };
270
271        (val_namespace, eval_namespace)
272    }
273
274    pub fn remove_member_role(&mut self, remove_members: &Vec<String>) {
275        for remove in remove_members {
276            self.evaluator.retain(|x| x.name != *remove);
277            self.validator.retain(|x| x.name != *remove);
278            self.witness.retain(|x| x.name != *remove);
279            self.issuer.signers.retain(|x| x.name != *remove);
280        }
281    }
282
283    pub fn change_name_role(
284        &mut self,
285        chang_name_members: &Vec<(String, String)>,
286    ) {
287        for (old_name, new_name) in chang_name_members {
288            self.evaluator = self
289                .evaluator
290                .iter()
291                .map(|x| {
292                    if x.name == *old_name {
293                        Role {
294                            name: new_name.clone(),
295                            namespace: x.namespace.clone(),
296                        }
297                    } else {
298                        x.clone()
299                    }
300                })
301                .collect();
302
303            self.validator = self
304                .validator
305                .iter()
306                .map(|x| {
307                    if x.name == *old_name {
308                        Role {
309                            name: new_name.clone(),
310                            namespace: x.namespace.clone(),
311                        }
312                    } else {
313                        x.clone()
314                    }
315                })
316                .collect();
317
318            self.witness = self
319                .witness
320                .iter()
321                .map(|x| {
322                    if x.name == *old_name {
323                        Role {
324                            name: new_name.clone(),
325                            namespace: x.namespace.clone(),
326                        }
327                    } else {
328                        x.clone()
329                    }
330                })
331                .collect();
332
333            self.issuer.signers = self
334                .issuer
335                .signers
336                .iter()
337                .map(|x| {
338                    if x.name == *old_name {
339                        Role {
340                            name: new_name.clone(),
341                            namespace: x.namespace.clone(),
342                        }
343                    } else {
344                        x.clone()
345                    }
346                })
347                .collect();
348        }
349    }
350
351    pub const fn issuer_any(&self) -> bool {
352        self.issuer.any
353    }
354
355    pub fn hash_this_rol(
356        &self,
357        role: RoleTypes,
358        namespace: Namespace,
359        name: &str,
360    ) -> bool {
361        match role {
362            RoleTypes::Evaluator => self.evaluator.iter().any(|x| {
363                let namespace_role = x.namespace.clone();
364                namespace_role.is_ancestor_or_equal_of(&namespace)
365                    && x.name == name
366            }),
367            RoleTypes::Validator => self.validator.iter().any(|x| {
368                let namespace_role = x.namespace.clone();
369                namespace_role.is_ancestor_or_equal_of(&namespace)
370                    && x.name == name
371            }),
372            RoleTypes::Witness => self.witness.iter().any(|x| {
373                let namespace_role = x.namespace.clone();
374                namespace_role.is_ancestor_or_equal_of(&namespace)
375                    && x.name == name
376            }),
377            RoleTypes::Issuer => {
378                self.issuer.signers.iter().any(|x| {
379                    let namespace_role = x.namespace.clone();
380                    namespace_role.is_ancestor_or_equal_of(&namespace)
381                        && x.name == name
382                }) || self.issuer.any
383            }
384            RoleTypes::Approver | RoleTypes::Creator => false,
385        }
386    }
387
388    pub fn get_signers(
389        &self,
390        role: RoleTypes,
391        namespace: Namespace,
392    ) -> (Vec<String>, bool) {
393        match role {
394            RoleTypes::Evaluator => (
395                self.evaluator
396                    .iter()
397                    .filter(|x| {
398                        let namespace_role = x.namespace.clone();
399                        namespace_role.is_ancestor_or_equal_of(&namespace)
400                    })
401                    .map(|x| x.name.clone())
402                    .collect::<Vec<String>>(),
403                false,
404            ),
405            RoleTypes::Validator => (
406                self.validator
407                    .iter()
408                    .filter(|x| {
409                        let namespace_role = x.namespace.clone();
410                        namespace_role.is_ancestor_or_equal_of(&namespace)
411                    })
412                    .map(|x| x.name.clone())
413                    .collect::<Vec<String>>(),
414                false,
415            ),
416            RoleTypes::Witness => (
417                self.witness
418                    .iter()
419                    .filter(|x| {
420                        let namespace_role = x.namespace.clone();
421                        namespace_role.is_ancestor_or_equal_of(&namespace)
422                    })
423                    .map(|x| x.name.clone())
424                    .collect::<Vec<String>>(),
425                false,
426            ),
427            RoleTypes::Issuer => (
428                self.issuer
429                    .signers
430                    .iter()
431                    .filter(|x| {
432                        let namespace_role = x.namespace.clone();
433                        namespace_role.is_ancestor_or_equal_of(&namespace)
434                    })
435                    .map(|x| x.name.clone())
436                    .collect::<Vec<String>>(),
437                self.issuer.any,
438            ),
439            RoleTypes::Approver | RoleTypes::Creator => (vec![], false),
440        }
441    }
442}
443
444#[derive(
445    Serialize,
446    Deserialize,
447    Clone,
448    Debug,
449    PartialEq,
450    Eq,
451    Default,
452    BorshDeserialize,
453    BorshSerialize,
454)]
455pub struct RolesSchema {
456    pub evaluator: BTreeSet<Role>,
457    pub validator: BTreeSet<Role>,
458    pub witness: BTreeSet<Role>,
459    pub creator: BTreeSet<RoleCreator>,
460    pub issuer: RoleSchemaIssuer,
461}
462
463impl RolesSchema {
464    pub fn creator_witnesses(
465        &self,
466        name: &str,
467        namespace: Namespace,
468    ) -> BTreeSet<String> {
469        self.creator
470            .get(&RoleCreator::create(name, namespace))
471            .map(|x| x.witnesses.clone())
472            .unwrap_or_default()
473    }
474
475    pub fn remove_member_role(&mut self, remove_members: &Vec<String>) {
476        for remove in remove_members {
477            self.evaluator.retain(|x| x.name != *remove);
478            self.validator.retain(|x| x.name != *remove);
479            self.witness.retain(|x| x.name != *remove);
480            self.issuer.signers.retain(|x| x.name != *remove);
481            self.creator = std::mem::take(&mut self.creator)
482                .into_iter()
483                .filter(|x| x.name != *remove)
484                .map(|mut c| {
485                    c.witnesses.remove(remove);
486                    c
487                })
488                .collect();
489        }
490    }
491
492    pub fn change_name_role(
493        &mut self,
494        chang_name_members: &Vec<(String, String)>,
495    ) {
496        for (old_name, new_name) in chang_name_members {
497            self.evaluator = self
498                .evaluator
499                .iter()
500                .map(|x| {
501                    if x.name == *old_name {
502                        Role {
503                            name: new_name.clone(),
504                            namespace: x.namespace.clone(),
505                        }
506                    } else {
507                        x.clone()
508                    }
509                })
510                .collect();
511
512            self.validator = self
513                .validator
514                .iter()
515                .map(|x| {
516                    if x.name == *old_name {
517                        Role {
518                            name: new_name.clone(),
519                            namespace: x.namespace.clone(),
520                        }
521                    } else {
522                        x.clone()
523                    }
524                })
525                .collect();
526
527            self.witness = self
528                .witness
529                .iter()
530                .map(|x| {
531                    if x.name == *old_name {
532                        Role {
533                            name: new_name.clone(),
534                            namespace: x.namespace.clone(),
535                        }
536                    } else {
537                        x.clone()
538                    }
539                })
540                .collect();
541
542            self.creator = self
543                .creator
544                .iter()
545                .map(|x| {
546                    if x.name == *old_name {
547                        RoleCreator {
548                            quantity: x.quantity.clone(),
549                            name: new_name.clone(),
550                            witnesses: x.witnesses.clone(),
551                            namespace: x.namespace.clone(),
552                        }
553                    } else {
554                        x.clone()
555                    }
556                })
557                .collect();
558
559            self.issuer.signers = self
560                .issuer
561                .signers
562                .iter()
563                .map(|x| {
564                    if x.name == *old_name {
565                        Role {
566                            name: new_name.clone(),
567                            namespace: x.namespace.clone(),
568                        }
569                    } else {
570                        x.clone()
571                    }
572                })
573                .collect();
574        }
575    }
576
577    pub fn roles_creators(
578        &self,
579        name: &str,
580        not_gov_val: Option<Vec<Namespace>>,
581        not_gov_eval: Option<Vec<Namespace>>,
582    ) -> NameCreators {
583        let mut val_namespace = self
584            .validator
585            .iter()
586            .filter(|x| x.name == name)
587            .map(|x| x.namespace.clone())
588            .collect::<Vec<Namespace>>();
589        if let Some(mut not_gov_val) = not_gov_val {
590            val_namespace.append(&mut not_gov_val);
591        }
592
593        let mut eval_namespace = self
594            .evaluator
595            .iter()
596            .filter(|x| x.name == name)
597            .map(|x| x.namespace.clone())
598            .collect::<Vec<Namespace>>();
599        if let Some(mut not_gov_eval) = not_gov_eval {
600            eval_namespace.append(&mut not_gov_eval);
601        }
602
603        let mut creators_val: Vec<String> = vec![];
604        for namespace in val_namespace.clone() {
605            let mut creators = self
606                .creator
607                .iter()
608                .filter(|x| {
609                    let namespace_role = x.namespace.clone();
610                    namespace.is_ancestor_or_equal_of(&namespace_role)
611                })
612                .map(|x| x.name.clone())
613                .collect::<Vec<String>>();
614
615            creators_val.append(&mut creators);
616        }
617
618        let mut creators_eval: Vec<String> = vec![];
619        for namespace in eval_namespace.clone() {
620            let mut creators = self
621                .creator
622                .iter()
623                .filter(|x| {
624                    let namespace_role = x.namespace.clone();
625                    namespace.is_ancestor_or_equal_of(&namespace_role)
626                })
627                .map(|x| x.name.clone())
628                .collect::<Vec<String>>();
629
630            creators_eval.append(&mut creators);
631        }
632
633        let hash_val: Option<HashSet<String>> = if val_namespace.is_empty() {
634            None
635        } else {
636            Some(HashSet::from_iter(creators_val.iter().cloned()))
637        };
638
639        let hash_eval: Option<HashSet<String>> = if eval_namespace.is_empty() {
640            None
641        } else {
642            Some(HashSet::from_iter(creators_eval.iter().cloned()))
643        };
644
645        NameCreators {
646            validation: hash_val,
647            evaluation: hash_eval,
648        }
649    }
650
651    pub const fn issuer_any(&self) -> bool {
652        self.issuer.any
653    }
654
655    pub fn hash_this_rol(
656        &self,
657        role: RoleTypes,
658        namespace: Namespace,
659        name: &str,
660    ) -> bool {
661        match role {
662            RoleTypes::Evaluator => self.evaluator.iter().any(|x| {
663                let namespace_role = x.namespace.clone();
664                namespace_role.is_ancestor_or_equal_of(&namespace)
665                    && x.name == name
666            }),
667            RoleTypes::Validator => self.validator.iter().any(|x| {
668                let namespace_role = x.namespace.clone();
669                namespace_role.is_ancestor_or_equal_of(&namespace)
670                    && x.name == name
671            }),
672            RoleTypes::Witness => self.witness.iter().any(|x| {
673                let namespace_role = x.namespace.clone();
674                namespace_role.is_ancestor_or_equal_of(&namespace)
675                    && x.name == name
676            }),
677            RoleTypes::Creator => self.creator.iter().any(|x| {
678                let namespace_role = x.namespace.clone();
679                namespace_role.is_ancestor_or_equal_of(&namespace)
680                    && x.name == name
681            }),
682            RoleTypes::Issuer => {
683                self.issuer.signers.iter().any(|x| {
684                    let namespace_role = x.namespace.clone();
685                    namespace_role.is_ancestor_or_equal_of(&namespace)
686                        && x.name == name
687                }) || self.issuer.any
688            }
689            RoleTypes::Approver => false,
690        }
691    }
692
693    pub fn role_namespace(
694        &self,
695        role: ProtocolTypes,
696        name: &str,
697    ) -> Vec<Namespace> {
698        let role = RoleTypes::from(role);
699        match role {
700            RoleTypes::Evaluator => self
701                .evaluator
702                .iter()
703                .filter(|x| x.name == name)
704                .map(|x| x.namespace.clone())
705                .collect(),
706            RoleTypes::Validator => self
707                .validator
708                .iter()
709                .filter(|x| x.name == name)
710                .map(|x| x.namespace.clone())
711                .collect(),
712            RoleTypes::Approver => {
713                vec![]
714            }
715            _ => unreachable!("The role is obtained from ProtocolTypes"),
716        }
717    }
718
719    pub fn hash_this_rol_not_namespace(
720        &self,
721        role: ProtocolTypes,
722        name: &str,
723    ) -> bool {
724        let role = RoleTypes::from(role);
725        match role {
726            RoleTypes::Evaluator => {
727                self.evaluator.iter().any(|x| x.name == name)
728            }
729            RoleTypes::Validator => {
730                self.validator.iter().any(|x| x.name == name)
731            }
732            RoleTypes::Approver => false,
733            _ => unreachable!("The role is obtained from ProtocolTypes"),
734        }
735    }
736
737    pub fn max_creations(
738        &self,
739        namespace: Namespace,
740        name: &str,
741    ) -> Option<CreatorQuantity> {
742        self.creator
743            .get(&RoleCreator {
744                name: name.to_string(),
745                namespace,
746                witnesses: BTreeSet::default(),
747                quantity: CreatorQuantity::Infinity,
748            })
749            .map(|x| x.quantity.clone())
750    }
751
752    pub fn get_signers(
753        &self,
754        role: RoleTypes,
755        namespace: Namespace,
756    ) -> (Vec<String>, bool) {
757        match role {
758            RoleTypes::Evaluator => (
759                self.evaluator
760                    .iter()
761                    .filter(|x| {
762                        let namespace_role = x.namespace.clone();
763                        namespace_role.is_ancestor_or_equal_of(&namespace)
764                    })
765                    .map(|x| x.name.clone())
766                    .collect::<Vec<String>>(),
767                false,
768            ),
769            RoleTypes::Validator => (
770                self.validator
771                    .iter()
772                    .filter(|x| {
773                        let namespace_role = x.namespace.clone();
774                        namespace_role.is_ancestor_or_equal_of(&namespace)
775                    })
776                    .map(|x| x.name.clone())
777                    .collect::<Vec<String>>(),
778                false,
779            ),
780            RoleTypes::Witness => (
781                self.witness
782                    .iter()
783                    .filter(|x| {
784                        let namespace_role = x.namespace.clone();
785                        namespace_role.is_ancestor_or_equal_of(&namespace)
786                    })
787                    .map(|x| x.name.clone())
788                    .collect::<Vec<String>>(),
789                false,
790            ),
791            RoleTypes::Creator => (
792                self.creator
793                    .iter()
794                    .filter(|x| {
795                        let namespace_role = x.namespace.clone();
796                        namespace_role.is_ancestor_or_equal_of(&namespace)
797                    })
798                    .map(|x| x.name.clone())
799                    .collect::<Vec<String>>(),
800                false,
801            ),
802            RoleTypes::Issuer => (
803                self.issuer
804                    .signers
805                    .iter()
806                    .filter(|x| {
807                        let namespace_role = x.namespace.clone();
808                        namespace_role.is_ancestor_or_equal_of(&namespace)
809                    })
810                    .map(|x| x.name.clone())
811                    .collect::<Vec<String>>(),
812                self.issuer.any,
813            ),
814            RoleTypes::Approver => (vec![], false),
815        }
816    }
817}
818
819#[derive(Serialize, Deserialize, Clone, Debug)]
820pub enum RoleTypes {
821    Approver,
822    Evaluator,
823    Validator,
824    Witness,
825    Creator,
826    Issuer,
827}
828
829impl From<ProtocolTypes> for RoleTypes {
830    fn from(value: ProtocolTypes) -> Self {
831        match value {
832            ProtocolTypes::Approval => Self::Approver,
833            ProtocolTypes::Evaluation => Self::Evaluator,
834            ProtocolTypes::Validation => Self::Validator,
835        }
836    }
837}
838
839pub enum WitnessesData {
840    Gov,
841    Schema {
842        creator: PublicKey,
843        schema_id: SchemaType,
844        namespace: Namespace,
845    },
846}
847
848impl WitnessesData {
849    pub fn build(
850        schema_id: SchemaType,
851        namespace: Namespace,
852        creator: PublicKey,
853    ) -> Self {
854        if schema_id.is_gov() {
855            Self::Gov
856        } else {
857            Self::Schema {
858                creator,
859                schema_id,
860                namespace,
861            }
862        }
863    }
864}
865
866pub enum HashThisRole {
867    Gov {
868        who: PublicKey,
869        role: RoleTypes,
870    },
871    Schema {
872        who: PublicKey,
873        role: RoleTypes,
874        schema_id: SchemaType,
875        namespace: Namespace,
876    },
877    SchemaWitness {
878        who: PublicKey,
879        creator: PublicKey,
880        schema_id: SchemaType,
881        namespace: Namespace,
882    },
883}
884
885impl HashThisRole {
886    pub fn get_who(&self) -> PublicKey {
887        match self {
888            Self::Gov { who, .. } => who.clone(),
889            Self::Schema { who, .. } => who.clone(),
890            Self::SchemaWitness { who, .. } => who.clone(),
891        }
892    }
893}
894
895/// Governance role.
896#[derive(
897    Debug,
898    Serialize,
899    Deserialize,
900    Clone,
901    PartialEq,
902    Hash,
903    Eq,
904    PartialOrd,
905    Ord,
906    BorshDeserialize,
907    BorshSerialize,
908)]
909pub struct Role {
910    pub name: String,
911    pub namespace: Namespace,
912}
913
914#[derive(
915    Debug, Serialize, Deserialize, Clone, BorshDeserialize, BorshSerialize,
916)]
917pub struct RoleCreator {
918    pub name: String,
919    pub namespace: Namespace,
920    #[serde(default = "default_witnesses_creator")]
921    pub witnesses: BTreeSet<String>,
922    pub quantity: CreatorQuantity,
923}
924
925fn default_witnesses_creator() -> BTreeSet<String> {
926    BTreeSet::from([ReservedWords::Witnesses.to_string()])
927}
928
929impl Hash for RoleCreator {
930    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
931        self.name.hash(state);
932        self.namespace.hash(state);
933    }
934}
935
936impl PartialOrd for RoleCreator {
937    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
938        Some(self.cmp(other))
939    }
940}
941
942impl Ord for RoleCreator {
943    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
944        (self.name.clone(), self.namespace.clone())
945            .cmp(&(other.name.clone(), other.namespace.clone()))
946    }
947}
948
949impl PartialEq for RoleCreator {
950    fn eq(&self, other: &Self) -> bool {
951        self.name == other.name && self.namespace == other.namespace
952    }
953}
954
955impl Eq for RoleCreator {}
956
957impl RoleCreator {
958    pub fn create(name: &str, namespace: Namespace) -> Self {
959        Self {
960            name: name.to_owned(),
961            namespace,
962            witnesses: BTreeSet::default(),
963            quantity: CreatorQuantity::Infinity,
964        }
965    }
966}
967
968#[derive(
969    Debug,
970    Serialize,
971    Deserialize,
972    Clone,
973    PartialEq,
974    Eq,
975    Default,
976    BorshDeserialize,
977    BorshSerialize,
978)]
979pub struct RoleGovIssuer {
980    pub signers: BTreeSet<MemberName>,
981    pub any: bool,
982}
983
984#[derive(
985    Debug,
986    Serialize,
987    Deserialize,
988    Clone,
989    PartialEq,
990    Eq,
991    Default,
992    BorshDeserialize,
993    BorshSerialize,
994)]
995pub struct RoleSchemaIssuer {
996    pub signers: BTreeSet<Role>,
997    pub any: bool,
998}
999
1000#[derive(
1001    Debug,
1002    Clone,
1003    Eq,
1004    PartialEq,
1005    Hash,
1006    PartialOrd,
1007    Ord,
1008    BorshDeserialize,
1009    BorshSerialize,
1010)]
1011pub enum CreatorQuantity {
1012    Quantity(u32),
1013    Infinity,
1014}
1015
1016impl CreatorQuantity {
1017    pub const fn check(&self) -> bool {
1018        match self {
1019            Self::Quantity(quantity) => *quantity != 0,
1020            Self::Infinity => true,
1021        }
1022    }
1023}
1024
1025impl<'de> Deserialize<'de> for CreatorQuantity {
1026    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1027    where
1028        D: serde::Deserializer<'de>,
1029    {
1030        let value = serde_json::Value::deserialize(deserializer)?;
1031
1032        match value {
1033            serde_json::Value::String(s) if s == "infinity" => {
1034                Ok(Self::Infinity)
1035            }
1036            serde_json::Value::Number(n) if n.is_u64() => {
1037                Ok(Self::Quantity(n.as_u64().ok_or_else(|| {
1038                    serde::de::Error::custom(
1039                        "Quantity must be a number or 'infinity'",
1040                    )
1041                })? as u32))
1042            }
1043            _ => Err(serde::de::Error::custom(
1044                "Quantity must be a number or 'infinity'",
1045            )),
1046        }
1047    }
1048}
1049
1050impl Serialize for CreatorQuantity {
1051    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1052    where
1053        S: Serializer,
1054    {
1055        match self {
1056            Self::Quantity(n) => serializer.serialize_u32(*n),
1057            Self::Infinity => serializer.serialize_str("infinity"),
1058        }
1059    }
1060}
1061
1062/// Governance member.
1063#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
1064pub struct Member {
1065    pub id: PublicKey,
1066    pub name: String,
1067}
1068
1069#[derive(Debug, Serialize, Deserialize, Clone)]
1070pub enum ProtocolTypes {
1071    Approval,
1072    Evaluation,
1073    Validation,
1074}
1075
1076impl fmt::Display for ProtocolTypes {
1077    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1078        match self {
1079            Self::Approval => write!(f, "Approval"),
1080            Self::Evaluation => write!(f, "Evaluation"),
1081            Self::Validation => write!(f, "Validation"),
1082        }
1083    }
1084}
1085
1086/// Governance quorum.
1087#[derive(
1088    Debug,
1089    Clone,
1090    Default,
1091    Serialize,
1092    Deserialize,
1093    PartialEq,
1094    Hash,
1095    Eq,
1096    BorshDeserialize,
1097    BorshSerialize,
1098)]
1099#[serde(rename_all = "lowercase")]
1100pub enum Quorum {
1101    #[default]
1102    Majority,
1103    Fixed(u32),
1104    Percentage(u8),
1105}
1106
1107impl Quorum {
1108    pub fn check_values(&self) -> Result<(), String> {
1109        if let Self::Percentage(percentage) = self
1110            && (*percentage == 0_u8 || *percentage > 100_u8)
1111        {
1112            return Err("the percentage must be between 1 and 100".to_owned());
1113        }
1114
1115        Ok(())
1116    }
1117
1118    pub fn get_signers(&self, total_members: u32, pending: u32) -> u32 {
1119        let signers = match self {
1120            Self::Fixed(fixed) => {
1121                let min = std::cmp::min(fixed, &total_members);
1122                *min
1123            }
1124            Self::Majority => total_members / 2 + 1,
1125            Self::Percentage(percentage) => {
1126                total_members * (percentage / 100) as u32
1127            }
1128        };
1129
1130        std::cmp::min(signers, pending)
1131    }
1132
1133    pub fn check_quorum(&self, total_members: u32, signers: u32) -> bool {
1134        match self {
1135            Self::Fixed(fixed) => {
1136                let min = std::cmp::min(fixed, &total_members);
1137                signers >= *min
1138            }
1139            Self::Majority => signers > total_members / 2,
1140            Self::Percentage(percentage) => {
1141                signers >= (total_members * (percentage / 100) as u32)
1142            }
1143        }
1144    }
1145}
1146
1147/// Governance policy.
1148#[derive(
1149    Debug,
1150    Serialize,
1151    Deserialize,
1152    Clone,
1153    Default,
1154    BorshDeserialize,
1155    BorshSerialize,
1156)]
1157pub struct PolicyGov {
1158    /// Approve quorum
1159    pub approve: Quorum,
1160    /// Evaluate quorum
1161    pub evaluate: Quorum,
1162    /// Validate quorum
1163    pub validate: Quorum,
1164}
1165
1166impl PolicyGov {
1167    pub fn get_quorum(&self, role: ProtocolTypes) -> Option<Quorum> {
1168        match role {
1169            ProtocolTypes::Approval => Some(self.approve.clone()),
1170            ProtocolTypes::Evaluation => Some(self.evaluate.clone()),
1171            ProtocolTypes::Validation => Some(self.validate.clone()),
1172        }
1173    }
1174}
1175
1176#[derive(
1177    Debug,
1178    Serialize,
1179    Deserialize,
1180    Clone,
1181    Hash,
1182    PartialEq,
1183    Eq,
1184    Default,
1185    BorshDeserialize,
1186    BorshSerialize,
1187)]
1188pub struct PolicySchema {
1189    /// Evaluate quorum
1190    pub evaluate: Quorum,
1191    /// Validate quorum
1192    pub validate: Quorum,
1193}
1194
1195impl PolicySchema {
1196    pub fn get_quorum(&self, role: ProtocolTypes) -> Option<Quorum> {
1197        match role {
1198            ProtocolTypes::Approval => None,
1199            ProtocolTypes::Evaluation => Some(self.evaluate.clone()),
1200            ProtocolTypes::Validation => Some(self.validate.clone()),
1201        }
1202    }
1203}