Skip to main content

ave_core/validation/
mod.rs

1//! # Validation module.
2//!
3use crate::{
4    governance::model::Quorum,
5    helpers::network::service::NetworkSender,
6    metrics::try_core_metrics,
7    model::{
8        common::{
9            abort_req, emit_fail, send_reboot_to_req, take_random_signers,
10        },
11        event::{ValidationData, ValidationMetadata},
12    },
13    request::manager::{RebootType, RequestManager, RequestManagerMessage},
14    validation::{
15        coordinator::{ValiCoordinator, ValiCoordinatorMessage},
16        response::ResponseSummary,
17        worker::{
18            CurrentRequestRoles, CurrentWorkerRoles, ValiWorker,
19            ValiWorkerMessage,
20        },
21    },
22};
23use ave_actors::{
24    Actor, ActorContext, ActorError, ActorPath, ChildAction, Handler, Message,
25    NotPersistentActor,
26};
27
28use async_trait::async_trait;
29use ave_common::{
30    ValueWrapper,
31    identity::{
32        CryptoError, DigestIdentifier, HashAlgorithm, PublicKey, Signature,
33        Signed, hash_borsh,
34    },
35};
36
37use request::ValidationReq;
38use response::ValidationRes;
39use tracing::{Span, debug, error, info_span, warn};
40
41use std::{collections::HashSet, sync::Arc};
42
43pub mod coordinator;
44pub mod request;
45pub mod response;
46pub mod schema;
47pub mod worker;
48
49#[derive(Clone, Debug)]
50pub struct Validation {
51    our_key: Arc<PublicKey>,
52    // Quorum
53    quorum: Quorum,
54    // Actual responses
55    validators_signatures: Vec<Signature>,
56
57    validators_response: Vec<ValidationMetadata>,
58
59    validators_quantity: u32,
60
61    request: Signed<ValidationReq>,
62
63    hash: HashAlgorithm,
64
65    network: Arc<NetworkSender>,
66
67    request_id: DigestIdentifier,
68
69    version: u64,
70
71    validation_request_hash: DigestIdentifier,
72
73    reboot: bool,
74
75    current_validators: HashSet<PublicKey>,
76
77    pending_validators: HashSet<PublicKey>,
78
79    init_state: Option<ValueWrapper>,
80
81    current_request_roles: CurrentRequestRoles,
82}
83
84impl Validation {
85    fn observe_event(result: &'static str) {
86        if let Some(metrics) = try_core_metrics() {
87            metrics.observe_protocol_event("validation", result);
88        }
89    }
90
91    pub fn new(
92        our_key: Arc<PublicKey>,
93        request: Signed<ValidationReq>,
94        init_state: Option<ValueWrapper>,
95        current_request_roles: CurrentRequestRoles,
96        quorum: Quorum,
97        hash: HashAlgorithm,
98        network: Arc<NetworkSender>,
99    ) -> Self {
100        Self {
101            our_key,
102            quorum,
103            init_state,
104            validators_response: vec![],
105            validators_signatures: vec![],
106            validators_quantity: 0,
107            request,
108            hash,
109            network,
110            request_id: DigestIdentifier::default(),
111            version: 0,
112            validation_request_hash: DigestIdentifier::default(),
113            reboot: false,
114            current_validators: HashSet::new(),
115            pending_validators: HashSet::new(),
116            current_request_roles,
117        }
118    }
119
120    fn check_validator(&mut self, validator: PublicKey) -> bool {
121        self.current_validators.remove(&validator)
122    }
123
124    async fn create_validators(
125        &self,
126        ctx: &mut ActorContext<Self>,
127        signer: PublicKey,
128    ) -> Result<(), ActorError> {
129        if signer != *self.our_key {
130            let child = ctx
131                .create_child(
132                    &format!("{}", signer),
133                    ValiCoordinator::new(
134                        signer.clone(),
135                        self.request_id.to_string(),
136                        self.version,
137                        self.network.clone(),
138                    ),
139                )
140                .await?;
141
142            child
143                .tell(ValiCoordinatorMessage::NetworkValidation {
144                    validation_req: Box::new(self.request.clone()),
145                    node_key: signer,
146                })
147                .await?
148        } else {
149            let child = ctx
150                .create_child(
151                    &format!("{}", signer),
152                    ValiWorker {
153                        node_key: (*self.our_key).clone(),
154                        our_key: self.our_key.clone(),
155                        init_state: self.init_state.clone(),
156                        governance_id: self
157                            .request
158                            .content().get_governance_id().expect("The build process verified that the event request is valid")
159                            ,
160                        gov_version: self.request.content().get_gov_version(),
161                        sn: self.request.content().get_sn(),
162                        hash: self.hash,
163                        network: self.network.clone(),
164                        current_roles: CurrentWorkerRoles {
165                            evaluation: self
166                                .current_request_roles
167                                .evaluation
168                                .clone(),
169                            approval: self.current_request_roles.approval.clone(),
170                        },
171                        stop:true
172                    },
173                )
174                .await?;
175
176            child
177                .tell(ValiWorkerMessage::LocalValidation {
178                    validation_req: Box::new(self.request.clone()),
179                })
180                .await?
181        }
182
183        Ok(())
184    }
185
186    async fn send_validation_to_req(
187        &self,
188        ctx: &ActorContext<Self>,
189        response: ValidationData,
190    ) -> Result<(), ActorError> {
191        let req_actor = ctx.get_parent::<RequestManager>().await?;
192
193        req_actor
194            .tell(RequestManagerMessage::ValidationRes {
195                request_id: self.request_id.clone(),
196                val_req: Box::new(self.request.content().clone()),
197                val_res: response,
198            })
199            .await?;
200
201        Ok(())
202    }
203
204    fn create_vali_req_hash(&self) -> Result<DigestIdentifier, CryptoError> {
205        hash_borsh(&*self.hash.hasher(), &self.request)
206    }
207
208    fn check_responses(&self) -> ResponseSummary {
209        let res_set: HashSet<ValidationMetadata> =
210            HashSet::from_iter(self.validators_response.iter().cloned());
211
212        if res_set.len() == 1 {
213            ResponseSummary::Ok
214        } else {
215            ResponseSummary::Reboot
216        }
217    }
218
219    fn build_validation_data(&self) -> ValidationData {
220        ValidationData {
221            validation_req_signature: self.request.signature().clone(),
222            validation_req_hash: self.validation_request_hash.clone(),
223            validators_signatures: self.validators_signatures.clone(),
224            validation_metadata: self.validators_response[0].clone(),
225        }
226    }
227}
228
229#[derive(Debug, Clone)]
230pub enum ValidationMessage {
231    Create {
232        request_id: DigestIdentifier,
233        version: u64,
234        signers: HashSet<PublicKey>,
235    },
236    Response {
237        validation_res: Box<ValidationRes>,
238        sender: PublicKey,
239        signature: Option<Signature>,
240    },
241}
242
243impl Message for ValidationMessage {}
244
245impl NotPersistentActor for Validation {}
246
247#[async_trait]
248impl Actor for Validation {
249    type Event = ();
250    type Message = ValidationMessage;
251    type Response = ();
252
253    fn get_span(_id: &str, parent_span: Option<Span>) -> tracing::Span {
254        parent_span.map_or_else(
255            || info_span!("Validation"),
256            |parent_span| info_span!(parent: parent_span, "Validation"),
257        )
258    }
259}
260
261#[async_trait]
262impl Handler<Self> for Validation {
263    async fn handle_message(
264        &mut self,
265        _sender: ActorPath,
266        msg: ValidationMessage,
267        ctx: &mut ActorContext<Self>,
268    ) -> Result<(), ActorError> {
269        match msg {
270            ValidationMessage::Create {
271                request_id,
272                version,
273                signers,
274            } => {
275                let vali_req_hash = match self.create_vali_req_hash() {
276                    Ok(digest) => digest,
277                    Err(e) => {
278                        error!(
279                            msg_type = "Create",
280                            error = %e,
281                            "Failed to create validation request hash"
282                        );
283                        return Err(emit_fail(
284                            ctx,
285                            ActorError::FunctionalCritical {
286                                description: format!(
287                                    "Cannot create validation request hash: {}",
288                                    e
289                                ),
290                            },
291                        )
292                        .await);
293                    }
294                };
295
296                self.validation_request_hash = vali_req_hash;
297                self.validators_quantity = signers.len() as u32;
298                self.request_id = request_id.clone();
299                self.version = version;
300
301                let validators_quantity = self.quorum.get_signers(
302                    self.validators_quantity,
303                    signers.len() as u32,
304                );
305
306                let (current_vali, pending_vali) =
307                    take_random_signers(signers, validators_quantity as usize);
308                self.current_validators.clone_from(&current_vali);
309                self.pending_validators.clone_from(&pending_vali);
310
311                for signer in current_vali.clone() {
312                    if let Err(e) =
313                        self.create_validators(ctx, signer.clone()).await
314                    {
315                        error!(
316                            msg_type = "Create",
317                            error = %e,
318                            signer = %signer,
319                            "Failed to create validator"
320                        );
321                    }
322                }
323
324                debug!(
325                    msg_type = "Create",
326                    request_id = %request_id,
327                    version = version,
328                    validators_count = current_vali.len(),
329                    "Validation created and validators initialized"
330                );
331            }
332            ValidationMessage::Response {
333                validation_res,
334                sender,
335                signature,
336            } => {
337                if !self.reboot {
338                    if self.check_validator(sender.clone()) {
339                        match *validation_res {
340                            ValidationRes::Create {
341                                vali_req_hash,
342                                subject_metadata,
343                            } => {
344                                let Some(signature) = signature else {
345                                    error!(
346                                        msg_type = "Response",
347                                        sender = %sender,
348                                        "Validation response without signature"
349                                    );
350                                    return Err(ActorError::Functional {
351                                        description: "Validation Response solver without signature".to_owned(),
352                                    });
353                                };
354
355                                if vali_req_hash != self.validation_request_hash
356                                {
357                                    error!(
358                                        msg_type = "Response",
359                                        expected_hash = %self.validation_request_hash,
360                                        received_hash = %vali_req_hash,
361                                        "Invalid validation request hash"
362                                    );
363                                    return Err(ActorError::Functional {
364                                        description: "Validation Response, Invalid validation request hash".to_owned(),
365                                    });
366                                }
367
368                                self.validators_response.push(
369                                    ValidationMetadata::Metadata(
370                                        subject_metadata,
371                                    ),
372                                );
373                                self.validators_signatures.push(signature);
374                            }
375                            ValidationRes::Response {
376                                vali_req_hash,
377                                modified_metadata_without_propierties_hash,
378                                propierties_hash,
379                                event_request_hash,
380                                viewpoints_hash,
381                            } => {
382                                let Some(signature) = signature else {
383                                    error!(
384                                        msg_type = "Response",
385                                        sender = %sender,
386                                        "Validation response without signature"
387                                    );
388                                    return Err(ActorError::Functional {
389                                        description: "Validation Response solver without signature".to_owned(),
390                                    });
391                                };
392
393                                if vali_req_hash != self.validation_request_hash
394                                {
395                                    error!(
396                                        msg_type = "Response",
397                                        expected_hash = %self.validation_request_hash,
398                                        received_hash = %vali_req_hash,
399                                        "Invalid validation request hash"
400                                    );
401                                    return Err(ActorError::Functional {
402                                        description: "Validation Response, Invalid validation request hash".to_owned(),
403                                    });
404                                }
405
406                                self.validators_response.push(
407                                    ValidationMetadata::ModifiedHash {
408                                        modified_metadata_without_propierties_hash,
409                                        propierties_hash,
410                                        event_request_hash,
411                                        viewpoints_hash,
412                                    },
413                                );
414                                self.validators_signatures.push(signature);
415                            }
416                            ValidationRes::TimeOut => {
417                                Self::observe_event("timeout");
418                            }
419                            ValidationRes::Abort(error) => {
420                                Self::observe_event("abort");
421                                if let Err(e) = abort_req(
422                                    ctx,
423                                    self.request_id.clone(),
424                                    sender.clone(),
425                                    error,
426                                    self.request.content().get_sn(),
427                                )
428                                .await
429                                {
430                                    error!(
431                                        msg_type = "Response",
432                                        error = %e,
433                                        sender = %sender,
434                                        "Failed to abort request"
435                                    );
436                                    return Err(emit_fail(ctx, e).await);
437                                }
438                            }
439                            ValidationRes::Reboot => {
440                                Self::observe_event("reboot");
441                                if let Err(e) = send_reboot_to_req(
442                                    ctx,
443                                    self.request_id.clone(),
444                                    self.request
445                                        .content().get_governance_id().expect("The build process verified that the event request is valid"),
446                                    RebootType::Normal
447                                )
448                                .await
449                                {
450                                    error!(
451                                        msg_type = "Response",
452                                        error = %e,
453                                        "Failed to send reboot to request actor"
454                                    );
455                                    return Err(emit_fail(ctx, e).await);
456                                }
457
458                                self.reboot = true;
459
460                                return Ok(());
461                            }
462                        };
463
464                        if self.quorum.check_quorum(
465                            self.validators_quantity,
466                            self.validators_response.len() as u32,
467                        ) {
468                            let summary = self.check_responses();
469                            if matches!(summary, ResponseSummary::Reboot)
470                                && let Err(e) = send_reboot_to_req(
471                                    ctx,
472                                    self.request_id.clone(),
473                                    self.request
474                                        .content().get_governance_id().expect("The build process verified that the event request is valid"),
475                                    RebootType::Diff
476                                )
477                                .await
478                                {
479                                    error!(
480                                        msg_type = "Response",
481                                        error = %e,
482                                        "Failed to send reboot to request actor"
483                                    );
484                                    return Err(emit_fail(ctx, e).await);
485                                }
486                            if matches!(summary, ResponseSummary::Reboot) {
487                                Self::observe_event("reboot");
488                                return Ok(());
489                            }
490
491                            let validation_data = self.build_validation_data();
492
493                            if let Err(e) = self
494                                .send_validation_to_req(ctx, validation_data)
495                                .await
496                            {
497                                error!(
498                                    msg_type = "Response",
499                                    error = %e,
500                                    "Failed to send validation to request actor"
501                                );
502                                return Err(emit_fail(ctx, e).await);
503                            };
504
505                            if !matches!(summary, ResponseSummary::Reboot) {
506                                Self::observe_event("success");
507                            }
508
509                            debug!(
510                                msg_type = "Response",
511                                request_id = %self.request_id,
512                                version = self.version,
513                                "Validation completed and sent to request"
514                            );
515                        } else if self.current_validators.is_empty()
516                            && !self.pending_validators.is_empty()
517                        {
518                            let validators_quantity = self.quorum.get_signers(
519                                self.validators_quantity,
520                                self.pending_validators.len() as u32,
521                            );
522
523                            let (curren_vali, pending_vali) =
524                                take_random_signers(
525                                    self.pending_validators.clone(),
526                                    validators_quantity as usize,
527                                );
528                            self.current_validators.clone_from(&curren_vali);
529                            self.pending_validators.clone_from(&pending_vali);
530
531                            for signer in curren_vali.clone() {
532                                if let Err(e) = self
533                                    .create_validators(ctx, signer.clone())
534                                    .await
535                                {
536                                    error!(
537                                        msg_type = "Response",
538                                        error = %e,
539                                        signer = %signer,
540                                        "Failed to create validator from pending pool"
541                                    );
542                                }
543                            }
544
545                            debug!(
546                                msg_type = "Response",
547                                new_validators = curren_vali.len(),
548                                "Created additional validators from pending pool"
549                            );
550                        } else if self.current_validators.is_empty()
551                            && let Err(e) = send_reboot_to_req(
552                                    ctx,
553                                    self.request_id.clone(),
554                                    self.request
555                                        .content().get_governance_id().expect("The build process verified that the event request is valid"),
556                                    RebootType::TimeOut
557                                )
558                                .await
559                                {
560                                    error!(
561                                        msg_type = "Response",
562                                        error = %e,
563                                        "Failed to send reboot to request actor"
564                                    );
565                                    return Err(emit_fail(ctx, e).await);
566                                } else if self.current_validators.is_empty() {
567                                    Self::observe_event("reboot");
568                                }
569                    } else {
570                        warn!(
571                            msg_type = "Response",
572                            sender = %sender,
573                            "Response from unexpected sender"
574                        );
575                    }
576                }
577            }
578        };
579        Ok(())
580    }
581
582    async fn on_child_fault(
583        &mut self,
584        error: ActorError,
585        ctx: &mut ActorContext<Self>,
586    ) -> ChildAction {
587        Self::observe_event("error");
588        error!(
589            request_id = %self.request_id,
590            version = self.version,
591            error = %error,
592            "Child fault in validation actor"
593        );
594        emit_fail(ctx, error).await;
595        ChildAction::Stop
596    }
597}
598
599#[cfg(test)]
600pub mod tests {
601    use core::panic;
602    use std::{sync::Arc, time::Duration};
603    use tempfile::TempDir;
604    use test_log::test;
605
606    use ave_actors::{ActorPath, ActorRef, PersistentActor, SystemRef};
607    use ave_common::{
608        Namespace, SchemaType,
609        identity::{
610            DigestIdentifier, HashAlgorithm, KeyPair, keys::Ed25519Signer,
611        },
612        request::{CreateRequest, EOLRequest},
613        response::RequestEventDB,
614    };
615    use tokio::sync::mpsc;
616
617    use crate::{
618        EventRequest, Node, NodeMessage, NodeResponse, Signed,
619        evaluation::tests::wait_request,
620        governance::{
621            Governance, GovernanceMessage, GovernanceResponse,
622            data::GovernanceData,
623        },
624        helpers::{
625            db::{ExternalDB, ReadStore},
626            network::service::NetworkSender,
627        },
628        model::common::node::SignTypesNode,
629        node::InitParamsNode,
630        request::{
631            RequestHandler, RequestHandlerMessage, RequestHandlerResponse,
632            tracking::RequestTracking,
633        },
634        system::tests::create_system,
635    };
636
637    async fn get_subject_state(
638        db: &Arc<ExternalDB>,
639        subject_id: &DigestIdentifier,
640        expected_sn: u64,
641    ) -> ave_common::response::SubjectDB {
642        let started = tokio::time::Instant::now();
643        loop {
644            match db.get_subject_state(&subject_id.to_string()).await {
645                Ok(state) if state.sn >= expected_sn => return state,
646                Ok(_) | Err(_)
647                    if started.elapsed() < Duration::from_secs(5) =>
648                {
649                    tokio::time::sleep(Duration::from_millis(10)).await;
650                }
651                Ok(state) => {
652                    panic!(
653                        "subject state not updated in time for {}: expected sn >= {}, got {}",
654                        subject_id, expected_sn, state.sn
655                    );
656                }
657                Err(error) => {
658                    panic!(
659                        "subject state not available in time for {}: {}",
660                        subject_id, error
661                    );
662                }
663            }
664        }
665    }
666
667    async fn get_event_sn(
668        db: &Arc<ExternalDB>,
669        subject_id: &DigestIdentifier,
670        sn: u64,
671    ) -> ave_common::response::LedgerDB {
672        let started = tokio::time::Instant::now();
673        loop {
674            match db.get_event_sn(&subject_id.to_string(), sn).await {
675                Ok(event) => return event,
676                Err(_) if started.elapsed() < Duration::from_secs(5) => {
677                    tokio::time::sleep(Duration::from_millis(10)).await;
678                }
679                Err(error) => {
680                    panic!(
681                        "event {} for {} not available in time: {}",
682                        sn, subject_id, error
683                    );
684                }
685            }
686        }
687    }
688
689    pub async fn create_gov() -> (
690        SystemRef,
691        ActorRef<Node>,
692        ActorRef<RequestHandler>,
693        Arc<ExternalDB>,
694        ActorRef<Governance>,
695        ActorRef<RequestTracking>,
696        DigestIdentifier,
697        Vec<TempDir>,
698    ) {
699        let node_keys = KeyPair::Ed25519(Ed25519Signer::generate().unwrap());
700        let (system, .., _dirs) = create_system().await;
701
702        let (command_sender, _command_receiver) = mpsc::channel(10);
703        let network = Arc::new(NetworkSender::new(command_sender));
704
705        system.add_helper("network", network.clone()).await;
706
707        let public_key = Arc::new(node_keys.public_key());
708        let node_actor = system
709            .create_root_actor(
710                "node",
711                Node::initial(InitParamsNode {
712                    key_pair: node_keys.clone(),
713                    public_key: public_key.clone(),
714                    hash: HashAlgorithm::Blake3,
715                    is_service: true,
716                    only_clear_events: false,
717                    ledger_batch_size: 100,
718                }),
719            )
720            .await
721            .unwrap();
722
723        let request_actor = system
724            .create_root_actor(
725                "request",
726                RequestHandler::initial((
727                    public_key.clone(),
728                    (HashAlgorithm::Blake3, network),
729                )),
730            )
731            .await
732            .unwrap();
733
734        let ext_db = system
735            .get_helper::<Arc<ExternalDB>>("ext_db")
736            .await
737            .unwrap();
738
739        let create_req = EventRequest::Create(CreateRequest {
740            name: Some("Name".to_string()),
741            description: Some("Description".to_string()),
742            governance_id: DigestIdentifier::default(),
743            schema_id: SchemaType::Governance,
744            namespace: Namespace::new(),
745        });
746
747        let response = node_actor
748            .ask(NodeMessage::SignRequest(Box::new(
749                SignTypesNode::EventRequest(create_req.clone()),
750            )))
751            .await
752            .unwrap();
753        let NodeResponse::SignRequest(signature) = response else {
754            panic!("Invalid Response")
755        };
756
757        let signed_event_req = Signed::from_parts(create_req, signature);
758
759        let RequestHandlerResponse::Ok(response) = request_actor
760            .ask(RequestHandlerMessage::NewRequest {
761                request: signed_event_req.clone(),
762            })
763            .await
764            .unwrap()
765        else {
766            panic!("Invalid response")
767        };
768
769        let owned_subj = response.subject_id;
770
771        let tracking = system
772            .get_actor::<RequestTracking>(&ActorPath::from(
773                "/user/request/tracking",
774            ))
775            .await
776            .unwrap();
777
778        wait_request(&tracking, response.request_id).await;
779
780        let subject_actor: ActorRef<Governance> = system
781            .get_actor(&ActorPath::from(format!(
782                "/user/node/subject_manager/{}",
783                owned_subj
784            )))
785            .await
786            .unwrap();
787
788        let GovernanceResponse::Metadata(metadata) = subject_actor
789            .ask(GovernanceMessage::GetMetadata)
790            .await
791            .unwrap()
792        else {
793            panic!("Invalid response")
794        };
795        let subject_data = get_subject_state(&ext_db, &owned_subj, 0).await;
796        let event = get_event_sn(&ext_db, &owned_subj, 0).await;
797
798        let RequestEventDB::Create {
799            name,
800            description,
801            schema_id,
802            namespace,
803        } = event.event
804        else {
805            panic!()
806        };
807
808        assert_eq!(metadata.name, name);
809        assert_eq!(metadata.name, subject_data.name);
810        assert_eq!(metadata.name.unwrap(), "Name");
811
812        assert_eq!(metadata.description, description);
813        assert_eq!(metadata.description, subject_data.description);
814        assert_eq!(metadata.description.unwrap(), "Description");
815
816        assert_eq!(metadata.subject_id.to_string(), event.subject_id);
817        assert_eq!(metadata.subject_id.to_string(), subject_data.subject_id);
818        assert_eq!(metadata.subject_id, owned_subj);
819
820        assert_eq!(
821            metadata.governance_id.to_string(),
822            subject_data.governance_id
823        );
824        assert_eq!(metadata.governance_id, owned_subj);
825
826        assert_eq!(
827            metadata.genesis_gov_version,
828            subject_data.genesis_gov_version
829        );
830        assert_eq!(metadata.genesis_gov_version, 0);
831
832        assert_eq!(metadata.schema_id.to_string(), schema_id);
833        assert_eq!(
834            metadata.schema_id.to_string(),
835            subject_data.schema_id.to_string()
836        );
837        assert_eq!(metadata.schema_id, SchemaType::Governance);
838
839        assert_eq!(metadata.namespace.to_string(), namespace);
840        assert_eq!(
841            metadata.namespace.to_string(),
842            subject_data.namespace.to_string()
843        );
844        assert_eq!(metadata.namespace, Namespace::new());
845
846        assert!(subject_data.new_owner.is_none());
847        assert!(metadata.new_owner.is_none());
848
849        assert_eq!(metadata.sn, event.sn);
850        assert_eq!(metadata.sn, subject_data.sn);
851        assert_eq!(metadata.sn, 0);
852
853        assert!(subject_data.active);
854        assert!(metadata.active);
855
856        assert_eq!(metadata.properties.0, subject_data.properties);
857        let gov = GovernanceData::try_from(metadata.properties).unwrap();
858        assert_eq!(gov.version, 0);
859
860        assert!(!gov.members.is_empty());
861        assert!(gov.roles_schema.is_empty());
862        assert!(gov.schemas.is_empty());
863        assert!(gov.policies_schema.is_empty());
864
865        (
866            system,
867            node_actor,
868            request_actor,
869            ext_db,
870            subject_actor,
871            tracking,
872            metadata.subject_id,
873            _dirs,
874        )
875    }
876
877    #[test(tokio::test)]
878    async fn test_create_gov() {
879        let _ = create_gov().await;
880    }
881
882    #[test(tokio::test)]
883    async fn test_eol_gov() {
884        let (
885            _system,
886            node_actor,
887            request_actor,
888            db,
889            subject_actor,
890            tracking,
891            subject_id,
892            _dirs,
893        ) = create_gov().await;
894
895        let eol_reques = EventRequest::EOL(EOLRequest {
896            subject_id: subject_id.clone(),
897        });
898
899        let response = node_actor
900            .ask(NodeMessage::SignRequest(Box::new(
901                SignTypesNode::EventRequest(eol_reques.clone()),
902            )))
903            .await
904            .unwrap();
905        let NodeResponse::SignRequest(signature) = response else {
906            panic!("Invalid Response")
907        };
908
909        let signed_event_req = Signed::from_parts(eol_reques, signature);
910
911        let RequestHandlerResponse::Ok(response) = request_actor
912            .ask(RequestHandlerMessage::NewRequest {
913                request: signed_event_req.clone(),
914            })
915            .await
916            .unwrap()
917        else {
918            panic!("Invalid response")
919        };
920
921        wait_request(&tracking, response.request_id).await;
922
923        let GovernanceResponse::Metadata(metadata) = subject_actor
924            .ask(GovernanceMessage::GetMetadata)
925            .await
926            .unwrap()
927        else {
928            panic!("Invalid response")
929        };
930
931        let subject_data = get_subject_state(&db, &subject_id, 1).await;
932        let event = get_event_sn(&db, &subject_id, 1).await;
933
934        let RequestEventDB::EOL = event.event else {
935            panic!()
936        };
937
938        assert_eq!(metadata.name, subject_data.name);
939        assert_eq!(metadata.name.unwrap(), "Name");
940
941        assert_eq!(metadata.description, subject_data.description);
942        assert_eq!(metadata.description.unwrap(), "Description");
943
944        assert_eq!(metadata.subject_id.to_string(), event.subject_id);
945        assert_eq!(metadata.subject_id.to_string(), subject_data.subject_id);
946        assert_eq!(metadata.subject_id, subject_id);
947
948        assert_eq!(
949            metadata.governance_id.to_string(),
950            subject_data.governance_id
951        );
952        assert_eq!(metadata.governance_id, subject_id);
953
954        assert_eq!(
955            metadata.genesis_gov_version,
956            subject_data.genesis_gov_version
957        );
958        assert_eq!(metadata.genesis_gov_version, 0);
959
960        assert_eq!(
961            metadata.schema_id.to_string(),
962            subject_data.schema_id.to_string()
963        );
964        assert_eq!(metadata.schema_id, SchemaType::Governance);
965
966        assert_eq!(
967            metadata.namespace.to_string(),
968            subject_data.namespace.to_string()
969        );
970        assert_eq!(metadata.namespace, Namespace::new());
971
972        assert!(subject_data.new_owner.is_none());
973        assert!(metadata.new_owner.is_none());
974
975        assert_eq!(metadata.sn, event.sn);
976        assert_eq!(metadata.sn, subject_data.sn);
977        assert_eq!(metadata.sn, 1);
978
979        assert!(!subject_data.active);
980        assert!(!metadata.active);
981
982        assert_eq!(metadata.properties.0, subject_data.properties);
983        let gov = GovernanceData::try_from(metadata.properties).unwrap();
984        assert_eq!(gov.version, 1);
985
986        assert!(!gov.members.is_empty());
987        assert!(gov.roles_schema.is_empty());
988        assert!(gov.schemas.is_empty());
989        assert!(gov.policies_schema.is_empty());
990
991        if !request_actor
992            .ask(RequestHandlerMessage::NewRequest {
993                request: signed_event_req.clone(),
994            })
995            .await
996            .is_err()
997        {
998            panic!("Invalid response")
999        }
1000    }
1001}