Skip to main content

arc_malachitebft_sync/
types.rs

1use std::{ops::RangeInclusive, sync::Arc};
2
3use bytes::Bytes;
4use derive_where::derive_where;
5use displaydoc::Display;
6use libp2p::request_response;
7use serde::{Deserialize, Serialize};
8
9use malachitebft_core_types::ValueResponse as CoreValueResponse;
10use malachitebft_core_types::{CommitCertificate, Context, Height};
11
12pub use malachitebft_peer::PeerId;
13
14/// Indicates whether the height is the start of a new height or a restart of the latest height
15#[derive(Copy, Clone, Debug, PartialEq, Eq)]
16pub enum HeightStartType {
17    /// This is the start of a new height
18    Start,
19
20    /// This is a restart of the latest height
21    Restart,
22}
23
24impl HeightStartType {
25    pub const fn from_is_restart(is_restart: bool) -> Self {
26        if is_restart {
27            Self::Restart
28        } else {
29            Self::Start
30        }
31    }
32
33    pub const fn is_start(&self) -> bool {
34        matches!(self, Self::Start)
35    }
36
37    pub const fn is_restart(&self) -> bool {
38        matches!(self, Self::Restart)
39    }
40}
41
42#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
43#[displaydoc("{0}")]
44pub struct InboundRequestId(Arc<str>);
45
46impl InboundRequestId {
47    pub fn new(id: impl ToString) -> Self {
48        Self(Arc::from(id.to_string()))
49    }
50}
51
52#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Display)]
53#[displaydoc("{0}")]
54pub struct OutboundRequestId(Arc<str>);
55
56impl OutboundRequestId {
57    pub fn new(id: impl ToString) -> Self {
58        Self(Arc::from(id.to_string()))
59    }
60}
61
62pub type ResponseChannel = request_response::ResponseChannel<RawResponse>;
63
64#[derive_where(Clone, Debug, PartialEq, Eq)]
65pub struct Status<Ctx: Context> {
66    pub peer_id: PeerId,
67    pub tip_height: Ctx::Height,
68    pub history_min_height: Ctx::Height,
69}
70
71#[derive_where(Clone, Debug, PartialEq, Eq)]
72pub enum Request<Ctx: Context> {
73    ValueRequest(ValueRequest<Ctx>),
74}
75
76#[derive_where(Clone, Debug, PartialEq, Eq)]
77pub enum Response<Ctx: Context> {
78    ValueResponse(ValueResponse<Ctx>),
79}
80
81#[derive_where(Clone, Debug, PartialEq, Eq)]
82pub struct ValueRequest<Ctx: Context> {
83    pub range: RangeInclusive<Ctx::Height>,
84}
85
86impl<Ctx: Context> ValueRequest<Ctx> {
87    pub fn new(range: RangeInclusive<Ctx::Height>) -> Self {
88        Self { range }
89    }
90}
91
92#[derive_where(Clone, Debug, PartialEq, Eq)]
93pub struct ValueResponse<Ctx: Context> {
94    /// The height of the first value in the response.
95    pub start_height: Ctx::Height,
96
97    /// Values are sequentially ordered by height.
98    pub values: Vec<RawDecidedValue<Ctx>>,
99}
100
101impl<Ctx: Context> ValueResponse<Ctx> {
102    pub fn new(start_height: Ctx::Height, values: Vec<RawDecidedValue<Ctx>>) -> Self {
103        Self {
104            start_height,
105            values,
106        }
107    }
108
109    pub fn end_height(&self) -> Option<Ctx::Height> {
110        if self.values.is_empty() {
111            None
112        } else {
113            Some(self.start_height.increment_by(self.values.len() as u64 - 1))
114        }
115    }
116}
117
118#[derive_where(Clone, Debug, PartialEq, Eq)]
119pub struct RawDecidedValue<Ctx: Context> {
120    pub value_bytes: Bytes,
121    pub certificate: CommitCertificate<Ctx>,
122}
123
124impl<Ctx: Context> RawDecidedValue<Ctx> {
125    pub fn new(value_bytes: Bytes, certificate: CommitCertificate<Ctx>) -> Self {
126        Self {
127            value_bytes,
128            certificate,
129        }
130    }
131
132    pub fn height(&self) -> Ctx::Height {
133        self.certificate.height
134    }
135
136    pub fn to_core(self, peer: PeerId) -> CoreValueResponse<Ctx> {
137        CoreValueResponse::new(peer, self.value_bytes, self.certificate)
138    }
139}
140
141#[derive(Clone, Debug)]
142pub enum RawMessage {
143    Request {
144        request_id: request_response::InboundRequestId,
145        peer: PeerId,
146        body: Bytes,
147    },
148    Response {
149        request_id: request_response::OutboundRequestId,
150        peer: PeerId,
151        body: Bytes,
152    },
153}
154
155#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
156pub struct RawRequest(pub Bytes);
157
158#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
159pub struct RawResponse(pub Bytes);