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::{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: Quorum,
53 evaluators_response: Vec<(EvalRes, DigestIdentifier)>,
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, 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(¤t_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 self.check_evaluator(sender.clone()) {
424 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(¤t_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}