node/recorder/
mod.rs

1#[allow(clippy::module_inception)]
2mod recorder;
3pub use recorder::Recorder;
4
5mod replayer;
6pub use replayer::StateWithInputActionsReader;
7
8use std::{
9    borrow::Cow,
10    io::Write,
11    path::{Path, PathBuf},
12};
13
14use serde::{Deserialize, Serialize};
15
16use crate::{p2p::identity::SecretKey as P2pSecretKey, Action, ActionKind, ActionWithMeta, State};
17
18fn initial_state_path<P: AsRef<Path>>(path: P) -> PathBuf {
19    path.as_ref().join("initial_state.postcard")
20}
21
22fn actions_path<P: AsRef<Path>>(path: P, file_index: usize) -> PathBuf {
23    path.as_ref()
24        .join(format!("actions_{}.postcard", file_index))
25}
26
27#[derive(Serialize, Deserialize)]
28pub struct RecordedInitialState<'a> {
29    pub rng_seed: [u8; 32],
30    pub p2p_sec_key: P2pSecretKey,
31    pub state: Cow<'a, State>,
32}
33
34impl RecordedInitialState<'_> {
35    pub fn write_to<W: Write>(&self, writer: &mut W) -> postcard::Result<()> {
36        postcard::to_io(self, writer).and(Ok(()))
37    }
38
39    pub fn decode(encoded: &[u8]) -> postcard::Result<Self> {
40        postcard::from_bytes(encoded)
41    }
42}
43
44#[derive(Serialize, Deserialize, Debug)]
45pub struct RecordedActionWithMeta<'a> {
46    pub kind: ActionKind,
47    pub meta: redux::ActionMeta,
48    pub action: Option<Cow<'a, Action>>,
49}
50
51impl RecordedActionWithMeta<'_> {
52    pub fn encode(&self) -> postcard::Result<Vec<u8>> {
53        postcard::to_stdvec(self)
54    }
55
56    pub fn decode(encoded: &[u8]) -> postcard::Result<Self> {
57        postcard::from_bytes(encoded)
58    }
59
60    pub fn as_action_with_meta(self) -> Result<ActionWithMeta, Self> {
61        if self.action.is_some() {
62            let action = self.action.unwrap().into_owned();
63            Ok(self.meta.with_action(action))
64        } else {
65            Err(self)
66        }
67    }
68}
69
70impl<'a> From<&'a ActionWithMeta> for RecordedActionWithMeta<'a> {
71    fn from(value: &'a ActionWithMeta) -> Self {
72        Self {
73            kind: value.action().kind(),
74            meta: value.meta().clone(),
75            action: Some(Cow::Borrowed(value.action())),
76        }
77    }
78}
79
80impl From<(ActionKind, redux::ActionMeta)> for RecordedActionWithMeta<'static> {
81    fn from((kind, meta): (ActionKind, redux::ActionMeta)) -> Self {
82        Self {
83            kind,
84            meta,
85            action: None,
86        }
87    }
88}