massa_execution_exports/
event_store.rs1use massa_models::execution::EventFilter;
7use massa_models::output_event::SCOutputEvent;
8use serde::Serialize;
9use std::collections::VecDeque;
10
11#[derive(Default, Debug, Clone, Serialize)]
13pub struct EventStore(pub VecDeque<SCOutputEvent>);
14
15impl EventStore {
16 pub fn push(&mut self, event: SCOutputEvent) {
18 self.0.push_back(event);
19 }
20
21 pub fn take(&mut self) -> VecDeque<SCOutputEvent> {
23 std::mem::take(&mut self.0)
24 }
25
26 pub fn clear(&mut self) {
28 self.0.clear()
29 }
30
31 pub fn prune(&mut self, max_events: usize) {
33 while self.0.len() > max_events {
34 self.0.pop_front();
35 }
36 }
37
38 pub fn extend(&mut self, other: EventStore) {
40 self.0.extend(other.0);
41 }
42
43 pub fn finalize(&mut self) {
45 for output in self.0.iter_mut() {
46 output.context.is_final = true;
47 }
48 }
49
50 pub fn get_filtered_sc_output_events(&self, filter: &EventFilter) -> VecDeque<SCOutputEvent> {
58 self.get_filtered_sc_output_events_iter(filter)
59 .cloned()
60 .collect()
61 }
62
63 pub fn get_filtered_sc_output_events_iter<'b, 'a: 'b>(
65 &'a self,
66 filter: &'b EventFilter,
67 ) -> impl Iterator<Item = &'a SCOutputEvent> + 'b {
68 self.0.iter().filter(|x| {
74 if let Some(start) = filter.start {
75 if x.context.slot < start {
76 return false;
77 }
78 }
79 if let Some(end) = filter.end {
80 if x.context.slot >= end {
81 return false;
82 }
83 }
84 if let Some(is_final) = filter.is_final {
85 if x.context.is_final != is_final {
86 return false;
87 }
88 }
89 if let Some(is_error) = filter.is_error {
90 if x.context.is_error != is_error {
91 return false;
92 }
93 }
94
95 match (filter.original_caller_address, x.context.call_stack.front()) {
96 (Some(addr1), Some(addr2)) if addr1 != *addr2 => return false,
97 (Some(_), None) => return false,
98 _ => (),
99 }
100 match (filter.emitter_address, x.context.call_stack.back()) {
101 (Some(addr1), Some(addr2)) if addr1 != *addr2 => return false,
102 (Some(_), None) => return false,
103 _ => (),
104 }
105 match (filter.original_operation_id, x.context.origin_operation_id) {
106 (Some(addr1), Some(addr2)) if addr1 != addr2 => return false,
107 (Some(_), None) => return false,
108 _ => (),
109 }
110
111 true
112 })
113 }
114}
115
116#[test]
117fn test_prune() {
118 use massa_models::output_event::{EventExecutionContext, SCOutputEvent};
119 use massa_models::slot::Slot;
120
121 let mut store = EventStore(VecDeque::new());
122 for i in 0..10 {
123 store.push(SCOutputEvent {
124 context: EventExecutionContext {
125 slot: Slot::new(i, 0),
126 block: None,
127 read_only: false,
128 index_in_slot: 1,
129 call_stack: VecDeque::new(),
130 origin_operation_id: None,
131 is_final: false,
132 is_error: false,
133 deferred_call_id: None,
134 async_msg_id: None,
135 },
136 data: i.to_string(),
137 });
138 }
139 assert_eq!(store.0.len(), 10);
140 store.prune(3);
141 assert_eq!(store.0.len(), 3);
142 assert_eq!(store.0[2].data, "9");
143 assert_eq!(store.0[1].data, "8");
144 assert_eq!(store.0[0].data, "7");
145}