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