pallas_network/miniprotocols/chainsync/
codec.rs1use 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()?; match variant {
136 0 => {
138 d.array()?;
139
140 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 _ => {
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 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}