pallas_network/miniprotocols/chainsync/
codec.rs

1use pallas_codec::minicbor;
2use pallas_codec::minicbor::encode::Error;
3use pallas_codec::minicbor::{decode, encode, Decode, Decoder, Encode, Encoder};
4
5use super::{BlockContent, HeaderContent, Message, SkippedContent, Tip};
6
7impl minicbor::encode::Encode<()> for Tip {
8    fn encode<W: encode::Write>(
9        &self,
10        e: &mut Encoder<W>,
11        _ctx: &mut (),
12    ) -> Result<(), encode::Error<W::Error>> {
13        e.array(2)?;
14        e.encode(&self.0)?;
15        e.u64(self.1)?;
16
17        Ok(())
18    }
19}
20
21impl<'b> Decode<'b, ()> for Tip {
22    fn decode(d: &mut Decoder<'b>, _ctx: &mut ()) -> Result<Self, decode::Error> {
23        d.array()?;
24        let point = d.decode()?;
25        let block_num = d.u64()?;
26
27        Ok(Tip(point, block_num))
28    }
29}
30
31impl<C> Encode<()> for Message<C>
32where
33    C: Encode<()>,
34{
35    fn encode<W: encode::Write>(
36        &self,
37        e: &mut Encoder<W>,
38        _ctx: &mut (),
39    ) -> Result<(), encode::Error<W::Error>> {
40        match self {
41            Message::RequestNext => {
42                e.array(1)?.u16(0)?;
43                Ok(())
44            }
45            Message::AwaitReply => {
46                e.array(1)?.u16(1)?;
47                Ok(())
48            }
49            Message::RollForward(content, tip) => {
50                e.array(3)?.u16(2)?;
51                e.encode(content)?;
52                e.encode(tip)?;
53                Ok(())
54            }
55            Message::RollBackward(point, tip) => {
56                e.array(3)?.u16(3)?;
57                e.encode(point)?;
58                e.encode(tip)?;
59                Ok(())
60            }
61            Message::FindIntersect(points) => {
62                e.array(2)?.u16(4)?;
63                e.array(points.len() as u64)?;
64                for point in points.iter() {
65                    e.encode(point)?;
66                }
67                Ok(())
68            }
69            Message::IntersectFound(point, tip) => {
70                e.array(3)?.u16(5)?;
71                e.encode(point)?;
72                e.encode(tip)?;
73                Ok(())
74            }
75            Message::IntersectNotFound(tip) => {
76                e.array(1)?.u16(6)?;
77                e.encode(tip)?;
78                Ok(())
79            }
80            Message::Done => {
81                e.array(1)?.u16(7)?;
82                Ok(())
83            }
84        }
85    }
86}
87
88impl<'b, C> Decode<'b, ()> for Message<C>
89where
90    C: Decode<'b, ()>,
91{
92    fn decode(d: &mut Decoder<'b>, _ctx: &mut ()) -> Result<Self, decode::Error> {
93        d.array()?;
94        let label = d.u16()?;
95
96        match label {
97            0 => Ok(Message::RequestNext),
98            1 => Ok(Message::AwaitReply),
99            2 => {
100                let content = d.decode()?;
101                let tip = d.decode()?;
102                Ok(Message::RollForward(content, tip))
103            }
104            3 => {
105                let point = d.decode()?;
106                let tip = d.decode()?;
107                Ok(Message::RollBackward(point, tip))
108            }
109            4 => {
110                let points = d.decode()?;
111                Ok(Message::FindIntersect(points))
112            }
113            5 => {
114                let point = d.decode()?;
115                let tip = d.decode()?;
116                Ok(Message::IntersectFound(point, tip))
117            }
118            6 => {
119                let tip = d.decode()?;
120                Ok(Message::IntersectNotFound(tip))
121            }
122            7 => Ok(Message::Done),
123            _ => Err(decode::Error::message(
124                "unknown variant for chainsync message",
125            )),
126        }
127    }
128}
129
130impl<'b> Decode<'b, ()> for HeaderContent {
131    fn decode(d: &mut Decoder<'b>, _ctx: &mut ()) -> Result<Self, decode::Error> {
132        d.array()?;
133        let variant = d.u8()?; // era variant
134
135        match variant {
136            // byron
137            0 => {
138                d.array()?;
139
140                // can't find a reference anywhere about the structure of these values, but they
141                // seem to provide the Byron-specific variant of the header
142                let (a, b): (u8, u64) = d.decode()?;
143
144                d.tag()?;
145                let bytes = d.bytes()?;
146
147                Ok(HeaderContent {
148                    variant,
149                    byron_prefix: Some((a, b)),
150                    cbor: Vec::from(bytes),
151                })
152            }
153            // shelley and beyond
154            _ => {
155                d.tag()?;
156                let bytes = d.bytes()?;
157
158                Ok(HeaderContent {
159                    variant,
160                    byron_prefix: None,
161                    cbor: Vec::from(bytes),
162                })
163            }
164        }
165    }
166}
167
168impl Encode<()> for HeaderContent {
169    fn encode<W: encode::Write>(
170        &self,
171        e: &mut Encoder<W>,
172        _ctx: &mut (),
173    ) -> Result<(), encode::Error<W::Error>> {
174        e.array(2)?;
175        e.u8(self.variant)?;
176
177        // variant 0 is byron
178        if self.variant == 0 {
179            e.array(2)?;
180
181            if let Some((a, b)) = self.byron_prefix {
182                e.array(2)?;
183                e.u8(a)?;
184                e.u64(b)?;
185            } else {
186                return Err(Error::message("header variant 0 but no byron prefix"));
187            }
188
189            e.tag(minicbor::data::IanaTag::Cbor)?;
190            e.bytes(&self.cbor)?;
191        } else {
192            e.tag(minicbor::data::IanaTag::Cbor)?;
193            e.bytes(&self.cbor)?;
194        }
195
196        Ok(())
197    }
198}
199
200impl<'b> Decode<'b, ()> for BlockContent {
201    fn decode(d: &mut Decoder<'b>, _ctx: &mut ()) -> Result<Self, decode::Error> {
202        d.tag()?;
203        let bytes = d.bytes()?;
204        Ok(BlockContent(Vec::from(bytes)))
205    }
206}
207
208impl Encode<()> for BlockContent {
209    fn encode<W: encode::Write>(
210        &self,
211        e: &mut Encoder<W>,
212        _ctx: &mut (),
213    ) -> Result<(), encode::Error<W::Error>> {
214        e.tag(minicbor::data::IanaTag::Cbor)?;
215        e.bytes(&self.0)?;
216
217        Ok(())
218    }
219}
220
221impl<'b> Decode<'b, ()> for SkippedContent {
222    fn decode(d: &mut Decoder<'b>, _ctx: &mut ()) -> Result<Self, decode::Error> {
223        d.skip()?;
224        Ok(SkippedContent)
225    }
226}
227
228impl Encode<()> for SkippedContent {
229    fn encode<W: encode::Write>(
230        &self,
231        e: &mut Encoder<W>,
232        _ctx: &mut (),
233    ) -> Result<(), encode::Error<W::Error>> {
234        e.null()?;
235
236        Ok(())
237    }
238}