1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
pub mod rpc;
use crate::{prelude::verify::TxErr, serializer::*};
use std::io::{self, Cursor, Error};
#[derive(Clone, Debug, PartialEq)]
pub struct Msg {
pub id: u32,
pub body: Body,
}
impl Msg {
pub fn serialize(&self, buf: &mut Vec<u8>) {
buf.push_u32(self.id);
match &self.body {
Body::Error(e) => {
buf.push(BodyType::Error as u8);
e.serialize(buf);
}
Body::Request(req) => {
buf.push(BodyType::Request as u8);
req.serialize(buf);
}
Body::Response(res) => {
buf.push(BodyType::Response as u8);
res.serialize(buf);
}
Body::Ping(nonce) => {
buf.reserve_exact(9);
buf.push(BodyType::Ping as u8);
buf.push_u64(*nonce);
}
Body::Pong(nonce) => {
buf.reserve_exact(9);
buf.push(BodyType::Pong as u8);
buf.push_u64(*nonce);
}
}
}
pub fn deserialize(cursor: &mut Cursor<&[u8]>) -> io::Result<Self> {
let id = cursor.take_u32()?;
let body = match cursor.take_u8()? {
t if t == BodyType::Error as u8 => Body::Error(ErrorKind::deserialize(cursor)?),
t if t == BodyType::Request as u8 => Body::Request(rpc::Request::deserialize(cursor)?),
t if t == BodyType::Response as u8 => {
Body::Response(rpc::Response::deserialize(cursor)?)
}
t if t == BodyType::Ping as u8 => Body::Ping(cursor.take_u64()?),
t if t == BodyType::Pong as u8 => Body::Pong(cursor.take_u64()?),
_ => return Err(Error::new(io::ErrorKind::InvalidData, "invalid msg type")),
};
Ok(Self { id, body })
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[repr(u8)]
pub enum BodyType {
Error = 0x00,
Request = 0x01,
Response = 0x02,
Ping = 0x03,
Pong = 0x04,
}
#[derive(Clone, Debug, PartialEq)]
pub enum Body {
Error(ErrorKind),
Request(rpc::Request),
Response(rpc::Response),
Ping(u64),
Pong(u64),
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ErrorKind {
Io,
BytesRemaining,
InvalidRequest,
InvalidHeight,
TxValidation(TxErr),
}
impl ErrorKind {
fn serialize(self, buf: &mut Vec<u8>) {
match self {
Self::Io => buf.push(0x00),
Self::BytesRemaining => buf.push(0x01),
Self::InvalidRequest => buf.push(0x02),
Self::InvalidHeight => buf.push(0x03),
Self::TxValidation(err) => {
buf.reserve_exact(2048);
buf.push(0x04);
err.serialize(buf);
}
}
}
fn deserialize(cursor: &mut Cursor<&[u8]>) -> io::Result<Self> {
let tag = cursor.take_u8()?;
Ok(match tag {
0x00 => Self::Io,
0x01 => Self::BytesRemaining,
0x02 => Self::InvalidRequest,
0x03 => Self::InvalidHeight,
0x04 => Self::TxValidation(TxErr::deserialize(cursor)?),
_ => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"failed to deserialize ErrorKind",
))
}
})
}
}