Skip to main content

ave_core/governance/
data.rs

1//! # GovernanceData module.
2//!
3
4use crate::governance::{
5    RolesUpdateConfirm, RolesUpdateRemove,
6    error::GovernanceError,
7    model::{
8        HashThisRole, PolicyGov, PolicySchema, ProtocolTypes, Quorum,
9        RoleGovIssuer, RoleSchemaIssuer, RoleTypes, RolesGov, RolesSchema,
10        RolesTrackerSchemas, Schema, WitnessesData,
11    },
12};
13
14use ave_common::{
15    Namespace, SchemaType, ValueWrapper, identity::PublicKey,
16    schematype::ReservedWords,
17};
18
19use borsh::{BorshDeserialize, BorshSerialize};
20use serde::{Deserialize, Serialize};
21
22use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
23
24pub type MemberName = String;
25
26#[derive(
27    Debug,
28    Clone,
29    PartialEq,
30    Eq,
31    Serialize,
32    Deserialize,
33    Default,
34    BorshDeserialize,
35    BorshSerialize,
36)]
37pub struct GovernanceData {
38    pub version: u64,
39    pub members: BTreeMap<MemberName, PublicKey>,
40    pub roles_gov: RolesGov,
41    pub policies_gov: PolicyGov,
42    pub schemas: BTreeMap<SchemaType, Schema>,
43    pub roles_schema: BTreeMap<SchemaType, RolesSchema>,
44    pub roles_tracker_schemas: RolesTrackerSchemas,
45    pub policies_schema: BTreeMap<SchemaType, PolicySchema>,
46}
47
48impl GovernanceData {
49    pub fn new(owner_key: PublicKey) -> Self {
50        let policies_gov = PolicyGov {
51            approve: Quorum::Majority,
52            evaluate: Quorum::Majority,
53            validate: Quorum::Majority,
54        };
55
56        let owner_signers_gov: BTreeSet<MemberName> =
57            BTreeSet::from([ReservedWords::Owner.to_string()]);
58
59        let roles_gov = RolesGov {
60            approver: owner_signers_gov.clone(),
61            evaluator: owner_signers_gov.clone(),
62            validator: owner_signers_gov.clone(),
63            witness: owner_signers_gov.clone(),
64            issuer: RoleGovIssuer {
65                any: false,
66                signers: owner_signers_gov,
67            },
68        };
69
70        let not_gov_role = RolesTrackerSchemas {
71            evaluator: BTreeSet::new(),
72            validator: BTreeSet::new(),
73            witness: BTreeSet::new(),
74            issuer: RoleSchemaIssuer {
75                signers: BTreeSet::new(),
76                any: false,
77            },
78        };
79
80        Self {
81            version: 0,
82            members: BTreeMap::from([(
83                ReservedWords::Owner.to_string(),
84                owner_key,
85            )]),
86            roles_gov,
87            policies_gov,
88            schemas: BTreeMap::new(),
89            roles_schema: BTreeMap::new(),
90            roles_tracker_schemas: not_gov_role,
91            policies_schema: BTreeMap::new(),
92        }
93    }
94
95    pub fn roles_update_remove_confirm(
96        &self,
97        old_owner_key: &PublicKey,
98        new_owner_key: &PublicKey,
99    ) -> RolesUpdateConfirm {
100        let mut remove_creator: HashSet<(SchemaType, String, PublicKey)> =
101            HashSet::new();
102
103        let mut new_approver = None;
104        let mut new_evaluator = None;
105        let mut new_validator = None;
106
107        let mut remove_witnesses: HashMap<
108            (SchemaType, PublicKey),
109            Vec<Namespace>,
110        > = HashMap::new();
111
112        let remove_approver: PublicKey = old_owner_key.clone();
113        let mut remove_evaluators: HashMap<
114            (SchemaType, PublicKey),
115            Vec<Namespace>,
116        > = HashMap::new();
117        let mut remove_validators: HashMap<
118            (SchemaType, PublicKey),
119            Vec<Namespace>,
120        > = HashMap::new();
121
122        let old_name = self
123            .members
124            .iter()
125            .find(|x| x.1 == new_owner_key)
126            .map(|x| x.0)
127            .cloned();
128
129        // gov
130        if let Some(old_name) = old_name {
131            if !self.roles_gov.approver.contains(&old_name) {
132                new_approver = Some(new_owner_key.clone());
133            }
134
135            if !self.roles_gov.evaluator.contains(&old_name) {
136                new_evaluator = Some(new_owner_key.clone());
137            }
138            remove_evaluators
139                .entry((SchemaType::Governance, old_owner_key.clone()))
140                .or_default()
141                .push(Namespace::new());
142            if !self.roles_gov.validator.contains(&old_name) {
143                new_validator = Some(new_owner_key.clone());
144            }
145
146            remove_validators
147                .entry((SchemaType::Governance, old_owner_key.clone()))
148                .or_default()
149                .push(Namespace::new());
150
151            // schema
152            for (schema_id, roles_schema) in self.roles_schema.iter() {
153                for evaluators in roles_schema.evaluator.iter() {
154                    if evaluators.name == ReservedWords::Owner.to_string() {
155                        remove_evaluators
156                            .entry((schema_id.clone(), old_owner_key.clone()))
157                            .or_default()
158                            .push(evaluators.namespace.clone());
159                    } else if evaluators.name == old_name {
160                        remove_evaluators
161                            .entry((schema_id.clone(), new_owner_key.clone()))
162                            .or_default()
163                            .push(evaluators.namespace.clone());
164                    }
165                }
166
167                for validators in roles_schema.validator.iter() {
168                    if validators.name == ReservedWords::Owner.to_string() {
169                        remove_validators
170                            .entry((schema_id.clone(), old_owner_key.clone()))
171                            .or_default()
172                            .push(validators.namespace.clone());
173                    } else if validators.name == old_name {
174                        remove_validators
175                            .entry((schema_id.clone(), new_owner_key.clone()))
176                            .or_default()
177                            .push(validators.namespace.clone());
178                    }
179                }
180
181                for creators in roles_schema.creator.iter() {
182                    if creators.name == ReservedWords::Owner.to_string() {
183                        remove_creator.insert((
184                            schema_id.clone(),
185                            creators.namespace.to_string(),
186                            old_owner_key.clone(),
187                        ));
188                    } else if creators.name == old_name {
189                        remove_creator.insert((
190                            schema_id.clone(),
191                            creators.namespace.to_string(),
192                            new_owner_key.clone(),
193                        ));
194                    }
195                }
196                for witness in roles_schema.witness.iter() {
197                    if witness.name == ReservedWords::Owner.to_string() {
198                        remove_witnesses
199                            .entry((schema_id.clone(), old_owner_key.clone()))
200                            .or_default()
201                            .push(witness.namespace.clone());
202                    } else if witness.name == old_name {
203                        remove_witnesses
204                            .entry((schema_id.clone(), new_owner_key.clone()))
205                            .or_default()
206                            .push(witness.namespace.clone());
207                    }
208                }
209            }
210
211            for evaluators in self.roles_tracker_schemas.evaluator.iter() {
212                if evaluators.name == ReservedWords::Owner.to_string() {
213                    remove_evaluators
214                        .entry((
215                            SchemaType::TrackerSchemas,
216                            old_owner_key.clone(),
217                        ))
218                        .or_default()
219                        .push(evaluators.namespace.clone());
220                } else if evaluators.name == old_name {
221                    remove_evaluators
222                        .entry((
223                            SchemaType::TrackerSchemas,
224                            new_owner_key.clone(),
225                        ))
226                        .or_default()
227                        .push(evaluators.namespace.clone());
228                }
229            }
230            for validators in self.roles_tracker_schemas.validator.iter() {
231                if validators.name == ReservedWords::Owner.to_string() {
232                    remove_validators
233                        .entry((
234                            SchemaType::TrackerSchemas,
235                            old_owner_key.clone(),
236                        ))
237                        .or_default()
238                        .push(validators.namespace.clone());
239                } else if validators.name == old_name {
240                    remove_validators
241                        .entry((
242                            SchemaType::TrackerSchemas,
243                            new_owner_key.clone(),
244                        ))
245                        .or_default()
246                        .push(validators.namespace.clone());
247                }
248            }
249            for witness in self.roles_tracker_schemas.witness.iter() {
250                if witness.name == ReservedWords::Owner.to_string() {
251                    remove_witnesses
252                        .entry((
253                            SchemaType::TrackerSchemas,
254                            old_owner_key.clone(),
255                        ))
256                        .or_default()
257                        .push(witness.namespace.clone());
258                } else if witness.name == old_name {
259                    remove_witnesses
260                        .entry((
261                            SchemaType::TrackerSchemas,
262                            new_owner_key.clone(),
263                        ))
264                        .or_default()
265                        .push(witness.namespace.clone());
266                }
267            }
268        }
269
270        RolesUpdateConfirm {
271            new_approver,
272            new_evaluator,
273            new_validator,
274            remove_approver,
275            remove_creator,
276            remove_evaluators,
277            remove_validators,
278            remove_witnesses,
279        }
280    }
281
282    pub fn roles_update_remove_fact(
283        &self,
284        remove_members: Option<HashSet<String>>,
285        remove_schemas: Option<HashSet<SchemaType>>,
286    ) -> RolesUpdateRemove {
287        let mut remove_creator: HashSet<(SchemaType, String, PublicKey)> =
288            HashSet::new();
289
290        let mut remove_witnesses: HashMap<
291            (SchemaType, PublicKey),
292            Vec<Namespace>,
293        > = HashMap::new();
294
295        let mut remove_approvers: Vec<PublicKey> = vec![];
296        let mut remove_evaluators: HashMap<
297            (SchemaType, PublicKey),
298            Vec<Namespace>,
299        > = HashMap::new();
300        let mut remove_validators: HashMap<
301            (SchemaType, PublicKey),
302            Vec<Namespace>,
303        > = HashMap::new();
304
305        let remove_schemas = remove_schemas.unwrap_or_default();
306
307        for schema_id in remove_schemas.iter() {
308            if let Some(roles_schema) = self.roles_schema.get(schema_id) {
309                for evaluators in roles_schema.evaluator.iter() {
310                    if let Some(user) = self.members.get(&evaluators.name) {
311                        remove_evaluators
312                            .entry((schema_id.clone(), user.clone()))
313                            .or_default()
314                            .push(evaluators.namespace.clone());
315                    }
316                }
317
318                for validators in roles_schema.validator.iter() {
319                    if let Some(user) = self.members.get(&validators.name) {
320                        remove_validators
321                            .entry((schema_id.clone(), user.clone()))
322                            .or_default()
323                            .push(validators.namespace.clone());
324                    }
325                }
326
327                for creators in roles_schema.creator.iter() {
328                    if let Some(user) = self.members.get(&creators.name) {
329                        remove_creator.insert((
330                            schema_id.clone(),
331                            creators.namespace.to_string(),
332                            user.clone(),
333                        ));
334                    }
335                }
336                for witness in roles_schema.witness.iter() {
337                    if let Some(user) = self.members.get(&witness.name) {
338                        remove_witnesses
339                            .entry((schema_id.clone(), user.clone()))
340                            .or_default()
341                            .push(witness.namespace.clone());
342                    }
343                }
344            }
345        }
346
347        if let Some(remove_members) = remove_members {
348            // gov
349            for user in remove_members.iter() {
350                if let Some(user_key) = self.members.get(user) {
351                    if self.roles_gov.approver.contains(user) {
352                        remove_approvers.push(user_key.clone());
353                    }
354                    if self.roles_gov.evaluator.contains(user) {
355                        remove_evaluators
356                            .entry((SchemaType::Governance, user_key.clone()))
357                            .or_default()
358                            .push(Namespace::new());
359                    }
360                    if self.roles_gov.validator.contains(user) {
361                        remove_validators
362                            .entry((SchemaType::Governance, user_key.clone()))
363                            .or_default()
364                            .push(Namespace::new());
365                    }
366                }
367            }
368
369            // schema
370            for (schema_id, roles_schema) in self.roles_schema.iter() {
371                if !remove_schemas.contains(schema_id) {
372                    for evaluators in roles_schema.evaluator.iter() {
373                        if remove_members.contains(&evaluators.name)
374                            && let Some(user) =
375                                self.members.get(&evaluators.name)
376                        {
377                            remove_evaluators
378                                .entry((schema_id.clone(), user.clone()))
379                                .or_default()
380                                .push(evaluators.namespace.clone());
381                        }
382                    }
383
384                    for validators in roles_schema.validator.iter() {
385                        if remove_members.contains(&validators.name)
386                            && let Some(user) =
387                                self.members.get(&validators.name)
388                        {
389                            remove_validators
390                                .entry((schema_id.clone(), user.clone()))
391                                .or_default()
392                                .push(validators.namespace.clone());
393                        }
394                    }
395
396                    for creators in roles_schema.creator.iter() {
397                        if remove_members.contains(&creators.name)
398                            && let Some(user) = self.members.get(&creators.name)
399                        {
400                            remove_creator.insert((
401                                schema_id.clone(),
402                                creators.namespace.to_string(),
403                                user.clone(),
404                            ));
405                        }
406                    }
407                    for witness in roles_schema.witness.iter() {
408                        if remove_members.contains(&witness.name)
409                            && let Some(user) = self.members.get(&witness.name)
410                        {
411                            remove_witnesses
412                                .entry((schema_id.clone(), user.clone()))
413                                .or_default()
414                                .push(witness.namespace.clone());
415                        }
416                    }
417                }
418            }
419
420            // tracker_schemas
421            for evaluators in self.roles_tracker_schemas.evaluator.iter() {
422                if remove_members.contains(&evaluators.name)
423                    && let Some(user) = self.members.get(&evaluators.name)
424                {
425                    remove_evaluators
426                        .entry((SchemaType::TrackerSchemas, user.clone()))
427                        .or_default()
428                        .push(evaluators.namespace.clone());
429                }
430            }
431            for validators in self.roles_tracker_schemas.validator.iter() {
432                if remove_members.contains(&validators.name)
433                    && let Some(user) = self.members.get(&validators.name)
434                {
435                    remove_validators
436                        .entry((SchemaType::TrackerSchemas, user.clone()))
437                        .or_default()
438                        .push(validators.namespace.clone());
439                }
440            }
441            for witness in self.roles_tracker_schemas.witness.iter() {
442                if remove_members.contains(&witness.name)
443                    && let Some(user) = self.members.get(&witness.name)
444                {
445                    remove_witnesses
446                        .entry((SchemaType::TrackerSchemas, user.clone()))
447                        .or_default()
448                        .push(witness.namespace.clone());
449                }
450            }
451        }
452
453        RolesUpdateRemove {
454            witnesses: remove_witnesses,
455            creator: remove_creator,
456            approvers: remove_approvers,
457            evaluators: remove_evaluators,
458            validators: remove_validators,
459        }
460    }
461
462    pub fn remove_schema(&mut self, remove_schemas: HashSet<SchemaType>) {
463        for schema_id in remove_schemas {
464            self.roles_schema.remove(&schema_id);
465            self.policies_schema.remove(&schema_id);
466        }
467    }
468
469    pub fn add_schema(&mut self, add_schema: HashSet<SchemaType>) {
470        for schema_id in add_schema {
471            self.roles_schema
472                .insert(schema_id.clone(), RolesSchema::default());
473            self.policies_schema
474                .insert(schema_id, PolicySchema::default());
475        }
476    }
477
478    pub fn remove_member_role(&mut self, remove_members: &Vec<MemberName>) {
479        self.roles_gov.remove_member_role(remove_members);
480        self.roles_tracker_schemas
481            .remove_member_role(remove_members);
482
483        for (_, roles) in self.roles_schema.iter_mut() {
484            roles.remove_member_role(remove_members);
485        }
486    }
487
488    pub fn update_name_role(&mut self, old_name: String) {
489        let old_name = vec![old_name];
490        let owner_name = vec![ReservedWords::Owner.to_string()];
491        self.roles_gov.remove_member_role(&old_name);
492
493        self.roles_tracker_schemas.remove_member_role(&old_name);
494        self.roles_tracker_schemas.remove_member_role(&owner_name);
495
496        for (_, roles) in self.roles_schema.iter_mut() {
497            roles.remove_member_role(&old_name);
498            roles.remove_member_role(&owner_name);
499        }
500    }
501
502    pub fn to_value_wrapper(&self) -> ValueWrapper {
503        ValueWrapper(serde_json::to_value(self).expect("It cannot fail; it does not contain a map with keys other than strings"))
504    }
505
506    pub fn check_basic_gov(&self) -> bool {
507        self.roles_gov.check_basic_gov()
508    }
509
510    /// Get the initial state for GovernanceData model
511    ///  # Arguments
512    ///  * `schema_id` - The identifier of the [`Schema`].
513    /// # Returns
514    /// * [`ValueWrapper`] - The initial state.
515    /// # Errors
516    /// * `GovernanceError` - If the schema is not found.
517    pub fn get_init_state(
518        &self,
519        schema_id: &SchemaType,
520    ) -> Result<ValueWrapper, GovernanceError> {
521        let Some(schema) = self.schemas.get(schema_id) else {
522            return Err(GovernanceError::SchemaDoesNotExist {
523                schema_id: schema_id.to_string(),
524            });
525        };
526
527        Ok(schema.initial_value.clone())
528    }
529
530    /// Check if the user has a role.
531    /// # Arguments
532    /// * `user` - The user id.
533    /// * [`Roles`] - The role.
534    /// * `schema` - The schema id from [`Schema`].
535    /// * [`Namespace`] - The namespace.
536    pub fn has_this_role(&self, data: HashThisRole) -> bool {
537        let who = data.get_who();
538
539        let Some(name) = self
540            .members
541            .iter()
542            .find(|x| *x.1 == who)
543            .map(|x| x.0)
544            .cloned()
545        else {
546            if let HashThisRole::Schema {
547                role: RoleTypes::Issuer,
548                schema_id,
549                ..
550            } = data
551            {
552                if self.roles_tracker_schemas.issuer_any() {
553                    return true;
554                }
555
556                let Some(roles) = self.roles_schema.get(&schema_id) else {
557                    return false;
558                };
559
560                return roles.issuer_any();
561            } else {
562                return false;
563            }
564        };
565
566        match data {
567            HashThisRole::Gov { role, .. } => {
568                if matches!(role, RoleTypes::Witness) {
569                    return true;
570                }
571
572                self.roles_gov.hash_this_rol(role, &name)
573            }
574            HashThisRole::Schema {
575                role,
576                schema_id,
577                namespace,
578                ..
579            } => {
580                if self.roles_tracker_schemas.hash_this_rol(
581                    role.clone(),
582                    namespace.clone(),
583                    &name,
584                ) {
585                    return true;
586                }
587
588                let Some(roles) = self.roles_schema.get(&schema_id) else {
589                    return false;
590                };
591
592                roles.hash_this_rol(role, namespace, &name)
593            }
594            HashThisRole::SchemaWitness {
595                creator,
596                schema_id,
597                namespace,
598                ..
599            } => {
600                let Some(creator_name) = self
601                    .members
602                    .iter()
603                    .find(|x| *x.1 == creator)
604                    .map(|x| x.0)
605                    .cloned()
606                else {
607                    return false;
608                };
609
610                let Some(roles_schema) = self.roles_schema.get(&schema_id)
611                else {
612                    return false;
613                };
614
615                let witnesses_creator = roles_schema
616                    .creator_witnesses(&creator_name, namespace.clone());
617
618                if witnesses_creator.contains(&name) {
619                    return true;
620                }
621
622                if witnesses_creator
623                    .contains(&ReservedWords::Witnesses.to_string())
624                {
625                    let not_gov_witnesses = self
626                        .roles_tracker_schemas
627                        .get_signers(RoleTypes::Witness, namespace.clone())
628                        .0;
629
630                    if not_gov_witnesses.contains(&name) {
631                        return true;
632                    }
633
634                    let schema_witnesses = roles_schema
635                        .get_signers(RoleTypes::Witness, namespace)
636                        .0;
637
638                    if schema_witnesses.contains(&name) {
639                        return true;
640                    }
641                }
642
643                false
644            }
645        }
646    }
647
648    /// Gets the signers for the request stage.
649    /// # Arguments
650    /// * [`Roles`] - The role.
651    /// * `schema_id` - The schema id from [`Schema`].
652    /// * [`Namespace`] - The namespace.
653    /// # Returns
654    /// * (HashSet<[`PublicKey`]>, bool) - The set of key identifiers and a flag indicating if the user is not a member.
655    pub fn get_signers(
656        &self,
657        role: RoleTypes,
658        schema_id: &SchemaType,
659        namespace: Namespace,
660    ) -> (HashSet<PublicKey>, bool) {
661        let (names, any) = if schema_id.is_gov() {
662            self.roles_gov.get_signers(role)
663        } else {
664            let (mut not_gov_signers, not_gov_any) = self
665                .roles_tracker_schemas
666                .get_signers(role.clone(), namespace.clone());
667            let (mut schema_signers, schema_any) =
668                self.roles_schema.get(schema_id).map_or_else(
669                    || (vec![], false),
670                    |roles| roles.get_signers(role, namespace),
671                );
672
673            not_gov_signers.append(&mut schema_signers);
674
675            (not_gov_signers, not_gov_any || schema_any)
676        };
677
678        let mut signers = HashSet::new();
679        for name in names {
680            if let Some(key) = self.members.get(&name) {
681                signers.insert(key.clone());
682            }
683        }
684
685        (signers, any)
686    }
687
688    pub fn get_witnesses(
689        &self,
690        data: WitnessesData,
691    ) -> Result<HashSet<PublicKey>, GovernanceError> {
692        let names = match data {
693            WitnessesData::Gov => {
694                self.roles_gov.get_signers(RoleTypes::Witness).0
695            }
696            WitnessesData::Schema {
697                creator,
698                schema_id,
699                namespace,
700            } => {
701                let Some(creator) = self
702                    .members
703                    .iter()
704                    .find(|x| *x.1 == creator)
705                    .map(|x| x.0)
706                    .cloned()
707                else {
708                    return Err(GovernanceError::CreatorNotMember);
709                };
710
711                let Some(roles_schema) = self.roles_schema.get(&schema_id)
712                else {
713                    return Err(GovernanceError::WitnessesForNonexistentSchema);
714                };
715                let witnesses_creator =
716                    roles_schema.creator_witnesses(&creator, namespace.clone());
717
718                let mut names = vec![];
719                for witness in witnesses_creator {
720                    if witness == ReservedWords::Witnesses.to_string() {
721                        let mut not_gov_witnesses = self
722                            .roles_tracker_schemas
723                            .get_signers(RoleTypes::Witness, namespace.clone())
724                            .0;
725                        let mut schema_witnesses = roles_schema
726                            .get_signers(RoleTypes::Witness, namespace.clone())
727                            .0;
728
729                        names.append(&mut not_gov_witnesses);
730                        names.append(&mut schema_witnesses);
731                    } else {
732                        names.push(witness);
733                    }
734                }
735
736                names
737            }
738        };
739
740        let mut signers = HashSet::new();
741        for name in names {
742            if let Some(key) = self.members.get(&name) {
743                signers.insert(key.clone());
744            }
745        }
746
747        Ok(signers)
748    }
749
750    /// Get the quorum for the role and schema.
751    /// # Arguments
752    /// * [`Roles`] - The role.
753    /// * `schema_id` - The schema id from [`Schema`].
754    /// # Returns
755    /// * Option<[`Quorum`]> - The quorum.
756    fn get_quorum(
757        &self,
758        role: ProtocolTypes,
759        schema_id: &SchemaType,
760    ) -> Option<Quorum> {
761        if schema_id.is_gov() {
762            self.policies_gov.get_quorum(role)
763        } else {
764            let policie = self.policies_schema.get(schema_id)?;
765
766            policie.get_quorum(role)
767        }
768    }
769
770    /// Get the quorum and signers for the role and schema.
771    /// # Arguments
772    /// * [`Roles`] - The role.
773    /// * `schema_id` - The schema id from [`Schema`].
774    /// * [`Namespace`] - The namespace.
775    /// # Returns
776    /// * (HashSet<[`PublicKey`]>, [`Quorum`]) - The set of key identifiers and the quorum.
777    pub fn get_quorum_and_signers(
778        &self,
779        role: ProtocolTypes,
780        schema_id: &SchemaType,
781        namespace: Namespace,
782    ) -> Result<(HashSet<PublicKey>, Quorum), GovernanceError> {
783        let (signers, _not_members) = self.get_signers(
784            RoleTypes::from(role.clone()),
785            schema_id,
786            namespace,
787        );
788
789        let Some(quorum) = self.get_quorum(role.clone(), schema_id) else {
790            return Err(GovernanceError::QuorumNotFound {
791                role: role.to_string(),
792                schema_id: schema_id.to_string(),
793            });
794        };
795
796        Ok((signers, quorum))
797    }
798
799    pub fn schemas_name(
800        &self,
801        role: ProtocolTypes,
802        key: &PublicKey,
803    ) -> BTreeSet<SchemaType> {
804        let Some(name) = self
805            .members
806            .iter()
807            .find(|x| x.1 == key)
808            .map(|x| x.0)
809            .cloned()
810        else {
811            return BTreeSet::new();
812        };
813
814        if self
815            .roles_tracker_schemas
816            .hash_this_rol_not_namespace(role.clone(), &name)
817        {
818            return self.schemas.keys().cloned().collect();
819        }
820
821        let mut schemas: BTreeSet<SchemaType> = BTreeSet::new();
822
823        for (schema_id, roles) in self.roles_schema.iter() {
824            if roles.hash_this_rol_not_namespace(role.clone(), &name) {
825                schemas.insert(schema_id.clone());
826            }
827        }
828
829        schemas
830    }
831
832    pub fn schemas_namespace(
833        &self,
834        role: ProtocolTypes,
835        key: &PublicKey,
836    ) -> BTreeMap<SchemaType, Vec<Namespace>> {
837        let mut map = BTreeMap::new();
838
839        let Some(name) = self
840            .members
841            .iter()
842            .find(|x| x.1 == key)
843            .map(|x| x.0)
844            .cloned()
845        else {
846            return map;
847        };
848
849        let vec = self
850            .roles_tracker_schemas
851            .role_namespace(role.clone(), &name);
852
853        if !vec.is_empty() {
854            map.insert(SchemaType::TrackerSchemas, vec);
855        }
856
857        for (schema_id, roles) in self.roles_schema.iter() {
858            let vec = roles.role_namespace(role.clone(), &name);
859            if !vec.is_empty() {
860                map.insert(schema_id.clone(), vec);
861            }
862        }
863        map
864    }
865
866    pub fn schema_creators_namespace(
867        &self,
868        schema_namespaces: BTreeMap<SchemaType, Vec<Namespace>>,
869    ) -> BTreeMap<SchemaType, BTreeMap<PublicKey, BTreeSet<Namespace>>> {
870        let mut map: BTreeMap<
871            SchemaType,
872            BTreeMap<PublicKey, BTreeSet<Namespace>>,
873        > = BTreeMap::new();
874
875        for (schema_id, namespace) in schema_namespaces {
876            if schema_id == SchemaType::TrackerSchemas {
877                for (schema_id, roles) in self.roles_schema.iter() {
878                    let schema_entry =
879                        map.entry(schema_id.clone()).or_default();
880                    for ns in namespace.iter() {
881                        for user in roles.creator.iter() {
882                            if ns.is_ancestor_or_equal_of(&user.namespace)
883                                && let Some(pub_key) =
884                                    self.members.get(&user.name)
885                            {
886                                schema_entry
887                                    .entry(pub_key.clone())
888                                    .or_default()
889                                    .insert(user.namespace.clone());
890                            }
891                        }
892                    }
893                }
894            } else if let Some(roles) = self.roles_schema.get(&schema_id) {
895                let schema_entry = map.entry(schema_id).or_default();
896                for ns in namespace.iter() {
897                    for user in roles.creator.iter() {
898                        if ns.is_ancestor_or_equal_of(&user.namespace)
899                            && let Some(pub_key) = self.members.get(&user.name)
900                        {
901                            schema_entry
902                                .entry(pub_key.clone())
903                                .or_default()
904                                .insert(user.namespace.clone());
905                        }
906                    }
907                }
908            }
909        }
910
911        map
912    }
913
914    pub fn schemas(
915        &self,
916        role: ProtocolTypes,
917        key: &PublicKey,
918    ) -> BTreeMap<SchemaType, Schema> {
919        let Some(name) = self
920            .members
921            .iter()
922            .find(|x| x.1 == key)
923            .map(|x| x.0)
924            .cloned()
925        else {
926            return BTreeMap::new();
927        };
928
929        if self
930            .roles_tracker_schemas
931            .hash_this_rol_not_namespace(role.clone(), &name)
932        {
933            return self.schemas.clone();
934        }
935
936        let mut not_schemas: Vec<SchemaType> = vec![];
937
938        for (schema_id, roles) in self.roles_schema.iter() {
939            if !roles.hash_this_rol_not_namespace(role.clone(), &name) {
940                not_schemas.push(schema_id.clone());
941            }
942        }
943
944        let mut copy_schemas = self.schemas.clone();
945        for schema_id in not_schemas {
946            copy_schemas.remove(&schema_id);
947        }
948
949        copy_schemas
950    }
951
952    pub fn schemas_init_value(
953        &self,
954        role: ProtocolTypes,
955        key: &PublicKey,
956    ) -> BTreeMap<SchemaType, ValueWrapper> {
957        let Some(name) = self
958            .members
959            .iter()
960            .find(|x| x.1 == key)
961            .map(|x| x.0)
962            .cloned()
963        else {
964            return BTreeMap::new();
965        };
966
967        if self
968            .roles_tracker_schemas
969            .hash_this_rol_not_namespace(role.clone(), &name)
970        {
971            return self
972                .schemas
973                .iter()
974                .map(|x| (x.0.clone(), x.1.initial_value.clone()))
975                .collect();
976        }
977
978        let mut not_schemas: Vec<SchemaType> = vec![];
979
980        for (schema_id, roles) in self.roles_schema.iter() {
981            if !roles.hash_this_rol_not_namespace(role.clone(), &name) {
982                not_schemas.push(schema_id.clone());
983            }
984        }
985
986        let mut copy_schemas = self.schemas.clone();
987        for schema_id in not_schemas {
988            copy_schemas.remove(&schema_id);
989        }
990
991        copy_schemas
992            .iter()
993            .map(|x| (x.0.clone(), x.1.initial_value.clone()))
994            .collect()
995    }
996
997    /// Check if the key is a member.
998    pub fn is_member(&self, key: &PublicKey) -> bool {
999        self.members.iter().any(|x| x.1 == key)
1000    }
1001}
1002
1003impl TryFrom<ValueWrapper> for GovernanceData {
1004    type Error = GovernanceError;
1005
1006    fn try_from(value: ValueWrapper) -> Result<Self, Self::Error> {
1007        let governance: Self =
1008            serde_json::from_value(value.0).map_err(|e| {
1009                GovernanceError::ConversionFailed {
1010                    details: e.to_string(),
1011                }
1012            })?;
1013        Ok(governance)
1014    }
1015}