hotshot_task_impls/
rewind.rs1use std::{fs::OpenOptions, io::Write, sync::Arc};
8
9use async_broadcast::{Receiver, Sender};
10use async_trait::async_trait;
11use hotshot_task::task::TaskState;
12use hotshot_types::traits::node_implementation::NodeType;
13use hotshot_utils::anytrace::Result;
14
15use crate::events::HotShotEvent;
16
17pub struct RewindTaskState<TYPES: NodeType> {
20 pub events: Vec<Arc<HotShotEvent<TYPES>>>,
22
23 pub id: u64,
25}
26
27impl<TYPES: NodeType> RewindTaskState<TYPES> {
28 pub fn handle(&mut self, event: &Arc<HotShotEvent<TYPES>>) {
30 self.events.push(Arc::clone(event));
31 }
32}
33
34#[async_trait]
35impl<TYPES: NodeType> TaskState for RewindTaskState<TYPES> {
36 type Event = HotShotEvent<TYPES>;
37
38 async fn handle_event(
39 &mut self,
40 event: Arc<Self::Event>,
41 _sender: &Sender<Arc<Self::Event>>,
42 _receiver: &Receiver<Arc<Self::Event>>,
43 ) -> Result<()> {
44 self.handle(&event);
45 Ok(())
46 }
47
48 fn cancel_subtasks(&mut self) {
49 tracing::info!("Node ID {} Recording {} events", self.id, self.events.len());
50 let filename = format!("rewind_{}.log", self.id);
51 let mut file = match OpenOptions::new()
52 .write(true)
53 .create(true)
54 .truncate(true)
55 .open(&filename)
56 {
57 Ok(file) => file,
58 Err(e) => {
59 tracing::error!("Failed to write file {filename}; error = {e}");
60 return;
61 },
62 };
63
64 for (event_number, event) in self.events.iter().enumerate() {
65 if let Err(e) = writeln!(file, "{event_number}: {event}") {
67 tracing::error!(
68 "Failed to write event number {event_number} and event {event}; error = {e}"
69 );
70 }
71 }
72 }
73}