Skip to main content

ave_core/governance/
events.rs

1use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
2
3use ave_common::{
4    Namespace, SchemaType, identity::PublicKey, schematype::ReservedWords,
5};
6use serde::{Deserialize, Serialize};
7use serde_json::Value;
8
9use crate::{
10    evaluation::runner::error::{self, RunnerError},
11    governance::{
12        CreatorRoleUpdate, RolesUpdate, RolesUpdateRemove,
13        data::GovernanceData,
14        model::{Quorum, Role},
15        witnesses_register::WitnessesType,
16    },
17};
18
19use super::model::{
20    CreatorQuantity, RoleCreator, RolesGov, RolesSchema, RolesTrackerSchemas,
21};
22
23pub type MemberName = String;
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct GovernanceEvent {
27    pub members: Option<MemberEvent>,
28    pub roles: Option<RolesEvent>,
29    pub schemas: Option<SchemasEvent>,
30    pub policies: Option<PoliciesEvent>,
31}
32
33impl GovernanceEvent {
34    pub fn update_creator_change(
35        &self,
36        members: &BTreeMap<MemberName, PublicKey>,
37        roles_schema: &BTreeMap<SchemaType, RolesSchema>,
38    ) -> CreatorRoleUpdate {
39        let mut new_creator: HashMap<
40            (SchemaType, String, PublicKey),
41            (CreatorQuantity, BTreeSet<String>),
42        > = HashMap::new();
43
44        let mut update_creator_quantity: HashSet<(
45            SchemaType,
46            String,
47            PublicKey,
48            CreatorQuantity,
49        )> = HashSet::new();
50
51        let mut update_creator_witnesses: HashSet<(
52            SchemaType,
53            String,
54            PublicKey,
55            BTreeSet<String>,
56        )> = HashSet::new();
57
58        let mut remove_creator: HashSet<(SchemaType, String, PublicKey)> =
59            HashSet::new();
60
61        if let Some(roles) = &self.roles
62            && let Some(schemas) = &roles.schema
63        {
64            for schema in schemas {
65                if let Some(change) = &schema.change
66                    && let Some(creator) = &change.creator
67                    && let Some(roles) = roles_schema.get(&schema.schema_id)
68                {
69                    creator.iter().for_each(|x| {
70                        if let Some(user) = members.get(&x.actual_name) {
71                            if let Some(new_namespace) = &x.new_namespace {
72                                remove_creator.insert((
73                                    schema.schema_id.clone(),
74                                    x.actual_namespace.to_string(),
75                                    user.clone(),
76                                ));
77
78                                match (&x.new_witnesses, &x.new_quantity) {
79                                    (None, None) => {
80                                        if let Some(creator) =
81                                            roles.creator.get(&RoleCreator {
82                                                name: x.actual_name.clone(),
83                                                namespace: x
84                                                    .actual_namespace
85                                                    .clone(),
86                                                witnesses: BTreeSet::new(),
87                                                quantity:
88                                                    CreatorQuantity::Infinity,
89                                            })
90                                            && let Some(user) =
91                                                members.get(&creator.name)
92                                        {
93                                            new_creator.insert(
94                                                (
95                                                    schema.schema_id.clone(),
96                                                    new_namespace.to_string(),
97                                                    user.clone(),
98                                                ),
99                                                (
100                                                    creator.quantity.clone(),
101                                                    creator.witnesses.clone(),
102                                                ),
103                                            );
104                                        }
105                                    }
106                                    (None, Some(q)) => {
107                                        if let Some(creator) =
108                                            roles.creator.get(&RoleCreator {
109                                                name: x.actual_name.clone(),
110                                                namespace: x
111                                                    .actual_namespace
112                                                    .clone(),
113                                                witnesses: BTreeSet::new(),
114                                                quantity:
115                                                    CreatorQuantity::Infinity,
116                                            })
117                                            && let Some(user) =
118                                                members.get(&creator.name)
119                                        {
120                                            new_creator.insert(
121                                                (
122                                                    schema.schema_id.clone(),
123                                                    new_namespace.to_string(),
124                                                    user.clone(),
125                                                ),
126                                                (
127                                                    q.clone(),
128                                                    creator.witnesses.clone(),
129                                                ),
130                                            );
131                                        }
132                                    }
133                                    (Some(w), None) => {
134                                        if let Some(creator) =
135                                            roles.creator.get(&RoleCreator {
136                                                name: x.actual_name.clone(),
137                                                namespace: x
138                                                    .actual_namespace
139                                                    .clone(),
140                                                witnesses: BTreeSet::new(),
141                                                quantity:
142                                                    CreatorQuantity::Infinity,
143                                            })
144                                            && let Some(user) =
145                                                members.get(&creator.name)
146                                        {
147                                            new_creator.insert(
148                                                (
149                                                    schema.schema_id.clone(),
150                                                    new_namespace.to_string(),
151                                                    user.clone(),
152                                                ),
153                                                (
154                                                    creator.quantity.clone(),
155                                                    w.clone(),
156                                                ),
157                                            );
158                                        }
159                                    }
160                                    (Some(w), Some(q)) => {
161                                        new_creator.insert(
162                                            (
163                                                schema.schema_id.clone(),
164                                                new_namespace.to_string(),
165                                                user.clone(),
166                                            ),
167                                            (q.clone(), w.clone()),
168                                        );
169                                    }
170                                }
171                            } else {
172                                if let Some(q) = &x.new_quantity {
173                                    update_creator_quantity.insert((
174                                        schema.schema_id.clone(),
175                                        x.actual_namespace.to_string(),
176                                        user.clone(),
177                                        q.clone(),
178                                    ));
179                                }
180
181                                if let Some(w) = &x.new_witnesses {
182                                    update_creator_witnesses.insert((
183                                        schema.schema_id.clone(),
184                                        x.actual_namespace.to_string(),
185                                        user.clone(),
186                                        w.clone(),
187                                    ));
188                                }
189                            }
190                        }
191                    });
192                }
193            }
194        }
195
196        CreatorRoleUpdate {
197            new_creator,
198            update_creator_quantity,
199            update_creator_witnesses,
200            remove_creator,
201        }
202    }
203
204    pub fn roles_update_fact(
205        &self,
206        members: &BTreeMap<MemberName, PublicKey>,
207        rm_roles: Option<RolesUpdateRemove>,
208    ) -> RolesUpdate {
209        let mut appr_quorum: Option<Quorum> = None;
210        let mut eval_quorum: HashMap<SchemaType, Quorum> = HashMap::new();
211        let mut vali_quorum: HashMap<SchemaType, Quorum> = HashMap::new();
212
213        let mut new_approvers: Vec<PublicKey> = vec![];
214        let mut remove_approvers: Vec<PublicKey> = vec![];
215
216        let mut new_evaluators: HashMap<
217            (SchemaType, PublicKey),
218            Vec<Namespace>,
219        > = HashMap::new();
220
221        let mut remove_evaluators: HashMap<
222            (SchemaType, PublicKey),
223            Vec<Namespace>,
224        > = HashMap::new();
225
226        let mut new_validators: HashMap<
227            (SchemaType, PublicKey),
228            Vec<Namespace>,
229        > = HashMap::new();
230
231        let mut remove_validators: HashMap<
232            (SchemaType, PublicKey),
233            Vec<Namespace>,
234        > = HashMap::new();
235
236        let mut new_creator: HashMap<
237            (SchemaType, String, PublicKey),
238            (CreatorQuantity, Vec<WitnessesType>),
239        > = HashMap::new();
240
241        let mut remove_creator: HashSet<(SchemaType, String, PublicKey)> =
242            HashSet::new();
243
244        let mut new_witnesses: HashMap<
245            (SchemaType, PublicKey),
246            Vec<Namespace>,
247        > = HashMap::new();
248
249        let mut remove_witnesses: HashMap<
250            (SchemaType, PublicKey),
251            Vec<Namespace>,
252        > = HashMap::new();
253
254        if let Some(schema) = &self.schemas
255            && let Some(schema_add) = &schema.add
256        {
257            for schema_data in schema_add {
258                eval_quorum.insert(schema_data.id.clone(), Quorum::Majority);
259                vali_quorum.insert(schema_data.id.clone(), Quorum::Majority);
260            }
261        }
262
263        if let Some(roles) = &self.roles {
264            // Gov
265            if let Some(governance) = &roles.governance {
266                if let Some(add) = &governance.add {
267                    if let Some(approvers) = &add.approver {
268                        approvers.iter().for_each(|x| {
269                            if let Some(user) = members.get(x) {
270                                new_approvers.push(user.clone());
271                            }
272                        });
273                    }
274
275                    if let Some(evaluators) = &add.evaluator {
276                        evaluators.iter().for_each(|x| {
277                            if let Some(user) = members.get(x) {
278                                new_evaluators
279                                    .entry((
280                                        SchemaType::Governance,
281                                        user.clone(),
282                                    ))
283                                    .or_default()
284                                    .push(Namespace::new());
285                            }
286                        });
287                    }
288
289                    if let Some(validators) = &add.validator {
290                        validators.iter().for_each(|x| {
291                            if let Some(user) = members.get(x) {
292                                new_validators
293                                    .entry((
294                                        SchemaType::Governance,
295                                        user.clone(),
296                                    ))
297                                    .or_default()
298                                    .push(Namespace::new());
299                            }
300                        });
301                    }
302                }
303                if let Some(remove) = &governance.remove {
304                    if let Some(approvers) = &remove.approver {
305                        approvers.iter().for_each(|x| {
306                            if let Some(user) = members.get(x) {
307                                remove_approvers.push(user.clone());
308                            }
309                        });
310                    }
311
312                    if let Some(evaluators) = &remove.evaluator {
313                        evaluators.iter().for_each(|x| {
314                            if let Some(user) = members.get(x) {
315                                remove_evaluators
316                                    .entry((
317                                        SchemaType::Governance,
318                                        user.clone(),
319                                    ))
320                                    .or_default()
321                                    .push(Namespace::new());
322                            }
323                        });
324                    }
325
326                    if let Some(validators) = &remove.validator {
327                        validators.iter().for_each(|x| {
328                            if let Some(user) = members.get(x) {
329                                remove_validators
330                                    .entry((
331                                        SchemaType::Governance,
332                                        user.clone(),
333                                    ))
334                                    .or_default()
335                                    .push(Namespace::new());
336                            }
337                        });
338                    }
339                }
340            }
341
342            // all schemas
343            if let Some(tracker_schemas) = &roles.tracker_schemas {
344                if let Some(add) = &tracker_schemas.add {
345                    if let Some(evaluators) = &add.evaluator {
346                        evaluators.iter().for_each(|x| {
347                            if let Some(user) = members.get(&x.name) {
348                                new_evaluators
349                                    .entry((
350                                        SchemaType::TrackerSchemas,
351                                        user.clone(),
352                                    ))
353                                    .or_default()
354                                    .push(x.namespace.clone());
355                            }
356                        });
357                    }
358
359                    if let Some(validators) = &add.validator {
360                        validators.iter().for_each(|x| {
361                            if let Some(user) = members.get(&x.name) {
362                                new_validators
363                                    .entry((
364                                        SchemaType::TrackerSchemas,
365                                        user.clone(),
366                                    ))
367                                    .or_default()
368                                    .push(x.namespace.clone());
369                            }
370                        });
371                    }
372
373                    if let Some(witnesses) = &add.witness {
374                        witnesses.iter().for_each(|x| {
375                            if let Some(user) = members.get(&x.name) {
376                                new_witnesses
377                                    .entry((
378                                        SchemaType::TrackerSchemas,
379                                        user.clone(),
380                                    ))
381                                    .or_default()
382                                    .push(x.namespace.clone());
383                            }
384                        });
385                    }
386                }
387                if let Some(remove) = &tracker_schemas.remove {
388                    if let Some(evaluators) = &remove.evaluator {
389                        evaluators.iter().for_each(|x| {
390                            if let Some(user) = members.get(&x.name) {
391                                remove_evaluators
392                                    .entry((
393                                        SchemaType::TrackerSchemas,
394                                        user.clone(),
395                                    ))
396                                    .or_default()
397                                    .push(x.namespace.clone());
398                            }
399                        });
400                    }
401
402                    if let Some(validators) = &remove.validator {
403                        validators.iter().for_each(|x| {
404                            if let Some(user) = members.get(&x.name) {
405                                remove_validators
406                                    .entry((
407                                        SchemaType::TrackerSchemas,
408                                        user.clone(),
409                                    ))
410                                    .or_default()
411                                    .push(x.namespace.clone());
412                            }
413                        });
414                    }
415
416                    if let Some(witnesses) = &remove.witness {
417                        witnesses.iter().for_each(|x| {
418                            if let Some(user) = members.get(&x.name) {
419                                remove_witnesses
420                                    .entry((
421                                        SchemaType::TrackerSchemas,
422                                        user.clone(),
423                                    ))
424                                    .or_default()
425                                    .push(x.namespace.clone());
426                            }
427                        });
428                    }
429                }
430                if let Some(change) = &tracker_schemas.change {
431                    if let Some(evaluators) = &change.evaluator {
432                        evaluators.iter().for_each(|x| {
433                            if let Some(user) = members.get(&x.actual_name) {
434                                remove_evaluators
435                                    .entry((
436                                        SchemaType::TrackerSchemas,
437                                        user.clone(),
438                                    ))
439                                    .or_default()
440                                    .push(x.actual_namespace.clone());
441
442                                new_evaluators
443                                    .entry((
444                                        SchemaType::TrackerSchemas,
445                                        user.clone(),
446                                    ))
447                                    .or_default()
448                                    .push(x.new_namespace.clone());
449                            }
450                        });
451                    }
452
453                    if let Some(validators) = &change.validator {
454                        validators.iter().for_each(|x| {
455                            if let Some(user) = members.get(&x.actual_name) {
456                                remove_validators
457                                    .entry((
458                                        SchemaType::TrackerSchemas,
459                                        user.clone(),
460                                    ))
461                                    .or_default()
462                                    .push(x.actual_namespace.clone());
463
464                                new_validators
465                                    .entry((
466                                        SchemaType::TrackerSchemas,
467                                        user.clone(),
468                                    ))
469                                    .or_default()
470                                    .push(x.new_namespace.clone());
471                            }
472                        });
473                    }
474
475                    if let Some(witnesses) = &change.witness {
476                        witnesses.iter().for_each(|x| {
477                            if let Some(user) = members.get(&x.actual_name) {
478                                remove_witnesses
479                                    .entry((
480                                        SchemaType::TrackerSchemas,
481                                        user.clone(),
482                                    ))
483                                    .or_default()
484                                    .push(x.actual_namespace.clone());
485
486                                new_witnesses
487                                    .entry((
488                                        SchemaType::TrackerSchemas,
489                                        user.clone(),
490                                    ))
491                                    .or_default()
492                                    .push(x.new_namespace.clone());
493                            }
494                        });
495                    }
496                }
497            }
498
499            // schema
500            if let Some(schemas) = &roles.schema {
501                for schema in schemas {
502                    if let Some(add) = &schema.add {
503                        if let Some(evaluators) = &add.evaluator {
504                            evaluators.iter().for_each(|x| {
505                                if let Some(user) = members.get(&x.name) {
506                                    new_evaluators
507                                        .entry((
508                                            schema.schema_id.clone(),
509                                            user.clone(),
510                                        ))
511                                        .or_default()
512                                        .push(x.namespace.clone());
513                                }
514                            });
515                        }
516                        if let Some(validators) = &add.validator {
517                            validators.iter().for_each(|x| {
518                                if let Some(user) = members.get(&x.name) {
519                                    new_validators
520                                        .entry((
521                                            schema.schema_id.clone(),
522                                            user.clone(),
523                                        ))
524                                        .or_default()
525                                        .push(x.namespace.clone());
526                                }
527                            });
528                        }
529                        if let Some(creator) = &add.creator {
530                            creator.iter().for_each(|x| {
531                                if let Some(user) = members.get(&x.name) {
532                                    let mut witnesses = vec![];
533                                    for witness in x.witnesses.iter() {
534                                        if witness
535                                            == &ReservedWords::Witnesses
536                                                .to_string()
537                                        {
538                                            witnesses
539                                                .push(WitnessesType::Witnesses);
540                                        } else if let Some(w) =
541                                            members.get(witness)
542                                        {
543                                            witnesses.push(
544                                                WitnessesType::User(w.clone()),
545                                            );
546                                        }
547                                    }
548
549                                    new_creator.insert(
550                                        (
551                                            schema.schema_id.clone(),
552                                            x.namespace.to_string(),
553                                            user.clone(),
554                                        ),
555                                        (x.quantity.clone(), witnesses),
556                                    );
557                                }
558                            });
559                        }
560
561                        if let Some(witnesses) = &add.witness {
562                            witnesses.iter().for_each(|x| {
563                                if let Some(user) = members.get(&x.name) {
564                                    new_witnesses
565                                        .entry((
566                                            schema.schema_id.clone(),
567                                            user.clone(),
568                                        ))
569                                        .or_default()
570                                        .push(x.namespace.clone());
571                                }
572                            });
573                        }
574                    }
575
576                    if let Some(remove) = &schema.remove {
577                        if let Some(evaluators) = &remove.evaluator {
578                            evaluators.iter().for_each(|x| {
579                                if let Some(user) = members.get(&x.name) {
580                                    remove_evaluators
581                                        .entry((
582                                            schema.schema_id.clone(),
583                                            user.clone(),
584                                        ))
585                                        .or_default()
586                                        .push(x.namespace.clone());
587                                }
588                            });
589                        }
590                        if let Some(validators) = &remove.validator {
591                            validators.iter().for_each(|x| {
592                                if let Some(user) = members.get(&x.name) {
593                                    remove_validators
594                                        .entry((
595                                            schema.schema_id.clone(),
596                                            user.clone(),
597                                        ))
598                                        .or_default()
599                                        .push(x.namespace.clone());
600                                }
601                            });
602                        }
603                        if let Some(creator) = &remove.creator {
604                            creator.iter().for_each(|x| {
605                                if let Some(user) = members.get(&x.name) {
606                                    remove_creator.insert((
607                                        schema.schema_id.clone(),
608                                        x.namespace.to_string(),
609                                        user.clone(),
610                                    ));
611                                }
612                            });
613                        }
614                        if let Some(witnesses) = &remove.witness {
615                            witnesses.iter().for_each(|x| {
616                                if let Some(user) = members.get(&x.name) {
617                                    remove_witnesses
618                                        .entry((
619                                            schema.schema_id.clone(),
620                                            user.clone(),
621                                        ))
622                                        .or_default()
623                                        .push(x.namespace.clone());
624                                }
625                            });
626                        }
627                    }
628                    if let Some(change) = &schema.change {
629                        if let Some(evaluators) = &change.evaluator {
630                            evaluators.iter().for_each(|x| {
631                                if let Some(user) = members.get(&x.actual_name)
632                                {
633                                    remove_evaluators
634                                        .entry((
635                                            schema.schema_id.clone(),
636                                            user.clone(),
637                                        ))
638                                        .or_default()
639                                        .push(x.actual_namespace.clone());
640
641                                    new_evaluators
642                                        .entry((
643                                            schema.schema_id.clone(),
644                                            user.clone(),
645                                        ))
646                                        .or_default()
647                                        .push(x.new_namespace.clone());
648                                }
649                            });
650                        }
651
652                        if let Some(validators) = &change.validator {
653                            validators.iter().for_each(|x| {
654                                if let Some(user) = members.get(&x.actual_name)
655                                {
656                                    remove_validators
657                                        .entry((
658                                            schema.schema_id.clone(),
659                                            user.clone(),
660                                        ))
661                                        .or_default()
662                                        .push(x.actual_namespace.clone());
663
664                                    new_validators
665                                        .entry((
666                                            schema.schema_id.clone(),
667                                            user.clone(),
668                                        ))
669                                        .or_default()
670                                        .push(x.new_namespace.clone());
671                                }
672                            });
673                        }
674
675                        if let Some(witnesses) = &change.witness {
676                            witnesses.iter().for_each(|x| {
677                                if let Some(user) = members.get(&x.actual_name)
678                                {
679                                    remove_witnesses
680                                        .entry((
681                                            schema.schema_id.clone(),
682                                            user.clone(),
683                                        ))
684                                        .or_default()
685                                        .push(x.actual_namespace.clone());
686
687                                    new_witnesses
688                                        .entry((
689                                            schema.schema_id.clone(),
690                                            user.clone(),
691                                        ))
692                                        .or_default()
693                                        .push(x.new_namespace.clone());
694                                }
695                            });
696                        }
697                    }
698                }
699            }
700        }
701
702        if let Some(policies) = &self.policies {
703            // gov
704            if let Some(governance) = &policies.governance {
705                appr_quorum = governance.change.approve.clone();
706
707                if let Some(quorum) = &governance.change.evaluate {
708                    eval_quorum.insert(SchemaType::Governance, quorum.clone());
709                }
710                if let Some(quorum) = &governance.change.validate {
711                    vali_quorum.insert(SchemaType::Governance, quorum.clone());
712                }
713            }
714
715            // schemas
716            if let Some(schemas) = &policies.schema {
717                for schema in schemas {
718                    if let Some(quorum) = &schema.change.evaluate {
719                        eval_quorum
720                            .insert(schema.schema_id.clone(), quorum.clone());
721                    }
722                    if let Some(quorum) = &schema.change.validate {
723                        vali_quorum
724                            .insert(schema.schema_id.clone(), quorum.clone());
725                    }
726                }
727            }
728        }
729
730        if let Some(rm) = rm_roles {
731            remove_witnesses.extend(rm.witnesses);
732            remove_creator.extend(rm.creator);
733            remove_approvers.extend(rm.approvers);
734            remove_evaluators.extend(rm.evaluators);
735            remove_validators.extend(rm.validators);
736        }
737
738        RolesUpdate {
739            appr_quorum,
740            new_evaluators,
741            new_validators,
742            eval_quorum,
743            new_approvers,
744            remove_approvers,
745            vali_quorum,
746            remove_evaluators,
747            remove_validators,
748            new_creator,
749            remove_creator,
750            new_witnesses,
751            remove_witnesses,
752        }
753    }
754
755    pub const fn is_empty(&self) -> bool {
756        self.members.is_none()
757            && self.roles.is_none()
758            && self.schemas.is_none()
759            && self.policies.is_none()
760    }
761}
762
763///// Members /////
764#[derive(Debug, Clone, Serialize, Deserialize)]
765pub struct MemberEvent {
766    pub add: Option<HashSet<NewMember>>,
767    pub remove: Option<HashSet<MemberName>>,
768}
769
770impl MemberEvent {
771    pub const fn is_empty(&self) -> bool {
772        self.add.is_none() && self.remove.is_none()
773    }
774}
775
776#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
777pub struct NewMember {
778    pub name: MemberName,
779    pub key: PublicKey,
780}
781
782///// Roles /////
783#[derive(Debug, Clone, Serialize, Deserialize)]
784pub struct RolesEvent {
785    pub governance: Option<GovRoleEvent>,
786    pub tracker_schemas: Option<TrackerSchemasRoleEvent>,
787    pub schema: Option<HashSet<SchemaIdRole>>,
788}
789
790impl RolesEvent {
791    pub const fn is_empty(&self) -> bool {
792        self.governance.is_none()
793            && self.schema.is_none()
794            && self.tracker_schemas.is_none()
795    }
796}
797
798#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
799pub struct GovRoleEvent {
800    pub add: Option<GovRolesEvent>,
801    pub remove: Option<GovRolesEvent>,
802}
803
804impl GovRoleEvent {
805    pub const fn is_empty(&self) -> bool {
806        self.add.is_none() && self.remove.is_none()
807    }
808
809    pub fn check_data(
810        &self,
811        governance: &GovernanceData,
812        new_roles: &mut RolesGov,
813    ) -> Result<(), RunnerError> {
814        // Validar que cada (role_type, name) solo aparezca una vez
815        let mut seen_roles: HashSet<(String, String)> = HashSet::new();
816
817        // Helper para registrar un rol y detectar duplicados
818        let mut check_and_register = |role_type: &str,
819                                      name: &str|
820         -> Result<(), RunnerError> {
821            let key = (role_type.to_string(), name.trim().to_string());
822            if !seen_roles.insert(key) {
823                return Err(RunnerError::InvalidEvent {
824                    location: "GovRoleEvent::check_data",
825                    kind: error::InvalidEventKind::InvalidValue {
826                        field: format!("{} role operation", role_type),
827                        reason: format!(
828                            "Role {} appears multiple times in the same event. Only one operation per role is allowed",
829                            name.trim()
830                        ),
831                    },
832                });
833            }
834            Ok(())
835        };
836
837        // Validar add operations
838        if let Some(ref add) = self.add {
839            if let Some(ref approvers) = add.approver {
840                for approver in approvers {
841                    check_and_register("approver", approver)?;
842                }
843            }
844            if let Some(ref evaluators) = add.evaluator {
845                for evaluator in evaluators {
846                    check_and_register("evaluator", evaluator)?;
847                }
848            }
849            if let Some(ref validators) = add.validator {
850                for validator in validators {
851                    check_and_register("validator", validator)?;
852                }
853            }
854            if let Some(ref witnesses) = add.witness {
855                for witness in witnesses {
856                    check_and_register("witness", witness)?;
857                }
858            }
859            if let Some(ref issuers) = add.issuer {
860                for issuer in issuers {
861                    check_and_register("issuer", issuer)?;
862                }
863            }
864        }
865
866        // Validar remove operations
867        if let Some(ref remove) = self.remove {
868            if let Some(ref approvers) = remove.approver {
869                for approver in approvers {
870                    check_and_register("approver", approver)?;
871                }
872            }
873            if let Some(ref evaluators) = remove.evaluator {
874                for evaluator in evaluators {
875                    check_and_register("evaluator", evaluator)?;
876                }
877            }
878            if let Some(ref validators) = remove.validator {
879                for validator in validators {
880                    check_and_register("validator", validator)?;
881                }
882            }
883            if let Some(ref witnesses) = remove.witness {
884                for witness in witnesses {
885                    check_and_register("witness", witness)?;
886                }
887            }
888            if let Some(ref issuers) = remove.issuer {
889                for issuer in issuers {
890                    check_and_register("issuer", issuer)?;
891                }
892            }
893        }
894
895        if let Some(add) = self.add.clone() {
896            if add.is_empty() {
897                return Err(RunnerError::InvalidEvent {
898                    location: "GovRoleEvent::check_data",
899                    kind: error::InvalidEventKind::Empty {
900                        what: "GovRoleEvent add".to_owned(),
901                    },
902                });
903            }
904
905            let members: HashSet<String> =
906                governance.members.keys().cloned().collect();
907
908            // Approvers
909            if let Some(approvers) = add.approver {
910                if approvers.is_empty() {
911                    return Err(RunnerError::InvalidEvent {
912                        location: "GovRoleEvent::check_data",
913                        kind: error::InvalidEventKind::Empty {
914                            what: "approvers vec".to_owned(),
915                        },
916                    });
917                }
918
919                for approver in approvers {
920                    if approver != approver.trim() {
921                        return Err(RunnerError::InvalidEvent {
922                            location: "GovRoleEvent::check_data",
923                            kind: error::InvalidEventKind::InvalidValue {
924                                field: "approver name".to_owned(),
925                                reason:
926                                    "cannot have leading or trailing whitespace"
927                                        .to_owned(),
928                            },
929                        });
930                    }
931
932                    if approver.is_empty() {
933                        return Err(RunnerError::InvalidEvent {
934                            location: "GovRoleEvent::check_data",
935                            kind: error::InvalidEventKind::Empty {
936                                what: "approver name".to_owned(),
937                            },
938                        });
939                    }
940
941                    if approver.len() > 100 {
942                        return Err(RunnerError::InvalidEvent {
943                            location: "GovRoleEvent::check_data",
944                            kind: error::InvalidEventKind::InvalidSize {
945                                field: "approver name".to_owned(),
946                                actual: approver.len(),
947                                max: 100,
948                            },
949                        });
950                    }
951
952                    if !members.contains(&approver) {
953                        return Err(RunnerError::InvalidEvent {
954                            location: "GovRoleEvent::check_data",
955                            kind: error::InvalidEventKind::NotMember {
956                                who: approver,
957                            },
958                        });
959                    }
960
961                    if !new_roles.approver.insert(approver.clone()) {
962                        return Err(RunnerError::InvalidEvent {
963                            location: "GovRoleEvent::check_data",
964                            kind: error::InvalidEventKind::AlreadyExists {
965                                what: "governance approver".to_owned(),
966                                id: approver,
967                            },
968                        });
969                    };
970                }
971            }
972
973            // Evaluators
974            if let Some(evaluators) = add.evaluator {
975                if evaluators.is_empty() {
976                    return Err(RunnerError::InvalidEvent {
977                        location: "GovRoleEvent::check_data",
978                        kind: error::InvalidEventKind::Empty {
979                            what: "evaluators vec in governance roles add"
980                                .to_owned(),
981                        },
982                    });
983                }
984
985                for evaluator in evaluators {
986                    if evaluator != evaluator.trim() {
987                        return Err(RunnerError::InvalidEvent {
988                            location: "GovRoleEvent::check_data",
989                            kind: error::InvalidEventKind::InvalidValue {
990                                field: "evaluator name".to_owned(),
991                                reason:
992                                    "cannot have leading or trailing whitespace"
993                                        .to_owned(),
994                            },
995                        });
996                    }
997
998                    if evaluator.is_empty() {
999                        return Err(RunnerError::InvalidEvent {
1000                            location: "GovRoleEvent::check_data",
1001                            kind: error::InvalidEventKind::Empty {
1002                                what: "evaluator name".to_owned(),
1003                            },
1004                        });
1005                    }
1006
1007                    if evaluator.len() > 100 {
1008                        return Err(RunnerError::InvalidEvent {
1009                            location: "GovRoleEvent::check_data",
1010                            kind: error::InvalidEventKind::InvalidSize {
1011                                field: "evaluator name".to_owned(),
1012                                actual: evaluator.len(),
1013                                max: 100,
1014                            },
1015                        });
1016                    }
1017
1018                    if !members.contains(&evaluator) {
1019                        return Err(RunnerError::InvalidEvent {
1020                            location: "GovRoleEvent::check_data",
1021                            kind: error::InvalidEventKind::NotMember {
1022                                who: evaluator,
1023                            },
1024                        });
1025                    }
1026
1027                    if !new_roles.evaluator.insert(evaluator.clone()) {
1028                        return Err(RunnerError::InvalidEvent {
1029                            location: "GovRoleEvent::check_data",
1030                            kind: error::InvalidEventKind::AlreadyExists {
1031                                what: "governance evaluator".to_owned(),
1032                                id: evaluator,
1033                            },
1034                        });
1035                    };
1036                }
1037            }
1038
1039            // Validators
1040            if let Some(validators) = add.validator {
1041                if validators.is_empty() {
1042                    return Err(RunnerError::InvalidEvent {
1043                        location: "GovRoleEvent::check_data",
1044                        kind: error::InvalidEventKind::Empty {
1045                            what: "validators vec in governance roles add"
1046                                .to_owned(),
1047                        },
1048                    });
1049                }
1050
1051                for validator in validators {
1052                    if validator != validator.trim() {
1053                        return Err(RunnerError::InvalidEvent {
1054                            location: "GovRoleEvent::check_data",
1055                            kind: error::InvalidEventKind::InvalidValue {
1056                                field: "validator name".to_owned(),
1057                                reason:
1058                                    "cannot have leading or trailing whitespace"
1059                                        .to_owned(),
1060                            },
1061                        });
1062                    }
1063
1064                    if validator.is_empty() {
1065                        return Err(RunnerError::InvalidEvent {
1066                            location: "GovRoleEvent::check_data",
1067                            kind: error::InvalidEventKind::Empty {
1068                                what: "validator name".to_owned(),
1069                            },
1070                        });
1071                    }
1072
1073                    if validator.len() > 100 {
1074                        return Err(RunnerError::InvalidEvent {
1075                            location: "GovRoleEvent::check_data",
1076                            kind: error::InvalidEventKind::InvalidSize {
1077                                field: "validator name".to_owned(),
1078                                actual: validator.len(),
1079                                max: 100,
1080                            },
1081                        });
1082                    }
1083
1084                    if !members.contains(&validator) {
1085                        return Err(RunnerError::InvalidEvent {
1086                            location: "GovRoleEvent::check_data",
1087                            kind: error::InvalidEventKind::NotMember {
1088                                who: validator,
1089                            },
1090                        });
1091                    }
1092
1093                    if !new_roles.validator.insert(validator.clone()) {
1094                        return Err(RunnerError::InvalidEvent {
1095                            location: "GovRoleEvent::check_data",
1096                            kind: error::InvalidEventKind::AlreadyExists {
1097                                what: "governance validator".to_owned(),
1098                                id: validator,
1099                            },
1100                        });
1101                    };
1102                }
1103            }
1104
1105            // Witnesses
1106            if let Some(witnesses) = add.witness {
1107                if witnesses.is_empty() {
1108                    return Err(RunnerError::InvalidEvent {
1109                        location: "GovRoleEvent::check_data",
1110                        kind: error::InvalidEventKind::Empty {
1111                            what: "witnesses vec in governance roles add"
1112                                .to_owned(),
1113                        },
1114                    });
1115                }
1116
1117                for witness in witnesses {
1118                    if witness != witness.trim() {
1119                        return Err(RunnerError::InvalidEvent {
1120                            location: "GovRoleEvent::check_data",
1121                            kind: error::InvalidEventKind::InvalidValue {
1122                                field: "witness name".to_owned(),
1123                                reason:
1124                                    "cannot have leading or trailing whitespace"
1125                                        .to_owned(),
1126                            },
1127                        });
1128                    }
1129
1130                    if witness.is_empty() {
1131                        return Err(RunnerError::InvalidEvent {
1132                            location: "GovRoleEvent::check_data",
1133                            kind: error::InvalidEventKind::Empty {
1134                                what: "witness name".to_owned(),
1135                            },
1136                        });
1137                    }
1138
1139                    if witness.len() > 100 {
1140                        return Err(RunnerError::InvalidEvent {
1141                            location: "GovRoleEvent::check_data",
1142                            kind: error::InvalidEventKind::InvalidSize {
1143                                field: "witness name".to_owned(),
1144                                actual: witness.len(),
1145                                max: 100,
1146                            },
1147                        });
1148                    }
1149
1150                    if !members.contains(&witness) {
1151                        return Err(RunnerError::InvalidEvent {
1152                            location: "GovRoleEvent::check_data",
1153                            kind: error::InvalidEventKind::NotMember {
1154                                who: witness,
1155                            },
1156                        });
1157                    }
1158
1159                    if !new_roles.witness.insert(witness.clone()) {
1160                        return Err(RunnerError::InvalidEvent {
1161                            location: "GovRoleEvent::check_data",
1162                            kind: error::InvalidEventKind::AlreadyExists {
1163                                what: "governance witness".to_owned(),
1164                                id: witness,
1165                            },
1166                        });
1167                    };
1168                }
1169            }
1170
1171            // Issuers
1172            if let Some(issuers) = add.issuer {
1173                if issuers.is_empty() {
1174                    return Err(RunnerError::InvalidEvent {
1175                        location: "GovRoleEvent::check_data",
1176                        kind: error::InvalidEventKind::Empty {
1177                            what: "issuers vec in governance roles add"
1178                                .to_owned(),
1179                        },
1180                    });
1181                }
1182
1183                for issuer in issuers {
1184                    if issuer != issuer.trim() {
1185                        return Err(RunnerError::InvalidEvent {
1186                            location: "GovRoleEvent::check_data",
1187                            kind: error::InvalidEventKind::InvalidValue {
1188                                field: "issuer name".to_owned(),
1189                                reason:
1190                                    "cannot have leading or trailing whitespace"
1191                                        .to_owned(),
1192                            },
1193                        });
1194                    }
1195
1196                    if issuer.is_empty() {
1197                        return Err(RunnerError::InvalidEvent {
1198                            location: "GovRoleEvent::check_data",
1199                            kind: error::InvalidEventKind::Empty {
1200                                what: "issuer name".to_owned(),
1201                            },
1202                        });
1203                    }
1204
1205                    if issuer.len() > 100 {
1206                        return Err(RunnerError::InvalidEvent {
1207                            location: "GovRoleEvent::check_data",
1208                            kind: error::InvalidEventKind::InvalidSize {
1209                                field: "issuer name".to_owned(),
1210                                actual: issuer.len(),
1211                                max: 100,
1212                            },
1213                        });
1214                    }
1215
1216                    if issuer != ReservedWords::Any.to_string() {
1217                        if !members.contains(&issuer) {
1218                            return Err(RunnerError::InvalidEvent {
1219                                location: "GovRoleEvent::check_data",
1220                                kind: error::InvalidEventKind::NotMember {
1221                                    who: issuer,
1222                                },
1223                            });
1224                        }
1225
1226                        if !new_roles.issuer.signers.insert(issuer.clone()) {
1227                            return Err(RunnerError::InvalidEvent {
1228                                location: "GovRoleEvent::check_data",
1229                                kind: error::InvalidEventKind::AlreadyExists {
1230                                    what: "governance issuer".to_owned(),
1231                                    id: issuer,
1232                                },
1233                            });
1234                        };
1235                    } else {
1236                        if new_roles.issuer.any {
1237                            return Err(RunnerError::InvalidEvent {
1238                                location: "GovRoleEvent::check_data",
1239                                kind: error::InvalidEventKind::AlreadyExists {
1240                                    what: "governance issuer 'Any'".to_owned(),
1241                                    id: ReservedWords::Any.to_string(),
1242                                },
1243                            });
1244                        }
1245                        new_roles.issuer.any = true;
1246                    }
1247                }
1248            }
1249        }
1250
1251        if let Some(remove) = self.remove.clone() {
1252            if remove.is_empty() {
1253                return Err(RunnerError::InvalidEvent {
1254                    location: "GovRoleEvent::check_data",
1255                    kind: error::InvalidEventKind::Empty {
1256                        what: "GovRoleEvent remove".to_owned(),
1257                    },
1258                });
1259            }
1260
1261            // Approvers
1262            if let Some(approvers) = remove.approver {
1263                if approvers.is_empty() {
1264                    return Err(RunnerError::InvalidEvent {
1265                        location: "GovRoleEvent::check_data",
1266                        kind: error::InvalidEventKind::Empty {
1267                            what: "approvers vec in governance roles remove"
1268                                .to_owned(),
1269                        },
1270                    });
1271                }
1272
1273                for approver in approvers {
1274                    if approver != approver.trim() {
1275                        return Err(RunnerError::InvalidEvent {
1276                            location: "GovRoleEvent::check_data",
1277                            kind: error::InvalidEventKind::InvalidValue {
1278                                field: "approver name to remove".to_owned(),
1279                                reason:
1280                                    "cannot have leading or trailing whitespace"
1281                                        .to_owned(),
1282                            },
1283                        });
1284                    }
1285                    if !new_roles.approver.remove(&approver) {
1286                        return Err(RunnerError::InvalidEvent {
1287                            location: "GovRoleEvent::check_data",
1288                            kind: error::InvalidEventKind::CannotRemove {
1289                                what: format!("approver {}", approver),
1290                                reason: "does not have this role".to_owned(),
1291                            },
1292                        });
1293                    }
1294                }
1295            }
1296
1297            // Evaluators
1298            if let Some(evaluators) = remove.evaluator {
1299                if evaluators.is_empty() {
1300                    return Err(RunnerError::InvalidEvent {
1301                        location: "GovRoleEvent::check_data",
1302                        kind: error::InvalidEventKind::Empty {
1303                            what: "evaluators vec in governance roles remove"
1304                                .to_owned(),
1305                        },
1306                    });
1307                }
1308
1309                for evaluator in evaluators {
1310                    if evaluator != evaluator.trim() {
1311                        return Err(RunnerError::InvalidEvent {
1312                            location: "GovRoleEvent::check_data",
1313                            kind: error::InvalidEventKind::InvalidValue {
1314                                field: "evaluator name to remove".to_owned(),
1315                                reason:
1316                                    "cannot have leading or trailing whitespace"
1317                                        .to_owned(),
1318                            },
1319                        });
1320                    }
1321                    if !new_roles.evaluator.remove(&evaluator) {
1322                        return Err(RunnerError::InvalidEvent {
1323                            location: "GovRoleEvent::check_data",
1324                            kind: error::InvalidEventKind::CannotRemove {
1325                                what: format!("evaluator {}", evaluator),
1326                                reason: "does not have this role".to_owned(),
1327                            },
1328                        });
1329                    }
1330                }
1331            }
1332
1333            // Validators
1334            if let Some(validators) = remove.validator {
1335                if validators.is_empty() {
1336                    return Err(RunnerError::InvalidEvent {
1337                        location: "GovRoleEvent::check_data",
1338                        kind: error::InvalidEventKind::Empty {
1339                            what: "validators vec in governance roles remove"
1340                                .to_owned(),
1341                        },
1342                    });
1343                }
1344                for validator in validators {
1345                    if validator != validator.trim() {
1346                        return Err(RunnerError::InvalidEvent {
1347                            location: "GovRoleEvent::check_data",
1348                            kind: error::InvalidEventKind::InvalidValue {
1349                                field: "validator name to remove".to_owned(),
1350                                reason:
1351                                    "cannot have leading or trailing whitespace"
1352                                        .to_owned(),
1353                            },
1354                        });
1355                    }
1356                    if !new_roles.validator.remove(&validator) {
1357                        return Err(RunnerError::InvalidEvent {
1358                            location: "GovRoleEvent::check_data",
1359                            kind: error::InvalidEventKind::CannotRemove {
1360                                what: format!("validator {}", validator),
1361                                reason: "does not have this role".to_owned(),
1362                            },
1363                        });
1364                    }
1365                }
1366            }
1367
1368            // Witnesses
1369            if let Some(witnesses) = remove.witness {
1370                if witnesses.is_empty() {
1371                    return Err(RunnerError::InvalidEvent {
1372                        location: "GovRoleEvent::check_data",
1373                        kind: error::InvalidEventKind::Empty {
1374                            what: "witnesses vec in governance roles remove"
1375                                .to_owned(),
1376                        },
1377                    });
1378                }
1379                for witness in witnesses {
1380                    if witness != witness.trim() {
1381                        return Err(RunnerError::InvalidEvent {
1382                            location: "GovRoleEvent::check_data",
1383                            kind: error::InvalidEventKind::InvalidValue {
1384                                field: "witness name to remove".to_owned(),
1385                                reason:
1386                                    "cannot have leading or trailing whitespace"
1387                                        .to_owned(),
1388                            },
1389                        });
1390                    }
1391                    if !new_roles.witness.remove(&witness) {
1392                        return Err(RunnerError::InvalidEvent {
1393                            location: "GovRoleEvent::check_data",
1394                            kind: error::InvalidEventKind::CannotRemove {
1395                                what: format!("witness {}", witness),
1396                                reason: "does not have this role".to_owned(),
1397                            },
1398                        });
1399                    };
1400                }
1401            }
1402
1403            // Issuers
1404            if let Some(issuers) = remove.issuer {
1405                if issuers.is_empty() {
1406                    return Err(RunnerError::InvalidEvent {
1407                        location: "GovRoleEvent::check_data",
1408                        kind: error::InvalidEventKind::Empty {
1409                            what: "issuers vec in governance roles remove"
1410                                .to_owned(),
1411                        },
1412                    });
1413                }
1414                for issuer in issuers {
1415                    if issuer != issuer.trim() {
1416                        return Err(RunnerError::InvalidEvent {
1417                            location: "GovRoleEvent::check_data",
1418                            kind: error::InvalidEventKind::InvalidValue {
1419                                field: "issuer name to remove".to_owned(),
1420                                reason:
1421                                    "cannot have leading or trailing whitespace"
1422                                        .to_owned(),
1423                            },
1424                        });
1425                    }
1426                    if issuer != ReservedWords::Any.to_string() {
1427                        if !new_roles.issuer.signers.remove(&issuer) {
1428                            return Err(RunnerError::InvalidEvent {
1429                                location: "GovRoleEvent::check_data",
1430                                kind: error::InvalidEventKind::CannotRemove {
1431                                    what: format!("issuer {}", issuer),
1432                                    reason: "does not have this role"
1433                                        .to_owned(),
1434                                },
1435                            });
1436                        };
1437                    } else {
1438                        if !new_roles.issuer.any {
1439                            return Err(RunnerError::InvalidEvent {
1440                                location: "GovRoleEvent::check_data",
1441                                kind: error::InvalidEventKind::CannotRemove {
1442                                    what: "governance issuer 'Any'".to_owned(),
1443                                    reason: "issuer 'Any' is not set"
1444                                        .to_owned(),
1445                                },
1446                            });
1447                        }
1448                        new_roles.issuer.any = false;
1449                    }
1450                }
1451            }
1452        }
1453
1454        Ok(())
1455    }
1456}
1457
1458#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
1459pub struct SchemaIdRole {
1460    pub schema_id: SchemaType,
1461    pub add: Option<SchemaRolesAddEvent>,
1462    pub remove: Option<SchemaRolesRemoveEvent>,
1463    pub change: Option<SchemaRolesChangeEvent>,
1464}
1465
1466#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)]
1467pub struct TrackerSchemasRoleEvent {
1468    pub add: Option<TrackerSchemasRolesAddEvent>,
1469    pub remove: Option<TrackerSchemasRolesRemoveEvent>,
1470    pub change: Option<TrackerSchemasRolesChangeEvent>,
1471}
1472
1473impl TrackerSchemasRoleEvent {
1474    pub const fn is_empty(&self) -> bool {
1475        self.add.is_none() && self.remove.is_none() && self.change.is_none()
1476    }
1477
1478    pub fn check_data(
1479        &self,
1480        governance: &GovernanceData,
1481        roles_not_gov: RolesTrackerSchemas,
1482        schema_id: &SchemaType,
1483    ) -> Result<RolesTrackerSchemas, RunnerError> {
1484        let schema_role = SchemaIdRole::from(self.clone());
1485
1486        let mut roles_schema = RolesSchema::from(roles_not_gov);
1487        schema_role.check_data(governance, &mut roles_schema, schema_id)?;
1488        let roles_not_gov = RolesTrackerSchemas::from(roles_schema.clone());
1489        Ok(roles_not_gov)
1490    }
1491}
1492
1493impl From<TrackerSchemasRoleEvent> for SchemaIdRole {
1494    fn from(value: TrackerSchemasRoleEvent) -> Self {
1495        Self {
1496            schema_id: SchemaType::TrackerSchemas,
1497            add: value.add.map(SchemaRolesAddEvent::from),
1498            remove: value.remove.map(SchemaRolesRemoveEvent::from),
1499            change: value.change.map(SchemaRolesChangeEvent::from),
1500        }
1501    }
1502}
1503
1504impl SchemaIdRole {
1505    pub fn is_empty(&self) -> bool {
1506        !self.schema_id.is_valid()
1507            || self.add.is_none()
1508                && self.change.is_none()
1509                && self.remove.is_none()
1510    }
1511
1512    pub fn check_data(
1513        &self,
1514        governance: &GovernanceData,
1515        roles_schema: &mut RolesSchema,
1516        schema_id: &SchemaType,
1517    ) -> Result<(), RunnerError> {
1518        // Validar que cada (role_type, name, namespace) solo aparezca una vez
1519        let mut seen_roles: HashSet<(String, String, String)> = HashSet::new();
1520
1521        // Helper para registrar un rol y detectar duplicados
1522        let mut check_and_register = |role_type: &str,
1523                                      name: &str,
1524                                      namespace: &Namespace|
1525         -> Result<(), RunnerError> {
1526            let key = (
1527                role_type.to_string(),
1528                name.trim().to_string(),
1529                namespace.to_string(),
1530            );
1531            if !seen_roles.insert(key) {
1532                return Err(RunnerError::InvalidEvent {
1533                    location: "SchemaIdRole::check_data",
1534                    kind: error::InvalidEventKind::InvalidValue {
1535                        field: format!("{} role operation", role_type),
1536                        reason: format!(
1537                            "Role ({}, {}) appears multiple times in the same event. Only one operation per role is allowed",
1538                            name.trim(),
1539                            namespace
1540                        ),
1541                    },
1542                });
1543            }
1544            Ok(())
1545        };
1546
1547        // Validar add operations
1548        if let Some(ref add) = self.add {
1549            if let Some(ref evaluators) = add.evaluator {
1550                for eval in evaluators {
1551                    check_and_register(
1552                        "evaluator",
1553                        &eval.name,
1554                        &eval.namespace,
1555                    )?;
1556                }
1557            }
1558            if let Some(ref validators) = add.validator {
1559                for val in validators {
1560                    check_and_register("validator", &val.name, &val.namespace)?;
1561                }
1562            }
1563            if let Some(ref witnesses) = add.witness {
1564                for wit in witnesses {
1565                    check_and_register("witness", &wit.name, &wit.namespace)?;
1566                }
1567            }
1568            if let Some(ref creators) = add.creator {
1569                for creator in creators {
1570                    check_and_register(
1571                        "creator",
1572                        &creator.name,
1573                        &creator.namespace,
1574                    )?;
1575                }
1576            }
1577            if let Some(ref issuers) = add.issuer {
1578                for issuer in issuers {
1579                    check_and_register(
1580                        "issuer",
1581                        &issuer.name,
1582                        &issuer.namespace,
1583                    )?;
1584                }
1585            }
1586        }
1587
1588        // Validar change operations
1589        if let Some(ref change) = self.change {
1590            if let Some(ref evaluators) = change.evaluator {
1591                for eval in evaluators {
1592                    check_and_register(
1593                        "evaluator",
1594                        &eval.actual_name,
1595                        &eval.actual_namespace,
1596                    )?;
1597                }
1598            }
1599            if let Some(ref validators) = change.validator {
1600                for val in validators {
1601                    check_and_register(
1602                        "validator",
1603                        &val.actual_name,
1604                        &val.actual_namespace,
1605                    )?;
1606                }
1607            }
1608            if let Some(ref witnesses) = change.witness {
1609                for wit in witnesses {
1610                    check_and_register(
1611                        "witness",
1612                        &wit.actual_name,
1613                        &wit.actual_namespace,
1614                    )?;
1615                }
1616            }
1617            if let Some(ref creators) = change.creator {
1618                for creator in creators {
1619                    check_and_register(
1620                        "creator",
1621                        &creator.actual_name,
1622                        &creator.actual_namespace,
1623                    )?;
1624                }
1625            }
1626            if let Some(ref issuers) = change.issuer {
1627                for issuer in issuers {
1628                    check_and_register(
1629                        "issuer",
1630                        &issuer.actual_name,
1631                        &issuer.actual_namespace,
1632                    )?;
1633                }
1634            }
1635        }
1636
1637        // Validar remove operations
1638        if let Some(ref remove) = self.remove {
1639            if let Some(ref evaluators) = remove.evaluator {
1640                for eval in evaluators {
1641                    check_and_register(
1642                        "evaluator",
1643                        &eval.name,
1644                        &eval.namespace,
1645                    )?;
1646                }
1647            }
1648            if let Some(ref validators) = remove.validator {
1649                for val in validators {
1650                    check_and_register("validator", &val.name, &val.namespace)?;
1651                }
1652            }
1653            if let Some(ref witnesses) = remove.witness {
1654                for wit in witnesses {
1655                    check_and_register("witness", &wit.name, &wit.namespace)?;
1656                }
1657            }
1658            if let Some(ref creators) = remove.creator {
1659                for creator in creators {
1660                    check_and_register(
1661                        "creator",
1662                        &creator.name,
1663                        &creator.namespace,
1664                    )?;
1665                }
1666            }
1667            if let Some(ref issuers) = remove.issuer {
1668                for issuer in issuers {
1669                    check_and_register(
1670                        "issuer",
1671                        &issuer.name,
1672                        &issuer.namespace,
1673                    )?;
1674                }
1675            }
1676        }
1677
1678        let members: HashSet<String> =
1679            governance.members.keys().cloned().collect();
1680
1681        if let Some(add) = self.add.clone() {
1682            if add.is_empty() {
1683                return Err(RunnerError::InvalidEvent {
1684                    location: "SchemaIdRole::check_data",
1685                    kind: error::InvalidEventKind::Empty {
1686                        what: "SchemaRolesEvent add".to_owned(),
1687                    },
1688                });
1689            }
1690
1691            if let Some(evaluators) = add.evaluator {
1692                if evaluators.is_empty() {
1693                    return Err(RunnerError::InvalidEvent {
1694                        location: "SchemaIdRole::check_data",
1695                        kind: error::InvalidEventKind::Empty {
1696                            what: "evaluators vec in schema roles add"
1697                                .to_owned(),
1698                        },
1699                    });
1700                }
1701
1702                for evaluator in evaluators {
1703                    if evaluator.name != evaluator.name.trim() {
1704                        return Err(RunnerError::InvalidEvent {
1705                            location: "SchemaIdRole::check_data",
1706                            kind: error::InvalidEventKind::InvalidValue {
1707                                field: format!(
1708                                    "evaluator name in schema {}",
1709                                    schema_id
1710                                ),
1711                                reason:
1712                                    "cannot have leading or trailing whitespace"
1713                                        .to_owned(),
1714                            },
1715                        });
1716                    }
1717
1718                    if evaluator.name.is_empty() {
1719                        return Err(RunnerError::InvalidEvent {
1720                            location: "SchemaIdRole::check_data",
1721                            kind: error::InvalidEventKind::Empty {
1722                                what: format!(
1723                                    "evaluator name in schema {}",
1724                                    schema_id
1725                                ),
1726                            },
1727                        });
1728                    }
1729
1730                    if evaluator.name.len() > 100 {
1731                        return Err(RunnerError::InvalidEvent {
1732                            location: "SchemaIdRole::check_data",
1733                            kind: error::InvalidEventKind::InvalidSize {
1734                                field: format!(
1735                                    "evaluator name in schema {}",
1736                                    schema_id
1737                                ),
1738                                actual: evaluator.name.len(),
1739                                max: 100,
1740                            },
1741                        });
1742                    }
1743
1744                    if !evaluator.namespace.check() {
1745                        return Err(RunnerError::InvalidEvent {
1746                            location: "SchemaIdRole::check_data",
1747                            kind: error::InvalidEventKind::InvalidValue {
1748                                field: format!(
1749                                    "evaluator namespace in schema {}",
1750                                    schema_id
1751                                ),
1752                                reason: "namespace is invalid".to_owned(),
1753                            },
1754                        });
1755                    }
1756
1757                    if !members.contains(&evaluator.name) {
1758                        return Err(RunnerError::InvalidEvent {
1759                            location: "SchemaIdRole::check_data",
1760                            kind: error::InvalidEventKind::NotMember {
1761                                who: evaluator.name,
1762                            },
1763                        });
1764                    }
1765
1766                    if !roles_schema.evaluator.insert(evaluator.clone()) {
1767                        return Err(RunnerError::InvalidEvent {
1768                            location: "SchemaIdRole::check_data",
1769                            kind: error::InvalidEventKind::AlreadyExists {
1770                                what: format!("schema {} evaluator", schema_id),
1771                                id: evaluator.name,
1772                            },
1773                        });
1774                    };
1775                }
1776            }
1777
1778            if let Some(validators) = add.validator {
1779                if validators.is_empty() {
1780                    return Err(RunnerError::InvalidEvent {
1781                        location: "SchemaIdRole::check_data",
1782                        kind: error::InvalidEventKind::Empty {
1783                            what: "validators vec".to_owned(),
1784                        },
1785                    });
1786                }
1787
1788                for validator in validators {
1789                    if validator.name != validator.name.trim() {
1790                        return Err(RunnerError::InvalidEvent {
1791                            location: "SchemaIdRole::check_data",
1792                            kind: error::InvalidEventKind::InvalidValue {
1793                                field: format!(
1794                                    "validator name in schema {}",
1795                                    schema_id
1796                                ),
1797                                reason:
1798                                    "cannot have leading or trailing whitespace"
1799                                        .to_owned(),
1800                            },
1801                        });
1802                    }
1803
1804                    if validator.name.is_empty() {
1805                        return Err(RunnerError::InvalidEvent {
1806                            location: "SchemaIdRole::check_data",
1807                            kind: error::InvalidEventKind::Empty {
1808                                what: format!(
1809                                    "validator name in schema {}",
1810                                    schema_id
1811                                ),
1812                            },
1813                        });
1814                    }
1815
1816                    if validator.name.len() > 100 {
1817                        return Err(RunnerError::InvalidEvent {
1818                            location: "SchemaIdRole::check_data",
1819                            kind: error::InvalidEventKind::InvalidSize {
1820                                field: format!(
1821                                    "validator name in schema {}",
1822                                    schema_id
1823                                ),
1824                                actual: validator.name.len(),
1825                                max: 100,
1826                            },
1827                        });
1828                    }
1829
1830                    if !validator.namespace.check() {
1831                        return Err(RunnerError::InvalidEvent {
1832                            location: "SchemaIdRole::check_data",
1833                            kind: error::InvalidEventKind::InvalidValue {
1834                                field: format!(
1835                                    "validator namespace in schema {}",
1836                                    schema_id
1837                                ),
1838                                reason: "invalid namespace".to_owned(),
1839                            },
1840                        });
1841                    }
1842
1843                    if !members.contains(&validator.name) {
1844                        return Err(RunnerError::InvalidEvent {
1845                            location: "SchemaIdRole::check_data",
1846                            kind: error::InvalidEventKind::NotMember {
1847                                who: validator.name,
1848                            },
1849                        });
1850                    }
1851
1852                    if !roles_schema.validator.insert(validator.clone()) {
1853                        return Err(RunnerError::InvalidEvent {
1854                            location: "SchemaIdRole::check_data",
1855                            kind: error::InvalidEventKind::AlreadyExists {
1856                                what: "validator".to_owned(),
1857                                id: validator.name,
1858                            },
1859                        });
1860                    };
1861                }
1862            }
1863
1864            if let Some(witnesses) = add.witness {
1865                if witnesses.is_empty() {
1866                    return Err(RunnerError::InvalidEvent {
1867                        location: "SchemaIdRole::check_data",
1868                        kind: error::InvalidEventKind::Empty {
1869                            what: "witnesses vec".to_owned(),
1870                        },
1871                    });
1872                }
1873
1874                for witness in witnesses {
1875                    if witness.name != witness.name.trim() {
1876                        return Err(RunnerError::InvalidEvent {
1877                            location: "SchemaIdRole::check_data",
1878                            kind: error::InvalidEventKind::InvalidValue {
1879                                field: format!(
1880                                    "witness name in schema {}",
1881                                    schema_id
1882                                ),
1883                                reason:
1884                                    "cannot have leading or trailing whitespace"
1885                                        .to_owned(),
1886                            },
1887                        });
1888                    }
1889
1890                    if witness.name.is_empty() {
1891                        return Err(RunnerError::InvalidEvent {
1892                            location: "SchemaIdRole::check_data",
1893                            kind: error::InvalidEventKind::Empty {
1894                                what: format!(
1895                                    "witness name in schema {}",
1896                                    schema_id
1897                                ),
1898                            },
1899                        });
1900                    }
1901
1902                    if witness.name.len() > 100 {
1903                        return Err(RunnerError::InvalidEvent {
1904                            location: "SchemaIdRole::check_data",
1905                            kind: error::InvalidEventKind::InvalidSize {
1906                                field: format!(
1907                                    "witness name in schema {}",
1908                                    schema_id
1909                                ),
1910                                actual: witness.name.len(),
1911                                max: 100,
1912                            },
1913                        });
1914                    }
1915
1916                    if !witness.namespace.check() {
1917                        return Err(RunnerError::InvalidEvent {
1918                            location: "SchemaIdRole::check_data",
1919                            kind: error::InvalidEventKind::InvalidValue {
1920                                field: format!(
1921                                    "witness namespace in schema {}",
1922                                    schema_id
1923                                ),
1924                                reason: "invalid namespace".to_owned(),
1925                            },
1926                        });
1927                    }
1928
1929                    if !members.contains(&witness.name) {
1930                        return Err(RunnerError::InvalidEvent {
1931                            location: "SchemaIdRole::check_data",
1932                            kind: error::InvalidEventKind::NotMember {
1933                                who: witness.name,
1934                            },
1935                        });
1936                    }
1937
1938                    if !roles_schema.witness.insert(witness.clone()) {
1939                        return Err(RunnerError::InvalidEvent {
1940                            location: "SchemaIdRole::check_data",
1941                            kind: error::InvalidEventKind::AlreadyExists {
1942                                what: "witness".to_owned(),
1943                                id: witness.name,
1944                            },
1945                        });
1946                    };
1947                }
1948            }
1949
1950            if let Some(creators) = add.creator {
1951                if creators.is_empty() {
1952                    return Err(RunnerError::InvalidEvent {
1953                        location: "SchemaIdRole::check_data",
1954                        kind: error::InvalidEventKind::Empty {
1955                            what: "creators vec".to_owned(),
1956                        },
1957                    });
1958                }
1959
1960                for creator in creators {
1961                    if creator.name != creator.name.trim() {
1962                        return Err(RunnerError::InvalidEvent {
1963                            location: "SchemaIdRole::check_data",
1964                            kind: error::InvalidEventKind::InvalidValue {
1965                                field: format!(
1966                                    "creator name in schema {}",
1967                                    schema_id
1968                                ),
1969                                reason:
1970                                    "cannot have leading or trailing whitespace"
1971                                        .to_owned(),
1972                            },
1973                        });
1974                    }
1975
1976                    if creator.name.is_empty() {
1977                        return Err(RunnerError::InvalidEvent {
1978                            location: "SchemaIdRole::check_data",
1979                            kind: error::InvalidEventKind::Empty {
1980                                what: format!(
1981                                    "creator name in schema {}",
1982                                    schema_id
1983                                ),
1984                            },
1985                        });
1986                    }
1987
1988                    if creator.name.len() > 100 {
1989                        return Err(RunnerError::InvalidEvent {
1990                            location: "SchemaIdRole::check_data",
1991                            kind: error::InvalidEventKind::InvalidSize {
1992                                field: format!(
1993                                    "creator name in schema {}",
1994                                    schema_id
1995                                ),
1996                                actual: creator.name.len(),
1997                                max: 100,
1998                            },
1999                        });
2000                    }
2001
2002                    if !creator.quantity.check() {
2003                        return Err(RunnerError::InvalidEvent {
2004                            location: "SchemaIdRole::check_data",
2005                            kind: error::InvalidEventKind::InvalidValue {
2006                                field: "creator quantity".to_owned(),
2007                                reason: "cannot be 0".to_owned(),
2008                            },
2009                        });
2010                    }
2011
2012                    if !creator.namespace.check() {
2013                        return Err(RunnerError::InvalidEvent {
2014                            location: "SchemaIdRole::check_data",
2015                            kind: error::InvalidEventKind::InvalidValue {
2016                                field: format!(
2017                                    "creator namespace in schema {}",
2018                                    schema_id
2019                                ),
2020                                reason: "invalid namespace".to_owned(),
2021                            },
2022                        });
2023                    }
2024
2025                    if !members.contains(&creator.name) {
2026                        return Err(RunnerError::InvalidEvent {
2027                            location: "SchemaIdRole::check_data",
2028                            kind: error::InvalidEventKind::NotMember {
2029                                who: creator.name,
2030                            },
2031                        });
2032                    }
2033
2034                    for witness in creator.witnesses.iter() {
2035                        if witness != &ReservedWords::Witnesses.to_string() {
2036                            if witness != witness.trim() {
2037                                return Err(RunnerError::InvalidEvent {
2038                                    location: "SchemaIdRole::check_data",
2039                                    kind: error::InvalidEventKind::InvalidValue {
2040                                        field: format!("creator witness name in schema {}", schema_id),
2041                                        reason: "cannot have leading or trailing whitespace".to_owned(),
2042                                    },
2043                                });
2044                            }
2045                            if witness == &creator.name {
2046                                return Err(RunnerError::InvalidEvent {
2047                                    location: "SchemaIdRole::check_data",
2048                                    kind: error::InvalidEventKind::InvalidValue {
2049                                        field: format!("creator {} witnesses in schema {}", creator.name, schema_id),
2050                                        reason: "a creator cannot be listed as their own witness".to_owned(),
2051                                    },
2052                                });
2053                            }
2054                            if !members.contains(witness) {
2055                                return Err(RunnerError::InvalidEvent {
2056                                    location: "SchemaIdRole::check_data",
2057                                    kind: error::InvalidEventKind::NotMember {
2058                                        who: witness.clone(),
2059                                    },
2060                                });
2061                            }
2062                        }
2063                    }
2064
2065                    if !roles_schema.creator.insert(creator.clone()) {
2066                        return Err(RunnerError::InvalidEvent {
2067                            location: "SchemaIdRole::check_data",
2068                            kind: error::InvalidEventKind::AlreadyExists {
2069                                what: "creator".to_owned(),
2070                                id: creator.name,
2071                            },
2072                        });
2073                    };
2074                }
2075            }
2076
2077            if let Some(issuers) = add.issuer {
2078                if issuers.is_empty() {
2079                    return Err(RunnerError::InvalidEvent {
2080                        location: "SchemaIdRole::check_data",
2081                        kind: error::InvalidEventKind::Empty {
2082                            what: "issuers vec".to_owned(),
2083                        },
2084                    });
2085                }
2086
2087                for issuer in issuers {
2088                    if issuer.name != issuer.name.trim() {
2089                        return Err(RunnerError::InvalidEvent {
2090                            location: "SchemaIdRole::check_data",
2091                            kind: error::InvalidEventKind::InvalidValue {
2092                                field: format!(
2093                                    "issuer name in schema {}",
2094                                    schema_id
2095                                ),
2096                                reason:
2097                                    "cannot have leading or trailing whitespace"
2098                                        .to_owned(),
2099                            },
2100                        });
2101                    }
2102
2103                    if issuer.name.is_empty() {
2104                        return Err(RunnerError::InvalidEvent {
2105                            location: "SchemaIdRole::check_data",
2106                            kind: error::InvalidEventKind::Empty {
2107                                what: format!(
2108                                    "issuer name in schema {}",
2109                                    schema_id
2110                                ),
2111                            },
2112                        });
2113                    }
2114
2115                    if issuer.name.len() > 100 {
2116                        return Err(RunnerError::InvalidEvent {
2117                            location: "SchemaIdRole::check_data",
2118                            kind: error::InvalidEventKind::InvalidSize {
2119                                field: format!(
2120                                    "issuer name in schema {}",
2121                                    schema_id
2122                                ),
2123                                actual: issuer.name.len(),
2124                                max: 100,
2125                            },
2126                        });
2127                    }
2128
2129                    if issuer.name != ReservedWords::Any.to_string() {
2130                        if !issuer.namespace.check() {
2131                            return Err(RunnerError::InvalidEvent {
2132                                location: "SchemaIdRole::check_data",
2133                                kind: error::InvalidEventKind::InvalidValue {
2134                                    field: format!(
2135                                        "issuer namespace in schema {}",
2136                                        schema_id
2137                                    ),
2138                                    reason: "invalid namespace".to_owned(),
2139                                },
2140                            });
2141                        }
2142
2143                        if !members.contains(&issuer.name) {
2144                            return Err(RunnerError::InvalidEvent {
2145                                location: "SchemaIdRole::check_data",
2146                                kind: error::InvalidEventKind::NotMember {
2147                                    who: issuer.name,
2148                                },
2149                            });
2150                        }
2151
2152                        if !roles_schema.issuer.signers.insert(issuer.clone()) {
2153                            return Err(RunnerError::InvalidEvent {
2154                                location: "SchemaIdRole::check_data",
2155                                kind: error::InvalidEventKind::AlreadyExists {
2156                                    what: "issuer".to_owned(),
2157                                    id: issuer.name,
2158                                },
2159                            });
2160                        };
2161                    } else {
2162                        if !issuer.namespace.is_empty() {
2163                            return Err(RunnerError::InvalidEvent {
2164                                location: "SchemaIdRole::check_data",
2165                                kind: error::InvalidEventKind::InvalidValue {
2166                                    field: format!("issuer 'Any' namespace in schema {}", schema_id),
2167                                    reason: "namespace must be empty for 'Any' issuer".to_owned(),
2168                                },
2169                            });
2170                        }
2171
2172                        if roles_schema.issuer.any {
2173                            return Err(RunnerError::InvalidEvent {
2174                                location: "SchemaIdRole::check_data",
2175                                kind: error::InvalidEventKind::AlreadyExists {
2176                                    what: format!(
2177                                        "issuer 'Any' in schema {}",
2178                                        schema_id
2179                                    ),
2180                                    id: ReservedWords::Any.to_string(),
2181                                },
2182                            });
2183                        }
2184
2185                        roles_schema.issuer.any = true;
2186                    }
2187                }
2188            }
2189        }
2190
2191        if let Some(remove) = self.remove.clone() {
2192            if remove.is_empty() {
2193                return Err(RunnerError::InvalidEvent {
2194                    location: "SchemaIdRole::check_data",
2195                    kind: error::InvalidEventKind::Empty {
2196                        what: "SchemaRolesEvent remove".to_owned(),
2197                    },
2198                });
2199            }
2200
2201            if let Some(evaluators) = remove.evaluator {
2202                if evaluators.is_empty() {
2203                    return Err(RunnerError::InvalidEvent {
2204                        location: "SchemaIdRole::check_data",
2205                        kind: error::InvalidEventKind::Empty {
2206                            what: "evaluators vec in remove".to_owned(),
2207                        },
2208                    });
2209                }
2210
2211                for evaluator in evaluators {
2212                    if evaluator.name != evaluator.name.trim() {
2213                        return Err(RunnerError::InvalidEvent {
2214                            location: "SchemaIdRole::check_data",
2215                            kind: error::InvalidEventKind::InvalidValue {
2216                                field: format!(
2217                                    "evaluator name to remove in schema {}",
2218                                    schema_id
2219                                ),
2220                                reason:
2221                                    "cannot have leading or trailing whitespace"
2222                                        .to_owned(),
2223                            },
2224                        });
2225                    }
2226                    if !evaluator.namespace.check() {
2227                        return Err(RunnerError::InvalidEvent {
2228                            location: "SchemaIdRole::check_data",
2229                            kind: error::InvalidEventKind::InvalidValue {
2230                                field: format!(
2231                                    "evaluator namespace to remove in schema {}",
2232                                    schema_id
2233                                ),
2234                                reason: "invalid namespace".to_owned(),
2235                            },
2236                        });
2237                    }
2238                    if !roles_schema.evaluator.remove(&evaluator) {
2239                        return Err(RunnerError::InvalidEvent {
2240                            location: "SchemaIdRole::check_data",
2241                            kind: error::InvalidEventKind::CannotRemove {
2242                                what: "evaluator".to_owned(),
2243                                reason: format!(
2244                                    "{} {} does not have this role in schema {}",
2245                                    evaluator.name,
2246                                    evaluator.namespace,
2247                                    schema_id
2248                                ),
2249                            },
2250                        });
2251                    };
2252                }
2253            }
2254
2255            if let Some(validators) = remove.validator {
2256                if validators.is_empty() {
2257                    return Err(RunnerError::InvalidEvent {
2258                        location: "SchemaIdRole::check_data",
2259                        kind: error::InvalidEventKind::Empty {
2260                            what: "validators vec in remove".to_owned(),
2261                        },
2262                    });
2263                }
2264
2265                for validator in validators {
2266                    if validator.name != validator.name.trim() {
2267                        return Err(RunnerError::InvalidEvent {
2268                            location: "SchemaIdRole::check_data",
2269                            kind: error::InvalidEventKind::InvalidValue {
2270                                field: format!(
2271                                    "validator name to remove in schema {}",
2272                                    schema_id
2273                                ),
2274                                reason:
2275                                    "cannot have leading or trailing whitespace"
2276                                        .to_owned(),
2277                            },
2278                        });
2279                    }
2280                    if !validator.namespace.check() {
2281                        return Err(RunnerError::InvalidEvent {
2282                            location: "SchemaIdRole::check_data",
2283                            kind: error::InvalidEventKind::InvalidValue {
2284                                field: format!(
2285                                    "validator namespace to remove in schema {}",
2286                                    schema_id
2287                                ),
2288                                reason: "invalid namespace".to_owned(),
2289                            },
2290                        });
2291                    }
2292                    if !roles_schema.validator.remove(&validator) {
2293                        return Err(RunnerError::InvalidEvent {
2294                            location: "SchemaIdRole::check_data",
2295                            kind: error::InvalidEventKind::CannotRemove {
2296                                what: "validator".to_owned(),
2297                                reason: format!(
2298                                    "{} {} does not have this role in schema {}",
2299                                    validator.name,
2300                                    validator.namespace,
2301                                    schema_id
2302                                ),
2303                            },
2304                        });
2305                    };
2306                }
2307            }
2308
2309            if let Some(witnesses) = remove.witness {
2310                if witnesses.is_empty() {
2311                    return Err(RunnerError::InvalidEvent {
2312                        location: "SchemaIdRole::check_data",
2313                        kind: error::InvalidEventKind::Empty {
2314                            what: "witnesses vec in remove".to_owned(),
2315                        },
2316                    });
2317                }
2318
2319                for witness in witnesses {
2320                    if witness.name != witness.name.trim() {
2321                        return Err(RunnerError::InvalidEvent {
2322                            location: "SchemaIdRole::check_data",
2323                            kind: error::InvalidEventKind::InvalidValue {
2324                                field: format!(
2325                                    "witness name to remove in schema {}",
2326                                    schema_id
2327                                ),
2328                                reason:
2329                                    "cannot have leading or trailing whitespace"
2330                                        .to_owned(),
2331                            },
2332                        });
2333                    }
2334                    if !witness.namespace.check() {
2335                        return Err(RunnerError::InvalidEvent {
2336                            location: "SchemaIdRole::check_data",
2337                            kind: error::InvalidEventKind::InvalidValue {
2338                                field: format!(
2339                                    "witness namespace to remove in schema {}",
2340                                    schema_id
2341                                ),
2342                                reason: "invalid namespace".to_owned(),
2343                            },
2344                        });
2345                    }
2346                    if !roles_schema.witness.remove(&witness) {
2347                        return Err(RunnerError::InvalidEvent {
2348                            location: "SchemaIdRole::check_data",
2349                            kind: error::InvalidEventKind::CannotRemove {
2350                                what: "witness".to_owned(),
2351                                reason: format!(
2352                                    "{} {} does not have this role in schema {}",
2353                                    witness.name, witness.namespace, schema_id
2354                                ),
2355                            },
2356                        });
2357                    };
2358                }
2359            }
2360
2361            if let Some(creators) = remove.creator {
2362                if creators.is_empty() {
2363                    return Err(RunnerError::InvalidEvent {
2364                        location: "SchemaIdRole::check_data",
2365                        kind: error::InvalidEventKind::Empty {
2366                            what: "creators vec in remove".to_owned(),
2367                        },
2368                    });
2369                }
2370
2371                for creator in creators {
2372                    if creator.name != creator.name.trim() {
2373                        return Err(RunnerError::InvalidEvent {
2374                            location: "SchemaIdRole::check_data",
2375                            kind: error::InvalidEventKind::InvalidValue {
2376                                field: format!(
2377                                    "creator name to remove in schema {}",
2378                                    schema_id
2379                                ),
2380                                reason:
2381                                    "cannot have leading or trailing whitespace"
2382                                        .to_owned(),
2383                            },
2384                        });
2385                    }
2386                    if !creator.namespace.check() {
2387                        return Err(RunnerError::InvalidEvent {
2388                            location: "SchemaIdRole::check_data",
2389                            kind: error::InvalidEventKind::InvalidValue {
2390                                field: format!(
2391                                    "creator namespace to remove in schema {}",
2392                                    schema_id
2393                                ),
2394                                reason: "invalid namespace".to_owned(),
2395                            },
2396                        });
2397                    }
2398                    if !roles_schema.creator.remove(&RoleCreator::create(
2399                        &creator.name,
2400                        creator.namespace.clone(),
2401                    )) {
2402                        return Err(RunnerError::InvalidEvent {
2403                            location: "SchemaIdRole::check_data",
2404                            kind: error::InvalidEventKind::CannotRemove {
2405                                what: "creator".to_owned(),
2406                                reason: format!(
2407                                    "{} {} does not have this role in schema {}",
2408                                    creator.name, creator.namespace, schema_id
2409                                ),
2410                            },
2411                        });
2412                    }
2413                }
2414            }
2415
2416            if let Some(issuers) = remove.issuer {
2417                if issuers.is_empty() {
2418                    return Err(RunnerError::InvalidEvent {
2419                        location: "SchemaIdRole::check_data",
2420                        kind: error::InvalidEventKind::Empty {
2421                            what: "issuers vec in remove".to_owned(),
2422                        },
2423                    });
2424                }
2425
2426                for issuer in issuers {
2427                    if issuer.name != issuer.name.trim() {
2428                        return Err(RunnerError::InvalidEvent {
2429                            location: "SchemaIdRole::check_data",
2430                            kind: error::InvalidEventKind::InvalidValue {
2431                                field: format!(
2432                                    "issuer name to remove in schema {}",
2433                                    schema_id
2434                                ),
2435                                reason:
2436                                    "cannot have leading or trailing whitespace"
2437                                        .to_owned(),
2438                            },
2439                        });
2440                    }
2441                    if issuer.name != ReservedWords::Any.to_string() {
2442                        if !issuer.namespace.check() {
2443                            return Err(RunnerError::InvalidEvent {
2444                                location: "SchemaIdRole::check_data",
2445                                kind: error::InvalidEventKind::InvalidValue {
2446                                    field: format!(
2447                                        "issuer namespace to remove in schema {}",
2448                                        schema_id
2449                                    ),
2450                                    reason: "invalid namespace".to_owned(),
2451                                },
2452                            });
2453                        }
2454                        if !roles_schema.issuer.signers.remove(&issuer) {
2455                            return Err(RunnerError::InvalidEvent {
2456                                location: "SchemaIdRole::check_data",
2457                                kind: error::InvalidEventKind::CannotRemove {
2458                                    what: "issuer".to_owned(),
2459                                    reason: format!(
2460                                        "{} {} does not have this role in schema {}",
2461                                        issuer.name,
2462                                        issuer.namespace,
2463                                        schema_id
2464                                    ),
2465                                },
2466                            });
2467                        }
2468                    } else {
2469                        if !issuer.namespace.is_empty() {
2470                            return Err(RunnerError::InvalidEvent {
2471                                location: "SchemaIdRole::check_data",
2472                                kind: error::InvalidEventKind::InvalidValue {
2473                                    field: "issuer 'Any' namespace in remove".to_owned(),
2474                                    reason: "namespace must be empty for 'Any' issuer".to_owned(),
2475                                },
2476                            });
2477                        }
2478                        if !roles_schema.issuer.any {
2479                            return Err(RunnerError::InvalidEvent {
2480                                location: "SchemaIdRole::check_data",
2481                                kind: error::InvalidEventKind::CannotRemove {
2482                                    what: "issuer 'Any'".to_owned(),
2483                                    reason: "issuer 'Any' is not set"
2484                                        .to_owned(),
2485                                },
2486                            });
2487                        }
2488                        roles_schema.issuer.any = false;
2489                    }
2490                }
2491            }
2492        }
2493
2494        if let Some(change) = self.change.clone() {
2495            if change.is_empty() {
2496                return Err(RunnerError::InvalidEvent {
2497                    location: "SchemaIdRole::check_data",
2498                    kind: error::InvalidEventKind::Empty {
2499                        what: "SchemaRolesEvent change".to_owned(),
2500                    },
2501                });
2502            }
2503
2504            if let Some(evaluators) = change.evaluator {
2505                if evaluators.is_empty() {
2506                    return Err(RunnerError::InvalidEvent {
2507                        location: "SchemaIdRole::check_data",
2508                        kind: error::InvalidEventKind::Empty {
2509                            what: "evaluators vec in change".to_owned(),
2510                        },
2511                    });
2512                }
2513
2514                for evaluator in evaluators {
2515                    if evaluator.actual_name != evaluator.actual_name.trim() {
2516                        return Err(RunnerError::InvalidEvent {
2517                            location: "SchemaIdRole::check_data",
2518                            kind: error::InvalidEventKind::InvalidValue {
2519                                field: format!(
2520                                    "evaluator actual name in schema {}",
2521                                    schema_id
2522                                ),
2523                                reason:
2524                                    "cannot have leading or trailing whitespace"
2525                                        .to_owned(),
2526                            },
2527                        });
2528                    }
2529                    if !evaluator.actual_namespace.check() {
2530                        return Err(RunnerError::InvalidEvent {
2531                            location: "SchemaIdRole::check_data",
2532                            kind: error::InvalidEventKind::InvalidValue {
2533                                field: format!(
2534                                    "evaluator actual namespace in schema {}",
2535                                    schema_id
2536                                ),
2537                                reason: "invalid namespace".to_owned(),
2538                            },
2539                        });
2540                    }
2541                    if !evaluator.new_namespace.check() {
2542                        return Err(RunnerError::InvalidEvent {
2543                            location: "SchemaIdRole::check_data",
2544                            kind: error::InvalidEventKind::InvalidValue {
2545                                field: format!(
2546                                    "evaluator {} {} new namespace in schema {}",
2547                                    evaluator.actual_name,
2548                                    evaluator.actual_namespace,
2549                                    schema_id
2550                                ),
2551                                reason: "invalid new namespace".to_owned(),
2552                            },
2553                        });
2554                    }
2555
2556                    if evaluator.new_namespace == evaluator.actual_namespace {
2557                        return Err(RunnerError::InvalidEvent {
2558                            location: "SchemaIdRole::check_data",
2559                            kind: error::InvalidEventKind::SameValue {
2560                                what: format!(
2561                                    "evaluator {} namespace in schema {}",
2562                                    evaluator.actual_name, schema_id
2563                                ),
2564                            },
2565                        });
2566                    }
2567
2568                    if !roles_schema.evaluator.remove(&Role {
2569                        name: evaluator.actual_name.clone(),
2570                        namespace: evaluator.actual_namespace.clone(),
2571                    }) {
2572                        return Err(RunnerError::InvalidEvent {
2573                            location: "SchemaIdRole::check_data",
2574                            kind: error::InvalidEventKind::CannotModify {
2575                                what: "evaluator".to_owned(),
2576                                reason: format!(
2577                                    "{} {} does not have this role in schema {}",
2578                                    evaluator.actual_name,
2579                                    evaluator.actual_namespace,
2580                                    schema_id
2581                                ),
2582                            },
2583                        });
2584                    };
2585
2586                    if !roles_schema.evaluator.insert(Role {
2587                        name: evaluator.actual_name.clone(),
2588                        namespace: evaluator.new_namespace.clone(),
2589                    }) {
2590                        return Err(RunnerError::InvalidEvent {
2591                            location: "SchemaIdRole::check_data",
2592                            kind: error::InvalidEventKind::AlreadyExists {
2593                                what: "evaluator with new namespace".to_owned(),
2594                                id: format!(
2595                                    "{} {} in schema {}",
2596                                    evaluator.actual_name,
2597                                    evaluator.new_namespace,
2598                                    schema_id
2599                                ),
2600                            },
2601                        });
2602                    }
2603                }
2604            }
2605
2606            if let Some(validators) = change.validator {
2607                if validators.is_empty() {
2608                    return Err(RunnerError::InvalidEvent {
2609                        location: "SchemaIdRole::check_data",
2610                        kind: error::InvalidEventKind::Empty {
2611                            what: "validators vec in change".to_owned(),
2612                        },
2613                    });
2614                }
2615
2616                for validator in validators {
2617                    if validator.actual_name != validator.actual_name.trim() {
2618                        return Err(RunnerError::InvalidEvent {
2619                            location: "SchemaIdRole::check_data",
2620                            kind: error::InvalidEventKind::InvalidValue {
2621                                field: format!(
2622                                    "validator actual name in schema {}",
2623                                    schema_id
2624                                ),
2625                                reason:
2626                                    "cannot have leading or trailing whitespace"
2627                                        .to_owned(),
2628                            },
2629                        });
2630                    }
2631                    if !validator.actual_namespace.check() {
2632                        return Err(RunnerError::InvalidEvent {
2633                            location: "SchemaIdRole::check_data",
2634                            kind: error::InvalidEventKind::InvalidValue {
2635                                field: format!(
2636                                    "validator actual namespace in schema {}",
2637                                    schema_id
2638                                ),
2639                                reason: "invalid namespace".to_owned(),
2640                            },
2641                        });
2642                    }
2643                    if !validator.new_namespace.check() {
2644                        return Err(RunnerError::InvalidEvent {
2645                            location: "SchemaIdRole::check_data",
2646                            kind: error::InvalidEventKind::InvalidValue {
2647                                field: format!(
2648                                    "validator {} {} new namespace in schema {}",
2649                                    validator.actual_name,
2650                                    validator.actual_namespace,
2651                                    schema_id
2652                                ),
2653                                reason: "invalid new namespace".to_owned(),
2654                            },
2655                        });
2656                    }
2657
2658                    if validator.new_namespace == validator.actual_namespace {
2659                        return Err(RunnerError::InvalidEvent {
2660                            location: "SchemaIdRole::check_data",
2661                            kind: error::InvalidEventKind::SameValue {
2662                                what: format!(
2663                                    "validator {} namespace in schema {}",
2664                                    validator.actual_name, schema_id
2665                                ),
2666                            },
2667                        });
2668                    }
2669
2670                    if !roles_schema.validator.remove(&Role {
2671                        name: validator.actual_name.clone(),
2672                        namespace: validator.actual_namespace.clone(),
2673                    }) {
2674                        return Err(RunnerError::InvalidEvent {
2675                            location: "SchemaIdRole::check_data",
2676                            kind: error::InvalidEventKind::CannotModify {
2677                                what: "validator".to_owned(),
2678                                reason: format!(
2679                                    "{} {} does not have this role in schema {}",
2680                                    validator.actual_name,
2681                                    validator.actual_namespace,
2682                                    schema_id
2683                                ),
2684                            },
2685                        });
2686                    };
2687
2688                    if !roles_schema.validator.insert(Role {
2689                        name: validator.actual_name.clone(),
2690                        namespace: validator.new_namespace.clone(),
2691                    }) {
2692                        return Err(RunnerError::InvalidEvent {
2693                            location: "SchemaIdRole::check_data",
2694                            kind: error::InvalidEventKind::AlreadyExists {
2695                                what: "validator with new namespace".to_owned(),
2696                                id: format!(
2697                                    "{} {} in schema {}",
2698                                    validator.actual_name,
2699                                    validator.new_namespace,
2700                                    schema_id
2701                                ),
2702                            },
2703                        });
2704                    }
2705                }
2706            }
2707
2708            if let Some(witnesses) = change.witness {
2709                if witnesses.is_empty() {
2710                    return Err(RunnerError::InvalidEvent {
2711                        location: "SchemaIdRole::check_data",
2712                        kind: error::InvalidEventKind::Empty {
2713                            what: "witnesses vec in change".to_owned(),
2714                        },
2715                    });
2716                }
2717
2718                for witness in witnesses {
2719                    if witness.actual_name != witness.actual_name.trim() {
2720                        return Err(RunnerError::InvalidEvent {
2721                            location: "SchemaIdRole::check_data",
2722                            kind: error::InvalidEventKind::InvalidValue {
2723                                field: format!(
2724                                    "witness actual name in schema {}",
2725                                    schema_id
2726                                ),
2727                                reason:
2728                                    "cannot have leading or trailing whitespace"
2729                                        .to_owned(),
2730                            },
2731                        });
2732                    }
2733                    if !witness.actual_namespace.check() {
2734                        return Err(RunnerError::InvalidEvent {
2735                            location: "SchemaIdRole::check_data",
2736                            kind: error::InvalidEventKind::InvalidValue {
2737                                field: format!(
2738                                    "witness actual namespace in schema {}",
2739                                    schema_id
2740                                ),
2741                                reason: "invalid namespace".to_owned(),
2742                            },
2743                        });
2744                    }
2745                    if !witness.new_namespace.check() {
2746                        return Err(RunnerError::InvalidEvent {
2747                            location: "SchemaIdRole::check_data",
2748                            kind: error::InvalidEventKind::InvalidValue {
2749                                field: format!(
2750                                    "witness {} {} new namespace in schema {}",
2751                                    witness.actual_name,
2752                                    witness.actual_namespace,
2753                                    schema_id
2754                                ),
2755                                reason: "invalid new namespace".to_owned(),
2756                            },
2757                        });
2758                    }
2759
2760                    if witness.new_namespace == witness.actual_namespace {
2761                        return Err(RunnerError::InvalidEvent {
2762                            location: "SchemaIdRole::check_data",
2763                            kind: error::InvalidEventKind::SameValue {
2764                                what: format!(
2765                                    "witness {} namespace in schema {}",
2766                                    witness.actual_name, schema_id
2767                                ),
2768                            },
2769                        });
2770                    }
2771
2772                    if !roles_schema.witness.remove(&Role {
2773                        name: witness.actual_name.clone(),
2774                        namespace: witness.actual_namespace.clone(),
2775                    }) {
2776                        return Err(RunnerError::InvalidEvent {
2777                            location: "SchemaIdRole::check_data",
2778                            kind: error::InvalidEventKind::CannotModify {
2779                                what: "witness".to_owned(),
2780                                reason: format!(
2781                                    "{} {} does not have this role in schema {}",
2782                                    witness.actual_name,
2783                                    witness.actual_namespace,
2784                                    schema_id
2785                                ),
2786                            },
2787                        });
2788                    };
2789
2790                    if !roles_schema.witness.insert(Role {
2791                        name: witness.actual_name.clone(),
2792                        namespace: witness.new_namespace.clone(),
2793                    }) {
2794                        return Err(RunnerError::InvalidEvent {
2795                            location: "SchemaIdRole::check_data",
2796                            kind: error::InvalidEventKind::AlreadyExists {
2797                                what: "witness with new namespace".to_owned(),
2798                                id: format!(
2799                                    "{} {} in schema {}",
2800                                    witness.actual_name,
2801                                    witness.new_namespace,
2802                                    schema_id
2803                                ),
2804                            },
2805                        });
2806                    }
2807                }
2808            }
2809
2810            if let Some(creators) = change.creator {
2811                if creators.is_empty() {
2812                    return Err(RunnerError::InvalidEvent {
2813                        location: "SchemaIdRole::check_data",
2814                        kind: error::InvalidEventKind::Empty {
2815                            what: "creators vec in change".to_owned(),
2816                        },
2817                    });
2818                }
2819
2820                for creator in creators {
2821                    if creator.actual_name != creator.actual_name.trim() {
2822                        return Err(RunnerError::InvalidEvent {
2823                            location: "SchemaIdRole::check_data",
2824                            kind: error::InvalidEventKind::InvalidValue {
2825                                field: format!(
2826                                    "creator actual name in schema {}",
2827                                    schema_id
2828                                ),
2829                                reason:
2830                                    "cannot have leading or trailing whitespace"
2831                                        .to_owned(),
2832                            },
2833                        });
2834                    }
2835                    if !creator.actual_namespace.check() {
2836                        return Err(RunnerError::InvalidEvent {
2837                            location: "SchemaIdRole::check_data",
2838                            kind: error::InvalidEventKind::InvalidValue {
2839                                field: format!(
2840                                    "creator actual namespace in schema {}",
2841                                    schema_id
2842                                ),
2843                                reason: "invalid namespace".to_owned(),
2844                            },
2845                        });
2846                    }
2847                    if creator.is_empty() {
2848                        return Err(RunnerError::InvalidEvent {
2849                            location: "SchemaIdRole::check_data",
2850                            kind: error::InvalidEventKind::InvalidValue {
2851                                field: format!("creator {} {} change in schema {}", creator.actual_name, creator.actual_namespace, schema_id),
2852                                reason: "must specify at least one of: new namespace, new quantity, or new witnesses".to_owned(),
2853                            },
2854                        });
2855                    }
2856
2857                    let Some(old_creator) =
2858                        roles_schema.creator.take(&RoleCreator::create(
2859                            &creator.actual_name,
2860                            creator.actual_namespace.clone(),
2861                        ))
2862                    else {
2863                        return Err(RunnerError::InvalidEvent {
2864                            location: "SchemaIdRole::check_data",
2865                            kind: error::InvalidEventKind::CannotModify {
2866                                what: "creator".to_owned(),
2867                                reason: format!(
2868                                    "{} {} does not have this role in schema {}",
2869                                    creator.actual_name,
2870                                    creator.actual_namespace,
2871                                    schema_id
2872                                ),
2873                            },
2874                        });
2875                    };
2876
2877                    let new_namespace = if let Some(new_namespace) =
2878                        creator.new_namespace
2879                    {
2880                        if !new_namespace.check() {
2881                            return Err(RunnerError::InvalidEvent {
2882                                location: "SchemaIdRole::check_data",
2883                                kind: error::InvalidEventKind::InvalidValue {
2884                                    field: format!(
2885                                        "creator {} {} new namespace in schema {}",
2886                                        creator.actual_name,
2887                                        creator.actual_namespace,
2888                                        schema_id
2889                                    ),
2890                                    reason: "invalid new namespace".to_owned(),
2891                                },
2892                            });
2893                        }
2894                        if new_namespace == creator.actual_namespace {
2895                            return Err(RunnerError::InvalidEvent {
2896                                location: "SchemaIdRole::check_data",
2897                                kind: error::InvalidEventKind::SameValue {
2898                                    what: format!(
2899                                        "creator {} namespace in schema {}",
2900                                        creator.actual_name, schema_id
2901                                    ),
2902                                },
2903                            });
2904                        }
2905                        new_namespace
2906                    } else {
2907                        old_creator.namespace
2908                    };
2909
2910                    let new_quantity = if let Some(quantity) =
2911                        creator.new_quantity
2912                    {
2913                        if !quantity.check() {
2914                            return Err(RunnerError::InvalidEvent {
2915                                location: "SchemaIdRole::check_data",
2916                                kind: error::InvalidEventKind::InvalidValue {
2917                                    field: "creator quantity".to_owned(),
2918                                    reason: "cannot be 0".to_owned(),
2919                                },
2920                            });
2921                        }
2922                        if quantity == old_creator.quantity {
2923                            return Err(RunnerError::InvalidEvent {
2924                                location: "SchemaIdRole::check_data",
2925                                kind: error::InvalidEventKind::SameValue {
2926                                    what: format!(
2927                                        "creator {} quantity in schema {}",
2928                                        creator.actual_name, schema_id
2929                                    ),
2930                                },
2931                            });
2932                        }
2933                        quantity
2934                    } else {
2935                        old_creator.quantity
2936                    };
2937
2938                    let new_witnesses = if let Some(witnesses) =
2939                        creator.new_witnesses
2940                    {
2941                        let mut witnesses = witnesses.clone();
2942
2943                        if witnesses.is_empty() {
2944                            witnesses
2945                                .insert(ReservedWords::Witnesses.to_string());
2946                        }
2947
2948                        for witness in witnesses.iter() {
2949                            if witness != &ReservedWords::Witnesses.to_string()
2950                            {
2951                                if witness != witness.trim() {
2952                                    return Err(RunnerError::InvalidEvent {
2953                                        location: "SchemaIdRole::check_data",
2954                                        kind: error::InvalidEventKind::InvalidValue {
2955                                            field: format!("creator new witness name in schema {}", schema_id),
2956                                            reason: "cannot have leading or trailing whitespace".to_owned(),
2957                                        },
2958                                    });
2959                                }
2960                                if witness == &creator.actual_name {
2961                                    return Err(RunnerError::InvalidEvent {
2962                                        location: "SchemaIdRole::check_data",
2963                                        kind: error::InvalidEventKind::InvalidValue {
2964                                            field: format!("creator {} new witnesses in schema {}", creator.actual_name, schema_id),
2965                                            reason: "a creator cannot be listed as their own witness".to_owned(),
2966                                        },
2967                                    });
2968                                }
2969                                if !members.contains(witness) {
2970                                    return Err(RunnerError::InvalidEvent {
2971                                        location: "SchemaIdRole::check_data",
2972                                        kind:
2973                                            error::InvalidEventKind::NotMember {
2974                                                who: witness.clone(),
2975                                            },
2976                                    });
2977                                }
2978                            }
2979                        }
2980
2981                        if witnesses == old_creator.witnesses {
2982                            return Err(RunnerError::InvalidEvent {
2983                                location: "SchemaIdRole::check_data",
2984                                kind: error::InvalidEventKind::SameValue {
2985                                    what: format!(
2986                                        "creator {} witnesses in schema {}",
2987                                        creator.actual_name, schema_id
2988                                    ),
2989                                },
2990                            });
2991                        }
2992                        witnesses
2993                    } else {
2994                        old_creator.witnesses
2995                    };
2996
2997                    if !roles_schema.creator.insert(RoleCreator {
2998                        name: creator.actual_name.clone(),
2999                        namespace: new_namespace.clone(),
3000                        quantity: new_quantity,
3001                        witnesses: new_witnesses,
3002                    }) {
3003                        return Err(RunnerError::InvalidEvent {
3004                            location: "SchemaIdRole::check_data",
3005                            kind: error::InvalidEventKind::AlreadyExists {
3006                                what: "creator with new namespace".to_owned(),
3007                                id: format!(
3008                                    "{} {} in schema {}",
3009                                    creator.actual_name,
3010                                    new_namespace,
3011                                    schema_id
3012                                ),
3013                            },
3014                        });
3015                    }
3016                }
3017            }
3018
3019            if let Some(issuers) = change.issuer {
3020                if issuers.is_empty() {
3021                    return Err(RunnerError::InvalidEvent {
3022                        location: "SchemaIdRole::check_data",
3023                        kind: error::InvalidEventKind::Empty {
3024                            what: "issuers vec in change".to_owned(),
3025                        },
3026                    });
3027                }
3028
3029                for issuer in issuers {
3030                    if issuer.actual_name != issuer.actual_name.trim() {
3031                        return Err(RunnerError::InvalidEvent {
3032                            location: "SchemaIdRole::check_data",
3033                            kind: error::InvalidEventKind::InvalidValue {
3034                                field: format!(
3035                                    "issuer actual name in schema {}",
3036                                    schema_id
3037                                ),
3038                                reason:
3039                                    "cannot have leading or trailing whitespace"
3040                                        .to_owned(),
3041                            },
3042                        });
3043                    }
3044                    if issuer.actual_name != ReservedWords::Any.to_string() {
3045                        if !issuer.actual_namespace.check() {
3046                            return Err(RunnerError::InvalidEvent {
3047                                location: "SchemaIdRole::check_data",
3048                                kind: error::InvalidEventKind::InvalidValue {
3049                                    field: format!(
3050                                        "issuer actual namespace in schema {}",
3051                                        schema_id
3052                                    ),
3053                                    reason: "invalid namespace".to_owned(),
3054                                },
3055                            });
3056                        }
3057                        if !issuer.new_namespace.check() {
3058                            return Err(RunnerError::InvalidEvent {
3059                                location: "SchemaIdRole::check_data",
3060                                kind: error::InvalidEventKind::InvalidValue {
3061                                    field: format!(
3062                                        "issuer {} {} new namespace in schema {}",
3063                                        issuer.actual_name,
3064                                        issuer.actual_namespace,
3065                                        schema_id
3066                                    ),
3067                                    reason: "invalid new namespace".to_owned(),
3068                                },
3069                            });
3070                        }
3071
3072                        if issuer.new_namespace == issuer.actual_namespace {
3073                            return Err(RunnerError::InvalidEvent {
3074                                location: "SchemaIdRole::check_data",
3075                                kind: error::InvalidEventKind::SameValue {
3076                                    what: format!(
3077                                        "issuer {} namespace in schema {}",
3078                                        issuer.actual_name, schema_id
3079                                    ),
3080                                },
3081                            });
3082                        }
3083
3084                        if !roles_schema.issuer.signers.remove(&Role {
3085                            name: issuer.actual_name.clone(),
3086                            namespace: issuer.actual_namespace.clone(),
3087                        }) {
3088                            return Err(RunnerError::InvalidEvent {
3089                                location: "SchemaIdRole::check_data",
3090                                kind: error::InvalidEventKind::CannotModify {
3091                                    what: "issuer".to_owned(),
3092                                    reason: format!(
3093                                        "{} {} does not have this role in schema {}",
3094                                        issuer.actual_name,
3095                                        issuer.actual_namespace,
3096                                        schema_id
3097                                    ),
3098                                },
3099                            });
3100                        };
3101
3102                        if !roles_schema.issuer.signers.insert(Role {
3103                            name: issuer.actual_name.clone(),
3104                            namespace: issuer.new_namespace.clone(),
3105                        }) {
3106                            return Err(RunnerError::InvalidEvent {
3107                                location: "SchemaIdRole::check_data",
3108                                kind: error::InvalidEventKind::AlreadyExists {
3109                                    what: "issuer with new namespace"
3110                                        .to_owned(),
3111                                    id: format!(
3112                                        "{} {} in schema {}",
3113                                        issuer.actual_name,
3114                                        issuer.new_namespace,
3115                                        schema_id
3116                                    ),
3117                                },
3118                            });
3119                        }
3120                    } else {
3121                        return Err(RunnerError::InvalidEvent {
3122                            location: "SchemaIdRole::check_data",
3123                            kind: error::InvalidEventKind::CannotModify {
3124                                what: "issuer 'Any'".to_owned(),
3125                                reason: "cannot change issuer 'Any'".to_owned(),
3126                            },
3127                        });
3128                    }
3129                }
3130            }
3131        }
3132
3133        Ok(())
3134    }
3135}
3136
3137#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
3138pub struct GovRolesEvent {
3139    pub approver: Option<BTreeSet<MemberName>>,
3140    pub evaluator: Option<BTreeSet<MemberName>>,
3141    pub validator: Option<BTreeSet<MemberName>>,
3142    pub witness: Option<BTreeSet<MemberName>>,
3143    pub issuer: Option<BTreeSet<MemberName>>,
3144}
3145
3146impl GovRolesEvent {
3147    pub const fn is_empty(&self) -> bool {
3148        self.approver.is_none()
3149            && self.evaluator.is_none()
3150            && self.validator.is_none()
3151            && self.witness.is_none()
3152            && self.issuer.is_none()
3153    }
3154}
3155
3156#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
3157pub struct TrackerSchemasRolesAddEvent {
3158    pub evaluator: Option<BTreeSet<Role>>,
3159    pub validator: Option<BTreeSet<Role>>,
3160    pub witness: Option<BTreeSet<Role>>,
3161    pub issuer: Option<BTreeSet<Role>>,
3162}
3163
3164impl TrackerSchemasRolesAddEvent {
3165    pub const fn is_empty(&self) -> bool {
3166        self.evaluator.is_none()
3167            && self.validator.is_none()
3168            && self.witness.is_none()
3169            && self.issuer.is_none()
3170    }
3171}
3172
3173impl From<TrackerSchemasRolesAddEvent> for SchemaRolesAddEvent {
3174    fn from(value: TrackerSchemasRolesAddEvent) -> Self {
3175        Self {
3176            evaluator: value.evaluator,
3177            validator: value.validator,
3178            witness: value.witness,
3179            creator: None,
3180            issuer: value.issuer,
3181        }
3182    }
3183}
3184
3185#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
3186pub struct SchemaRolesAddEvent {
3187    pub evaluator: Option<BTreeSet<Role>>,
3188    pub validator: Option<BTreeSet<Role>>,
3189    pub witness: Option<BTreeSet<Role>>,
3190    pub creator: Option<BTreeSet<RoleCreator>>,
3191    pub issuer: Option<BTreeSet<Role>>,
3192}
3193
3194impl SchemaRolesAddEvent {
3195    pub const fn is_empty(&self) -> bool {
3196        self.creator.is_none()
3197            && self.evaluator.is_none()
3198            && self.validator.is_none()
3199            && self.witness.is_none()
3200            && self.issuer.is_none()
3201    }
3202}
3203
3204#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
3205pub struct TrackerSchemasRolesRemoveEvent {
3206    pub evaluator: Option<BTreeSet<Role>>,
3207    pub validator: Option<BTreeSet<Role>>,
3208    pub witness: Option<BTreeSet<Role>>,
3209    pub issuer: Option<BTreeSet<Role>>,
3210}
3211
3212impl TrackerSchemasRolesRemoveEvent {
3213    pub const fn is_empty(&self) -> bool {
3214        self.evaluator.is_none()
3215            && self.validator.is_none()
3216            && self.witness.is_none()
3217            && self.issuer.is_none()
3218    }
3219}
3220
3221impl From<TrackerSchemasRolesRemoveEvent> for SchemaRolesRemoveEvent {
3222    fn from(value: TrackerSchemasRolesRemoveEvent) -> Self {
3223        Self {
3224            evaluator: value.evaluator,
3225            validator: value.validator,
3226            witness: value.witness,
3227            creator: None,
3228            issuer: value.issuer,
3229        }
3230    }
3231}
3232
3233#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
3234pub struct SchemaRolesRemoveEvent {
3235    pub evaluator: Option<BTreeSet<Role>>,
3236    pub validator: Option<BTreeSet<Role>>,
3237    pub witness: Option<BTreeSet<Role>>,
3238    pub creator: Option<BTreeSet<Role>>,
3239    pub issuer: Option<BTreeSet<Role>>,
3240}
3241
3242impl SchemaRolesRemoveEvent {
3243    pub const fn is_empty(&self) -> bool {
3244        self.creator.is_none()
3245            && self.evaluator.is_none()
3246            && self.validator.is_none()
3247            && self.witness.is_none()
3248            && self.issuer.is_none()
3249    }
3250}
3251
3252#[derive(
3253    Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord,
3254)]
3255pub struct TrackerSchemasRolesChangeEvent {
3256    pub evaluator: Option<BTreeSet<RoleChange>>,
3257    pub validator: Option<BTreeSet<RoleChange>>,
3258    pub witness: Option<BTreeSet<RoleChange>>,
3259    pub issuer: Option<BTreeSet<RoleChange>>,
3260}
3261
3262impl TrackerSchemasRolesChangeEvent {
3263    pub const fn is_empty(&self) -> bool {
3264        self.evaluator.is_none()
3265            && self.validator.is_none()
3266            && self.witness.is_none()
3267            && self.issuer.is_none()
3268    }
3269}
3270
3271impl From<TrackerSchemasRolesChangeEvent> for SchemaRolesChangeEvent {
3272    fn from(value: TrackerSchemasRolesChangeEvent) -> Self {
3273        Self {
3274            evaluator: value.evaluator,
3275            validator: value.validator,
3276            witness: value.witness,
3277            creator: None,
3278            issuer: value.issuer,
3279        }
3280    }
3281}
3282
3283#[derive(
3284    Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord,
3285)]
3286pub struct SchemaRolesChangeEvent {
3287    pub evaluator: Option<BTreeSet<RoleChange>>,
3288    pub validator: Option<BTreeSet<RoleChange>>,
3289    pub witness: Option<BTreeSet<RoleChange>>,
3290    pub creator: Option<BTreeSet<RoleCreatorChange>>,
3291    pub issuer: Option<BTreeSet<RoleChange>>,
3292}
3293
3294impl SchemaRolesChangeEvent {
3295    pub const fn is_empty(&self) -> bool {
3296        self.creator.is_none()
3297            && self.evaluator.is_none()
3298            && self.validator.is_none()
3299            && self.witness.is_none()
3300            && self.issuer.is_none()
3301    }
3302}
3303
3304#[derive(
3305    Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord,
3306)]
3307pub struct RoleCreatorChange {
3308    pub actual_name: MemberName,
3309    pub actual_namespace: Namespace,
3310    pub new_namespace: Option<Namespace>,
3311    pub new_witnesses: Option<BTreeSet<String>>,
3312    pub new_quantity: Option<CreatorQuantity>,
3313}
3314
3315impl RoleCreatorChange {
3316    pub const fn is_empty(&self) -> bool {
3317        self.new_namespace.is_none()
3318            && self.new_quantity.is_none()
3319            && self.new_witnesses.is_none()
3320    }
3321}
3322
3323#[derive(
3324    Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord,
3325)]
3326pub struct RoleChange {
3327    pub actual_name: MemberName,
3328    pub actual_namespace: Namespace,
3329    pub new_namespace: Namespace,
3330}
3331
3332///// Schemas /////
3333#[derive(Debug, Clone, Serialize, Deserialize)]
3334pub struct SchemasEvent {
3335    pub add: Option<HashSet<SchemaAdd>>,
3336    pub remove: Option<HashSet<SchemaType>>,
3337    pub change: Option<HashSet<SchemaChange>>,
3338}
3339
3340impl SchemasEvent {
3341    pub const fn is_empty(&self) -> bool {
3342        self.add.is_none() && self.remove.is_none() && self.change.is_none()
3343    }
3344}
3345
3346#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
3347pub struct SchemaAdd {
3348    pub id: SchemaType,
3349    pub contract: String,
3350    pub initial_value: Value,
3351}
3352
3353#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
3354pub struct SchemaChange {
3355    pub actual_id: SchemaType,
3356    pub new_contract: Option<String>,
3357    pub new_initial_value: Option<Value>,
3358}
3359
3360impl SchemaChange {
3361    pub fn is_empty(&self) -> bool {
3362        !self.actual_id.is_valid()
3363            || self.new_contract.is_none() && self.new_initial_value.is_none()
3364    }
3365}
3366
3367///// Policies /////
3368#[derive(Debug, Clone, Serialize, Deserialize)]
3369pub struct PoliciesEvent {
3370    pub governance: Option<GovPolicieEvent>,
3371    pub schema: Option<HashSet<SchemaIdPolicie>>,
3372}
3373
3374impl PoliciesEvent {
3375    pub const fn is_empty(&self) -> bool {
3376        self.governance.is_none() && self.schema.is_none()
3377    }
3378}
3379
3380#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)]
3381pub struct SchemaIdPolicie {
3382    pub schema_id: SchemaType,
3383    pub change: SchemaPolicieChange,
3384}
3385
3386impl SchemaIdPolicie {
3387    pub fn is_empty(&self) -> bool {
3388        !self.schema_id.is_valid() || self.change.is_empty()
3389    }
3390}
3391
3392#[derive(Debug, Clone, Serialize, Deserialize)]
3393pub struct GovPolicieEvent {
3394    pub change: GovPolicieChange,
3395}
3396
3397#[derive(Debug, Clone, Serialize, Deserialize)]
3398pub struct GovPolicieChange {
3399    pub approve: Option<Quorum>,
3400    pub evaluate: Option<Quorum>,
3401    pub validate: Option<Quorum>,
3402}
3403
3404impl GovPolicieChange {
3405    pub const fn is_empty(&self) -> bool {
3406        self.approve.is_none()
3407            && self.evaluate.is_none()
3408            && self.validate.is_none()
3409    }
3410}
3411
3412#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)]
3413pub struct SchemaPolicieChange {
3414    pub evaluate: Option<Quorum>,
3415    pub validate: Option<Quorum>,
3416}
3417
3418impl SchemaPolicieChange {
3419    pub const fn is_empty(&self) -> bool {
3420        self.evaluate.is_none() && self.validate.is_none()
3421    }
3422}