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_hash,
378                            } => {
379                                let Some(signature) = signature else {
380                                    error!(
381                                        msg_type = "Response",
382                                        sender = %sender,
383                                        "Validation response without signature"
384                                    );
385                                    return Err(ActorError::Functional {
386                                        description: "Validation Response solver without signature".to_owned(),
387                                    });
388                                };
389
390                                if vali_req_hash != self.validation_request_hash
391                                {
392                                    error!(
393                                        msg_type = "Response",
394                                        expected_hash = %self.validation_request_hash,
395                                        received_hash = %vali_req_hash,
396                                        "Invalid validation request hash"
397                                    );
398                                    return Err(ActorError::Functional {
399                                        description: "Validation Response, Invalid validation request hash".to_owned(),
400                                    });
401                                }
402
403                                self.validators_response.push(
404                                    ValidationMetadata::ModifiedHash(
405                                        modified_metadata_hash,
406                                    ),
407                                );
408                                self.validators_signatures.push(signature);
409                            }
410                            ValidationRes::TimeOut => {
411                                Self::observe_event("timeout");
412                            }
413                            ValidationRes::Abort(error) => {
414                                Self::observe_event("abort");
415                                if let Err(e) = abort_req(
416                                    ctx,
417                                    self.request_id.clone(),
418                                    sender.clone(),
419                                    error,
420                                    self.request.content().get_sn(),
421                                )
422                                .await
423                                {
424                                    error!(
425                                        msg_type = "Response",
426                                        error = %e,
427                                        sender = %sender,
428                                        "Failed to abort request"
429                                    );
430                                    return Err(emit_fail(ctx, e).await);
431                                }
432                            }
433                            ValidationRes::Reboot => {
434                                Self::observe_event("reboot");
435                                if let Err(e) = send_reboot_to_req(
436                                    ctx,
437                                    self.request_id.clone(),
438                                    self.request
439                                        .content().get_governance_id().expect("The build process verified that the event request is valid"),
440                                    RebootType::Normal
441                                )
442                                .await
443                                {
444                                    error!(
445                                        msg_type = "Response",
446                                        error = %e,
447                                        "Failed to send reboot to request actor"
448                                    );
449                                    return Err(emit_fail(ctx, e).await);
450                                }
451
452                                self.reboot = true;
453
454                                return Ok(());
455                            }
456                        };
457
458                        if self.quorum.check_quorum(
459                            self.validators_quantity,
460                            self.validators_response.len() as u32,
461                        ) {
462                            let summary = self.check_responses();
463                            if matches!(summary, ResponseSummary::Reboot)
464                                && let Err(e) = send_reboot_to_req(
465                                    ctx,
466                                    self.request_id.clone(),
467                                    self.request
468                                        .content().get_governance_id().expect("The build process verified that the event request is valid"),
469                                    RebootType::Diff
470                                )
471                                .await
472                                {
473                                    error!(
474                                        msg_type = "Response",
475                                        error = %e,
476                                        "Failed to send reboot to request actor"
477                                    );
478                                    return Err(emit_fail(ctx, e).await);
479                                }
480                            if matches!(summary, ResponseSummary::Reboot) {
481                                Self::observe_event("reboot");
482                            }
483
484                            let validation_data = self.build_validation_data();
485
486                            if let Err(e) = self
487                                .send_validation_to_req(ctx, validation_data)
488                                .await
489                            {
490                                error!(
491                                    msg_type = "Response",
492                                    error = %e,
493                                    "Failed to send validation to request actor"
494                                );
495                                return Err(emit_fail(ctx, e).await);
496                            };
497
498                            if !matches!(summary, ResponseSummary::Reboot) {
499                                Self::observe_event("success");
500                            }
501
502                            debug!(
503                                msg_type = "Response",
504                                request_id = %self.request_id,
505                                version = self.version,
506                                "Validation completed and sent to request"
507                            );
508                        } else if self.current_validators.is_empty()
509                            && !self.pending_validators.is_empty()
510                        {
511                            let validators_quantity = self.quorum.get_signers(
512                                self.validators_quantity,
513                                self.pending_validators.len() as u32,
514                            );
515
516                            let (curren_vali, pending_vali) =
517                                take_random_signers(
518                                    self.pending_validators.clone(),
519                                    validators_quantity as usize,
520                                );
521                            self.current_validators.clone_from(&curren_vali);
522                            self.pending_validators.clone_from(&pending_vali);
523
524                            for signer in curren_vali.clone() {
525                                if let Err(e) = self
526                                    .create_validators(ctx, signer.clone())
527                                    .await
528                                {
529                                    error!(
530                                        msg_type = "Response",
531                                        error = %e,
532                                        signer = %signer,
533                                        "Failed to create validator from pending pool"
534                                    );
535                                }
536                            }
537
538                            debug!(
539                                msg_type = "Response",
540                                new_validators = curren_vali.len(),
541                                "Created additional validators from pending pool"
542                            );
543                        } else if self.current_validators.is_empty()
544                            && let Err(e) = send_reboot_to_req(
545                                    ctx,
546                                    self.request_id.clone(),
547                                    self.request
548                                        .content().get_governance_id().expect("The build process verified that the event request is valid"),
549                                    RebootType::TimeOut
550                                )
551                                .await
552                                {
553                                    error!(
554                                        msg_type = "Response",
555                                        error = %e,
556                                        "Failed to send reboot to request actor"
557                                    );
558                                    return Err(emit_fail(ctx, e).await);
559                                } else if self.current_validators.is_empty() {
560                                    Self::observe_event("reboot");
561                                }
562                    } else {
563                        warn!(
564                            msg_type = "Response",
565                            sender = %sender,
566                            "Response from unexpected sender"
567                        );
568                    }
569                }
570            }
571        };
572        Ok(())
573    }
574
575    async fn on_child_fault(
576        &mut self,
577        error: ActorError,
578        ctx: &mut ActorContext<Self>,
579    ) -> ChildAction {
580        Self::observe_event("error");
581        error!(
582            request_id = %self.request_id,
583            version = self.version,
584            error = %error,
585            "Child fault in validation actor"
586        );
587        emit_fail(ctx, error).await;
588        ChildAction::Stop
589    }
590}
591
592#[cfg(test)]
593pub mod tests {
594    use core::panic;
595    use std::{sync::Arc, time::Duration};
596    use tempfile::TempDir;
597    use test_log::test;
598
599    use ave_actors::{ActorPath, ActorRef, PersistentActor, SystemRef};
600    use ave_common::{
601        Namespace, SchemaType,
602        identity::{
603            DigestIdentifier, HashAlgorithm, KeyPair, keys::Ed25519Signer,
604        },
605        request::{CreateRequest, EOLRequest},
606        response::RequestEventDB,
607    };
608    use tokio::sync::mpsc;
609
610    use crate::{
611        EventRequest, Node, NodeMessage, NodeResponse, Signed,
612        evaluation::tests::wait_request,
613        governance::{
614            Governance, GovernanceMessage, GovernanceResponse,
615            data::GovernanceData,
616        },
617        helpers::{
618            db::{ExternalDB, ReadStore},
619            network::service::NetworkSender,
620        },
621        model::common::node::SignTypesNode,
622        node::InitParamsNode,
623        request::{
624            RequestHandler, RequestHandlerMessage, RequestHandlerResponse,
625            tracking::RequestTracking,
626        },
627        system::tests::create_system,
628    };
629
630    async fn get_subject_state(
631        db: &Arc<ExternalDB>,
632        subject_id: &DigestIdentifier,
633        expected_sn: u64,
634    ) -> ave_common::response::SubjectDB {
635        let started = tokio::time::Instant::now();
636        loop {
637            match db.get_subject_state(&subject_id.to_string()).await {
638                Ok(state) if state.sn >= expected_sn => return state,
639                Ok(_) | Err(_)
640                    if started.elapsed() < Duration::from_secs(5) =>
641                {
642                    tokio::time::sleep(Duration::from_millis(10)).await;
643                }
644                Ok(state) => {
645                    panic!(
646                        "subject state not updated in time for {}: expected sn >= {}, got {}",
647                        subject_id, expected_sn, state.sn
648                    );
649                }
650                Err(error) => {
651                    panic!(
652                        "subject state not available in time for {}: {}",
653                        subject_id, error
654                    );
655                }
656            }
657        }
658    }
659
660    async fn get_event_sn(
661        db: &Arc<ExternalDB>,
662        subject_id: &DigestIdentifier,
663        sn: u64,
664    ) -> ave_common::response::LedgerDB {
665        let started = tokio::time::Instant::now();
666        loop {
667            match db.get_event_sn(&subject_id.to_string(), sn).await {
668                Ok(event) => return event,
669                Err(_) if started.elapsed() < Duration::from_secs(5) => {
670                    tokio::time::sleep(Duration::from_millis(10)).await;
671                }
672                Err(error) => {
673                    panic!(
674                        "event {} for {} not available in time: {}",
675                        sn, subject_id, error
676                    );
677                }
678            }
679        }
680    }
681
682    pub async fn create_gov() -> (
683        SystemRef,
684        ActorRef<Node>,
685        ActorRef<RequestHandler>,
686        Arc<ExternalDB>,
687        ActorRef<Governance>,
688        ActorRef<RequestTracking>,
689        DigestIdentifier,
690        Vec<TempDir>,
691    ) {
692        let node_keys = KeyPair::Ed25519(Ed25519Signer::generate().unwrap());
693        let (system, .., _dirs) = create_system().await;
694
695        let (command_sender, _command_receiver) = mpsc::channel(10);
696        let network = Arc::new(NetworkSender::new(command_sender));
697
698        system.add_helper("network", network.clone()).await;
699
700        let public_key = Arc::new(node_keys.public_key());
701        let node_actor = system
702            .create_root_actor(
703                "node",
704                Node::initial(InitParamsNode {
705                    key_pair: node_keys.clone(),
706                    public_key: public_key.clone(),
707                    hash: HashAlgorithm::Blake3,
708                    is_service: true,
709                }),
710            )
711            .await
712            .unwrap();
713
714        let request_actor = system
715            .create_root_actor(
716                "request",
717                RequestHandler::initial((
718                    public_key.clone(),
719                    (HashAlgorithm::Blake3, network),
720                )),
721            )
722            .await
723            .unwrap();
724
725        let ext_db = system
726            .get_helper::<Arc<ExternalDB>>("ext_db")
727            .await
728            .unwrap();
729
730        let create_req = EventRequest::Create(CreateRequest {
731            name: Some("Name".to_string()),
732            description: Some("Description".to_string()),
733            governance_id: DigestIdentifier::default(),
734            schema_id: SchemaType::Governance,
735            namespace: Namespace::new(),
736        });
737
738        let response = node_actor
739            .ask(NodeMessage::SignRequest(Box::new(
740                SignTypesNode::EventRequest(create_req.clone()),
741            )))
742            .await
743            .unwrap();
744        let NodeResponse::SignRequest(signature) = response else {
745            panic!("Invalid Response")
746        };
747
748        let signed_event_req = Signed::from_parts(create_req, signature);
749
750        let RequestHandlerResponse::Ok(response) = request_actor
751            .ask(RequestHandlerMessage::NewRequest {
752                request: signed_event_req.clone(),
753            })
754            .await
755            .unwrap()
756        else {
757            panic!("Invalid response")
758        };
759
760        let owned_subj = response.subject_id;
761
762        let tracking = system
763            .get_actor::<RequestTracking>(&ActorPath::from(
764                "/user/request/tracking",
765            ))
766            .await
767            .unwrap();
768
769        wait_request(&tracking, response.request_id).await;
770
771        let subject_actor: ActorRef<Governance> = system
772            .get_actor(&ActorPath::from(format!(
773                "/user/node/subject_manager/{}",
774                owned_subj
775            )))
776            .await
777            .unwrap();
778
779        let GovernanceResponse::Metadata(metadata) = subject_actor
780            .ask(GovernanceMessage::GetMetadata)
781            .await
782            .unwrap()
783        else {
784            panic!("Invalid response")
785        };
786        let subject_data = get_subject_state(&ext_db, &owned_subj, 0).await;
787        let event = get_event_sn(&ext_db, &owned_subj, 0).await;
788
789        let RequestEventDB::Create {
790            name,
791            description,
792            schema_id,
793            namespace,
794        } = event.event
795        else {
796            panic!()
797        };
798
799        assert_eq!(metadata.name, name);
800        assert_eq!(metadata.name, subject_data.name);
801        assert_eq!(metadata.name.unwrap(), "Name");
802
803        assert_eq!(metadata.description, description);
804        assert_eq!(metadata.description, subject_data.description);
805        assert_eq!(metadata.description.unwrap(), "Description");
806
807        assert_eq!(metadata.subject_id.to_string(), event.subject_id);
808        assert_eq!(metadata.subject_id.to_string(), subject_data.subject_id);
809        assert_eq!(metadata.subject_id, owned_subj);
810
811        assert_eq!(
812            metadata.governance_id.to_string(),
813            subject_data.governance_id
814        );
815        assert_eq!(metadata.governance_id, owned_subj);
816
817        assert_eq!(
818            metadata.genesis_gov_version,
819            subject_data.genesis_gov_version
820        );
821        assert_eq!(metadata.genesis_gov_version, 0);
822
823        assert_eq!(metadata.schema_id.to_string(), schema_id);
824        assert_eq!(
825            metadata.schema_id.to_string(),
826            subject_data.schema_id.to_string()
827        );
828        assert_eq!(metadata.schema_id, SchemaType::Governance);
829
830        assert_eq!(metadata.namespace.to_string(), namespace);
831        assert_eq!(
832            metadata.namespace.to_string(),
833            subject_data.namespace.to_string()
834        );
835        assert_eq!(metadata.namespace, Namespace::new());
836
837        assert!(subject_data.new_owner.is_none());
838        assert!(metadata.new_owner.is_none());
839
840        assert_eq!(metadata.sn, event.sn);
841        assert_eq!(metadata.sn, subject_data.sn);
842        assert_eq!(metadata.sn, 0);
843
844        assert!(subject_data.active);
845        assert!(metadata.active);
846
847        assert_eq!(metadata.properties.0, subject_data.properties);
848        let gov = GovernanceData::try_from(metadata.properties).unwrap();
849        assert_eq!(gov.version, 0);
850
851        assert!(!gov.members.is_empty());
852        assert!(gov.roles_schema.is_empty());
853        assert!(gov.schemas.is_empty());
854        assert!(gov.policies_schema.is_empty());
855
856        (
857            system,
858            node_actor,
859            request_actor,
860            ext_db,
861            subject_actor,
862            tracking,
863            metadata.subject_id,
864            _dirs,
865        )
866    }
867
868    #[test(tokio::test)]
869    async fn test_create_gov() {
870        let _ = create_gov().await;
871    }
872
873    #[test(tokio::test)]
874    async fn test_eol_gov() {
875        let (
876            _system,
877            node_actor,
878            request_actor,
879            db,
880            subject_actor,
881            tracking,
882            subject_id,
883            _dirs,
884        ) = create_gov().await;
885
886        let eol_reques = EventRequest::EOL(EOLRequest {
887            subject_id: subject_id.clone(),
888        });
889
890        let response = node_actor
891            .ask(NodeMessage::SignRequest(Box::new(
892                SignTypesNode::EventRequest(eol_reques.clone()),
893            )))
894            .await
895            .unwrap();
896        let NodeResponse::SignRequest(signature) = response else {
897            panic!("Invalid Response")
898        };
899
900        let signed_event_req = Signed::from_parts(eol_reques, signature);
901
902        let RequestHandlerResponse::Ok(response) = request_actor
903            .ask(RequestHandlerMessage::NewRequest {
904                request: signed_event_req.clone(),
905            })
906            .await
907            .unwrap()
908        else {
909            panic!("Invalid response")
910        };
911
912        wait_request(&tracking, response.request_id).await;
913
914        let GovernanceResponse::Metadata(metadata) = subject_actor
915            .ask(GovernanceMessage::GetMetadata)
916            .await
917            .unwrap()
918        else {
919            panic!("Invalid response")
920        };
921
922        let subject_data = get_subject_state(&db, &subject_id, 1).await;
923        let event = get_event_sn(&db, &subject_id, 1).await;
924
925        let RequestEventDB::EOL = event.event else {
926            panic!()
927        };
928
929        assert_eq!(metadata.name, subject_data.name);
930        assert_eq!(metadata.name.unwrap(), "Name");
931
932        assert_eq!(metadata.description, subject_data.description);
933        assert_eq!(metadata.description.unwrap(), "Description");
934
935        assert_eq!(metadata.subject_id.to_string(), event.subject_id);
936        assert_eq!(metadata.subject_id.to_string(), subject_data.subject_id);
937        assert_eq!(metadata.subject_id, subject_id);
938
939        assert_eq!(
940            metadata.governance_id.to_string(),
941            subject_data.governance_id
942        );
943        assert_eq!(metadata.governance_id, subject_id);
944
945        assert_eq!(
946            metadata.genesis_gov_version,
947            subject_data.genesis_gov_version
948        );
949        assert_eq!(metadata.genesis_gov_version, 0);
950
951        assert_eq!(
952            metadata.schema_id.to_string(),
953            subject_data.schema_id.to_string()
954        );
955        assert_eq!(metadata.schema_id, SchemaType::Governance);
956
957        assert_eq!(
958            metadata.namespace.to_string(),
959            subject_data.namespace.to_string()
960        );
961        assert_eq!(metadata.namespace, Namespace::new());
962
963        assert!(subject_data.new_owner.is_none());
964        assert!(metadata.new_owner.is_none());
965
966        assert_eq!(metadata.sn, event.sn);
967        assert_eq!(metadata.sn, subject_data.sn);
968        assert_eq!(metadata.sn, 1);
969
970        assert!(!subject_data.active);
971        assert!(!metadata.active);
972
973        assert_eq!(metadata.properties.0, subject_data.properties);
974        let gov = GovernanceData::try_from(metadata.properties).unwrap();
975        assert_eq!(gov.version, 1);
976
977        assert!(!gov.members.is_empty());
978        assert!(gov.roles_schema.is_empty());
979        assert!(gov.schemas.is_empty());
980        assert!(gov.policies_schema.is_empty());
981
982        if !request_actor
983            .ask(RequestHandlerMessage::NewRequest {
984                request: signed_event_req.clone(),
985            })
986            .await
987            .is_err()
988        {
989            panic!("Invalid response")
990        }
991    }
992}