pallas_chainsync/
codec.rs

1use pallas_machines::{
2    primitives::Point, CodecError, DecodePayload, EncodePayload, PayloadDecoder, PayloadEncoder,
3};
4
5use crate::{Message, Tip};
6
7impl EncodePayload for Tip {
8    fn encode_payload(&self, e: &mut PayloadEncoder) -> Result<(), Box<dyn std::error::Error>> {
9        e.array(2)?;
10        self.0.encode_payload(e)?;
11        e.u64(self.1)?;
12
13        Ok(())
14    }
15}
16
17impl DecodePayload for Tip {
18    fn decode_payload(d: &mut PayloadDecoder) -> Result<Self, Box<dyn std::error::Error>> {
19        d.array()?;
20        let point = Point::decode_payload(d)?;
21        let block_num = d.u64()?;
22
23        Ok(Tip(point, block_num))
24    }
25}
26
27impl<C> EncodePayload for Message<C>
28where
29    C: EncodePayload + DecodePayload,
30{
31    fn encode_payload(&self, e: &mut PayloadEncoder) -> Result<(), Box<dyn std::error::Error>> {
32        match self {
33            Message::RequestNext => {
34                e.array(1)?.u16(0)?;
35                Ok(())
36            }
37            Message::AwaitReply => {
38                e.array(1)?.u16(1)?;
39                Ok(())
40            }
41            Message::RollForward(header, tip) => {
42                e.array(3)?.u16(2)?;
43                header.encode_payload(e)?;
44                tip.encode_payload(e)?;
45                Ok(())
46            }
47            Message::RollBackward(point, tip) => {
48                e.array(3)?.u16(3)?;
49                point.encode_payload(e)?;
50                tip.encode_payload(e)?;
51                Ok(())
52            }
53            Message::FindIntersect(points) => {
54                e.array(2)?.u16(4)?;
55                e.array(points.len() as u64)?;
56                for point in points.iter() {
57                    point.encode_payload(e)?;
58                }
59                Ok(())
60            }
61            Message::IntersectFound(point, tip) => {
62                e.array(3)?.u16(5)?;
63                point.encode_payload(e)?;
64                tip.encode_payload(e)?;
65                Ok(())
66            }
67            Message::IntersectNotFound(tip) => {
68                e.array(1)?.u16(6)?;
69                tip.encode_payload(e)?;
70                Ok(())
71            }
72            Message::Done => {
73                e.array(1)?.u16(7)?;
74                Ok(())
75            }
76        }
77    }
78}
79
80impl<C> DecodePayload for Message<C>
81where
82    C: EncodePayload + DecodePayload,
83{
84    fn decode_payload(d: &mut PayloadDecoder) -> Result<Self, Box<dyn std::error::Error>> {
85        d.array()?;
86        let label = d.u16()?;
87
88        match label {
89            0 => Ok(Message::RequestNext),
90            1 => Ok(Message::AwaitReply),
91            2 => {
92                let content = C::decode_payload(d)?;
93                let tip = Tip::decode_payload(d)?;
94                Ok(Message::RollForward(content, tip))
95            }
96            3 => {
97                let point = Point::decode_payload(d)?;
98                let tip = Tip::decode_payload(d)?;
99                Ok(Message::RollBackward(point, tip))
100            }
101            4 => {
102                let points = Vec::<Point>::decode_payload(d)?;
103                Ok(Message::FindIntersect(points))
104            }
105            5 => {
106                let point = Point::decode_payload(d)?;
107                let tip = Tip::decode_payload(d)?;
108                Ok(Message::IntersectFound(point, tip))
109            }
110            6 => {
111                let tip = Tip::decode_payload(d)?;
112                Ok(Message::IntersectNotFound(tip))
113            }
114            7 => Ok(Message::Done),
115            x => Err(Box::new(CodecError::BadLabel(x))),
116        }
117    }
118}