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