saito_core/core/msg/
message.rs1use std::fmt::Debug;
2use std::io::{Error, ErrorKind};
3
4use log::{error, warn};
5
6use crate::core::consensus::block::{Block, BlockType};
7use crate::core::consensus::peers::peer_service::PeerService;
8use crate::core::consensus::transaction::Transaction;
9use crate::core::defs::{BlockHash, BlockId, ForkId, SaitoPublicKey};
10use crate::core::msg::api_message::ApiMessage;
11use crate::core::msg::block_request::BlockchainRequest;
12use crate::core::msg::ghost_chain_sync::GhostChainSync;
13use crate::core::msg::handshake::{HandshakeChallenge, HandshakeResponse};
14use crate::core::util::serialize::Serialize;
15
16#[derive(Debug)]
17pub enum Message {
18 HandshakeChallenge(HandshakeChallenge),
19 HandshakeResponse(HandshakeResponse),
20 Block(Block),
21 Transaction(Transaction),
22 BlockchainRequest(BlockchainRequest),
23 BlockHeaderHash(BlockHash, BlockId),
24 Ping(),
25 SPVChain(),
26 Services(Vec<PeerService>),
27 GhostChain(GhostChainSync),
28 GhostChainRequest(BlockId, BlockHash, ForkId),
29 ApplicationMessage(ApiMessage),
30 Result(ApiMessage),
31 Error(ApiMessage),
32 KeyListUpdate(Vec<SaitoPublicKey>),
33}
34
35impl Message {
36 pub fn serialize(&self) -> Vec<u8> {
37 let message_type: u8 = self.get_type_value();
38 let mut buffer: Vec<u8> = vec![];
39 buffer.extend(&message_type.to_be_bytes());
40 buffer.append(&mut match self {
41 Message::HandshakeChallenge(data) => data.serialize(),
42 Message::HandshakeResponse(data) => data.serialize(),
43 Message::ApplicationMessage(data) => data.serialize(),
44 Message::Block(data) => data.serialize_for_net(BlockType::Full),
46 Message::Transaction(data) => data.serialize_for_net(),
47 Message::BlockchainRequest(data) => data.serialize(),
48 Message::BlockHeaderHash(block_hash, block_id) => {
49 [block_hash.as_slice(), block_id.to_be_bytes().as_slice()].concat()
50 }
51 Message::GhostChain(chain) => chain.serialize(),
52 Message::GhostChainRequest(block_id, block_hash, fork_id) => [
53 block_id.to_be_bytes().as_slice(),
54 block_hash.as_slice(),
55 fork_id.as_slice(),
56 ]
57 .concat(),
58 Message::Ping() => {
59 vec![]
60 }
61 Message::Services(services) => PeerService::serialize_services(services),
62 Message::Result(data) => data.serialize(),
63 Message::Error(data) => data.serialize(),
64 Message::KeyListUpdate(data) => data.as_slice().concat(),
65 _ => {
66 error!("unhandled type : {:?}", message_type);
67 vec![]
68 }
69 });
70
71 buffer
72 }
73 pub fn deserialize(buffer: Vec<u8>) -> Result<Message, Error> {
74 if buffer.is_empty() {
75 warn!("empty buffer is not valid for message deserialization",);
76 return Err(Error::from(ErrorKind::InvalidData));
77 }
78 let message_type: u8 = u8::from_be_bytes(buffer[0..1].try_into().unwrap());
79 let buffer = buffer[1..].to_vec();
80
81 match message_type {
82 1 => {
83 let result = HandshakeChallenge::deserialize(&buffer)?;
84 Ok(Message::HandshakeChallenge(result))
85 }
86 2 => {
87 let result = HandshakeResponse::deserialize(&buffer)?;
88 Ok(Message::HandshakeResponse(result))
89 }
90 3 => {
91 let block = Block::deserialize_from_net(&buffer)?;
92 Ok(Message::Block(block))
93 }
94 4 => {
95 let tx = Transaction::deserialize_from_net(&buffer)?;
96 Ok(Message::Transaction(tx))
97 }
98 5 => {
99 let result = BlockchainRequest::deserialize(&buffer)?;
100 Ok(Message::BlockchainRequest(result))
101 }
102 6 => {
103 if buffer.len() != 40 {
104 warn!(
105 "buffer size : {:?} is not valid for type : {:?}",
106 buffer.len(),
107 message_type
108 );
109 return Err(Error::from(ErrorKind::InvalidData));
110 }
111 let block_hash = buffer[0..32].to_vec().try_into().unwrap();
112 let block_id = u64::from_be_bytes(buffer[32..40].to_vec().try_into().unwrap());
113 Ok(Message::BlockHeaderHash(block_hash, block_id))
114 }
115 7 => Ok(Message::Ping()),
116 8 => Ok(Message::SPVChain()),
117 9 => {
118 let services = PeerService::deserialize_services(buffer);
119 if services.is_err() {
120 warn!("couldn't parse peer service from buffer");
121 return Err(Error::from(ErrorKind::InvalidData));
122 }
123 let services = services.unwrap();
124 Ok(Message::Services(services))
125 }
126 10 => Ok(Message::GhostChain(GhostChainSync::deserialize(buffer))),
127 11 => {
128 if buffer.len() != 72 {
129 warn!(
130 "buffer size : {:?} is not valid for type : {:?}",
131 buffer.len(),
132 message_type
133 );
134 return Err(Error::from(ErrorKind::InvalidData));
135 }
136 let block_id = u64::from_be_bytes(buffer[0..8].try_into().unwrap());
137 let block_hash = buffer[8..40].to_vec().try_into().unwrap();
138 let fork_id = buffer[40..72].to_vec().try_into().unwrap();
139 return Ok(Message::GhostChainRequest(block_id, block_hash, fork_id));
140 }
141 12 => {
142 if buffer.len() < 4 {
143 warn!(
144 "buffer size : {:?} is not valid for type : {:?}",
145 buffer.len(),
146 message_type
147 );
148 return Err(Error::from(ErrorKind::InvalidData));
149 }
150 let result = ApiMessage::deserialize(&buffer);
151 Ok(Message::ApplicationMessage(result))
152 }
153 13 => {
154 if buffer.len() < 4 {
155 warn!(
156 "buffer size : {:?} is not valid for type : {:?}",
157 buffer.len(),
158 message_type
159 );
160 return Err(Error::from(ErrorKind::InvalidData));
161 }
162 let result = ApiMessage::deserialize(&buffer);
163 Ok(Message::Result(result))
164 }
165 14 => {
166 if buffer.len() < 4 {
167 warn!(
168 "buffer size : {:?} is not valid for type : {:?}",
169 buffer.len(),
170 message_type
171 );
172 return Err(Error::from(ErrorKind::InvalidData));
173 }
174 let result = ApiMessage::deserialize(&buffer);
175 Ok(Message::Error(result))
176 }
177 15 => {
178 if buffer.len() % 33 != 0 {
179 warn!(
180 "key list have invalid keys. total length : {:?}",
181 buffer.len()
182 );
183 return Err(Error::from(ErrorKind::InvalidData));
184 }
185 let key_count = buffer.len() / 33;
186 let mut keylist: Vec<SaitoPublicKey> = vec![];
187 let slice = buffer.as_slice();
188
189 for i in 0..key_count {
190 let key: SaitoPublicKey =
191 slice[i * 33..(i + 1) * 33].to_vec().try_into().unwrap();
192
193 keylist.push(key);
194 }
195 Ok(Message::KeyListUpdate(keylist))
196 }
197 _ => {
198 warn!("message type : {:?} not valid", message_type);
199 Err(Error::from(ErrorKind::InvalidData))
200 }
201 }
202 }
203 pub fn get_type_value(&self) -> u8 {
204 match self {
205 Message::HandshakeChallenge(_) => 1,
206 Message::HandshakeResponse(_) => 2,
207 Message::Block(_) => 3,
208 Message::Transaction(_) => 4,
209 Message::BlockchainRequest(_) => 5,
210 Message::BlockHeaderHash(_, _) => 6,
211 Message::Ping() => 7,
212 Message::SPVChain() => 8,
213 Message::Services(_) => 9,
214 Message::GhostChain(_) => 10,
215 Message::GhostChainRequest(..) => 11,
216 Message::ApplicationMessage(_) => 12,
217 Message::Result(_) => 13,
218 Message::Error(_) => 14,
219 Message::KeyListUpdate(_) => 15,
220 }
221 }
222}