1use cosmrs::tendermint::block::Height;
2
3use crate::error::Error;
4
5#[derive(Clone, Debug)]
6pub enum GevulotEvent {
7 Pin(PinEvent),
8 Task(TaskEvent),
9 Worker(WorkerEvent),
10 Workflow(WorkflowEvent),
11}
12
13impl GevulotEvent {
14 pub fn from_cosmos(
15 event: &cosmrs::tendermint::abci::Event,
16 block_height: Height,
17 ) -> crate::error::Result<Self> {
18 match event.kind.as_str() {
19 "create-worker" => {
20 let worker_id = event
21 .attributes
22 .iter()
23 .find(|attr| attr.key_bytes() == b"worker-id")
24 .ok_or(Error::MissingEventAttribute("worker-id"))?
25 .value_str()?
26 .to_string();
27
28 let creator = event
29 .attributes
30 .iter()
31 .find(|attr| attr.key_bytes() == b"creator")
32 .map(|attr| attr.value_str().unwrap_or_default().to_string())
33 .unwrap_or_default();
34
35 Ok(GevulotEvent::Worker(WorkerEvent::Create(
36 WorkerCreateEvent {
37 block_height,
38 worker_id,
39 creator,
40 },
41 )))
42 }
43 "update-worker" => {
44 let worker_id = event
45 .attributes
46 .iter()
47 .find(|attr| attr.key_bytes() == b"worker-id")
48 .ok_or(Error::MissingEventAttribute("worker-id"))?
49 .value_str()?
50 .to_string();
51
52 let creator = event
53 .attributes
54 .iter()
55 .find(|attr| attr.key_bytes() == b"creator")
56 .map(|attr| attr.value_str().unwrap_or_default().to_string())
57 .unwrap_or_default();
58
59 Ok(GevulotEvent::Worker(WorkerEvent::Update(
60 WorkerUpdateEvent {
61 block_height,
62 worker_id,
63 creator,
64 },
65 )))
66 }
67 "delete-worker" => {
68 let worker_id = event
69 .attributes
70 .iter()
71 .find(|attr| attr.key_bytes() == b"worker-id")
72 .ok_or(Error::MissingEventAttribute("worker-id"))?
73 .value_str()?
74 .to_string();
75
76 let creator = event
77 .attributes
78 .iter()
79 .find(|attr| attr.key_bytes() == b"creator")
80 .map(|attr| attr.value_str().unwrap_or_default().to_string())
81 .unwrap_or_default();
82
83 Ok(GevulotEvent::Worker(WorkerEvent::Delete(
84 WorkerDeleteEvent {
85 block_height,
86 worker_id,
87 creator,
88 },
89 )))
90 }
91 "announce-worker-exit" => {
92 let worker_id = event
93 .attributes
94 .iter()
95 .find(|attr| attr.key_bytes() == b"worker-id")
96 .ok_or(Error::MissingEventAttribute("worker-id"))?
97 .value_str()?
98 .to_string();
99
100 let creator = event
101 .attributes
102 .iter()
103 .find(|attr| attr.key_bytes() == b"creator")
104 .map(|attr| attr.value_str().unwrap_or_default().to_string())
105 .unwrap_or_default();
106
107 Ok(GevulotEvent::Worker(WorkerEvent::AnnounceExit(
108 WorkerAnnounceExitEvent {
109 block_height,
110 worker_id,
111 creator,
112 },
113 )))
114 }
115 "create-task" => {
116 let task_id = event
117 .attributes
118 .iter()
119 .find(|attr| attr.key_bytes() == b"task-id")
120 .ok_or(Error::MissingEventAttribute("task-id"))?
121 .value_str()?
122 .to_string();
123
124 let creator = event
125 .attributes
126 .iter()
127 .find(|attr| attr.key_bytes() == b"creator")
128 .map(|attr| attr.value_str().unwrap_or_default().to_string())
129 .unwrap_or_default();
130
131 let assigned_workers = event
132 .attributes
133 .iter()
134 .filter(|attr| attr.key_bytes() == b"worker-id")
135 .flat_map(|attr| {
136 attr.value_str()
137 .map(|s| {
138 s.split(',')
139 .map(|x| x.trim().to_string())
140 .collect::<Vec<_>>()
141 })
142 .unwrap_or_default()
143 })
144 .collect::<Vec<String>>();
145
146 Ok(GevulotEvent::Task(TaskEvent::Create(TaskCreateEvent {
147 block_height,
148 task_id,
149 creator,
150 assigned_workers,
151 })))
152 }
153 "delete-task" => {
154 let task_id = event
155 .attributes
156 .iter()
157 .find(|attr| attr.key_bytes() == b"task-id")
158 .ok_or(Error::MissingEventAttribute("task-id"))?
159 .value_str()?
160 .to_string();
161
162 let creator = event
163 .attributes
164 .iter()
165 .find(|attr| attr.key_bytes() == b"creator")
166 .map(|attr| attr.value_str().unwrap_or_default().to_string())
167 .unwrap_or_default();
168
169 Ok(GevulotEvent::Task(TaskEvent::Delete(TaskDeleteEvent {
170 block_height,
171 task_id,
172 creator,
173 })))
174 }
175 "finish-task" => {
176 let task_id = event
177 .attributes
178 .iter()
179 .find(|attr| attr.key_bytes() == b"task-id")
180 .ok_or(Error::MissingEventAttribute("task-id"))?
181 .value_str()?
182 .to_string();
183
184 let worker_id = event
185 .attributes
186 .iter()
187 .find(|attr| attr.key_bytes() == b"worker-id")
188 .ok_or(Error::MissingEventAttribute("worker-id"))?
189 .value_str()?
190 .to_string();
191
192 let creator = event
193 .attributes
194 .iter()
195 .find(|attr| attr.key_bytes() == b"creator")
196 .map(|attr| attr.value_str().unwrap_or_default().to_string())
197 .unwrap_or_default();
198 Ok(GevulotEvent::Task(TaskEvent::Finish(TaskFinishEvent {
199 block_height,
200 task_id,
201 worker_id,
202 creator,
203 })))
204 }
205 "decline-task" => {
206 let task_id = event
207 .attributes
208 .iter()
209 .find(|attr| attr.key_bytes() == b"task-id")
210 .ok_or(Error::MissingEventAttribute("task-id"))?
211 .value_str()?
212 .to_string();
213
214 let creator = event
215 .attributes
216 .iter()
217 .find(|attr| attr.key_bytes() == b"creator")
218 .map(|attr| attr.value_str().unwrap_or_default().to_string())
219 .unwrap_or_default();
220
221 let worker_id = event
222 .attributes
223 .iter()
224 .find(|attr| attr.key_bytes() == b"worker-id")
225 .ok_or(Error::MissingEventAttribute("worker-id"))?
226 .value_str()?
227 .to_string();
228 Ok(GevulotEvent::Task(TaskEvent::Decline(TaskDeclineEvent {
229 block_height,
230 task_id,
231 creator,
232 worker_id,
233 })))
234 }
235 "accept-task" => {
236 let task_id = event
237 .attributes
238 .iter()
239 .find(|attr| attr.key_bytes() == b"task-id")
240 .ok_or(Error::MissingEventAttribute("task-id"))?
241 .value_str()?
242 .to_string();
243
244 let creator = event
245 .attributes
246 .iter()
247 .find(|attr| attr.key_bytes() == b"creator")
248 .map(|attr| attr.value_str().unwrap_or_default().to_string())
249 .unwrap_or_default();
250
251 let worker_id = event
252 .attributes
253 .iter()
254 .find(|attr| attr.key_bytes() == b"worker-id")
255 .ok_or(Error::MissingEventAttribute("worker-id"))?
256 .value_str()?
257 .to_string();
258 Ok(GevulotEvent::Task(TaskEvent::Accept(TaskAcceptEvent {
259 block_height,
260 task_id,
261 creator,
262 worker_id,
263 })))
264 }
265 "create-workflow" => {
266 let workflow_id = event
267 .attributes
268 .iter()
269 .find(|attr| attr.key_bytes() == b"workflow-id")
270 .ok_or(Error::MissingEventAttribute("workflow-id"))?
271 .value_str()?
272 .to_string();
273
274 let creator = event
275 .attributes
276 .iter()
277 .find(|attr| attr.key_bytes() == b"creator")
278 .map(|attr| attr.value_str().unwrap_or_default().to_string())
279 .unwrap_or_default();
280
281 Ok(GevulotEvent::Workflow(WorkflowEvent::Create(
282 WorkflowCreateEvent {
283 block_height,
284 workflow_id,
285 creator,
286 },
287 )))
288 }
289 "delete-workflow" => {
290 let workflow_id = event
291 .attributes
292 .iter()
293 .find(|attr| attr.key_bytes() == b"workflow-id")
294 .ok_or(Error::MissingEventAttribute("workflow-id"))?
295 .value_str()?
296 .to_string();
297
298 let creator = event
299 .attributes
300 .iter()
301 .find(|attr| attr.key_bytes() == b"creator")
302 .map(|attr| attr.value_str().unwrap_or_default().to_string())
303 .unwrap_or_default();
304
305 Ok(GevulotEvent::Workflow(WorkflowEvent::Delete(
306 WorkflowDeleteEvent {
307 block_height,
308 workflow_id,
309 creator,
310 },
311 )))
312 }
313 "finish-workflow" => {
314 let workflow_id = event
315 .attributes
316 .iter()
317 .find(|attr| attr.key_bytes() == b"workflow-id")
318 .ok_or(Error::MissingEventAttribute("workflow-id"))?
319 .value_str()?
320 .to_string();
321
322 let creator = event
323 .attributes
324 .iter()
325 .find(|attr| attr.key_bytes() == b"creator")
326 .map(|attr| attr.value_str().unwrap_or_default().to_string())
327 .unwrap_or_default();
328
329 Ok(GevulotEvent::Workflow(WorkflowEvent::Finish(
330 WorkflowFinishEvent {
331 block_height,
332 workflow_id,
333 creator,
334 },
335 )))
336 }
337 "progress-workflow" => {
338 let workflow_id = event
339 .attributes
340 .iter()
341 .find(|attr| attr.key_bytes() == b"workflow-id")
342 .ok_or(Error::MissingEventAttribute("workflow-id"))?
343 .value_str()?
344 .to_string();
345
346 let creator = event
347 .attributes
348 .iter()
349 .find(|attr| attr.key_bytes() == b"creator")
350 .ok_or(Error::MissingEventAttribute("creator"))?
351 .value_str()?
352 .to_string();
353
354 Ok(GevulotEvent::Workflow(WorkflowEvent::Progress(
355 WorkflowProgressEvent {
356 block_height,
357 workflow_id,
358 creator,
359 },
360 )))
361 }
362 "create-pin" => {
363 let cid = event
364 .attributes
365 .iter()
366 .find(|attr| attr.key_bytes() == b"cid")
367 .ok_or(Error::MissingEventAttribute("cid"))?
368 .value_str()?
369 .to_string();
370 let creator = event
371 .attributes
372 .iter()
373 .find(|attr| attr.key_bytes() == b"creator")
374 .ok_or(Error::MissingEventAttribute("creator"))?
375 .value_str()?
376 .to_string();
377 let assigned_workers = event
378 .attributes
379 .iter()
380 .filter(|attr| attr.key_bytes() == b"assigned-workers")
381 .flat_map(|attr| {
382 attr.value_str()
383 .map(|s| {
384 s.split(',')
385 .map(|x| x.trim().to_string())
386 .collect::<Vec<_>>()
387 })
388 .unwrap_or_default()
389 })
390 .collect::<Vec<String>>();
391 let retention_period = event
392 .attributes
393 .iter()
394 .find(|attr| attr.key_bytes() == b"retention-period")
395 .ok_or(Error::MissingEventAttribute("retention-period"))?
396 .value_str()?
397 .parse()
398 .map_err(|_| Error::InvalidEventAttribute("retention-period"))?;
399 let fallback_urls = event
400 .attributes
401 .iter()
402 .filter(|attr| attr.key_bytes() == b"fallback-urls")
403 .flat_map(|attr| {
404 attr.value_str()
405 .map(|s| {
406 s.split(',')
407 .map(|x| x.trim().to_string())
408 .collect::<Vec<_>>()
409 })
410 .unwrap_or_default()
411 })
412 .filter(|url| !url.is_empty())
413 .collect::<Vec<String>>();
414 let id = event
415 .attributes
416 .iter()
417 .find(|attr| attr.key_bytes() == b"id")
418 .map(|attr| attr.value_str().unwrap_or_default().to_string())
419 .unwrap_or_else(|| cid.clone());
420
421 Ok(GevulotEvent::Pin(PinEvent::Create(PinCreateEvent {
422 block_height,
423 cid,
424 creator,
425 assigned_workers,
426 retention_period,
427 fallback_urls,
428 id,
429 })))
430 }
431 "delete-pin" => {
432 let cid = event
433 .attributes
434 .iter()
435 .find(|attr| attr.key_bytes() == b"cid")
436 .ok_or(Error::MissingEventAttribute("cid"))?
437 .value_str()?
438 .to_string();
439 let creator = event
440 .attributes
441 .iter()
442 .find(|attr| attr.key_bytes() == b"creator")
443 .ok_or(Error::MissingEventAttribute("creator"))?
444 .value_str()?
445 .to_string();
446 let id = event
447 .attributes
448 .iter()
449 .find(|attr| attr.key_bytes() == b"id")
450 .map(|attr| attr.value_str().unwrap_or_default().to_string())
451 .unwrap_or_else(|| cid.clone());
452
453 Ok(GevulotEvent::Pin(PinEvent::Delete(PinDeleteEvent {
454 block_height,
455 cid,
456 creator,
457 id,
458 })))
459 }
460 "ack-pin" => {
461 let cid = event
462 .attributes
463 .iter()
464 .find(|attr| attr.key_bytes() == b"cid")
465 .ok_or(Error::MissingEventAttribute("cid"))?
466 .value_str()?
467 .to_string();
468 let worker_id = event
469 .attributes
470 .iter()
471 .find(|attr| attr.key_bytes() == b"worker-id")
472 .ok_or(Error::MissingEventAttribute("worker-id"))?
473 .value_str()?
474 .to_string();
475 let success = event
476 .attributes
477 .iter()
478 .find(|attr| attr.key_bytes() == b"success")
479 .map(|attr| attr.value_str().unwrap_or("true").parse().unwrap_or(true))
480 .unwrap_or(true);
481 let id = event
482 .attributes
483 .iter()
484 .find(|attr| attr.key_bytes() == b"id")
485 .map(|attr| attr.value_str().unwrap_or_default().to_string())
486 .unwrap_or_else(|| cid.clone());
487 Ok(GevulotEvent::Pin(PinEvent::Ack(PinAckEvent {
488 block_height,
489 cid,
490 worker_id,
491 success,
492 id,
493 })))
494 }
495 _ => Err(Error::UnknownEventKind(event.kind.clone())),
496 }
497 }
498}
499
500#[derive(Clone, Debug)]
501pub struct PinCreateEvent {
502 pub block_height: Height,
503 pub cid: String,
504 pub id: String,
505 pub creator: String,
506 pub assigned_workers: Vec<String>,
507 pub retention_period: u64,
508 pub fallback_urls: Vec<String>,
509}
510
511#[derive(Clone, Debug)]
512pub struct PinDeleteEvent {
513 pub block_height: Height,
514 pub cid: String,
515 pub id: String,
516 pub creator: String,
517}
518
519#[derive(Clone, Debug)]
520pub struct PinAckEvent {
521 pub block_height: Height,
522 pub cid: String,
523 pub id: String,
524 pub worker_id: String,
525 pub success: bool,
526}
527
528#[derive(Clone, Debug)]
529pub enum PinEvent {
530 Create(PinCreateEvent),
531 Delete(PinDeleteEvent),
532 Ack(PinAckEvent),
533}
534
535#[derive(Clone, Debug)]
536pub struct TaskCreateEvent {
537 pub block_height: Height,
538 pub task_id: String,
539 pub creator: String,
540 pub assigned_workers: Vec<String>,
541}
542
543#[derive(Clone, Debug)]
544pub struct TaskDeleteEvent {
545 pub block_height: Height,
546 pub task_id: String,
547 pub creator: String,
548}
549
550#[derive(Clone, Debug)]
551pub struct TaskAcceptEvent {
552 pub block_height: Height,
553 pub task_id: String,
554 pub worker_id: String,
555 pub creator: String,
556}
557
558#[derive(Clone, Debug)]
559pub struct TaskDeclineEvent {
560 pub block_height: Height,
561 pub task_id: String,
562 pub worker_id: String,
563 pub creator: String,
564}
565
566#[derive(Clone, Debug)]
567pub struct TaskFinishEvent {
568 pub block_height: Height,
569 pub task_id: String,
570 pub worker_id: String,
571 pub creator: String,
572}
573
574#[derive(Clone, Debug)]
575pub enum TaskEvent {
576 Create(TaskCreateEvent),
577 Delete(TaskDeleteEvent),
578 Accept(TaskAcceptEvent),
579 Decline(TaskDeclineEvent),
580 Finish(TaskFinishEvent),
581}
582
583#[derive(Clone, Debug)]
584pub struct WorkerCreateEvent {
585 pub block_height: Height,
586 pub worker_id: String,
587 pub creator: String,
588}
589
590#[derive(Clone, Debug)]
591pub struct WorkerUpdateEvent {
592 pub block_height: Height,
593 pub worker_id: String,
594 pub creator: String,
595}
596
597#[derive(Clone, Debug)]
598pub struct WorkerDeleteEvent {
599 pub block_height: Height,
600 pub worker_id: String,
601 pub creator: String,
602}
603
604#[derive(Clone, Debug)]
605pub struct WorkerAnnounceExitEvent {
606 pub block_height: Height,
607 pub worker_id: String,
608 pub creator: String,
609}
610
611#[derive(Clone, Debug)]
612pub enum WorkerEvent {
613 Create(WorkerCreateEvent),
614 Update(WorkerUpdateEvent),
615 Delete(WorkerDeleteEvent),
616 AnnounceExit(WorkerAnnounceExitEvent),
617}
618
619#[derive(Clone, Debug)]
620pub struct WorkflowCreateEvent {
621 pub block_height: Height,
622 pub workflow_id: String,
623 pub creator: String,
624}
625
626#[derive(Clone, Debug)]
627pub struct WorkflowDeleteEvent {
628 pub block_height: Height,
629 pub workflow_id: String,
630 pub creator: String,
631}
632
633#[derive(Clone, Debug)]
634pub struct WorkflowProgressEvent {
635 pub block_height: Height,
636 pub workflow_id: String,
637 pub creator: String,
638}
639
640#[derive(Clone, Debug)]
641pub struct WorkflowFinishEvent {
642 pub block_height: Height,
643 pub workflow_id: String,
644 pub creator: String,
645}
646
647#[derive(Clone, Debug)]
648pub enum WorkflowEvent {
649 Create(WorkflowCreateEvent),
650 Delete(WorkflowDeleteEvent),
651 Progress(WorkflowProgressEvent),
652 Finish(WorkflowFinishEvent),
653}
654
655#[cfg(test)]
656mod tests {
657
658 use super::*;
659 use cosmrs::{rpc::dialect::v0_34::EventAttribute, tendermint::abci::Event};
660
661 #[test]
662 fn test_from_cosmos_create_pin() {
663 let event = Event::new(
664 "create-pin",
665 vec![
666 EventAttribute {
667 index: true,
668 key: b"cid".to_vec(),
669 value: b"QmYwMXeEc3Z64vqcPXx8p8Y8Y5tE9Y5sYW42FZ1U87Y".to_vec(),
670 },
671 EventAttribute {
672 index: true,
673 key: b"creator".to_vec(),
674 value: b"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh".to_vec(),
675 },
676 EventAttribute {
677 index: true,
678 key: b"assigned-workers".to_vec(),
679 value: b"1,2,3".to_vec(),
680 },
681 EventAttribute {
682 index: true,
683 key: b"retention-period".to_vec(),
684 value: b"86400".to_vec(),
685 },
686 EventAttribute {
687 index: true,
688 key: b"fallback-urls".to_vec(),
689 value: b"https://example1.com,https://example2.org".to_vec(),
690 },
691 EventAttribute {
692 index: true,
693 key: b"fallback-urls".to_vec(),
694 value: b"https://example3.com".to_vec(),
695 },
696 ],
697 );
698
699 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
700
701 assert!(parsed.is_ok());
702 if let Ok(GevulotEvent::Pin(PinEvent::Create(event))) = parsed {
703 assert_eq!(event.block_height, Height::from(1000u32));
704 assert_eq!(event.cid, "QmYwMXeEc3Z64vqcPXx8p8Y8Y5tE9Y5sYW42FZ1U87Y");
705 assert_eq!(
706 event.creator,
707 "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
708 );
709 assert_eq!(event.assigned_workers, vec!["1", "2", "3"]);
710 assert_eq!(event.retention_period, 86400);
711 assert_eq!(
712 event.fallback_urls,
713 vec![
714 "https://example1.com",
715 "https://example2.org",
716 "https://example3.com"
717 ]
718 );
719 } else {
720 panic!("Unexpected event type");
721 }
722 }
723
724 #[test]
725 fn test_from_cosmos_delete_pin() {
726 let event = Event::new(
727 "delete-pin",
728 vec![
729 EventAttribute {
730 index: true,
731 key: b"cid".to_vec(),
732 value: b"QmYwMXeEc3Z64vqcPXx8p8Y8Y5tE9Y5sYW42FZ1U87Y".to_vec(),
733 },
734 EventAttribute {
735 index: true,
736 key: b"creator".to_vec(),
737 value: b"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh".to_vec(),
738 },
739 ],
740 );
741
742 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
743
744 assert!(parsed.is_ok());
745 if let Ok(GevulotEvent::Pin(PinEvent::Delete(event))) = parsed {
746 assert_eq!(event.block_height, Height::from(1000u32));
747 assert_eq!(event.cid, "QmYwMXeEc3Z64vqcPXx8p8Y8Y5tE9Y5sYW42FZ1U87Y");
748 assert_eq!(
749 event.creator,
750 "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
751 );
752 } else {
753 panic!("Unexpected event type");
754 }
755 }
756
757 #[test]
758 fn test_from_cosmos_ack_pin() {
759 let event = Event::new(
760 "ack-pin",
761 vec![
762 EventAttribute {
763 index: true,
764 key: b"cid".to_vec(),
765 value: b"QmYwMXeEc3Z64vqcPXx8p8Y8Y5tE9Y5sYW42FZ1U87Y".to_vec(),
766 },
767 EventAttribute {
768 index: true,
769 key: b"worker-id".to_vec(),
770 value: b"worker1".to_vec(),
771 },
772 EventAttribute {
773 index: true,
774 key: b"success".to_vec(),
775 value: b"true".to_vec(),
776 },
777 EventAttribute {
778 index: true,
779 key: b"id".to_vec(),
780 value: b"123".to_vec(),
781 },
782 ],
783 );
784
785 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
786
787 assert!(parsed.is_ok());
788 if let Ok(GevulotEvent::Pin(PinEvent::Ack(event))) = parsed {
789 assert_eq!(event.block_height, Height::from(1000u32));
790 assert_eq!(event.cid, "QmYwMXeEc3Z64vqcPXx8p8Y8Y5tE9Y5sYW42FZ1U87Y");
791 assert_eq!(event.worker_id, "worker1");
792 assert!(event.success);
793 assert_eq!(event.id, "123");
794 } else {
795 panic!("Unexpected event type");
796 }
797 }
798
799 #[test]
800 fn test_from_cosmos_create_worker() {
801 let event = Event::new(
802 "create-worker",
803 vec![
804 EventAttribute {
805 index: true,
806 key: b"worker-id".to_vec(),
807 value: b"worker1".to_vec(),
808 },
809 EventAttribute {
810 index: true,
811 key: b"creator".to_vec(),
812 value: b"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh".to_vec(),
813 },
814 ],
815 );
816
817 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
818
819 assert!(parsed.is_ok());
820 if let Ok(GevulotEvent::Worker(WorkerEvent::Create(event))) = parsed {
821 assert_eq!(event.block_height, Height::from(1000u32));
822 assert_eq!(event.worker_id, "worker1");
823 assert_eq!(
824 event.creator,
825 "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
826 );
827 } else {
828 panic!("Unexpected event type");
829 }
830 }
831
832 #[test]
833 fn test_from_cosmos_update_worker() {
834 let event = Event::new(
835 "update-worker",
836 vec![
837 EventAttribute {
838 index: true,
839 key: b"worker-id".to_vec(),
840 value: b"worker1".to_vec(),
841 },
842 EventAttribute {
843 index: true,
844 key: b"creator".to_vec(),
845 value: b"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh".to_vec(),
846 },
847 ],
848 );
849
850 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
851
852 assert!(parsed.is_ok());
853 if let Ok(GevulotEvent::Worker(WorkerEvent::Update(event))) = parsed {
854 assert_eq!(event.block_height, Height::from(1000u32));
855 assert_eq!(event.worker_id, "worker1");
856 assert_eq!(
857 event.creator,
858 "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
859 );
860 } else {
861 panic!("Unexpected event type");
862 }
863 }
864
865 #[test]
866 fn test_from_cosmos_delete_worker() {
867 let event = Event::new(
868 "delete-worker",
869 vec![
870 EventAttribute {
871 index: true,
872 key: b"worker-id".to_vec(),
873 value: b"worker1".to_vec(),
874 },
875 EventAttribute {
876 index: true,
877 key: b"creator".to_vec(),
878 value: b"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh".to_vec(),
879 },
880 ],
881 );
882
883 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
884
885 assert!(parsed.is_ok());
886 if let Ok(GevulotEvent::Worker(WorkerEvent::Delete(event))) = parsed {
887 assert_eq!(event.block_height, Height::from(1000u32));
888 assert_eq!(event.worker_id, "worker1");
889 assert_eq!(
890 event.creator,
891 "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
892 );
893 } else {
894 panic!("Unexpected event type");
895 }
896 }
897
898 #[test]
899 fn test_from_cosmos_announce_worker_exit() {
900 let event = Event::new(
901 "announce-worker-exit",
902 vec![
903 EventAttribute {
904 index: true,
905 key: b"worker-id".to_vec(),
906 value: b"worker1".to_vec(),
907 },
908 EventAttribute {
909 index: true,
910 key: b"creator".to_vec(),
911 value: b"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh".to_vec(),
912 },
913 ],
914 );
915
916 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
917
918 assert!(parsed.is_ok());
919 if let Ok(GevulotEvent::Worker(WorkerEvent::AnnounceExit(event))) = parsed {
920 assert_eq!(event.block_height, Height::from(1000u32));
921 assert_eq!(event.worker_id, "worker1");
922 assert_eq!(
923 event.creator,
924 "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
925 );
926 } else {
927 panic!("Unexpected event type");
928 }
929 }
930
931 #[test]
932 fn test_from_cosmos_create_task() {
933 let event = Event::new(
934 "create-task",
935 vec![
936 EventAttribute {
937 index: true,
938 key: b"task-id".to_vec(),
939 value: b"task1".to_vec(),
940 },
941 EventAttribute {
942 index: true,
943 key: b"creator".to_vec(),
944 value: b"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh".to_vec(),
945 },
946 EventAttribute {
947 index: true,
948 key: b"worker-id".to_vec(),
949 value: b"worker1,worker2".to_vec(),
950 },
951 EventAttribute {
952 index: true,
953 key: b"worker-id".to_vec(),
954 value: b"worker3".to_vec(),
955 },
956 ],
957 );
958
959 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
960
961 assert!(parsed.is_ok());
962 if let Ok(GevulotEvent::Task(TaskEvent::Create(event))) = parsed {
963 assert_eq!(event.block_height, Height::from(1000u32));
964 assert_eq!(event.task_id, "task1");
965 assert_eq!(
966 event.creator,
967 "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
968 );
969 assert_eq!(
970 event.assigned_workers,
971 vec!["worker1", "worker2", "worker3"]
972 );
973 } else {
974 panic!("Unexpected event type");
975 }
976 }
977
978 #[test]
979 fn test_from_cosmos_delete_task() {
980 let event = Event::new(
981 "delete-task",
982 vec![
983 EventAttribute {
984 index: true,
985 key: b"task-id".to_vec(),
986 value: b"task1".to_vec(),
987 },
988 EventAttribute {
989 index: true,
990 key: b"creator".to_vec(),
991 value: b"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh".to_vec(),
992 },
993 ],
994 );
995
996 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
997
998 assert!(parsed.is_ok());
999 if let Ok(GevulotEvent::Task(TaskEvent::Delete(event))) = parsed {
1000 assert_eq!(event.block_height, Height::from(1000u32));
1001 assert_eq!(event.task_id, "task1");
1002 assert_eq!(
1003 event.creator,
1004 "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
1005 );
1006 } else {
1007 panic!("Unexpected event type");
1008 }
1009 }
1010
1011 #[test]
1012 fn test_from_cosmos_finish_task() {
1013 let event = Event::new(
1014 "finish-task",
1015 vec![
1016 EventAttribute {
1017 index: true,
1018 key: b"task-id".to_vec(),
1019 value: b"task1".to_vec(),
1020 },
1021 EventAttribute {
1022 index: true,
1023 key: b"creator".to_vec(),
1024 value: b"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh".to_vec(),
1025 },
1026 EventAttribute {
1027 index: true,
1028 key: b"worker-id".to_vec(),
1029 value: b"worker1".to_vec(),
1030 },
1031 ],
1032 );
1033
1034 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
1035
1036 assert!(parsed.is_ok());
1037 if let Ok(GevulotEvent::Task(TaskEvent::Finish(event))) = parsed {
1038 assert_eq!(event.block_height, Height::from(1000u32));
1039 assert_eq!(event.task_id, "task1");
1040 assert_eq!(
1041 event.creator,
1042 "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
1043 );
1044 assert_eq!(event.worker_id, "worker1");
1045 } else {
1046 panic!("Unexpected event type");
1047 }
1048 }
1049
1050 #[test]
1051 fn test_from_cosmos_create_workflow() {
1052 let event = Event::new(
1053 "create-workflow",
1054 vec![
1055 EventAttribute {
1056 index: true,
1057 key: b"workflow-id".to_vec(),
1058 value: b"workflow1".to_vec(),
1059 },
1060 EventAttribute {
1061 index: true,
1062 key: b"creator".to_vec(),
1063 value: b"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh".to_vec(),
1064 },
1065 ],
1066 );
1067
1068 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
1069
1070 assert!(parsed.is_ok());
1071 if let Ok(GevulotEvent::Workflow(WorkflowEvent::Create(event))) = parsed {
1072 assert_eq!(event.block_height, Height::from(1000u32));
1073 assert_eq!(event.workflow_id, "workflow1");
1074 assert_eq!(
1075 event.creator,
1076 "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
1077 );
1078 } else {
1079 panic!("Unexpected event type");
1080 }
1081 }
1082
1083 #[test]
1084 fn test_from_cosmos_delete_workflow() {
1085 let event = Event::new(
1086 "delete-workflow",
1087 vec![
1088 EventAttribute {
1089 index: true,
1090 key: b"workflow-id".to_vec(),
1091 value: b"workflow1".to_vec(),
1092 },
1093 EventAttribute {
1094 index: true,
1095 key: b"creator".to_vec(),
1096 value: b"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh".to_vec(),
1097 },
1098 ],
1099 );
1100
1101 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
1102
1103 assert!(parsed.is_ok());
1104 if let Ok(GevulotEvent::Workflow(WorkflowEvent::Delete(event))) = parsed {
1105 assert_eq!(event.block_height, Height::from(1000u32));
1106 assert_eq!(event.workflow_id, "workflow1");
1107 assert_eq!(
1108 event.creator,
1109 "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
1110 );
1111 } else {
1112 panic!("Unexpected event type");
1113 }
1114 }
1115
1116 #[test]
1117 fn test_from_cosmos_progress_workflow() {
1118 let event = Event::new(
1119 "progress-workflow",
1120 vec![
1121 EventAttribute {
1122 index: true,
1123 key: b"workflow-id".to_vec(),
1124 value: b"workflow1".to_vec(),
1125 },
1126 EventAttribute {
1127 index: true,
1128 key: b"creator".to_vec(),
1129 value: b"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh".to_vec(),
1130 },
1131 ],
1132 );
1133
1134 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
1135
1136 assert!(parsed.is_ok());
1137 if let Ok(GevulotEvent::Workflow(WorkflowEvent::Progress(event))) = parsed {
1138 assert_eq!(event.block_height, Height::from(1000u32));
1139 assert_eq!(event.workflow_id, "workflow1");
1140 assert_eq!(
1141 event.creator,
1142 "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
1143 );
1144 } else {
1145 panic!("Unexpected event type");
1146 }
1147 }
1148
1149 #[test]
1150 fn test_from_cosmos_finish_workflow() {
1151 let event = Event::new(
1152 "finish-workflow",
1153 vec![
1154 EventAttribute {
1155 index: true,
1156 key: b"workflow-id".to_vec(),
1157 value: b"workflow1".to_vec(),
1158 },
1159 EventAttribute {
1160 index: true,
1161 key: b"creator".to_vec(),
1162 value: b"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh".to_vec(),
1163 },
1164 ],
1165 );
1166
1167 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
1168
1169 assert!(parsed.is_ok());
1170 if let Ok(GevulotEvent::Workflow(WorkflowEvent::Finish(event))) = parsed {
1171 assert_eq!(event.block_height, Height::from(1000u32));
1172 assert_eq!(event.workflow_id, "workflow1");
1173 assert_eq!(
1174 event.creator,
1175 "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
1176 );
1177 } else {
1178 panic!("Unexpected event type");
1179 }
1180 }
1181
1182 #[test]
1183 fn test_from_cosmos_accept_task() {
1184 let event = Event::new(
1185 "accept-task",
1186 vec![
1187 EventAttribute {
1188 index: true,
1189 key: b"task-id".to_vec(),
1190 value: b"task1".to_vec(),
1191 },
1192 EventAttribute {
1193 index: true,
1194 key: b"worker-id".to_vec(),
1195 value: b"worker1".to_vec(),
1196 },
1197 EventAttribute {
1198 index: true,
1199 key: b"creator".to_vec(),
1200 value: b"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh".to_vec(),
1201 },
1202 ],
1203 );
1204
1205 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
1206
1207 assert!(parsed.is_ok());
1208 if let Ok(GevulotEvent::Task(TaskEvent::Accept(event))) = parsed {
1209 assert_eq!(event.block_height, Height::from(1000u32));
1210 assert_eq!(event.task_id, "task1");
1211 assert_eq!(event.worker_id, "worker1");
1212 assert_eq!(
1213 event.creator,
1214 "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
1215 );
1216 } else {
1217 panic!("Unexpected event type");
1218 }
1219 }
1220
1221 #[test]
1222 fn test_from_cosmos_decline_task() {
1223 let event = Event::new(
1224 "decline-task",
1225 vec![
1226 EventAttribute {
1227 index: true,
1228 key: b"task-id".to_vec(),
1229 value: b"task1".to_vec(),
1230 },
1231 EventAttribute {
1232 index: true,
1233 key: b"worker-id".to_vec(),
1234 value: b"worker1".to_vec(),
1235 },
1236 EventAttribute {
1237 index: true,
1238 key: b"creator".to_vec(),
1239 value: b"cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh".to_vec(),
1240 },
1241 ],
1242 );
1243
1244 let parsed = GevulotEvent::from_cosmos(&event, Height::from(1000u32));
1245
1246 assert!(parsed.is_ok());
1247 if let Ok(GevulotEvent::Task(TaskEvent::Decline(event))) = parsed {
1248 assert_eq!(event.block_height, Height::from(1000u32));
1249 assert_eq!(event.task_id, "task1");
1250 assert_eq!(event.worker_id, "worker1");
1251 assert_eq!(
1252 event.creator,
1253 "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
1254 );
1255 } else {
1256 panic!("Unexpected event type");
1257 }
1258 }
1259}