Skip to main content

ave_core/evaluation/
mod.rs

1//! # Evaluation module.
2//! This module contains the evaluation logic for the Ave protocol.
3//!
4use crate::{
5    evaluation::{
6        coordinator::{EvalCoordinator, EvalCoordinatorMessage},
7        response::{EvaluatorError, ResponseSummary},
8        worker::{EvalWorker, EvalWorkerMessage},
9    },
10    governance::model::Quorum,
11    helpers::network::service::NetworkSender,
12    metrics::try_core_metrics,
13    model::{
14        common::{
15            abort_req, emit_fail, send_reboot_to_req, take_random_signers,
16        },
17        event::{EvaluationData, EvaluationResponse},
18    },
19    request::manager::{RebootType, RequestManager, RequestManagerMessage},
20};
21use ave_actors::{
22    Actor, ActorContext, ActorError, ActorPath, ChildAction, Handler, Message,
23    NotPersistentActor,
24};
25
26use async_trait::async_trait;
27use ave_common::{
28    ValueWrapper,
29    identity::{
30        CryptoError, DigestIdentifier, HashAlgorithm, PublicKey, Signature,
31        Signed, hash_borsh,
32    },
33};
34
35use request::{EvalWorkerContext, EvaluationReq};
36use response::{EvaluationRes, EvaluatorResponse as EvalRes};
37
38use tracing::{Span, debug, error, info_span, warn};
39
40pub mod compiler;
41pub mod coordinator;
42pub mod request;
43pub mod response;
44pub mod runner;
45pub mod schema;
46pub mod worker;
47
48use std::{collections::HashSet, sync::Arc};
49pub struct Evaluation {
50    our_key: Arc<PublicKey>,
51    // Quorum
52    quorum: Quorum,
53    // Actual responses
54    evaluators_response: Vec<(EvalRes, DigestIdentifier)>,
55    // Evaluators quantity
56    evaluators_quantity: u32,
57
58    evaluators_signatures: Vec<Signature>,
59
60    request: Signed<EvaluationReq>,
61
62    hash: HashAlgorithm,
63
64    network: Arc<NetworkSender>,
65
66    request_id: DigestIdentifier,
67
68    version: u64,
69
70    errors: Vec<(EvaluatorError, DigestIdentifier)>,
71
72    evaluation_request_hash: DigestIdentifier,
73
74    reboot: bool,
75
76    current_evaluators: HashSet<PublicKey>,
77
78    pending_evaluators: HashSet<PublicKey>,
79
80    init_state: Option<ValueWrapper>,
81
82    context: EvalWorkerContext,
83}
84
85impl Evaluation {
86    fn observe_event(result: &'static str) {
87        if let Some(metrics) = try_core_metrics() {
88            metrics.observe_protocol_event("evaluation", result);
89        }
90    }
91
92    pub fn new(
93        our_key: Arc<PublicKey>,
94        request: Signed<EvaluationReq>,
95        quorum: Quorum,
96        init_state: Option<ValueWrapper>,
97        context: EvalWorkerContext,
98        hash: HashAlgorithm,
99        network: Arc<NetworkSender>,
100    ) -> Self {
101        Self {
102            our_key,
103            hash,
104            network,
105            request,
106            quorum,
107            init_state,
108            context,
109            current_evaluators: HashSet::new(),
110            errors: vec![],
111            evaluation_request_hash: DigestIdentifier::default(),
112            evaluators_quantity: 0,
113            evaluators_response: vec![],
114            evaluators_signatures: vec![],
115            pending_evaluators: HashSet::new(),
116            reboot: false,
117            request_id: DigestIdentifier::default(),
118            version: 0,
119        }
120    }
121
122    fn check_evaluator(&mut self, evaluator: PublicKey) -> bool {
123        self.current_evaluators.remove(&evaluator)
124    }
125
126    fn worker_context(&self) -> EvalWorkerContext {
127        match &self.request.content().data {
128            request::EvaluateData::GovFact { state }
129            | request::EvaluateData::GovTransfer { state }
130            | request::EvaluateData::GovConfirm { state } => {
131                let (issuers, issuer_any) = state.governance_issuers();
132                EvalWorkerContext::Governance {
133                    issuers,
134                    issuer_any,
135                }
136            }
137            request::EvaluateData::TrackerSchemasFact { .. }
138            | request::EvaluateData::TrackerSchemasTransfer { .. } => {
139                self.context.clone()
140            }
141        }
142    }
143
144    async fn create_evaluators(
145        &self,
146        ctx: &mut ActorContext<Self>,
147        signer: PublicKey,
148    ) -> Result<(), ActorError> {
149        if signer != *self.our_key {
150            let child = ctx
151                .create_child(
152                    &format!("{}", signer),
153                    EvalCoordinator::new(
154                        signer.clone(),
155                        self.request_id.to_string(),
156                        self.version,
157                        self.network.clone(),
158                        self.hash,
159                    ),
160                )
161                .await?;
162
163            child
164                .tell(EvalCoordinatorMessage::NetworkEvaluation {
165                    evaluation_req: Box::new(self.request.clone()),
166                    node_key: signer,
167                })
168                .await?
169        } else {
170            let child = ctx
171                .create_child(
172                    &format!("{}", signer),
173                    EvalWorker {
174                        init_state: self.init_state.clone(),
175                        node_key: (*self.our_key).clone(),
176                        our_key: self.our_key.clone(),
177                        governance_id: self
178                            .request
179                            .content()
180                            .governance_id
181                            .clone(),
182                        gov_version: self.request.content().gov_version,
183                        sn: self.request.content().sn,
184                        context: self.worker_context(),
185                        hash: self.hash,
186                        network: self.network.clone(),
187                        stop: true,
188                    },
189                )
190                .await?;
191
192            child
193                .tell(EvalWorkerMessage::LocalEvaluation {
194                    evaluation_req: self.request.clone(),
195                })
196                .await?
197        }
198
199        Ok(())
200    }
201
202    fn check_responses(&self) -> ResponseSummary {
203        let res_set: HashSet<(EvalRes, DigestIdentifier)> =
204            HashSet::from_iter(self.evaluators_response.iter().cloned());
205        let error_set: HashSet<(EvaluatorError, DigestIdentifier)> =
206            HashSet::from_iter(self.errors.iter().cloned());
207
208        if res_set.len() == 1 && error_set.is_empty() {
209            ResponseSummary::Ok
210        } else if error_set.len() == 1 && res_set.is_empty() {
211            ResponseSummary::Error
212        } else {
213            ResponseSummary::Reboot
214        }
215    }
216
217    fn build_evaluation_data(
218        &self,
219        is_ok: bool,
220    ) -> Result<EvaluationData, ActorError> {
221        if is_ok {
222            Ok(EvaluationData {
223                eval_req_signature: self.request.signature().clone(),
224                eval_req_hash: self.evaluation_request_hash.clone(),
225                evaluators_signatures: self.evaluators_signatures.clone(),
226                response: EvaluationResponse::Ok {
227                    result: self.evaluators_response[0].0.clone(),
228                    result_hash: self.evaluators_response[0].1.clone(),
229                },
230            })
231        } else {
232            Ok(EvaluationData {
233                eval_req_signature: self.request.signature().clone(),
234                eval_req_hash: self.evaluation_request_hash.clone(),
235                evaluators_signatures: self.evaluators_signatures.clone(),
236                response: EvaluationResponse::Error {
237                    result: self.errors[0].0.clone(),
238                    result_hash: self.errors[0].1.clone(),
239                },
240            })
241        }
242    }
243
244    async fn send_evaluation_to_req(
245        &self,
246        ctx: &ActorContext<Self>,
247        response: EvaluationData,
248    ) -> Result<(), ActorError> {
249        let req_actor = ctx.get_parent::<RequestManager>().await?;
250
251        req_actor
252            .tell(RequestManagerMessage::EvaluationRes {
253                request_id: self.request_id.clone(),
254                eval_req: Box::new(self.request.content().clone()),
255                eval_res: response,
256            })
257            .await
258    }
259
260    fn create_eval_req_hash(&self) -> Result<DigestIdentifier, CryptoError> {
261        hash_borsh(&*self.hash.hasher(), &self.request)
262    }
263
264    fn ensure_eval_req_hash(
265        &self,
266        eval_req_hash: DigestIdentifier,
267    ) -> Result<(), ActorError> {
268        if eval_req_hash != self.evaluation_request_hash {
269            error!(
270                msg_type = "Response",
271                expected_hash = %self.evaluation_request_hash,
272                received_hash = %eval_req_hash,
273                "Invalid evaluation request hash"
274            );
275            return Err(ActorError::Functional {
276                description:
277                    "Evaluation Response, Invalid evaluation request hash"
278                        .to_owned(),
279            });
280        }
281
282        Ok(())
283    }
284
285    fn store_response_result(
286        &mut self,
287        result: response::EvaluationResult,
288        result_hash: DigestIdentifier,
289        result_hash_signature: Signature,
290    ) -> Result<(), ActorError> {
291        match result {
292            response::EvaluationResult::Ok {
293                response,
294                eval_req_hash,
295                ..
296            } => {
297                self.ensure_eval_req_hash(eval_req_hash)?;
298                self.evaluators_response.push((response, result_hash));
299            }
300            response::EvaluationResult::Error {
301                error,
302                eval_req_hash,
303                ..
304            } => {
305                self.ensure_eval_req_hash(eval_req_hash)?;
306                self.errors.push((error, result_hash));
307            }
308        }
309
310        self.evaluators_signatures.push(result_hash_signature);
311        Ok(())
312    }
313}
314
315#[derive(Debug, Clone)]
316pub enum EvaluationMessage {
317    Create {
318        request_id: DigestIdentifier,
319        version: u64,
320        signers: HashSet<PublicKey>,
321    },
322    Response {
323        evaluation_res: EvaluationRes,
324        sender: PublicKey,
325    },
326}
327
328impl Message for EvaluationMessage {}
329
330impl NotPersistentActor for Evaluation {}
331
332#[async_trait]
333impl Actor for Evaluation {
334    type Event = ();
335    type Message = EvaluationMessage;
336    type Response = ();
337
338    fn get_span(_id: &str, parent_span: Option<Span>) -> tracing::Span {
339        parent_span.map_or_else(
340            || info_span!("Evaluation"),
341            |parent_span| info_span!(parent: parent_span, "Evaluation"),
342        )
343    }
344}
345
346#[async_trait]
347impl Handler<Self> for Evaluation {
348    async fn handle_message(
349        &mut self,
350        _sender: ActorPath,
351        msg: EvaluationMessage,
352        ctx: &mut ActorContext<Self>,
353    ) -> Result<(), ActorError> {
354        match msg {
355            EvaluationMessage::Create {
356                request_id,
357                version,
358                signers,
359            } => {
360                let eval_req_hash = match self.create_eval_req_hash() {
361                    Ok(digest) => digest,
362                    Err(e) => {
363                        error!(
364                            msg_type = "Create",
365                            error = %e,
366                            "Failed to create evaluation request hash"
367                        );
368                        return Err(emit_fail(
369                            ctx,
370                            ActorError::FunctionalCritical {
371                                description: format!(
372                                    "Cannot create evaluation request hash: {}",
373                                    e
374                                ),
375                            },
376                        )
377                        .await);
378                    }
379                };
380
381                self.evaluation_request_hash = eval_req_hash;
382                self.evaluators_quantity = signers.len() as u32;
383                self.request_id = request_id.clone();
384                self.version = version;
385
386                let evaluators_quantity = self.quorum.get_signers(
387                    self.evaluators_quantity,
388                    signers.len() as u32,
389                );
390
391                let (current_eval, pending_eval) =
392                    take_random_signers(signers, evaluators_quantity as usize);
393                self.current_evaluators.clone_from(&current_eval);
394                self.pending_evaluators.clone_from(&pending_eval);
395
396                for signer in current_eval.clone() {
397                    if let Err(e) =
398                        self.create_evaluators(ctx, signer.clone()).await
399                    {
400                        error!(
401                            msg_type = "Create",
402                            error = %e,
403                            signer = %signer,
404                            "Failed to create evaluator"
405                        );
406                    }
407                }
408
409                debug!(
410                    msg_type = "Create",
411                    request_id = %request_id,
412                    version = version,
413                    evaluators_count = current_eval.len(),
414                    "Evaluation created and evaluators initialized"
415                );
416            }
417            EvaluationMessage::Response {
418                evaluation_res,
419                sender,
420            } => {
421                if !self.reboot {
422                    // If node is in evaluator list
423                    if self.check_evaluator(sender.clone()) {
424                        // Check type of validation
425                        match evaluation_res {
426                            EvaluationRes::Response {
427                                result,
428                                result_hash,
429                                result_hash_signature,
430                            } => {
431                                self.store_response_result(
432                                    result,
433                                    result_hash,
434                                    result_hash_signature,
435                                )?;
436                            }
437                            EvaluationRes::TimeOut => {
438                                Self::observe_event("timeout");
439                            }
440                            EvaluationRes::Abort(error) => {
441                                Self::observe_event("abort");
442                                if let Err(e) = abort_req(
443                                    ctx,
444                                    self.request_id.clone(),
445                                    sender.clone(),
446                                    error.clone(),
447                                    self.request.content().sn,
448                                )
449                                .await
450                                {
451                                    error!(
452                                        msg_type = "Response",
453                                        request_id = %self.request_id,
454                                        sender = %sender,
455                                        abort_reason = %error,
456                                        error = %e,
457                                        "Failed to abort request"
458                                    );
459                                    return Err(emit_fail(ctx, e).await);
460                                };
461
462                                debug!(
463                                    msg_type = "Response",
464                                    request_id = %self.request_id,
465                                    sender = %sender,
466                                    abort_reason = %error,
467                                    "Evaluation aborted"
468                                );
469
470                                return Ok(());
471                            }
472                            EvaluationRes::Reboot => {
473                                Self::observe_event("reboot");
474                                if let Err(e) = send_reboot_to_req(
475                                    ctx,
476                                    self.request_id.clone(),
477                                    self.request
478                                        .content()
479                                        .governance_id
480                                        .clone(),
481                                    RebootType::Normal,
482                                )
483                                .await
484                                {
485                                    error!(
486                                        msg_type = "Response",
487                                        error = %e,
488                                        "Failed to send reboot to request actor"
489                                    );
490                                    return Err(emit_fail(ctx, e).await);
491                                }
492
493                                self.reboot = true;
494
495                                return Ok(());
496                            }
497                        };
498
499                        if self.quorum.check_quorum(
500                            self.evaluators_quantity,
501                            (self.evaluators_response.len() + self.errors.len())
502                                as u32,
503                        ) {
504                            let summary = self.check_responses();
505                            if matches!(summary, ResponseSummary::Reboot)
506                                && let Err(e) = send_reboot_to_req(
507                                    ctx,
508                                    self.request_id.clone(),
509                                    self.request
510                                        .content()
511                                        .governance_id
512                                        .clone(),
513                                    RebootType::Diff,
514                                )
515                                .await
516                            {
517                                error!(
518                                    msg_type = "Response",
519                                    error = %e,
520                                    "Failed to send reboot to request actor"
521                                );
522                                return Err(emit_fail(ctx, e).await);
523                            }
524                            if matches!(summary, ResponseSummary::Reboot) {
525                                Self::observe_event("reboot");
526                                return Ok(());
527                            }
528
529                            let response = match self
530                                .build_evaluation_data(summary.is_ok())
531                            {
532                                Ok(response) => response,
533                                Err(e) => {
534                                    error!(
535                                        msg_type = "Response",
536                                        error = %e,
537                                        "Failed to create evaluation response"
538                                    );
539                                    return Err(emit_fail(ctx, e).await);
540                                }
541                            };
542
543                            if let Err(e) = self
544                                .send_evaluation_to_req(ctx, response.clone())
545                                .await
546                            {
547                                error!(
548                                    msg_type = "Response",
549                                    error = %e,
550                                    "Failed to send evaluation to request actor"
551                                );
552                                return Err(emit_fail(ctx, e).await);
553                            };
554
555                            if !matches!(summary, ResponseSummary::Reboot) {
556                                Self::observe_event(if summary.is_ok() {
557                                    "success"
558                                } else {
559                                    "error"
560                                });
561                            }
562
563                            debug!(
564                                msg_type = "Response",
565                                request_id = %self.request_id,
566                                version = self.version,
567                                is_ok = summary.is_ok(),
568                                "Evaluation completed and sent to request"
569                            );
570                        } else if self.current_evaluators.is_empty()
571                            && !self.pending_evaluators.is_empty()
572                        {
573                            let evaluators_quantity = self.quorum.get_signers(
574                                self.evaluators_quantity,
575                                self.pending_evaluators.len() as u32,
576                            );
577
578                            let (current_eval, pending_eval) =
579                                take_random_signers(
580                                    self.pending_evaluators.clone(),
581                                    evaluators_quantity as usize,
582                                );
583                            self.current_evaluators.clone_from(&current_eval);
584                            self.pending_evaluators.clone_from(&pending_eval);
585
586                            for signer in current_eval.clone() {
587                                if let Err(e) = self
588                                    .create_evaluators(ctx, signer.clone())
589                                    .await
590                                {
591                                    error!(
592                                        msg_type = "Response",
593                                        error = %e,
594                                        signer = %signer,
595                                        "Failed to create evaluator from pending pool"
596                                    );
597                                }
598                            }
599
600                            debug!(
601                                msg_type = "Response",
602                                new_evaluators = current_eval.len(),
603                                "Created additional evaluators from pending pool"
604                            );
605                        } else if self.current_evaluators.is_empty()
606                            && let Err(e) = send_reboot_to_req(
607                                ctx,
608                                self.request_id.clone(),
609                                self.request.content().governance_id.clone(),
610                                RebootType::TimeOut,
611                            )
612                            .await
613                        {
614                            error!(
615                                msg_type = "Response",
616                                error = %e,
617                                "Failed to send reboot to request actor"
618                            );
619                            return Err(emit_fail(ctx, e).await);
620                        } else if self.current_evaluators.is_empty() {
621                            Self::observe_event("reboot");
622                        }
623                    } else {
624                        warn!(
625                            msg_type = "Response",
626                            sender = %sender,
627                            "Response from unexpected sender"
628                        );
629                    }
630                }
631            }
632        }
633
634        Ok(())
635    }
636
637    async fn on_child_fault(
638        &mut self,
639        error: ActorError,
640        ctx: &mut ActorContext<Self>,
641    ) -> ChildAction {
642        Self::observe_event("error");
643        error!(
644            request_id = %self.request_id,
645            version = self.version,
646            error = %error,
647            "Child fault in evaluation actor"
648        );
649        emit_fail(ctx, error).await;
650        ChildAction::Stop
651    }
652}
653
654#[cfg(test)]
655pub mod tests {
656    use std::{str::FromStr, sync::Arc, time::Duration};
657
658    use ave_actors::{ActorError, ActorPath, ActorRef, SystemRef};
659    use ave_common::{
660        DataToSinkEvent, Namespace, SchemaType, ValueWrapper,
661        bridge::request::{ApprovalState, ApprovalStateRes},
662        identity::{DigestIdentifier, PublicKey, Signed},
663        request::{CreateRequest, FactRequest, TransferRequest},
664        response::{EvalResDB, RequestEventDB, RequestState},
665    };
666    use serde_json::json;
667    use tempfile::TempDir;
668    use test_log::test;
669
670    use crate::{
671        EventRequest, NodeMessage, NodeResponse,
672        governance::{
673            Governance, GovernanceMessage, GovernanceResponse,
674            data::GovernanceData,
675        },
676        helpers::db::{ExternalDB, ReadStore},
677        model::common::node::SignTypesNode,
678        node::Node,
679        node::subject_manager::{
680            SubjectManager, SubjectManagerMessage, SubjectManagerResponse,
681        },
682        request::{
683            RequestData, RequestHandler, RequestHandlerMessage,
684            RequestHandlerResponse,
685            tracking::{
686                RequestTracking, RequestTrackingMessage,
687                RequestTrackingResponse,
688            },
689        },
690        subject::Metadata,
691        tracker::{Tracker, TrackerMessage, TrackerResponse},
692        validation::tests::create_gov,
693    };
694
695    async fn get_subject_state(
696        db: &Arc<ExternalDB>,
697        subject_id: &DigestIdentifier,
698        expected_sn: u64,
699    ) -> ave_common::response::SubjectDB {
700        let started = tokio::time::Instant::now();
701        loop {
702            match db.get_subject_state(&subject_id.to_string()).await {
703                Ok(state) if state.sn >= expected_sn => return state,
704                Ok(_) | Err(_)
705                    if started.elapsed() < Duration::from_secs(5) =>
706                {
707                    tokio::time::sleep(Duration::from_millis(10)).await;
708                }
709                Ok(state) => {
710                    panic!(
711                        "subject state not updated in time for {}: expected sn >= {}, got {}",
712                        subject_id, expected_sn, state.sn
713                    );
714                }
715                Err(error) => {
716                    panic!(
717                        "subject state not available in time for {}: {}",
718                        subject_id, error
719                    );
720                }
721            }
722        }
723    }
724
725    async fn get_event_sn(
726        db: &Arc<ExternalDB>,
727        subject_id: &DigestIdentifier,
728        sn: u64,
729    ) -> ave_common::response::LedgerDB {
730        let started = tokio::time::Instant::now();
731        loop {
732            match db.get_event_sn(&subject_id.to_string(), sn).await {
733                Ok(event) => return event,
734                Err(_) if started.elapsed() < Duration::from_secs(5) => {
735                    tokio::time::sleep(Duration::from_millis(10)).await;
736                }
737                Err(error) => {
738                    panic!(
739                        "event {} for {} not available in time: {}",
740                        sn, subject_id, error
741                    );
742                }
743            }
744        }
745    }
746
747    pub async fn emit_request(
748        request: EventRequest,
749        node_actor: &ActorRef<Node>,
750        request_actor: &ActorRef<RequestHandler>,
751        tracking_actor: &ActorRef<RequestTracking>,
752        wait_request_state: bool,
753    ) -> RequestData {
754        let response = node_actor
755            .ask(NodeMessage::SignRequest(Box::new(
756                SignTypesNode::EventRequest(request.clone()),
757            )))
758            .await
759            .unwrap();
760        let NodeResponse::SignRequest(signature) = response else {
761            panic!("Invalid Response")
762        };
763
764        let signed_event_req = Signed::from_parts(request, signature);
765
766        let RequestHandlerResponse::Ok(request_data) = request_actor
767            .ask(RequestHandlerMessage::NewRequest {
768                request: signed_event_req.clone(),
769            })
770            .await
771            .unwrap()
772        else {
773            panic!("Invalid response")
774        };
775
776        if wait_request_state {
777            wait_request(tracking_actor, request_data.request_id.clone()).await;
778        }
779
780        request_data
781    }
782
783    pub async fn wait_request(
784        tracking_actor: &ActorRef<RequestTracking>,
785        request_id: DigestIdentifier,
786    ) {
787        loop {
788            if let Ok(RequestTrackingResponse::Info(state)) = tracking_actor
789                .ask(RequestTrackingMessage::SearchRequest(request_id.clone()))
790                .await
791            {
792                match state.state {
793                    RequestState::Approval
794                    | RequestState::Abort { .. }
795                    | RequestState::Invalid { .. }
796                    | RequestState::Finish => break,
797                    _ => {}
798                }
799            } else {
800                tokio::time::sleep(Duration::from_secs(1)).await;
801            };
802        }
803    }
804
805    async fn get_sink_events(
806        node_actor: &ActorRef<Node>,
807        subject_id: &DigestIdentifier,
808        from_sn: u64,
809        to_sn: Option<u64>,
810        limit: u64,
811    ) -> ave_common::response::SinkEventsPage {
812        let response = node_actor
813            .ask(NodeMessage::GetSinkEvents {
814                subject_id: subject_id.clone(),
815                from_sn,
816                to_sn,
817                limit,
818            })
819            .await
820            .unwrap();
821
822        let NodeResponse::SinkEvents(events) = response else {
823            panic!("Invalid response")
824        };
825
826        events
827    }
828
829    async fn get_sink_events_error(
830        node_actor: &ActorRef<Node>,
831        subject_id: &DigestIdentifier,
832        from_sn: u64,
833        to_sn: Option<u64>,
834        limit: u64,
835    ) -> ActorError {
836        node_actor
837            .ask(NodeMessage::GetSinkEvents {
838                subject_id: subject_id.clone(),
839                from_sn,
840                to_sn,
841                limit,
842            })
843            .await
844            .unwrap_err()
845    }
846
847    async fn get_tracker_metadata(
848        system: &SystemRef,
849        subject_id: &DigestIdentifier,
850    ) -> Metadata {
851        let subject_manager = system
852            .get_actor::<SubjectManager>(&ActorPath::from(
853                "/user/node/subject_manager",
854            ))
855            .await
856            .unwrap();
857        let requester = format!("evaluation_test:{}", subject_id);
858
859        let SubjectManagerResponse::Up = subject_manager
860            .ask(SubjectManagerMessage::Up {
861                subject_id: subject_id.clone(),
862                requester: requester.clone(),
863                create_ledger: None,
864            })
865            .await
866            .unwrap()
867        else {
868            panic!("Invalid response")
869        };
870
871        let subject_actor: ActorRef<Tracker> = system
872            .get_actor(&ActorPath::from(format!(
873                "/user/node/subject_manager/{}",
874                subject_id
875            )))
876            .await
877            .unwrap();
878
879        let metadata = match subject_actor
880            .ask(TrackerMessage::GetMetadata)
881            .await
882            .unwrap()
883        {
884            TrackerResponse::Metadata(metadata) => *metadata,
885            _ => panic!("Invalid response"),
886        };
887
888        let SubjectManagerResponse::Finish = subject_manager
889            .ask(SubjectManagerMessage::Finish {
890                subject_id: subject_id.clone(),
891                requester,
892            })
893            .await
894            .unwrap()
895        else {
896            panic!("Invalid response")
897        };
898
899        metadata
900    }
901
902    #[test(tokio::test)]
903    async fn test_fact_gov() {
904        let (
905            _system,
906            node_actor,
907            request_actor,
908            db,
909            subject_actor,
910            tracking,
911            subject_id,
912            _dir,
913        ) = create_gov().await;
914
915        let payload = ValueWrapper(json!({
916            "members": {
917                "add": [
918                    {
919                        "name": "AveNode1",
920                        "key": "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbE"
921                    }
922                ]
923            }
924        }));
925        let fact_request = EventRequest::Fact(FactRequest {
926            subject_id: subject_id.clone(),
927            payload: payload.clone(),
928            viewpoints: Default::default(),
929        });
930
931        let request_data = emit_request(
932            fact_request,
933            &node_actor,
934            &request_actor,
935            &tracking,
936            true,
937        )
938        .await;
939
940        let RequestHandlerResponse::Approval(Some((.., state))) = request_actor
941            .ask(RequestHandlerMessage::GetApproval {
942                subject_id: subject_id.clone(),
943                state: Some(ApprovalState::Pending),
944            })
945            .await
946            .unwrap()
947        else {
948            panic!("Invalid response")
949        };
950
951        assert_eq!(state.to_string(), "pending");
952
953        let RequestHandlerResponse::Response(res) = request_actor
954            .ask(RequestHandlerMessage::ChangeApprovalState {
955                subject_id: subject_id.clone(),
956                state: ApprovalStateRes::Accepted,
957            })
958            .await
959            .unwrap()
960        else {
961            panic!("Invalid response")
962        };
963
964        assert_eq!(
965            res,
966            format!(
967                "The approval request for subject {} has changed to accepted",
968                subject_id.to_string()
969            )
970        );
971
972        wait_request(&tracking, request_data.request_id).await;
973
974        let GovernanceResponse::Metadata(metadata) = subject_actor
975            .ask(GovernanceMessage::GetMetadata)
976            .await
977            .unwrap()
978        else {
979            panic!("Invalid response")
980        };
981
982        let subject_data = get_subject_state(&db, &subject_id, 1).await;
983        let event = get_event_sn(&db, &subject_id, 1).await;
984
985        let RequestEventDB::GovernanceFact {
986            payload: request_payload,
987            evaluation_response,
988            approval_success,
989        } = event.event
990        else {
991            panic!()
992        };
993
994        let EvalResDB::Patch(_) = evaluation_response else {
995            panic!("");
996        };
997
998        assert!(approval_success.unwrap());
999
1000        assert_eq!(metadata.name, subject_data.name);
1001        assert_eq!(metadata.name.unwrap(), "Name");
1002
1003        assert_eq!(metadata.description, subject_data.description);
1004        assert_eq!(metadata.description.unwrap(), "Description");
1005
1006        assert_eq!(metadata.subject_id.to_string(), event.subject_id);
1007        assert_eq!(metadata.subject_id.to_string(), subject_data.subject_id);
1008        assert_eq!(metadata.subject_id, subject_id);
1009
1010        assert_eq!(
1011            metadata.governance_id.to_string(),
1012            subject_data.governance_id
1013        );
1014        assert_eq!(metadata.governance_id, subject_id);
1015
1016        assert_eq!(
1017            metadata.genesis_gov_version,
1018            subject_data.genesis_gov_version
1019        );
1020        assert_eq!(metadata.genesis_gov_version, 0);
1021
1022        assert_eq!(
1023            metadata.schema_id.to_string(),
1024            subject_data.schema_id.to_string()
1025        );
1026        assert_eq!(metadata.schema_id, SchemaType::Governance);
1027
1028        assert_eq!(
1029            metadata.namespace.to_string(),
1030            subject_data.namespace.to_string()
1031        );
1032        assert_eq!(metadata.namespace, Namespace::new());
1033
1034        assert!(subject_data.new_owner.is_none());
1035        assert!(metadata.new_owner.is_none());
1036
1037        assert_eq!(metadata.sn, event.sn);
1038        assert_eq!(metadata.sn, subject_data.sn);
1039        assert_eq!(metadata.sn, 1);
1040
1041        assert!(subject_data.active);
1042        assert!(metadata.active);
1043
1044        assert_eq!(payload.0, request_payload);
1045        assert_eq!(metadata.properties.0, subject_data.properties);
1046        let gov = GovernanceData::try_from(metadata.properties).unwrap();
1047        assert_eq!(gov.version, 1);
1048        assert!(!gov.members.is_empty());
1049        assert!(gov.roles_schema.is_empty());
1050        assert!(gov.schemas.is_empty());
1051        assert!(gov.policies_schema.is_empty());
1052    }
1053
1054    #[test(tokio::test)]
1055    async fn test_fact_fail_gov() {
1056        let (
1057            _system,
1058            node_actor,
1059            request_actor,
1060            db,
1061            subject_actor,
1062            tracking,
1063            subject_id,
1064            _dir,
1065        ) = create_gov().await;
1066
1067        let payload = ValueWrapper(json!({
1068            "members": {
1069                "add": [
1070                    {
1071                        "name": "Owner",
1072                        "key": "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbE"
1073                    }
1074                ]
1075            }
1076        }));
1077        let fact_request = EventRequest::Fact(FactRequest {
1078            subject_id: subject_id.clone(),
1079            payload: payload.clone(),
1080            viewpoints: Default::default(),
1081        });
1082
1083        let _request_data = emit_request(
1084            fact_request,
1085            &node_actor,
1086            &request_actor,
1087            &tracking,
1088            true,
1089        )
1090        .await;
1091
1092        let GovernanceResponse::Metadata(metadata) = subject_actor
1093            .ask(GovernanceMessage::GetMetadata)
1094            .await
1095            .unwrap()
1096        else {
1097            panic!("Invalid response")
1098        };
1099
1100        let subject_data = get_subject_state(&db, &subject_id, 1).await;
1101        let event = get_event_sn(&db, &subject_id, 1).await;
1102
1103        let RequestEventDB::GovernanceFact {
1104            payload: request_payload,
1105            evaluation_response,
1106            approval_success,
1107        } = event.event
1108        else {
1109            panic!()
1110        };
1111
1112        let EvalResDB::Error(e) = evaluation_response else {
1113            panic!("");
1114        };
1115
1116        assert_eq!(
1117            "runner error: invalid event: [check_members] invalid event: member name cannot be 'Owner' (reserved word)",
1118            e
1119        );
1120        assert!(approval_success.is_none());
1121
1122        assert_eq!(metadata.name, subject_data.name);
1123        assert_eq!(metadata.name.unwrap(), "Name");
1124
1125        assert_eq!(metadata.description, subject_data.description);
1126        assert_eq!(metadata.description.unwrap(), "Description");
1127
1128        assert_eq!(metadata.subject_id.to_string(), event.subject_id);
1129        assert_eq!(metadata.subject_id.to_string(), subject_data.subject_id);
1130        assert_eq!(metadata.subject_id, subject_id);
1131
1132        assert_eq!(
1133            metadata.governance_id.to_string(),
1134            subject_data.governance_id
1135        );
1136        assert_eq!(metadata.governance_id, subject_id);
1137
1138        assert_eq!(
1139            metadata.genesis_gov_version,
1140            subject_data.genesis_gov_version
1141        );
1142        assert_eq!(metadata.genesis_gov_version, 0);
1143
1144        assert_eq!(
1145            metadata.schema_id.to_string(),
1146            subject_data.schema_id.to_string()
1147        );
1148        assert_eq!(metadata.schema_id, SchemaType::Governance);
1149
1150        assert_eq!(
1151            metadata.namespace.to_string(),
1152            subject_data.namespace.to_string()
1153        );
1154        assert_eq!(metadata.namespace, Namespace::new());
1155
1156        assert!(subject_data.new_owner.is_none());
1157        assert!(metadata.new_owner.is_none());
1158
1159        assert_eq!(metadata.sn, event.sn);
1160        assert_eq!(metadata.sn, subject_data.sn);
1161        assert_eq!(metadata.sn, 1);
1162
1163        assert!(subject_data.active);
1164        assert!(metadata.active);
1165
1166        assert_eq!(payload.0, request_payload);
1167        assert_eq!(metadata.properties.0, subject_data.properties);
1168        let gov = GovernanceData::try_from(metadata.properties).unwrap();
1169        assert_eq!(gov.version, 0);
1170        assert!(!gov.members.is_empty());
1171        assert!(gov.roles_schema.is_empty());
1172        assert!(gov.schemas.is_empty());
1173        assert!(gov.policies_schema.is_empty());
1174    }
1175
1176    #[test(tokio::test)]
1177    async fn test_transfer_gov() {
1178        let (
1179            _system,
1180            node_actor,
1181            request_actor,
1182            db,
1183            subject_actor,
1184            tracking,
1185            subject_id,
1186            _dir,
1187        ) = create_gov().await;
1188
1189        let fact_request = EventRequest::Fact(FactRequest {
1190            subject_id: subject_id.clone(),
1191            payload: ValueWrapper(json!({
1192                "members": {
1193                    "add": [
1194                        {
1195                            "name": "TestMember",
1196                            "key": "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbE"
1197                        }
1198                    ]
1199                }
1200            })),
1201            viewpoints: Default::default(),
1202        });
1203
1204        let _request_data = emit_request(
1205            fact_request,
1206            &node_actor,
1207            &request_actor,
1208            &tracking,
1209            true,
1210        )
1211        .await;
1212
1213        let RequestHandlerResponse::Response(res) = request_actor
1214            .ask(RequestHandlerMessage::ChangeApprovalState {
1215                subject_id: subject_id.clone(),
1216                state: ApprovalStateRes::Accepted,
1217            })
1218            .await
1219            .unwrap()
1220        else {
1221            panic!("Invalid response")
1222        };
1223
1224        assert_eq!(
1225            res,
1226            format!(
1227                "The approval request for subject {} has changed to accepted",
1228                subject_id.to_string()
1229            )
1230        );
1231
1232        let transfer_request = EventRequest::Transfer(TransferRequest {
1233            subject_id: subject_id.clone(),
1234            new_owner: PublicKey::from_str(
1235                "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbE",
1236            )
1237            .unwrap(),
1238        });
1239
1240        let _request_data = emit_request(
1241            transfer_request.clone(),
1242            &node_actor,
1243            &request_actor,
1244            &tracking,
1245            true,
1246        )
1247        .await;
1248
1249        let GovernanceResponse::Metadata(metadata) = subject_actor
1250            .ask(GovernanceMessage::GetMetadata)
1251            .await
1252            .unwrap()
1253        else {
1254            panic!("Invalid response")
1255        };
1256
1257        let subject_data = get_subject_state(&db, &subject_id, 2).await;
1258        let event = get_event_sn(&db, &subject_id, 2).await;
1259
1260        let RequestEventDB::Transfer {
1261            evaluation_error,
1262            new_owner: new_owner_transfer,
1263        } = event.event
1264        else {
1265            panic!()
1266        };
1267
1268        assert!(evaluation_error.is_none());
1269
1270        assert_eq!(metadata.name, subject_data.name);
1271        assert_eq!(metadata.name.unwrap(), "Name");
1272
1273        assert_eq!(metadata.description, subject_data.description);
1274        assert_eq!(metadata.description.unwrap(), "Description");
1275
1276        assert_eq!(metadata.subject_id.to_string(), event.subject_id);
1277        assert_eq!(metadata.subject_id.to_string(), subject_data.subject_id);
1278        assert_eq!(metadata.subject_id, subject_id);
1279
1280        assert_eq!(
1281            metadata.governance_id.to_string(),
1282            subject_data.governance_id
1283        );
1284        assert_eq!(metadata.governance_id, subject_id);
1285
1286        assert_eq!(
1287            metadata.genesis_gov_version,
1288            subject_data.genesis_gov_version
1289        );
1290        assert_eq!(metadata.genesis_gov_version, 0);
1291
1292        assert_eq!(
1293            metadata.schema_id.to_string(),
1294            subject_data.schema_id.to_string()
1295        );
1296        assert_eq!(metadata.schema_id, SchemaType::Governance);
1297
1298        assert_eq!(
1299            metadata.namespace.to_string(),
1300            subject_data.namespace.to_string()
1301        );
1302        assert_eq!(metadata.namespace, Namespace::new());
1303
1304        assert_eq!(
1305            new_owner_transfer,
1306            "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbE"
1307        );
1308        assert_eq!(
1309            subject_data.new_owner.unwrap(),
1310            "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbE"
1311        );
1312        assert_eq!(
1313            metadata.new_owner.unwrap().to_string(),
1314            "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbE"
1315        );
1316
1317        assert_eq!(metadata.sn, event.sn);
1318        assert_eq!(metadata.sn, subject_data.sn);
1319        assert_eq!(metadata.sn, 2);
1320
1321        assert!(subject_data.active);
1322        assert!(metadata.active);
1323
1324        assert_eq!(metadata.properties.0, subject_data.properties);
1325        let gov = GovernanceData::try_from(metadata.properties).unwrap();
1326        assert_eq!(gov.version, 2);
1327        assert!(!gov.members.is_empty());
1328        assert!(gov.roles_schema.is_empty());
1329        assert!(gov.schemas.is_empty());
1330        assert!(gov.policies_schema.is_empty());
1331
1332        let response = node_actor
1333            .ask(NodeMessage::SignRequest(Box::new(
1334                SignTypesNode::EventRequest(transfer_request.clone()),
1335            )))
1336            .await
1337            .unwrap();
1338        let NodeResponse::SignRequest(signature) = response else {
1339            panic!("Invalid Response")
1340        };
1341
1342        let signed_event_req = Signed::from_parts(transfer_request, signature);
1343
1344        if !request_actor
1345            .ask(RequestHandlerMessage::NewRequest {
1346                request: signed_event_req.clone(),
1347            })
1348            .await
1349            .is_err()
1350        {
1351            panic!("Invalid response")
1352        }
1353    }
1354
1355    #[test(tokio::test)]
1356    async fn test_transfer_fail_gov() {
1357        let (
1358            _system,
1359            node_actor,
1360            request_actor,
1361            db,
1362            subject_actor,
1363            tracking,
1364            subject_id,
1365            _dir,
1366        ) = create_gov().await;
1367
1368        let fact_request = EventRequest::Fact(FactRequest {
1369            subject_id: subject_id.clone(),
1370            payload: ValueWrapper(json!({
1371                "members": {
1372                    "add": [
1373                        {
1374                            "name": "TestMember",
1375                            "key": "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbE"
1376                        }
1377                    ]
1378                }
1379            })),
1380            viewpoints: Default::default(),
1381        });
1382
1383        let _request_data = emit_request(
1384            fact_request,
1385            &node_actor,
1386            &request_actor,
1387            &tracking,
1388            true,
1389        )
1390        .await;
1391
1392        let RequestHandlerResponse::Response(res) = request_actor
1393            .ask(RequestHandlerMessage::ChangeApprovalState {
1394                subject_id: subject_id.clone(),
1395                state: ApprovalStateRes::Accepted,
1396            })
1397            .await
1398            .unwrap()
1399        else {
1400            panic!("Invalid response")
1401        };
1402
1403        assert_eq!(
1404            res,
1405            format!(
1406                "The approval request for subject {} has changed to accepted",
1407                subject_id.to_string()
1408            )
1409        );
1410
1411        let transfer_request = EventRequest::Transfer(TransferRequest {
1412            subject_id: subject_id.clone(),
1413            new_owner: PublicKey::from_str(
1414                "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbA",
1415            )
1416            .unwrap(),
1417        });
1418
1419        let _request_data = emit_request(
1420            transfer_request,
1421            &node_actor,
1422            &request_actor,
1423            &tracking,
1424            true,
1425        )
1426        .await;
1427
1428        let GovernanceResponse::Metadata(metadata) = subject_actor
1429            .ask(GovernanceMessage::GetMetadata)
1430            .await
1431            .unwrap()
1432        else {
1433            panic!("Invalid response")
1434        };
1435
1436        let subject_data = get_subject_state(&db, &subject_id, 2).await;
1437        let event = get_event_sn(&db, &subject_id, 2).await;
1438
1439        let RequestEventDB::Transfer {
1440            evaluation_error,
1441            new_owner: new_owner_transfer,
1442        } = event.event
1443        else {
1444            panic!()
1445        };
1446
1447        assert_eq!(
1448            "runner error: invalid event: [execute_transfer_gov] invalid event: 'new owner EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbA' is not a member of governance",
1449            evaluation_error.unwrap()
1450        );
1451
1452        assert_eq!(metadata.name, subject_data.name);
1453        assert_eq!(metadata.name.unwrap(), "Name");
1454
1455        assert_eq!(metadata.description, subject_data.description);
1456        assert_eq!(metadata.description.unwrap(), "Description");
1457
1458        assert_eq!(metadata.subject_id.to_string(), event.subject_id);
1459        assert_eq!(metadata.subject_id.to_string(), subject_data.subject_id);
1460        assert_eq!(metadata.subject_id, subject_id);
1461
1462        assert_eq!(
1463            metadata.governance_id.to_string(),
1464            subject_data.governance_id
1465        );
1466        assert_eq!(metadata.governance_id, subject_id);
1467
1468        assert_eq!(
1469            metadata.genesis_gov_version,
1470            subject_data.genesis_gov_version
1471        );
1472        assert_eq!(metadata.genesis_gov_version, 0);
1473
1474        assert_eq!(
1475            metadata.schema_id.to_string(),
1476            subject_data.schema_id.to_string()
1477        );
1478        assert_eq!(metadata.schema_id, SchemaType::Governance);
1479
1480        assert_eq!(
1481            metadata.namespace.to_string(),
1482            subject_data.namespace.to_string()
1483        );
1484        assert_eq!(metadata.namespace, Namespace::new());
1485
1486        assert_eq!(
1487            new_owner_transfer,
1488            "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbA"
1489        );
1490        assert!(subject_data.new_owner.is_none());
1491        assert!(metadata.new_owner.is_none());
1492
1493        assert_eq!(metadata.sn, event.sn);
1494        assert_eq!(metadata.sn, subject_data.sn);
1495        assert_eq!(metadata.sn, 2);
1496
1497        assert!(subject_data.active);
1498        assert!(metadata.active);
1499
1500        assert_eq!(metadata.properties.0, subject_data.properties);
1501        let gov = GovernanceData::try_from(metadata.properties).unwrap();
1502        assert_eq!(gov.version, 1);
1503        assert!(!gov.members.is_empty());
1504        assert!(gov.roles_schema.is_empty());
1505        assert!(gov.schemas.is_empty());
1506        assert!(gov.policies_schema.is_empty());
1507    }
1508
1509    async fn init_gov_with_member_and_schema() -> (
1510        SystemRef,
1511        ActorRef<Node>,
1512        ActorRef<RequestHandler>,
1513        Arc<ExternalDB>,
1514        ActorRef<Governance>,
1515        ActorRef<RequestTracking>,
1516        DigestIdentifier,
1517        Vec<TempDir>,
1518    ) {
1519        let (
1520            system,
1521            node_actor,
1522            request_actor,
1523            db,
1524            subject_actor,
1525            tracking,
1526            subject_id,
1527            _dir,
1528        ) = create_gov().await;
1529
1530        let fact_request = EventRequest::Fact(FactRequest {
1531            subject_id: subject_id.clone(),
1532            payload: ValueWrapper(json!({
1533                "members": {
1534                    "add": [
1535                        {
1536                            "name": "TestMember",
1537                            "key": "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbE"
1538                        }
1539                    ]
1540                },
1541                "schemas": {
1542                    "add": [
1543                        {
1544                            "id": "Example",
1545                            "contract": "dXNlIHNlcmRlOjp7U2VyaWFsaXplLCBEZXNlcmlhbGl6ZX07CnVzZSBhdmVfY29udHJhY3Rfc2RrIGFzIHNkazsKCi8vLyBEZWZpbmUgdGhlIHN0YXRlIG9mIHRoZSBjb250cmFjdC4gCiNbZGVyaXZlKFNlcmlhbGl6ZSwgRGVzZXJpYWxpemUsIENsb25lKV0Kc3RydWN0IFN0YXRlIHsKICBwdWIgb25lOiB1MzIsCiAgcHViIHR3bzogdTMyLAogIHB1YiB0aHJlZTogdTMyCn0KCiNbZGVyaXZlKFNlcmlhbGl6ZSwgRGVzZXJpYWxpemUpXQplbnVtIFN0YXRlRXZlbnQgewogIE1vZE9uZSB7IGRhdGE6IHUzMiB9LAogIE1vZFR3byB7IGRhdGE6IHUzMiB9LAogIE1vZFRocmVlIHsgZGF0YTogdTMyIH0sCiAgTW9kQWxsIHsgb25lOiB1MzIsIHR3bzogdTMyLCB0aHJlZTogdTMyIH0KfQoKI1t1bnNhZmUobm9fbWFuZ2xlKV0KcHViIHVuc2FmZSBmbiBtYWluX2Z1bmN0aW9uKHN0YXRlX3B0cjogaTMyLCBpbml0X3N0YXRlX3B0cjogaTMyLCBldmVudF9wdHI6IGkzMiwgaXNfb3duZXI6IGkzMikgLT4gdTMyIHsKICBzZGs6OmV4ZWN1dGVfY29udHJhY3Qoc3RhdGVfcHRyLCBpbml0X3N0YXRlX3B0ciwgZXZlbnRfcHRyLCBpc19vd25lciwgY29udHJhY3RfbG9naWMpCn0KCiNbdW5zYWZlKG5vX21hbmdsZSldCnB1YiB1bnNhZmUgZm4gaW5pdF9jaGVja19mdW5jdGlvbihzdGF0ZV9wdHI6IGkzMikgLT4gdTMyIHsKICBzZGs6OmNoZWNrX2luaXRfZGF0YShzdGF0ZV9wdHIsIGluaXRfbG9naWMpCn0KCmZuIGluaXRfbG9naWMoCiAgX3N0YXRlOiAmU3RhdGUsCiAgY29udHJhY3RfcmVzdWx0OiAmbXV0IHNkazo6Q29udHJhY3RJbml0Q2hlY2ssCikgewogIGNvbnRyYWN0X3Jlc3VsdC5zdWNjZXNzID0gdHJ1ZTsKfQoKZm4gY29udHJhY3RfbG9naWMoCiAgY29udGV4dDogJnNkazo6Q29udGV4dDxTdGF0ZUV2ZW50PiwKICBjb250cmFjdF9yZXN1bHQ6ICZtdXQgc2RrOjpDb250cmFjdFJlc3VsdDxTdGF0ZT4sCikgewogIGxldCBzdGF0ZSA9ICZtdXQgY29udHJhY3RfcmVzdWx0LnN0YXRlOwogIG1hdGNoIGNvbnRleHQuZXZlbnQgewogICAgICBTdGF0ZUV2ZW50OjpNb2RPbmUgeyBkYXRhIH0gPT4gewogICAgICAgIHN0YXRlLm9uZSA9IGRhdGE7CiAgICAgIH0sCiAgICAgIFN0YXRlRXZlbnQ6Ok1vZFR3byB7IGRhdGEgfSA9PiB7CiAgICAgICAgc3RhdGUudHdvID0gZGF0YTsKICAgICAgfSwKICAgICAgU3RhdGVFdmVudDo6TW9kVGhyZWUgeyBkYXRhIH0gPT4gewogICAgICAgIGlmIGRhdGEgPT0gNTAgewogICAgICAgICAgY29udHJhY3RfcmVzdWx0LmVycm9yID0gIkNhbiBub3QgY2hhbmdlIHRocmVlIHZhbHVlLCA1MCBpcyBhIGludmFsaWQgdmFsdWUiLnRvX293bmVkKCk7CiAgICAgICAgICByZXR1cm4KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgc3RhdGUudGhyZWUgPSBkYXRhOwogICAgICB9LAogICAgICBTdGF0ZUV2ZW50OjpNb2RBbGwgeyBvbmUsIHR3bywgdGhyZWUgfSA9PiB7CiAgICAgICAgc3RhdGUub25lID0gb25lOwogICAgICAgIHN0YXRlLnR3byA9IHR3bzsKICAgICAgICBzdGF0ZS50aHJlZSA9IHRocmVlOwogICAgICB9CiAgfQogIGNvbnRyYWN0X3Jlc3VsdC5zdWNjZXNzID0gdHJ1ZTsKfQ==",
1546                            "initial_value": {
1547                                "one": 0,
1548                                "two": 0,
1549                                "three": 0
1550                            }
1551                        }
1552                    ]
1553                },
1554                "roles": {
1555                    "tracker_schemas": {
1556                        "add": {
1557                            "evaluator": [
1558                                {
1559                                    "name": "Owner",
1560                                    "namespace": []
1561                                }
1562                            ],
1563                            "validator": [
1564                                {
1565                                    "name": "Owner",
1566                                    "namespace": []
1567                                }
1568                            ],
1569                            "witness": [
1570                                {
1571                                    "name": "Owner",
1572                                    "namespace": []
1573                                }
1574                            ],
1575                        }
1576                    },
1577                    "schema":
1578                        [
1579                        {
1580                            "schema_id": "Example",
1581                                "add": {
1582                                    "creator": [
1583                                        {
1584                                            "name": "Owner",
1585                                            "namespace": [],
1586                                            "quantity": 2
1587                                        },
1588                                        {
1589                                            "name": "TestMember",
1590                                            "namespace": [],
1591                                            "quantity": 2
1592                                        }
1593                                    ],
1594                                    "issuer": [
1595                                        {
1596                                            "name": "Owner",
1597                                            "namespace": [],
1598                                        }
1599                                    ]
1600                                }
1601                        }
1602                    ]
1603                }
1604            })),
1605            viewpoints: Default::default(),
1606        });
1607
1608        let request_data = emit_request(
1609            fact_request,
1610            &node_actor,
1611            &request_actor,
1612            &tracking,
1613            true,
1614        )
1615        .await;
1616
1617        let RequestHandlerResponse::Approval(Some((.., state))) = request_actor
1618            .ask(RequestHandlerMessage::GetApproval {
1619                subject_id: subject_id.clone(),
1620                state: Some(ApprovalState::Pending),
1621            })
1622            .await
1623            .unwrap()
1624        else {
1625            panic!("Invalid response")
1626        };
1627
1628        assert_eq!(state.to_string(), "pending");
1629
1630        let RequestHandlerResponse::Response(res) = request_actor
1631            .ask(RequestHandlerMessage::ChangeApprovalState {
1632                subject_id: subject_id.clone(),
1633                state: ApprovalStateRes::Accepted,
1634            })
1635            .await
1636            .unwrap()
1637        else {
1638            panic!("Invalid response")
1639        };
1640
1641        assert_eq!(
1642            res,
1643            format!(
1644                "The approval request for subject {} has changed to accepted",
1645                subject_id.to_string()
1646            )
1647        );
1648
1649        wait_request(&tracking, request_data.request_id).await;
1650
1651        let GovernanceResponse::Metadata(metadata) = subject_actor
1652            .ask(GovernanceMessage::GetMetadata)
1653            .await
1654            .unwrap()
1655        else {
1656            panic!("Invalid response")
1657        };
1658        let subject_data = get_subject_state(&db, &subject_id, 1).await;
1659
1660        assert_eq!(metadata.name, subject_data.name);
1661        assert_eq!(metadata.name.unwrap(), "Name");
1662
1663        assert_eq!(metadata.description, subject_data.description);
1664        assert_eq!(metadata.description.unwrap(), "Description");
1665
1666        assert_eq!(metadata.subject_id.to_string(), subject_data.subject_id);
1667        assert_eq!(metadata.subject_id, subject_id);
1668
1669        assert_eq!(
1670            metadata.governance_id.to_string(),
1671            subject_data.governance_id
1672        );
1673        assert_eq!(metadata.governance_id, subject_id);
1674
1675        assert_eq!(
1676            metadata.genesis_gov_version,
1677            subject_data.genesis_gov_version
1678        );
1679        assert_eq!(metadata.genesis_gov_version, 0);
1680
1681        assert_eq!(
1682            metadata.schema_id.to_string(),
1683            subject_data.schema_id.to_string()
1684        );
1685        assert_eq!(metadata.schema_id, SchemaType::Governance);
1686
1687        assert_eq!(
1688            metadata.namespace.to_string(),
1689            subject_data.namespace.to_string()
1690        );
1691        assert_eq!(metadata.namespace, Namespace::new());
1692
1693        assert!(subject_data.new_owner.is_none());
1694        assert!(metadata.new_owner.is_none());
1695
1696        assert_eq!(metadata.sn, subject_data.sn);
1697        assert_eq!(metadata.sn, 1);
1698
1699        assert!(subject_data.active);
1700        assert!(metadata.active);
1701
1702        assert_eq!(metadata.properties.0, subject_data.properties);
1703        let gov = GovernanceData::try_from(metadata.properties).unwrap();
1704        assert_eq!(gov.version, 1);
1705        assert!(!gov.members.is_empty());
1706        assert!(!gov.roles_schema.is_empty());
1707        assert!(!gov.schemas.is_empty());
1708        assert!(!gov.policies_schema.is_empty());
1709
1710        (
1711            system,
1712            node_actor,
1713            request_actor,
1714            db,
1715            subject_actor,
1716            tracking,
1717            subject_id,
1718            _dir,
1719        )
1720    }
1721
1722    #[test(tokio::test)]
1723    async fn test_fact_gov_2() {
1724        init_gov_with_member_and_schema().await;
1725    }
1726
1727    async fn create_tracker() -> (
1728        SystemRef,
1729        ActorRef<Node>,
1730        ActorRef<RequestHandler>,
1731        Arc<ExternalDB>,
1732        ActorRef<RequestTracking>,
1733        DigestIdentifier,
1734        DigestIdentifier,
1735        Vec<TempDir>,
1736    ) {
1737        let (
1738            system,
1739            node_actor,
1740            request_actor,
1741            db,
1742            _subject_actor,
1743            tracking,
1744            gov_id,
1745            _dir,
1746        ) = init_gov_with_member_and_schema().await;
1747
1748        let create_request = EventRequest::Create(CreateRequest {
1749            name: Some("Subject Name".to_owned()),
1750            description: Some("Subject Description".to_owned()),
1751            governance_id: gov_id.clone(),
1752            schema_id: SchemaType::Type("Example".to_owned()),
1753            namespace: Namespace::new(),
1754        });
1755
1756        let request_data = emit_request(
1757            create_request,
1758            &node_actor,
1759            &request_actor,
1760            &tracking,
1761            true,
1762        )
1763        .await;
1764
1765        let subject_id = request_data.subject_id.clone();
1766
1767        let metadata = get_tracker_metadata(&system, &subject_id).await;
1768
1769        let subject_data = get_subject_state(&db, &subject_id, 0).await;
1770        let event = get_event_sn(&db, &subject_id, 0).await;
1771
1772        let RequestEventDB::Create {
1773            name,
1774            description,
1775            schema_id,
1776            namespace,
1777        } = event.event
1778        else {
1779            panic!()
1780        };
1781
1782        assert_eq!(metadata.name, name);
1783        assert_eq!(metadata.name, subject_data.name);
1784        assert_eq!(metadata.name.unwrap(), "Subject Name");
1785
1786        assert_eq!(metadata.description, description);
1787        assert_eq!(metadata.description, subject_data.description);
1788        assert_eq!(metadata.description.unwrap(), "Subject Description");
1789
1790        assert_eq!(metadata.subject_id.to_string(), event.subject_id);
1791        assert_eq!(metadata.subject_id.to_string(), subject_data.subject_id);
1792        assert_eq!(metadata.subject_id, subject_id);
1793
1794        assert_eq!(
1795            metadata.governance_id.to_string(),
1796            subject_data.governance_id
1797        );
1798        assert_eq!(metadata.governance_id, gov_id);
1799
1800        assert_eq!(
1801            metadata.genesis_gov_version,
1802            subject_data.genesis_gov_version
1803        );
1804        assert_eq!(metadata.genesis_gov_version, 1);
1805
1806        assert_eq!(metadata.schema_id.to_string(), schema_id);
1807        assert_eq!(
1808            metadata.schema_id.to_string(),
1809            subject_data.schema_id.to_string()
1810        );
1811        assert_eq!(metadata.schema_id, SchemaType::Type("Example".to_string()));
1812
1813        assert_eq!(metadata.namespace.to_string(), namespace);
1814        assert_eq!(
1815            metadata.namespace.to_string(),
1816            subject_data.namespace.to_string()
1817        );
1818        assert_eq!(metadata.namespace, Namespace::new());
1819
1820        assert!(subject_data.new_owner.is_none());
1821        assert!(metadata.new_owner.is_none());
1822
1823        assert_eq!(metadata.sn, event.sn);
1824        assert_eq!(metadata.sn, subject_data.sn);
1825        assert_eq!(metadata.sn, 0);
1826
1827        assert!(subject_data.active);
1828        assert!(metadata.active);
1829
1830        assert_eq!(metadata.properties.0, subject_data.properties);
1831        assert!(metadata.properties.0["one"].as_u64().unwrap() == 0);
1832        assert!(metadata.properties.0["two"].as_u64().unwrap() == 0);
1833        assert!(metadata.properties.0["three"].as_u64().unwrap() == 0);
1834
1835        (
1836            system,
1837            node_actor,
1838            request_actor,
1839            db,
1840            tracking,
1841            request_data.subject_id,
1842            gov_id,
1843            _dir,
1844        )
1845    }
1846
1847    #[test(tokio::test)]
1848    async fn test_create_tracker() {
1849        let _ = create_tracker().await;
1850    }
1851
1852    #[test(tokio::test)]
1853    async fn test_replay_sink_events_tracker_create() {
1854        let (
1855            _system,
1856            node_actor,
1857            _request_actor,
1858            _db,
1859            _tracking,
1860            subject_id,
1861            gov_id,
1862            _dir,
1863        ) = create_tracker().await;
1864
1865        let replay =
1866            get_sink_events(&node_actor, &subject_id, 0, None, 100).await;
1867
1868        assert_eq!(replay.from_sn, 0);
1869        assert_eq!(replay.to_sn, None);
1870        assert_eq!(replay.limit, 100);
1871        assert!(!replay.has_more);
1872        assert!(replay.next_sn.is_none());
1873        assert_eq!(replay.events.len(), 1);
1874
1875        let event = &replay.events[0];
1876        assert!(!event.public_key.is_empty());
1877        assert!(event.sink_timestamp > 0);
1878        match &event.payload {
1879            DataToSinkEvent::Create {
1880                governance_id,
1881                subject_id: replay_subject_id,
1882                owner,
1883                schema_id,
1884                namespace,
1885                sn,
1886                gov_version,
1887                state,
1888            } => {
1889                assert_eq!(
1890                    governance_id.as_deref(),
1891                    Some(gov_id.to_string().as_str())
1892                );
1893                assert_eq!(replay_subject_id, &subject_id.to_string());
1894                assert_eq!(schema_id, &SchemaType::Type("Example".to_owned()));
1895                assert_eq!(namespace, "");
1896                assert_eq!(*sn, 0);
1897                assert_eq!(*gov_version, 1);
1898                assert!(!owner.is_empty());
1899                assert_eq!(state["one"].as_u64().unwrap(), 0);
1900                assert_eq!(state["two"].as_u64().unwrap(), 0);
1901                assert_eq!(state["three"].as_u64().unwrap(), 0);
1902            }
1903            other => panic!("Unexpected event: {other:?}"),
1904        }
1905    }
1906
1907    #[test(tokio::test)]
1908    async fn test_replay_sink_events_tracker_pagination() {
1909        let (
1910            _system,
1911            node_actor,
1912            request_actor,
1913            _db,
1914            tracking,
1915            subject_id,
1916            gov_id,
1917            _dir,
1918        ) = create_tracker().await;
1919
1920        let payload = json!({
1921            "ModOne": {
1922                "data": 100
1923            }
1924        });
1925
1926        let fact_request = EventRequest::Fact(FactRequest {
1927            subject_id: subject_id.clone(),
1928            payload: ValueWrapper(payload.clone()),
1929            viewpoints: Default::default(),
1930        });
1931
1932        let _request_data = emit_request(
1933            fact_request,
1934            &node_actor,
1935            &request_actor,
1936            &tracking,
1937            true,
1938        )
1939        .await;
1940
1941        let first_page =
1942            get_sink_events(&node_actor, &subject_id, 0, None, 1).await;
1943        assert_eq!(first_page.events.len(), 1);
1944        assert!(first_page.has_more);
1945        assert_eq!(first_page.next_sn, Some(1));
1946        match &first_page.events[0].payload {
1947            DataToSinkEvent::Create {
1948                governance_id,
1949                subject_id: replay_subject_id,
1950                sn,
1951                ..
1952            } => {
1953                assert_eq!(
1954                    governance_id.as_deref(),
1955                    Some(gov_id.to_string().as_str())
1956                );
1957                assert_eq!(replay_subject_id, &subject_id.to_string());
1958                assert_eq!(*sn, 0);
1959            }
1960            other => panic!("Unexpected event: {other:?}"),
1961        }
1962
1963        let second_page =
1964            get_sink_events(&node_actor, &subject_id, 1, None, 10).await;
1965        assert_eq!(second_page.events.len(), 1);
1966        assert!(!second_page.has_more);
1967        assert!(second_page.next_sn.is_none());
1968        match &second_page.events[0].payload {
1969            DataToSinkEvent::FactFull {
1970                governance_id,
1971                subject_id: replay_subject_id,
1972                payload: replay_payload,
1973                success,
1974                sn,
1975                gov_version,
1976                ..
1977            } => {
1978                assert_eq!(
1979                    governance_id.as_deref(),
1980                    Some(gov_id.to_string().as_str())
1981                );
1982                assert_eq!(replay_subject_id, &subject_id.to_string());
1983                assert_eq!(replay_payload.as_ref(), Some(&payload));
1984                assert!(*success);
1985                assert_eq!(*sn, 1);
1986                assert_eq!(*gov_version, 1);
1987            }
1988            other => panic!("Unexpected event: {other:?}"),
1989        }
1990    }
1991
1992    #[test(tokio::test)]
1993    async fn test_replay_sink_events_governance_create() {
1994        let (
1995            _system,
1996            node_actor,
1997            _request_actor,
1998            _db,
1999            _subject_actor,
2000            _tracking,
2001            subject_id,
2002            _dir,
2003        ) = create_gov().await;
2004
2005        let replay =
2006            get_sink_events(&node_actor, &subject_id, 0, None, 100).await;
2007
2008        assert_eq!(replay.events.len(), 1);
2009        assert!(!replay.has_more);
2010        assert!(replay.next_sn.is_none());
2011
2012        match &replay.events[0].payload {
2013            DataToSinkEvent::Create {
2014                governance_id,
2015                subject_id: replay_subject_id,
2016                schema_id,
2017                sn,
2018                gov_version,
2019                ..
2020            } => {
2021                assert!(governance_id.is_none());
2022                assert_eq!(replay_subject_id, &subject_id.to_string());
2023                assert_eq!(schema_id, &SchemaType::Governance);
2024                assert_eq!(*sn, 0);
2025                assert_eq!(*gov_version, 0);
2026            }
2027            other => panic!("Unexpected event: {other:?}"),
2028        }
2029    }
2030
2031    #[test(tokio::test)]
2032    async fn test_replay_sink_events_tracker_transfer() {
2033        let (
2034            _system,
2035            node_actor,
2036            request_actor,
2037            _db,
2038            tracking,
2039            subject_id,
2040            gov_id,
2041            _dir,
2042        ) = create_tracker().await;
2043
2044        let transfer_request = EventRequest::Transfer(TransferRequest {
2045            subject_id: subject_id.clone(),
2046            new_owner: PublicKey::from_str(
2047                "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbE",
2048            )
2049            .unwrap(),
2050        });
2051
2052        let _request_data = emit_request(
2053            transfer_request,
2054            &node_actor,
2055            &request_actor,
2056            &tracking,
2057            true,
2058        )
2059        .await;
2060
2061        let replay =
2062            get_sink_events(&node_actor, &subject_id, 1, Some(1), 100).await;
2063
2064        assert_eq!(replay.events.len(), 1);
2065        assert!(!replay.has_more);
2066        assert!(replay.next_sn.is_none());
2067
2068        match &replay.events[0].payload {
2069            DataToSinkEvent::Transfer {
2070                governance_id,
2071                subject_id: replay_subject_id,
2072                schema_id,
2073                owner,
2074                new_owner,
2075                sn,
2076                gov_version,
2077                ..
2078            } => {
2079                assert_eq!(
2080                    governance_id.as_deref(),
2081                    Some(gov_id.to_string().as_str())
2082                );
2083                assert_eq!(replay_subject_id, &subject_id.to_string());
2084                assert_eq!(schema_id, &SchemaType::Type("Example".to_owned()));
2085                assert!(!owner.is_empty());
2086                assert_eq!(
2087                    new_owner,
2088                    "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbE"
2089                );
2090                assert_eq!(*sn, 1);
2091                assert_eq!(*gov_version, 1);
2092            }
2093            other => panic!("Unexpected event: {other:?}"),
2094        }
2095    }
2096
2097    #[test(tokio::test)]
2098    async fn test_replay_sink_events_invalid_range() {
2099        let (
2100            _system,
2101            node_actor,
2102            _request_actor,
2103            _db,
2104            _tracking,
2105            subject_id,
2106            _gov_id,
2107            _dir,
2108        ) = create_tracker().await;
2109
2110        let error =
2111            get_sink_events_error(&node_actor, &subject_id, 5, Some(4), 100)
2112                .await;
2113
2114        let ActorError::Functional { description } = error else {
2115            panic!("Expected functional error")
2116        };
2117        assert_eq!(description, "Replay range requires from_sn <= to_sn");
2118    }
2119
2120    #[test(tokio::test)]
2121    async fn test_replay_sink_events_invalid_limit() {
2122        let (
2123            _system,
2124            node_actor,
2125            _request_actor,
2126            _db,
2127            _tracking,
2128            subject_id,
2129            _gov_id,
2130            _dir,
2131        ) = create_tracker().await;
2132
2133        let error =
2134            get_sink_events_error(&node_actor, &subject_id, 0, None, 0).await;
2135
2136        let ActorError::Functional { description } = error else {
2137            panic!("Expected functional error")
2138        };
2139        assert_eq!(description, "Replay limit must be greater than zero");
2140    }
2141
2142    #[test(tokio::test)]
2143    async fn test_replay_sink_events_subject_not_found() {
2144        let (
2145            _system,
2146            node_actor,
2147            _request_actor,
2148            _db,
2149            _tracking,
2150            _subject_id,
2151            _gov_id,
2152            _dir,
2153        ) = create_tracker().await;
2154
2155        let missing = DigestIdentifier::from_str(
2156            "B3B7tbY0OWp5jVq3OKYwYGQnM2zJ5V8i3G5znQJg4s8A",
2157        )
2158        .unwrap();
2159
2160        let error =
2161            get_sink_events_error(&node_actor, &missing, 0, None, 100).await;
2162
2163        let ActorError::NotFound { path } = error else {
2164            panic!("Expected not found error")
2165        };
2166        assert_eq!(
2167            path,
2168            ActorPath::from(format!("/user/node/subject_manager/{}", missing))
2169        );
2170    }
2171
2172    #[test(tokio::test)]
2173    async fn test_fact_tracker() {
2174        let (
2175            system,
2176            node_actor,
2177            request_actor,
2178            db,
2179            tracking,
2180            subject_id,
2181            gov_id,
2182            _dir,
2183        ) = create_tracker().await;
2184
2185        let payload = json!({
2186            "ModOne": {
2187                "data": 100
2188            }
2189        });
2190
2191        let fact_request = EventRequest::Fact(FactRequest {
2192            subject_id: subject_id.clone(),
2193            payload: ValueWrapper(payload.clone()),
2194            viewpoints: Default::default(),
2195        });
2196
2197        let request_data = emit_request(
2198            fact_request,
2199            &node_actor,
2200            &request_actor,
2201            &tracking,
2202            true,
2203        )
2204        .await;
2205
2206        let metadata = get_tracker_metadata(&system, &subject_id).await;
2207
2208        let subject_data =
2209            get_subject_state(&db, &request_data.subject_id, 1).await;
2210        let event = get_event_sn(&db, &subject_id, 1).await;
2211
2212        let RequestEventDB::TrackerFactFull {
2213            payload: payload_db,
2214            viewpoints,
2215            evaluation_response,
2216        } = event.event
2217        else {
2218            panic!()
2219        };
2220        assert!(viewpoints.is_empty());
2221
2222        let EvalResDB::Patch(_) = evaluation_response else {
2223            panic!("");
2224        };
2225
2226        assert_eq!(metadata.name, subject_data.name);
2227        assert_eq!(metadata.name.unwrap(), "Subject Name");
2228
2229        assert_eq!(metadata.description, subject_data.description);
2230        assert_eq!(metadata.description.unwrap(), "Subject Description");
2231
2232        assert_eq!(metadata.subject_id.to_string(), event.subject_id);
2233        assert_eq!(metadata.subject_id.to_string(), subject_data.subject_id);
2234        assert_eq!(metadata.subject_id, subject_id);
2235
2236        assert_eq!(
2237            metadata.governance_id.to_string(),
2238            subject_data.governance_id
2239        );
2240        assert_eq!(metadata.governance_id, gov_id);
2241
2242        assert_eq!(
2243            metadata.genesis_gov_version,
2244            subject_data.genesis_gov_version
2245        );
2246        assert_eq!(metadata.genesis_gov_version, 1);
2247
2248        assert_eq!(
2249            metadata.schema_id.to_string(),
2250            subject_data.schema_id.to_string()
2251        );
2252        assert_eq!(metadata.schema_id, SchemaType::Type("Example".to_string()));
2253
2254        assert_eq!(
2255            metadata.namespace.to_string(),
2256            subject_data.namespace.to_string()
2257        );
2258        assert_eq!(metadata.namespace, Namespace::new());
2259
2260        assert!(subject_data.new_owner.is_none());
2261        assert!(metadata.new_owner.is_none());
2262
2263        assert_eq!(metadata.sn, event.sn);
2264        assert_eq!(metadata.sn, subject_data.sn);
2265        assert_eq!(metadata.sn, 1);
2266
2267        assert!(subject_data.active);
2268        assert!(metadata.active);
2269
2270        assert_eq!(payload, payload_db);
2271        assert_eq!(metadata.properties.0, subject_data.properties);
2272        assert!(metadata.properties.0["one"].as_u64().unwrap() == 100);
2273        assert!(metadata.properties.0["two"].as_u64().unwrap() == 0);
2274        assert!(metadata.properties.0["three"].as_u64().unwrap() == 0);
2275    }
2276
2277    #[test(tokio::test)]
2278    async fn test_fact_fail_tracker() {
2279        let (
2280            system,
2281            node_actor,
2282            request_actor,
2283            db,
2284            tracking,
2285            subject_id,
2286            gov_id,
2287            _dir,
2288        ) = create_tracker().await;
2289
2290        let payload = json!({
2291            "ModOne": {
2292                "not_exist": "error"
2293            }
2294        });
2295
2296        let fact_request = EventRequest::Fact(FactRequest {
2297            subject_id: subject_id.clone(),
2298            payload: ValueWrapper(payload.clone()),
2299            viewpoints: Default::default(),
2300        });
2301
2302        let request_data = emit_request(
2303            fact_request,
2304            &node_actor,
2305            &request_actor,
2306            &tracking,
2307            true,
2308        )
2309        .await;
2310
2311        let metadata = get_tracker_metadata(&system, &subject_id).await;
2312
2313        let subject_data =
2314            get_subject_state(&db, &request_data.subject_id, 1).await;
2315        let event = get_event_sn(&db, &subject_id, 1).await;
2316
2317        let RequestEventDB::TrackerFactFull {
2318            payload: payload_db,
2319            viewpoints,
2320            evaluation_response,
2321        } = event.event
2322        else {
2323            panic!()
2324        };
2325        assert!(viewpoints.is_empty());
2326
2327        let EvalResDB::Error(e) = evaluation_response else {
2328            panic!("");
2329        };
2330
2331        assert_eq!(
2332            "runner error: contract failed: contract returned failure: Contract execution in running was not successful: Can not convert Event from value",
2333            e
2334        );
2335        assert_eq!(metadata.name, subject_data.name);
2336        assert_eq!(metadata.name.unwrap(), "Subject Name");
2337
2338        assert_eq!(metadata.description, subject_data.description);
2339        assert_eq!(metadata.description.unwrap(), "Subject Description");
2340
2341        assert_eq!(metadata.subject_id.to_string(), event.subject_id);
2342        assert_eq!(metadata.subject_id.to_string(), subject_data.subject_id);
2343        assert_eq!(metadata.subject_id, subject_id);
2344
2345        assert_eq!(
2346            metadata.governance_id.to_string(),
2347            subject_data.governance_id
2348        );
2349        assert_eq!(metadata.governance_id, gov_id);
2350
2351        assert_eq!(
2352            metadata.genesis_gov_version,
2353            subject_data.genesis_gov_version
2354        );
2355        assert_eq!(metadata.genesis_gov_version, 1);
2356
2357        assert_eq!(
2358            metadata.schema_id.to_string(),
2359            subject_data.schema_id.to_string()
2360        );
2361        assert_eq!(metadata.schema_id, SchemaType::Type("Example".to_string()));
2362
2363        assert_eq!(
2364            metadata.namespace.to_string(),
2365            subject_data.namespace.to_string()
2366        );
2367        assert_eq!(metadata.namespace, Namespace::new());
2368
2369        assert!(subject_data.new_owner.is_none());
2370        assert!(metadata.new_owner.is_none());
2371
2372        assert_eq!(metadata.sn, event.sn);
2373        assert_eq!(metadata.sn, subject_data.sn);
2374        assert_eq!(metadata.sn, 1);
2375
2376        assert!(subject_data.active);
2377        assert!(metadata.active);
2378
2379        assert_eq!(payload, payload_db);
2380        assert_eq!(metadata.properties.0, subject_data.properties);
2381        assert!(metadata.properties.0["one"].as_u64().unwrap() == 0);
2382        assert!(metadata.properties.0["two"].as_u64().unwrap() == 0);
2383        assert!(metadata.properties.0["three"].as_u64().unwrap() == 0);
2384    }
2385
2386    #[test(tokio::test)]
2387    async fn test_transfer_tracker() {
2388        let (
2389            system,
2390            node_actor,
2391            request_actor,
2392            db,
2393            tracking,
2394            subject_id,
2395            gov_id,
2396            _dir,
2397        ) = create_tracker().await;
2398
2399        let transfer_request = EventRequest::Transfer(TransferRequest {
2400            subject_id: subject_id.clone(),
2401            new_owner: PublicKey::from_str(
2402                "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbE",
2403            )
2404            .unwrap(),
2405        });
2406
2407        let _request_data = emit_request(
2408            transfer_request.clone(),
2409            &node_actor,
2410            &request_actor,
2411            &tracking,
2412            true,
2413        )
2414        .await;
2415
2416        let metadata = get_tracker_metadata(&system, &subject_id).await;
2417
2418        let subject_data = get_subject_state(&db, &subject_id, 1).await;
2419        let event = get_event_sn(&db, &subject_id, 1).await;
2420
2421        let RequestEventDB::Transfer {
2422            evaluation_error,
2423            new_owner: new_owner_transfer,
2424        } = event.event
2425        else {
2426            panic!()
2427        };
2428
2429        assert!(evaluation_error.is_none());
2430
2431        assert_eq!(metadata.name, subject_data.name);
2432        assert_eq!(metadata.name.unwrap(), "Subject Name");
2433
2434        assert_eq!(metadata.description, subject_data.description);
2435        assert_eq!(metadata.description.unwrap(), "Subject Description");
2436
2437        assert_eq!(metadata.subject_id.to_string(), event.subject_id);
2438        assert_eq!(metadata.subject_id.to_string(), subject_data.subject_id);
2439        assert_eq!(metadata.subject_id, subject_id);
2440
2441        assert_eq!(
2442            metadata.governance_id.to_string(),
2443            subject_data.governance_id
2444        );
2445        assert_eq!(metadata.governance_id, gov_id);
2446
2447        assert_eq!(
2448            metadata.genesis_gov_version,
2449            subject_data.genesis_gov_version
2450        );
2451        assert_eq!(metadata.genesis_gov_version, 1);
2452
2453        assert_eq!(
2454            metadata.schema_id.to_string(),
2455            subject_data.schema_id.to_string()
2456        );
2457        assert_eq!(metadata.schema_id, SchemaType::Type("Example".to_string()));
2458
2459        assert_eq!(
2460            metadata.namespace.to_string(),
2461            subject_data.namespace.to_string()
2462        );
2463        assert_eq!(metadata.namespace, Namespace::new());
2464
2465        assert_eq!(
2466            new_owner_transfer,
2467            "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbE"
2468        );
2469        assert_eq!(
2470            subject_data.new_owner.unwrap(),
2471            "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbE"
2472        );
2473        assert_eq!(
2474            metadata.new_owner.unwrap().to_string(),
2475            "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbE"
2476        );
2477
2478        assert_eq!(metadata.sn, event.sn);
2479        assert_eq!(metadata.sn, subject_data.sn);
2480        assert_eq!(metadata.sn, 1);
2481
2482        assert!(subject_data.active);
2483        assert!(metadata.active);
2484
2485        assert_eq!(metadata.properties.0, subject_data.properties);
2486        assert!(metadata.properties.0["one"].as_u64().unwrap() == 0);
2487        assert!(metadata.properties.0["two"].as_u64().unwrap() == 0);
2488        assert!(metadata.properties.0["three"].as_u64().unwrap() == 0);
2489
2490        let response = node_actor
2491            .ask(NodeMessage::SignRequest(Box::new(
2492                SignTypesNode::EventRequest(transfer_request.clone()),
2493            )))
2494            .await
2495            .unwrap();
2496        let NodeResponse::SignRequest(signature) = response else {
2497            panic!("Invalid Response")
2498        };
2499
2500        let signed_event_req = Signed::from_parts(transfer_request, signature);
2501
2502        if !request_actor
2503            .ask(RequestHandlerMessage::NewRequest {
2504                request: signed_event_req.clone(),
2505            })
2506            .await
2507            .is_err()
2508        {
2509            panic!("Invalid response")
2510        }
2511    }
2512
2513    #[test(tokio::test)]
2514    async fn test_transfer_fail_tracker() {
2515        let (
2516            system,
2517            node_actor,
2518            request_actor,
2519            db,
2520            tracking,
2521            subject_id,
2522            gov_id,
2523            _dir,
2524        ) = create_tracker().await;
2525
2526        let transfer_request = EventRequest::Transfer(TransferRequest {
2527            subject_id: subject_id.clone(),
2528            new_owner: PublicKey::from_str(
2529                "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbA",
2530            )
2531            .unwrap(),
2532        });
2533
2534        let _request_data = emit_request(
2535            transfer_request.clone(),
2536            &node_actor,
2537            &request_actor,
2538            &tracking,
2539            true,
2540        )
2541        .await;
2542
2543        let metadata = get_tracker_metadata(&system, &subject_id).await;
2544
2545        let subject_data = get_subject_state(&db, &subject_id, 1).await;
2546        let event = get_event_sn(&db, &subject_id, 1).await;
2547
2548        let RequestEventDB::Transfer {
2549            evaluation_error,
2550            new_owner: new_owner_transfer,
2551        } = event.event
2552        else {
2553            panic!()
2554        };
2555
2556        assert_eq!(
2557            "runner error: invalid event: [execute_transfer_not_gov] invalid event: 'new owner EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbA' is not a member of governance",
2558            evaluation_error.unwrap()
2559        );
2560
2561        assert_eq!(metadata.name, subject_data.name);
2562        assert_eq!(metadata.name.unwrap(), "Subject Name");
2563
2564        assert_eq!(metadata.description, subject_data.description);
2565        assert_eq!(metadata.description.unwrap(), "Subject Description");
2566
2567        assert_eq!(metadata.subject_id.to_string(), event.subject_id);
2568        assert_eq!(metadata.subject_id.to_string(), subject_data.subject_id);
2569        assert_eq!(metadata.subject_id, subject_id);
2570
2571        assert_eq!(
2572            metadata.governance_id.to_string(),
2573            subject_data.governance_id
2574        );
2575        assert_eq!(metadata.governance_id, gov_id);
2576
2577        assert_eq!(
2578            metadata.genesis_gov_version,
2579            subject_data.genesis_gov_version
2580        );
2581        assert_eq!(metadata.genesis_gov_version, 1);
2582
2583        assert_eq!(
2584            metadata.schema_id.to_string(),
2585            subject_data.schema_id.to_string()
2586        );
2587        assert_eq!(metadata.schema_id, SchemaType::Type("Example".to_string()));
2588
2589        assert_eq!(
2590            metadata.namespace.to_string(),
2591            subject_data.namespace.to_string()
2592        );
2593        assert_eq!(metadata.namespace, Namespace::new());
2594
2595        assert_eq!(
2596            new_owner_transfer,
2597            "EUrVnqpwo9EKBvMru4wWLMpJgOTKM5gZnxApRmjrRbbA"
2598        );
2599        assert!(subject_data.new_owner.is_none(),);
2600        assert!(metadata.new_owner.is_none());
2601
2602        assert_eq!(metadata.sn, event.sn);
2603        assert_eq!(metadata.sn, subject_data.sn);
2604        assert_eq!(metadata.sn, 1);
2605
2606        assert!(subject_data.active);
2607        assert!(metadata.active);
2608
2609        assert_eq!(metadata.properties.0, subject_data.properties);
2610        assert!(metadata.properties.0["one"].as_u64().unwrap() == 0);
2611        assert!(metadata.properties.0["two"].as_u64().unwrap() == 0);
2612        assert!(metadata.properties.0["three"].as_u64().unwrap() == 0);
2613    }
2614}