saito_core/core/msg/
message.rs

1use 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::ApplicationTransaction(data) => data.clone(),
45            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}