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