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
use shared::{Deserializable, DeserializationError, Serializable};
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Command {
Version,
Verack,
GetBlocks,
GetData,
Block,
GetHeaders,
Headers,
Inv,
MemPool,
MerkleBlock,
CmpctBlock,
GetBlockTxn,
BlockTxn,
SendCmpct,
NotFound,
Tx,
Addr,
Alert,
FeeFilter,
FilterAdd,
FilterClear,
FilterLoad,
GetAddr,
Ping,
Pong,
Reject,
SendHeaders,
}
impl Command {
pub fn bytes(&self) -> &[u8; 12] {
match self {
Command::Version => b"version\0\0\0\0\0",
Command::Verack => b"verack\0\0\0\0\0\0",
Command::GetBlocks => b"getblocks\0\0\0",
Command::GetData => b"getdata\0\0\0\0\0",
Command::Block => b"block\0\0\0\0\0\0\0",
Command::GetHeaders => b"getheaders\0\0",
Command::BlockTxn => b"blocktxn\0\0\0\0",
Command::CmpctBlock => b"cmpctblock\0\0",
Command::Headers => b"headers\0\0\0\0\0",
Command::Inv => b"inv\0\0\0\0\0\0\0\0\0",
Command::MemPool => b"mempool\0\0\0\0\0",
Command::MerkleBlock => b"merkleblock\0",
Command::SendCmpct => b"sendcmpct\0\0\0",
Command::GetBlockTxn => b"getblocktxn\0",
Command::NotFound => b"notfound\0\0\0\0",
Command::Tx => b"tx\0\0\0\0\0\0\0\0\0\0",
Command::Addr => b"addr\0\0\0\0\0\0\0\0",
Command::Alert => b"alert\0\0\0\0\0\0\0",
Command::FeeFilter => b"feefilter\0\0\0",
Command::FilterAdd => b"filteradd\0\0\0",
Command::FilterClear => b"filterclear\0",
Command::FilterLoad => b"filterload\0\0",
Command::GetAddr => b"getaddr\0\0\0\0\0",
Command::Ping => b"ping\0\0\0\0\0\0\0\0",
Command::Pong => b"pong\0\0\0\0\0\0\0\0",
Command::Reject => b"reject\0\0\0\0\0\0",
Command::SendHeaders => b"sendheaders\0",
}
}
}
impl Serializable for Command {
fn serialize<W>(&self, target: &mut W) -> Result<(), std::io::Error>
where
W: std::io::Write,
{
target.write_all(self.bytes())
}
}
impl Deserializable for Command {
fn deserialize<T>(reader: &mut T) -> Result<Command, DeserializationError>
where
T: std::io::Read,
{
let mut buf = [0u8; 12];
reader.read_exact(&mut buf)?;
let command = match &buf {
b"version\0\0\0\0\0" => Command::Version,
b"verack\0\0\0\0\0\0" => Command::Verack,
b"getblocks\0\0\0" => Command::GetBlocks,
b"getdata\0\0\0\0\0" => Command::GetData,
b"block\0\0\0\0\0\0\0" => Command::Block,
b"getheaders\0\0" => Command::GetHeaders,
b"blocktxn\0\0\0\0" => Command::BlockTxn,
b"cmpctblock\0\0" => Command::CmpctBlock,
b"headers\0\0\0\0\0" => Command::Headers,
b"inv\0\0\0\0\0\0\0\0\0" => Command::Inv,
b"mempool\0\0\0\0\0" => Command::MemPool,
b"merkleblock\0" => Command::MerkleBlock,
b"sendcmpct\0\0\0" => Command::SendCmpct,
b"getblocktxn\0" => Command::GetBlockTxn,
b"notfound\0\0\0\0" => Command::NotFound,
b"tx\0\0\0\0\0\0\0\0\0\0" => Command::Tx,
b"addr\0\0\0\0\0\0\0\0" => Command::Addr,
b"alert\0\0\0\0\0\0\0" => Command::Alert,
b"feefilter\0\0\0" => Command::FeeFilter,
b"filteradd\0\0\0" => Command::FilterAdd,
b"filterclear\0" => Command::FilterClear,
b"filterload\0\0" => Command::FilterLoad,
b"getaddr\0\0\0\0\0" => Command::GetAddr,
b"ping\0\0\0\0\0\0\0\0" => Command::Ping,
b"pong\0\0\0\0\0\0\0\0" => Command::Pong,
b"reject\0\0\0\0\0\0" => Command::Reject,
b"sendheaders\0" => Command::SendHeaders,
_ => return Err(DeserializationError::parse(&buf, "Command")),
};
Ok(command)
}
}