viewstamped_replication/
service.rs

1use serde::{Deserialize, Serialize};
2
3pub trait Payload: Clone + Serialize + Deserialize<'static> {}
4
5impl<P> Payload for P where P: Clone + Serialize + Deserialize<'static> {}
6
7/// A trait to associate all the necessary types together.
8/// All associated types must be serializable and not borrow data since replicas need to store these values.
9pub trait Protocol {
10    type Request: Payload;
11    type Prediction: Payload;
12    type Reply: Payload;
13    type Checkpoint: Payload;
14}
15
16pub trait Service: Protocol + From<<Self as Protocol>::Checkpoint> {
17    fn predict(&self, request: &<Self as Protocol>::Request) -> <Self as Protocol>::Prediction;
18
19    fn checkpoint(&self) -> <Self as Protocol>::Checkpoint;
20
21    fn invoke(
22        &mut self,
23        request: &<Self as Protocol>::Request,
24        prediction: &<Self as Protocol>::Prediction,
25    ) -> <Self as Protocol>::Reply;
26}
27
28#[cfg(test)]
29mod tests {
30    use super::*;
31
32    impl Protocol for i32 {
33        type Request = Self;
34        type Prediction = ();
35        type Reply = Self;
36        type Checkpoint = Self;
37    }
38
39    impl Service for i32 {
40        fn predict(&self, _: &<Self as Protocol>::Request) -> <Self as Protocol>::Prediction {
41            ()
42        }
43
44        fn checkpoint(&self) -> <Self as Protocol>::Checkpoint {
45            *self
46        }
47
48        fn invoke(
49            &mut self,
50            request: &<Self as Protocol>::Request,
51            _: &<Self as Protocol>::Prediction,
52        ) -> <Self as Protocol>::Reply {
53            *self += *request;
54            *self
55        }
56    }
57
58    #[test]
59    fn adder() {
60        let mut service = 0;
61
62        assert_eq!(service.predict(&42), ());
63        assert_eq!(service.checkpoint(), service);
64        assert_eq!(service.invoke(&45, &()), 45);
65        assert_eq!(service.invoke(&-3, &()), 42);
66        assert_eq!(service.checkpoint(), service);
67        assert_eq!(service.checkpoint(), 42);
68    }
69}