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, Role,
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                false
643            }
644        }
645    }
646
647    /// Gets the signers for the request stage.
648    /// # Arguments
649    /// * [`Roles`] - The role.
650    /// * `schema_id` - The schema id from [`Schema`].
651    /// * [`Namespace`] - The namespace.
652    /// # Returns
653    /// * (HashSet<[`PublicKey`]>, bool) - The set of key identifiers and a flag indicating if the user is not a member.
654    pub fn get_signers(
655        &self,
656        role: RoleTypes,
657        schema_id: &SchemaType,
658        namespace: Namespace,
659    ) -> (HashSet<PublicKey>, bool) {
660        let (names, any) = if schema_id.is_gov() {
661            self.roles_gov.get_signers(role)
662        } else {
663            let (mut not_gov_signers, not_gov_any) = self
664                .roles_tracker_schemas
665                .get_signers(role.clone(), namespace.clone());
666            let (mut schema_signers, schema_any) =
667                self.roles_schema.get(schema_id).map_or_else(
668                    || (vec![], false),
669                    |roles| roles.get_signers(role, namespace),
670                );
671
672            not_gov_signers.append(&mut schema_signers);
673
674            (not_gov_signers, not_gov_any || schema_any)
675        };
676
677        let mut signers = HashSet::new();
678        for name in names {
679            if let Some(key) = self.members.get(&name) {
680                signers.insert(key.clone());
681            }
682        }
683
684        (signers, any)
685    }
686
687    pub fn get_witnesses(
688        &self,
689        data: WitnessesData,
690    ) -> Result<HashSet<PublicKey>, GovernanceError> {
691        let names = match data {
692            WitnessesData::Gov => {
693                self.roles_gov.get_signers(RoleTypes::Witness).0
694            }
695            WitnessesData::Schema {
696                creator,
697                schema_id,
698                namespace,
699            } => {
700                let Some(creator) = self
701                    .members
702                    .iter()
703                    .find(|x| *x.1 == creator)
704                    .map(|x| x.0)
705                    .cloned()
706                else {
707                    return Err(GovernanceError::CreatorNotMember);
708                };
709
710                let Some(roles_schema) = self.roles_schema.get(&schema_id)
711                else {
712                    return Err(GovernanceError::WitnessesForNonexistentSchema);
713                };
714                let witnesses_creator =
715                    roles_schema.creator_witnesses(&creator, namespace.clone());
716
717                let mut names = vec![];
718                for witness in witnesses_creator {
719                    if witness == ReservedWords::Witnesses.to_string() {
720                        let mut not_gov_witnesses = self
721                            .roles_tracker_schemas
722                            .get_signers(RoleTypes::Witness, namespace.clone())
723                            .0;
724                        let mut schema_witnesses = roles_schema
725                            .get_signers(RoleTypes::Witness, namespace.clone())
726                            .0;
727
728                        names.append(&mut not_gov_witnesses);
729                        names.append(&mut schema_witnesses);
730                    } else {
731                        names.push(witness);
732                    }
733                }
734
735                names
736            }
737        };
738
739        let mut signers = HashSet::new();
740        for name in names {
741            if let Some(key) = self.members.get(&name) {
742                signers.insert(key.clone());
743            }
744        }
745
746        Ok(signers)
747    }
748
749    /// Get the quorum for the role and schema.
750    /// # Arguments
751    /// * [`Roles`] - The role.
752    /// * `schema_id` - The schema id from [`Schema`].
753    /// # Returns
754    /// * Option<[`Quorum`]> - The quorum.
755    fn get_quorum(
756        &self,
757        role: ProtocolTypes,
758        schema_id: &SchemaType,
759    ) -> Option<Quorum> {
760        if schema_id.is_gov() {
761            self.policies_gov.get_quorum(role)
762        } else {
763            let policie = self.policies_schema.get(schema_id)?;
764
765            policie.get_quorum(role)
766        }
767    }
768
769    /// Get the quorum and signers for the role and schema.
770    /// # Arguments
771    /// * [`Roles`] - The role.
772    /// * `schema_id` - The schema id from [`Schema`].
773    /// * [`Namespace`] - The namespace.
774    /// # Returns
775    /// * (HashSet<[`PublicKey`]>, [`Quorum`]) - The set of key identifiers and the quorum.
776    pub fn get_quorum_and_signers(
777        &self,
778        role: ProtocolTypes,
779        schema_id: &SchemaType,
780        namespace: Namespace,
781    ) -> Result<(HashSet<PublicKey>, Quorum), GovernanceError> {
782        let (signers, _not_members) = self.get_signers(
783            RoleTypes::from(role.clone()),
784            schema_id,
785            namespace,
786        );
787
788        let Some(quorum) = self.get_quorum(role.clone(), schema_id) else {
789            return Err(GovernanceError::QuorumNotFound {
790                role: role.to_string(),
791                schema_id: schema_id.to_string(),
792            });
793        };
794
795        Ok((signers, quorum))
796    }
797
798    pub fn schemas_name(
799        &self,
800        role: ProtocolTypes,
801        key: &PublicKey,
802    ) -> BTreeSet<SchemaType> {
803        let Some(name) = self
804            .members
805            .iter()
806            .find(|x| x.1 == key)
807            .map(|x| x.0)
808            .cloned()
809        else {
810            return BTreeSet::new();
811        };
812
813        if self
814            .roles_tracker_schemas
815            .hash_this_rol_not_namespace(role.clone(), &name)
816        {
817            return self.schemas.keys().cloned().collect();
818        }
819
820        let mut schemas: BTreeSet<SchemaType> = BTreeSet::new();
821
822        for (schema_id, roles) in self.roles_schema.iter() {
823            if roles.hash_this_rol_not_namespace(role.clone(), &name) {
824                schemas.insert(schema_id.clone());
825            }
826        }
827
828        schemas
829    }
830
831    pub fn schemas_namespace(
832        &self,
833        role: ProtocolTypes,
834        key: &PublicKey,
835    ) -> BTreeMap<SchemaType, Vec<Namespace>> {
836        let mut map = BTreeMap::new();
837
838        let Some(name) = self
839            .members
840            .iter()
841            .find(|x| x.1 == key)
842            .map(|x| x.0)
843            .cloned()
844        else {
845            return map;
846        };
847
848        let vec = self
849            .roles_tracker_schemas
850            .role_namespace(role.clone(), &name);
851
852        if !vec.is_empty() {
853            map.insert(SchemaType::TrackerSchemas, vec);
854        }
855
856        for (schema_id, roles) in self.roles_schema.iter() {
857            let vec = roles.role_namespace(role.clone(), &name);
858            if !vec.is_empty() {
859                map.insert(schema_id.clone(), vec);
860            }
861        }
862        map
863    }
864
865    pub fn schema_creators_namespace(
866        &self,
867        schema_namespaces: BTreeMap<SchemaType, Vec<Namespace>>,
868    ) -> BTreeMap<SchemaType, BTreeMap<PublicKey, BTreeSet<Namespace>>> {
869        let mut map: BTreeMap<
870            SchemaType,
871            BTreeMap<PublicKey, BTreeSet<Namespace>>,
872        > = BTreeMap::new();
873
874        for (schema_id, namespace) in schema_namespaces {
875            if schema_id == SchemaType::TrackerSchemas {
876                for (schema_id, roles) in self.roles_schema.iter() {
877                    let schema_entry =
878                        map.entry(schema_id.clone()).or_default();
879                    for ns in namespace.iter() {
880                        for user in roles.creator.iter() {
881                            if ns.is_ancestor_or_equal_of(&user.namespace)
882                                && let Some(pub_key) =
883                                    self.members.get(&user.name)
884                            {
885                                schema_entry
886                                    .entry(pub_key.clone())
887                                    .or_default()
888                                    .insert(user.namespace.clone());
889                            }
890                        }
891                    }
892                }
893            } else if let Some(roles) = self.roles_schema.get(&schema_id) {
894                let schema_entry = map.entry(schema_id).or_default();
895                for ns in namespace.iter() {
896                    for user in roles.creator.iter() {
897                        if ns.is_ancestor_or_equal_of(&user.namespace)
898                            && let Some(pub_key) = self.members.get(&user.name)
899                        {
900                            schema_entry
901                                .entry(pub_key.clone())
902                                .or_default()
903                                .insert(user.namespace.clone());
904                        }
905                    }
906                }
907            }
908        }
909
910        map
911    }
912
913    pub fn governance_issuers(&self) -> (BTreeSet<PublicKey>, bool) {
914        let mut issuers = BTreeSet::new();
915
916        for name in self.roles_gov.issuer.signers.iter() {
917            if let Some(key) = self.members.get(name) {
918                issuers.insert(key.clone());
919            }
920        }
921
922        (issuers, self.roles_gov.issuer.any)
923    }
924
925    pub fn schema_issuers_namespace(
926        &self,
927        schema_namespaces: BTreeMap<SchemaType, Vec<Namespace>>,
928    ) -> BTreeMap<SchemaType, (BTreeMap<PublicKey, BTreeSet<Namespace>>, bool)>
929    {
930        let mut map: BTreeMap<
931            SchemaType,
932            (BTreeMap<PublicKey, BTreeSet<Namespace>>, bool),
933        > = BTreeMap::new();
934
935        fn insert_issuers(
936            members: &BTreeMap<MemberName, PublicKey>,
937            schema_entry: &mut BTreeMap<PublicKey, BTreeSet<Namespace>>,
938            issuers: &BTreeSet<Role>,
939        ) {
940            for issuer in issuers {
941                if let Some(pub_key) = members.get(&issuer.name) {
942                    schema_entry
943                        .entry(pub_key.clone())
944                        .or_default()
945                        .insert(issuer.namespace.clone());
946                }
947            }
948        }
949
950        for (schema_id, _) in schema_namespaces {
951            if schema_id == SchemaType::TrackerSchemas {
952                for (current_schema_id, roles) in self.roles_schema.iter() {
953                    let (schema_entry, issuer_any) = map
954                        .entry(current_schema_id.clone())
955                        .or_insert_with(|| (BTreeMap::new(), false));
956                    *issuer_any |= self.roles_tracker_schemas.issuer.any
957                        || roles.issuer.any;
958
959                    insert_issuers(
960                        &self.members,
961                        schema_entry,
962                        &self.roles_tracker_schemas.issuer.signers,
963                    );
964                    insert_issuers(
965                        &self.members,
966                        schema_entry,
967                        &roles.issuer.signers,
968                    );
969                }
970            } else if let Some(roles) = self.roles_schema.get(&schema_id) {
971                let (schema_entry, issuer_any) = map
972                    .entry(schema_id)
973                    .or_insert_with(|| (BTreeMap::new(), false));
974                *issuer_any |=
975                    self.roles_tracker_schemas.issuer.any || roles.issuer.any;
976
977                insert_issuers(
978                    &self.members,
979                    schema_entry,
980                    &self.roles_tracker_schemas.issuer.signers,
981                );
982                insert_issuers(
983                    &self.members,
984                    schema_entry,
985                    &roles.issuer.signers,
986                );
987            }
988        }
989
990        map
991    }
992
993    pub fn schemas(
994        &self,
995        role: ProtocolTypes,
996        key: &PublicKey,
997    ) -> BTreeMap<SchemaType, Schema> {
998        let Some(name) = self
999            .members
1000            .iter()
1001            .find(|x| x.1 == key)
1002            .map(|x| x.0)
1003            .cloned()
1004        else {
1005            return BTreeMap::new();
1006        };
1007
1008        if self
1009            .roles_tracker_schemas
1010            .hash_this_rol_not_namespace(role.clone(), &name)
1011        {
1012            return self.schemas.clone();
1013        }
1014
1015        let mut not_schemas: Vec<SchemaType> = vec![];
1016
1017        for (schema_id, roles) in self.roles_schema.iter() {
1018            if !roles.hash_this_rol_not_namespace(role.clone(), &name) {
1019                not_schemas.push(schema_id.clone());
1020            }
1021        }
1022
1023        let mut copy_schemas = self.schemas.clone();
1024        for schema_id in not_schemas {
1025            copy_schemas.remove(&schema_id);
1026        }
1027
1028        copy_schemas
1029    }
1030
1031    pub fn schemas_init_value(
1032        &self,
1033        role: ProtocolTypes,
1034        key: &PublicKey,
1035    ) -> BTreeMap<SchemaType, ValueWrapper> {
1036        let Some(name) = self
1037            .members
1038            .iter()
1039            .find(|x| x.1 == key)
1040            .map(|x| x.0)
1041            .cloned()
1042        else {
1043            return BTreeMap::new();
1044        };
1045
1046        if self
1047            .roles_tracker_schemas
1048            .hash_this_rol_not_namespace(role.clone(), &name)
1049        {
1050            return self
1051                .schemas
1052                .iter()
1053                .map(|x| (x.0.clone(), x.1.initial_value.clone()))
1054                .collect();
1055        }
1056
1057        let mut not_schemas: Vec<SchemaType> = vec![];
1058
1059        for (schema_id, roles) in self.roles_schema.iter() {
1060            if !roles.hash_this_rol_not_namespace(role.clone(), &name) {
1061                not_schemas.push(schema_id.clone());
1062            }
1063        }
1064
1065        let mut copy_schemas = self.schemas.clone();
1066        for schema_id in not_schemas {
1067            copy_schemas.remove(&schema_id);
1068        }
1069
1070        copy_schemas
1071            .iter()
1072            .map(|x| (x.0.clone(), x.1.initial_value.clone()))
1073            .collect()
1074    }
1075
1076    /// Check if the key is a member.
1077    pub fn is_member(&self, key: &PublicKey) -> bool {
1078        self.members.iter().any(|x| x.1 == key)
1079    }
1080}
1081
1082impl TryFrom<ValueWrapper> for GovernanceData {
1083    type Error = GovernanceError;
1084
1085    fn try_from(value: ValueWrapper) -> Result<Self, Self::Error> {
1086        let governance: Self =
1087            serde_json::from_value(value.0).map_err(|e| {
1088                GovernanceError::ConversionFailed {
1089                    details: e.to_string(),
1090                }
1091            })?;
1092        Ok(governance)
1093    }
1094}