1use std::{io, iter, mem, fmt};
23use std::borrow::Cow;
24use std::io::Cursor;
25
26use blockdata::block;
27use blockdata::transaction;
28use network::address::Address;
29use network::message_network;
30use network::message_blockdata;
31use network::message_filter;
32use consensus::encode::{CheckedData, Decodable, Encodable, VarInt};
33use consensus::{encode, serialize};
34use consensus::encode::MAX_VEC_SIZE;
35
36#[derive(PartialEq, Eq, Clone, Debug)]
38pub struct CommandString(Cow<'static, str>);
39
40impl fmt::Display for CommandString {
41 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42 f.write_str(self.0.as_ref())
43 }
44}
45
46impl From<&'static str> for CommandString {
47 fn from(f: &'static str) -> Self {
48 CommandString(f.into())
49 }
50}
51
52impl From<String> for CommandString {
53 fn from(f: String) -> Self {
54 CommandString(f.into())
55 }
56}
57
58impl AsRef<str> for CommandString {
59 fn as_ref(&self) -> &str {
60 self.0.as_ref()
61 }
62}
63
64impl Encodable for CommandString {
65 #[inline]
66 fn consensus_encode<S: io::Write>(
67 &self,
68 s: S,
69 ) -> Result<usize, encode::Error> {
70 let mut rawbytes = [0u8; 12];
71 let strbytes = self.0.as_bytes();
72 if strbytes.len() > 12 {
73 return Err(encode::Error::UnrecognizedNetworkCommand(self.0.clone().into_owned()));
74 }
75 for x in 0..strbytes.len() {
76 rawbytes[x] = strbytes[x];
77 }
78 rawbytes.consensus_encode(s)
79 }
80}
81
82impl Decodable for CommandString {
83 #[inline]
84 fn consensus_decode<D: io::Read>(d: D) -> Result<Self, encode::Error> {
85 let rawbytes: [u8; 12] = Decodable::consensus_decode(d)?;
86 let rv = iter::FromIterator::from_iter(
87 rawbytes
88 .iter()
89 .filter_map(|&u| if u > 0 { Some(u as char) } else { None })
90 );
91 Ok(CommandString(rv))
92 }
93}
94
95#[derive(Debug, PartialEq, Eq)]
96pub struct RawNetworkMessage {
98 pub magic: u32,
100 pub payload: NetworkMessage
102}
103
104#[derive(Clone, PartialEq, Eq, Debug)]
105pub enum NetworkMessage {
108 Version(message_network::VersionMessage),
110 Verack,
112 Addr(Vec<(u32, Address)>),
114 Inv(Vec<message_blockdata::Inventory>),
116 GetData(Vec<message_blockdata::Inventory>),
118 NotFound(Vec<message_blockdata::Inventory>),
120 GetBlocks(message_blockdata::GetBlocksMessage),
122 GetHeaders(message_blockdata::GetHeadersMessage),
124 MemPool,
126 Tx(transaction::Transaction),
128 Block(block::Block),
130 Headers(Vec<block::BlockHeader>),
132 SendHeaders,
134 GetAddr,
136 Ping(u64),
141 Pong(u64),
143 GetCFilters(message_filter::GetCFilters),
146 CFilter(message_filter::CFilter),
148 GetCFHeaders(message_filter::GetCFHeaders),
150 CFHeaders(message_filter::CFHeaders),
152 GetCFCheckpt(message_filter::GetCFCheckpt),
154 CFCheckpt(message_filter::CFCheckpt),
156 Alert(Vec<u8>),
158 Reject(message_network::Reject)
160}
161
162impl NetworkMessage {
163 pub fn cmd(&self) -> &'static str {
165 match *self {
166 NetworkMessage::Version(_) => "version",
167 NetworkMessage::Verack => "verack",
168 NetworkMessage::Addr(_) => "addr",
169 NetworkMessage::Inv(_) => "inv",
170 NetworkMessage::GetData(_) => "getdata",
171 NetworkMessage::NotFound(_) => "notfound",
172 NetworkMessage::GetBlocks(_) => "getblocks",
173 NetworkMessage::GetHeaders(_) => "getheaders",
174 NetworkMessage::MemPool => "mempool",
175 NetworkMessage::Tx(_) => "tx",
176 NetworkMessage::Block(_) => "block",
177 NetworkMessage::Headers(_) => "headers",
178 NetworkMessage::SendHeaders => "sendheaders",
179 NetworkMessage::GetAddr => "getaddr",
180 NetworkMessage::Ping(_) => "ping",
181 NetworkMessage::Pong(_) => "pong",
182 NetworkMessage::GetCFilters(_) => "getcfilters",
183 NetworkMessage::CFilter(_) => "cfilter",
184 NetworkMessage::GetCFHeaders(_) => "getcfheaders",
185 NetworkMessage::CFHeaders(_) => "cfheaders",
186 NetworkMessage::GetCFCheckpt(_) => "getcfcheckpt",
187 NetworkMessage::CFCheckpt(_) => "cfcheckpt",
188 NetworkMessage::Alert(_) => "alert",
189 NetworkMessage::Reject(_) => "reject",
190 }
191 }
192
193 pub fn command(&self) -> CommandString {
195 self.cmd().into()
196 }
197}
198
199impl RawNetworkMessage {
200 pub fn cmd(&self) -> &'static str {
202 self.payload.cmd()
203 }
204
205 pub fn command(&self) -> CommandString {
207 self.payload.command()
208 }
209}
210
211struct HeaderSerializationWrapper<'a>(&'a Vec<block::BlockHeader>);
212
213impl<'a> Encodable for HeaderSerializationWrapper<'a> {
214 #[inline]
215 fn consensus_encode<S: io::Write>(
216 &self,
217 mut s: S,
218 ) -> Result<usize, encode::Error> {
219 let mut len = 0;
220 len += VarInt(self.0.len() as u64).consensus_encode(&mut s)?;
221 for header in self.0.iter() {
222 len += header.consensus_encode(&mut s)?;
223 len += 0u8.consensus_encode(&mut s)?;
224 }
225 Ok(len)
226 }
227}
228
229impl Encodable for RawNetworkMessage {
230 fn consensus_encode<S: io::Write>(
231 &self,
232 mut s: S,
233 ) -> Result<usize, encode::Error> {
234 let mut len = 0;
235 len += self.magic.consensus_encode(&mut s)?;
236 len += self.command().consensus_encode(&mut s)?;
237 len += CheckedData(match self.payload {
238 NetworkMessage::Version(ref dat) => serialize(dat),
239 NetworkMessage::Addr(ref dat) => serialize(dat),
240 NetworkMessage::Inv(ref dat) => serialize(dat),
241 NetworkMessage::GetData(ref dat) => serialize(dat),
242 NetworkMessage::NotFound(ref dat) => serialize(dat),
243 NetworkMessage::GetBlocks(ref dat) => serialize(dat),
244 NetworkMessage::GetHeaders(ref dat) => serialize(dat),
245 NetworkMessage::Tx(ref dat) => serialize(dat),
246 NetworkMessage::Block(ref dat) => serialize(dat),
247 NetworkMessage::Headers(ref dat) => serialize(&HeaderSerializationWrapper(dat)),
248 NetworkMessage::Ping(ref dat) => serialize(dat),
249 NetworkMessage::Pong(ref dat) => serialize(dat),
250 NetworkMessage::GetCFilters(ref dat) => serialize(dat),
251 NetworkMessage::CFilter(ref dat) => serialize(dat),
252 NetworkMessage::GetCFHeaders(ref dat) => serialize(dat),
253 NetworkMessage::CFHeaders(ref dat) => serialize(dat),
254 NetworkMessage::GetCFCheckpt(ref dat) => serialize(dat),
255 NetworkMessage::CFCheckpt(ref dat) => serialize(dat),
256 NetworkMessage::Alert(ref dat) => serialize(dat),
257 NetworkMessage::Reject(ref dat) => serialize(dat),
258 NetworkMessage::Verack
259 | NetworkMessage::SendHeaders
260 | NetworkMessage::MemPool
261 | NetworkMessage::GetAddr => vec![],
262 }).consensus_encode(&mut s)?;
263 Ok(len)
264 }
265}
266
267struct HeaderDeserializationWrapper(Vec<block::BlockHeader>);
268
269impl Decodable for HeaderDeserializationWrapper {
270 #[inline]
271 fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
272 let len = VarInt::consensus_decode(&mut d)?.0;
273 let byte_size = (len as usize)
274 .checked_mul(mem::size_of::<block::BlockHeader>())
275 .ok_or(encode::Error::ParseFailed("Invalid length"))?;
276 if byte_size > MAX_VEC_SIZE {
277 return Err(encode::Error::OversizedVectorAllocation { requested: byte_size, max: MAX_VEC_SIZE })
278 }
279 let mut ret = Vec::with_capacity(len as usize);
280 for _ in 0..len {
281 ret.push(Decodable::consensus_decode(&mut d)?);
282 if u8::consensus_decode(&mut d)? != 0u8 {
283 return Err(encode::Error::ParseFailed("Headers message should not contain transactions"));
284 }
285 }
286 Ok(HeaderDeserializationWrapper(ret))
287 }
288}
289
290impl Decodable for RawNetworkMessage {
291 fn consensus_decode<D: io::Read>(mut d: D) -> Result<Self, encode::Error> {
292 let magic = Decodable::consensus_decode(&mut d)?;
293 let cmd = CommandString::consensus_decode(&mut d)?.0;
294 let raw_payload = CheckedData::consensus_decode(&mut d)?.0;
295
296 let mut mem_d = Cursor::new(raw_payload);
297 let payload = match &cmd[..] {
298 "version" => NetworkMessage::Version(Decodable::consensus_decode(&mut mem_d)?),
299 "verack" => NetworkMessage::Verack,
300 "addr" => NetworkMessage::Addr(Decodable::consensus_decode(&mut mem_d)?),
301 "inv" => NetworkMessage::Inv(Decodable::consensus_decode(&mut mem_d)?),
302 "getdata" => NetworkMessage::GetData(Decodable::consensus_decode(&mut mem_d)?),
303 "notfound" => NetworkMessage::NotFound(Decodable::consensus_decode(&mut mem_d)?),
304 "getblocks" => NetworkMessage::GetBlocks(Decodable::consensus_decode(&mut mem_d)?),
305 "getheaders" => NetworkMessage::GetHeaders(Decodable::consensus_decode(&mut mem_d)?),
306 "mempool" => NetworkMessage::MemPool,
307 "block" => NetworkMessage::Block(Decodable::consensus_decode(&mut mem_d)?),
308 "headers" => NetworkMessage::Headers(
309 HeaderDeserializationWrapper::consensus_decode(&mut mem_d)?.0
310 ),
311 "sendheaders" => NetworkMessage::SendHeaders,
312 "getaddr" => NetworkMessage::GetAddr,
313 "ping" => NetworkMessage::Ping(Decodable::consensus_decode(&mut mem_d)?),
314 "pong" => NetworkMessage::Pong(Decodable::consensus_decode(&mut mem_d)?),
315 "tx" => NetworkMessage::Tx(Decodable::consensus_decode(&mut mem_d)?),
316 "getcfilters" => NetworkMessage::GetCFilters(Decodable::consensus_decode(&mut mem_d)?),
317 "cfilter" => NetworkMessage::CFilter(Decodable::consensus_decode(&mut mem_d)?),
318 "getcfheaders" => NetworkMessage::GetCFHeaders(Decodable::consensus_decode(&mut mem_d)?),
319 "cfheaders" => NetworkMessage::CFHeaders(Decodable::consensus_decode(&mut mem_d)?),
320 "getcfcheckpt" => NetworkMessage::GetCFCheckpt(Decodable::consensus_decode(&mut mem_d)?),
321 "cfcheckpt" => NetworkMessage::CFCheckpt(Decodable::consensus_decode(&mut mem_d)?),
322 "reject" => NetworkMessage::Reject(Decodable::consensus_decode(&mut mem_d)?),
323 "alert" => NetworkMessage::Alert(Decodable::consensus_decode(&mut mem_d)?),
324 _ => return Err(encode::Error::UnrecognizedNetworkCommand(cmd.into_owned())),
325 };
326 Ok(RawNetworkMessage {
327 magic: magic,
328 payload: payload
329 })
330 }
331}
332
333#[cfg(test)]
334mod test {
335 use std::io;
336 use super::{RawNetworkMessage, NetworkMessage, CommandString};
337 use network::constants::ServiceFlags;
338 use consensus::encode::{Encodable, deserialize, deserialize_partial, serialize};
339 use hashes::hex::FromHex;
340 use hashes::sha256d::Hash;
341 use hashes::Hash as HashTrait;
342 use network::address::Address;
343 use super::message_network::{Reject, RejectReason, VersionMessage};
344 use network::message_blockdata::{Inventory, GetBlocksMessage, GetHeadersMessage};
345 use blockdata::block::{Block, BlockHeader};
346 use network::message_filter::{GetCFilters, CFilter, GetCFHeaders, CFHeaders, GetCFCheckpt, CFCheckpt};
347 use blockdata::transaction::Transaction;
348
349 fn hash(slice: [u8;32]) -> Hash {
350 Hash::from_slice(&slice).unwrap()
351 }
352
353 #[test]
354 fn full_round_ser_der_raw_network_message_test() {
355 let version_msg: VersionMessage = deserialize(&Vec::from_hex("721101000100000000000000e6e0845300000000010000000000000000000000000000000000ffff0000000000000100000000000000fd87d87eeb4364f22cf54dca59412db7208d47d920cffce83ee8102f5361746f7368693a302e392e39392f2c9f040001").unwrap()).unwrap();
357 let tx: Transaction = deserialize(&Vec::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap()).unwrap();
358 let block: Block = deserialize(&Vec::from_hex("000000202aa2f2ca794ccbd40c16e2f3333f6b8b683f9e7179b2c4d7490600000000000010bc26e70a2f672ad420a6153dd0c28b40a6002c55531bfc99bf8994a8e8f67e5503bd5750d4061a4ed90a700f010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff3603da1b0e00045503bd5704c7dd8a0d0ced13bb5785010800000000000a636b706f6f6c122f4e696e6a61506f6f6c2f5345475749542fffffffff02b4e5a212000000001976a914876fbb82ec05caa6af7a3b5e5a983aae6c6cc6d688ac0000000000000000266a24aa21a9edf91c46b49eb8a29089980f02ee6b57e7d63d33b18b4fddac2bcd7db2a3983704012000000000000000000000000000000000000000000000000000000000000000000000000001000000017e4f81175332a733e26d4ba4e29f53f67b7a5d7c2adebb276e447ca71d130b55000000006b483045022100cac809cd1a3d9ad5d5e31a84e2e1d8ec5542841e4d14c6b52e8b38cbe1ff1728022064470b7fb0c2efeccb2e84bfa36ec5f9e434c84b1101c00f7ee32f726371b7410121020e62280798b6b8c37f068df0915b0865b63fabc401c2457cbc3ef96887dd3647ffffffff02ca2f780c000000001976a914c6b5545b3592cb477d709896fa705592c9b6113a88ac663b2a06000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac0000000001000000011e99f5a785e677e017d36b50aa4fd10010ffd039f38f42f447ca8895250e121f01000000d90047304402200d3d296ad641a281dd5c0d68b9ab0d1ad5f7052bec148c1fb81fb1ba69181ec502201a372bb16fb8e054ee9bef41e300d292153830f841a4db0ab7f7407f6581b9bc01473044022002584f313ae990236b6bebb82fbbb006a2b02a448dd5c93434428991eae960d60220491d67d2660c4dde19025cf86e5164a559e2c79c3b98b40e146fab974acd24690147522102632178d046673c9729d828cfee388e121f497707f810c131e0d3fc0fe0bd66d62103a0951ec7d3a9da9de171617026442fcd30f34d66100fab539853b43f508787d452aeffffffff0240420f000000000017a9140ffdcf96700455074292a821c74922e8652993998788997bc60000000017a9148ce5408cfeaddb7ccb2545ded41ef478109454848700000000010000000113100b09e6a78d63ec4850654ab0f68806de29710b09172eddfef730652b155501000000da00473044022015389408e3446a3f36a05060e0e4a3c8b92ff3901ba2511aa944ec91a537a1cb022045a33b6ec47605b1718ed2e753263e54918edbf6126508ff039621fb928d28a001483045022100bb952fde81f216f7063575c0bb2bedc050ce08c96d9b437ea922f5eb98c882da02201b7cbf3a2f94ea4c5eb7f0df3af2ebcafa8705af7f410ab5d3d4bac13d6bc6120147522102632178d046673c9729d828cfee388e121f497707f810c131e0d3fc0fe0bd66d62103a0951ec7d3a9da9de171617026442fcd30f34d66100fab539853b43f508787d452aeffffffff0240420f000000000017a914d3db9a20312c3ab896a316eb108dbd01e47e17d687e0ba7ac60000000017a9148ce5408cfeaddb7ccb2545ded41ef47810945484870000000001000000016e3cca1599cde54878e2f27f434df69df0afd1f313cb6e38c08d3ffb57f97a6c01000000da0048304502210095623b70ec3194fa4037a1c1106c2580caedc390e25e5b330bbeb3111e8184bc02205ae973c4a4454be2a3a03beb66297143c1044a3c4743742c5cdd1d516a1ad3040147304402202f3d6d89996f5b42773dd6ebaf367f1af1f3a95c7c7b487ec040131c40f4a4a30220524ffbb0b563f37b3eb1341228f792e8f84111b7c4a9f49cdd998e052ee42efa0147522102632178d046673c9729d828cfee388e121f497707f810c131e0d3fc0fe0bd66d62103a0951ec7d3a9da9de171617026442fcd30f34d66100fab539853b43f508787d452aeffffffff0240420f000000000017a9141ade6b95896dde8ec4dee9e59af8849d3797348e8728af7ac60000000017a9148ce5408cfeaddb7ccb2545ded41ef47810945484870000000001000000011d9dc3a5df9b5b2eeb2bd11a2db243be9e8cc23e2f180bf317d32a499904c15501000000db00483045022100ebbd1c9a8ce626edbb1a7881df81e872ef8c6424feda36faa8a5745157400c6a02206eb463bc8acd5ea06a289e86115e1daae0c2cf10d9cbbd199e1311170d5543ef01483045022100809411a917dc8cf4f3a777f0388fdea6de06243ef7691e500c60abd1c7f19ae602205255d2b1191d8adedb77b814ccb66471eb8486cb4ff8727824254ee5589f176b0147522102632178d046673c9729d828cfee388e121f497707f810c131e0d3fc0fe0bd66d62103a0951ec7d3a9da9de171617026442fcd30f34d66100fab539853b43f508787d452aeffffffff0240420f000000000017a914759a49c772347be81c49517f9e1e6def6a88d4dd87800b85c60000000017a9148ce5408cfeaddb7ccb2545ded41ef47810945484870000000001000000018c51902affd8e5247dfcc2e5d0528a3815f53c8b6d2c200ff290b2b2b486d7704f0000006a47304402201be0d485f6a3ce871be80064c593c5327b3fd7e450f05ab7fae38385bc40cfbe02206e2a6c9970b5d1d10207892376733757486634fce4f352e772149c486857612101210350c33bc9a790c9495195761577b34912a949b73d5bc5ae5343f5ba08b33220ccffffffff0110270000000000001976a9142ab1c62710a7bdfdb4bb6394bbedc58b32b4d5a388ac0000000001000000018c51902affd8e5247dfcc2e5d0528a3815f53c8b6d2c200ff290b2b2b486d7704e0000006b483045022100ccc8c0ac90bdb0402842aec91830c765cdead7a728552a6a34de7d13a6dab28e02206c96f8640cf3444054e9632b197be30598a09c3d5defcd95750bdb922a60d64801210350c33bc9a790c9495195761577b34912a949b73d5bc5ae5343f5ba08b33220ccffffffff0110270000000000001976a9142ab1c62710a7bdfdb4bb6394bbedc58b32b4d5a388ac0000000001000000011b436669c06cbf3442e21a2fe3edc20cd3cf13c358c53234bc4d88bfd8c4bd2a000000006a47304402204a63410ee13db52c7609ab08e25b7fe3c608cc21cc1755ad13460685eb55193202204cd1ea80c06a81571119be0b8cccd96ef7cdd90f62c1fe2d538622feb08e22ba0121024baa8b67cc9ed8a97d90895e3716b25469b67cb26d3324d7aff213f507764765ffffffff010000000000000000306a2e516d64523365345261445653324d436a736e536171734a5753324465655446624238354541794a4d5843784c7934000000000100000001be4a95ed36316cada5118b1982e4cb4a07f93e7a4153e227466f1cb0776de995000000006b483045022100a22d5251deea0470806bab817013d675a63cd52218d6e477ab0c9d601d018b7f022042121b46afcdcd0c66f189398212b66085e88c6973ae560f1810c13e55e2bee40121024baa8b67cc9ed8a97d90895e3716b25469b67cb26d3324d7aff213f507764765ffffffff010000000000000000306a2e516d57484d57504e5248515872504c7338554c586b4d483746745356413675366b5a6b4a4e3851796e4e583751340000000001000000016c061a65b49edec21acdbc22f97dc853aa872302aeef13fabf0bf6807de1b8bd010000006b483045022100dd80381f2d158b4dad7f98d2d97317c533fb36e737542473feb05fa74d0b73bb02207097d4331196069167e525b61d132532292fd75cc039a5839c04c2545d427e2b0121035e9a597df8b417bef66811882a2844604fc591c427f642628f0fef46be19a4c9feffffff0280a4bf07000000001976a914573b9106e16ee0b5c143dc40f0724f77dd0e282088ac9533b22c000000001976a9149c4da607efb1d759d33da71778bc6cafa56acb5988acd31b0e0001000000017dae20994b69b28534e5b22f3d7c50f9d7541348cbf6f43fcc654263ebaf8f68000000006b483045022100a85300eb94b24b044877d0b0d61e08e16dbc82ec7d69c723a8a45519f95c35b002203d78376e6bee31b455c097557af7fe4d6b620bc74269e9a75e2aad2b545abddb012103b0d08aba2a5ac6cf2788fda941c386040e35e49d3a57d2aefb16c0438fb98acbfeffffff022222305f000000001976a914cfda30dd836b596db6a9c230c45ae2179107f04888ac80a4bf07000000001976a91442dfcf5823aacb185844e663873c35fb98bfd21b88acd31b0e000100000002ad3e85e4af30678a330f8941ed7a9ca17cd0236368d238cac4e9ff09c466fed1020000006b483045022100d1196c48a0392e09592f1b96b4aec32ab0cecb6fd17b1d0c85ab3250a2fe45d9022059217c82f684fcdecdbe660a2077ea956dfbbb964d2648bc1e8ae0f0fe565449012103b64e32e5f62e03701428fb1e3151e9a57f149c67708f6164a235c8199fe17cc2ffffffff34f0a71c1c2cd610522e9c18c67931cded5e9647d4419c49b99715e2a0795f3d020000006a4730440220316e81d8242abf3c5f885d200feca12c3adb63cf2cd4dc74602f7b8b0cba50340220210d525758df77ccdca6908311c1895275e07bbb29b45963a19252acde55873f012103b64e32e5f62e03701428fb1e3151e9a57f149c67708f6164a235c8199fe17cc2ffffffff0510270000000000001976a914449d2394dde057bc199f23fb8aa2e400f344611788ac10270000000000001976a914449d2394dde057bc199f23fb8aa2e400f344611788aca0860100000000001976a91413d35ad337dd80a055757e5ea0a45b59fee3060c88ac70110100000000001976a91413d35ad337dd80a055757e5ea0a45b59fee3060c88ac0000000000000000026a000000000001000000018e33fecc2ddbd86c5ea919f7bd5a5acf8a09f3e0cdaaaf4f08c5ef095161ef1100000000fdfe0000483045022100d2489b225d39b7d8b6767a6928c8029a2a1297c08fdf00d683ba0c1987e7d7000220176cb66c8a243806bb7421f658325a69a51c82c0c3314e37f2400f33626390210148304502210096cfa57662a545830d0e29610becd41ea031e256339913718ce18dbb1a27bdb00220482911c851d15adcd37097dff99a9ff1f97d953bcebc528835118f447412553e014c695221028d9889862b29430278c084b5c4090b7b807b31e047bcd212ebc2c4e43fc0e3c52103160949a7c8c81f2c25d7763f57eb1cb407d867c5b7c290331bd2dc4b1182c6d32103fbef3b60914bda9173765902013a251ec89450c75d0b5a96a143db1dabf98d9553aeffffffff0220e8891c0100000017a914d996715e081c50f8f6b1b4e7fb6ca214f9924fdf87809698000000000017a9145611d812263f32960228cb5f85329bce4770a218870000000001000000017720507dcbe6c69f652b0c0ce19406f482372d1a8abc05d45fb7acf97fb80eec00000000fdfe00004830450221009821d8e117de44b1202c829c0f5063997acf007cf9b561c6fb8d1212cddb6c40022010ff5067b0d9d4eca2da0ceb876e9a16f1a2142da866d3042a7bae8968813e8001483045022100dea759d14a8a1c5da5f3dcc5509871aaa2c1e3be03752c1b858d80fa4227163702205183d70cc28dcb6df9b037714c8b6442ef84e0ddce07711a30c731e9f0925090014c695221028d70ea66fe7a7def282df7b2b498007e5072933e42c18f63ce85975dcbcf1a8821037e8f842b1e47e21d88002c5aab2559212a4c2c9dbe5ef5347f2a29afd0510ec1210251259cb9fd4f6206488408286e4475c9c9fe887e57a3e32ae4da222778a2aedf53aeffffffff023380cb020000000017a9143b5a7e85b22656a34d43187ac8dd09acd7109d2487809698000000000017a914b9b4b555f594a34deec3ad61d5c5f3738b17ee158700000000").unwrap()).unwrap();
359 let header: BlockHeader = deserialize(&Vec::from_hex("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b").unwrap()).unwrap();
360
361 let msgs = vec![
362 NetworkMessage::Version(version_msg),
363 NetworkMessage::Verack,
364 NetworkMessage::Addr(vec![(45, Address::new(&([123,255,000,100], 833).into(), ServiceFlags::NETWORK))]),
365 NetworkMessage::Inv(vec![Inventory::Block(hash([8u8; 32]).into())]),
366 NetworkMessage::GetData(vec![Inventory::Transaction(hash([45u8; 32]).into())]),
367 NetworkMessage::NotFound(vec![Inventory::Error]),
368 NetworkMessage::GetBlocks(GetBlocksMessage::new(vec![hash([1u8; 32]).into(), hash([4u8; 32]).into()], hash([5u8; 32]).into())),
369 NetworkMessage::GetHeaders(GetHeadersMessage::new(vec![hash([10u8; 32]).into(), hash([40u8; 32]).into()], hash([50u8; 32]).into())),
370 NetworkMessage::MemPool,
371 NetworkMessage::Tx(tx),
372 NetworkMessage::Block(block),
373 NetworkMessage::Headers(vec![header]),
374 NetworkMessage::SendHeaders,
375 NetworkMessage::GetAddr,
376 NetworkMessage::Ping(15),
377 NetworkMessage::Pong(23),
378 NetworkMessage::GetCFilters(GetCFilters{filter_type: 2, start_height: 52, stop_hash: hash([42u8; 32]).into()}),
379 NetworkMessage::CFilter(CFilter{filter_type: 7, block_hash: hash([25u8; 32]).into(), filter: vec![1,2,3]}),
380 NetworkMessage::GetCFHeaders(GetCFHeaders{filter_type: 4, start_height: 102, stop_hash: hash([47u8; 32]).into()}),
381 NetworkMessage::CFHeaders(CFHeaders{filter_type: 13, stop_hash: hash([53u8; 32]).into(), previous_filter: hash([12u8; 32]).into(), filter_hashes: vec![hash([4u8; 32]).into(), hash([12u8; 32]).into()]}),
382 NetworkMessage::GetCFCheckpt(GetCFCheckpt{filter_type: 17, stop_hash: hash([25u8; 32]).into()}),
383 NetworkMessage::CFCheckpt(CFCheckpt{filter_type: 27, stop_hash: hash([77u8; 32]).into(), filter_headers: vec![hash([3u8; 32]).into(), hash([99u8; 32]).into()]}),
384 NetworkMessage::Alert(vec![45,66,3,2,6,8,9,12,3,130]),
385 NetworkMessage::Reject(Reject{message: "Test reject".into(), ccode: RejectReason::Duplicate, reason: "Cause".into(), hash: hash([255u8; 32])}),
386 ];
387
388 for msg in msgs {
389 let raw_msg = RawNetworkMessage {magic: 57, payload: msg};
390 assert_eq!(deserialize::<RawNetworkMessage>(&serialize(&raw_msg)).unwrap(), raw_msg);
391 }
392
393 }
394
395 #[test]
396 fn serialize_commandstring_test() {
397 let cs = CommandString("Andrew".into());
398 assert_eq!(serialize(&cs), vec![0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0, 0]);
399
400 let mut encoder = io::Cursor::new(vec![]);
402 assert!(CommandString("AndrewAndrewA".into()).consensus_encode(&mut encoder).is_err());
403 }
404
405 #[test]
406 fn deserialize_commandstring_test() {
407 let cs: Result<CommandString, _> = deserialize(&[0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0, 0]);
408 assert!(cs.is_ok());
409 assert_eq!(cs.as_ref().unwrap().to_string(), "Andrew".to_owned());
410 assert_eq!(cs.unwrap(), "Andrew".into());
411
412 let short_cs: Result<CommandString, _> = deserialize(&[0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0]);
413 assert!(short_cs.is_err());
414 }
415
416 #[test]
417 fn serialize_verack_test() {
418 assert_eq!(serialize(&RawNetworkMessage { magic: 0xd9b4bef9, payload: NetworkMessage::Verack }),
419 vec![0xf9, 0xbe, 0xb4, 0xd9, 0x76, 0x65, 0x72, 0x61,
420 0x63, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421 0x00, 0x00, 0x00, 0x00, 0x5d, 0xf6, 0xe0, 0xe2]);
422 }
423
424 #[test]
425 fn serialize_ping_test() {
426 assert_eq!(serialize(&RawNetworkMessage { magic: 0xd9b4bef9, payload: NetworkMessage::Ping(100) }),
427 vec![0xf9, 0xbe, 0xb4, 0xd9, 0x70, 0x69, 0x6e, 0x67,
428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429 0x08, 0x00, 0x00, 0x00, 0x24, 0x67, 0xf1, 0x1d,
430 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
431 }
432
433
434 #[test]
435 fn serialize_mempool_test() {
436 assert_eq!(serialize(&RawNetworkMessage { magic: 0xd9b4bef9, payload: NetworkMessage::MemPool }),
437 vec![0xf9, 0xbe, 0xb4, 0xd9, 0x6d, 0x65, 0x6d, 0x70,
438 0x6f, 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
439 0x00, 0x00, 0x00, 0x00, 0x5d, 0xf6, 0xe0, 0xe2]);
440 }
441
442 #[test]
443 fn serialize_getaddr_test() {
444 assert_eq!(serialize(&RawNetworkMessage { magic: 0xd9b4bef9, payload: NetworkMessage::GetAddr }),
445 vec![0xf9, 0xbe, 0xb4, 0xd9, 0x67, 0x65, 0x74, 0x61,
446 0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00,
447 0x00, 0x00, 0x00, 0x00, 0x5d, 0xf6, 0xe0, 0xe2]);
448 }
449
450 #[test]
451 fn deserialize_getaddr_test() {
452 let msg = deserialize(
453 &[0xf9, 0xbe, 0xb4, 0xd9, 0x67, 0x65, 0x74, 0x61,
454 0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00,
455 0x00, 0x00, 0x00, 0x00, 0x5d, 0xf6, 0xe0, 0xe2]);
456 let preimage = RawNetworkMessage { magic: 0xd9b4bef9, payload: NetworkMessage::GetAddr };
457 assert!(msg.is_ok());
458 let msg : RawNetworkMessage = msg.unwrap();
459 assert_eq!(preimage.magic, msg.magic);
460 assert_eq!(preimage.payload, msg.payload);
461 }
462
463 #[test]
464 fn deserialize_version_test() {
465 let msg = deserialize::<RawNetworkMessage>(
466 &[ 0xf9, 0xbe, 0xb4, 0xd9, 0x76, 0x65, 0x72, 0x73,
467 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
468 0x66, 0x00, 0x00, 0x00, 0xbe, 0x61, 0xb8, 0x27,
469 0x7f, 0x11, 0x01, 0x00, 0x0d, 0x04, 0x00, 0x00,
470 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x4d, 0x5c,
471 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
474 0x5b, 0xf0, 0x8c, 0x80, 0xb4, 0xbd, 0x0d, 0x04,
475 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
476 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478 0xfa, 0xa9, 0x95, 0x59, 0xcc, 0x68, 0xa1, 0xc1,
479 0x10, 0x2f, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68,
480 0x69, 0x3a, 0x30, 0x2e, 0x31, 0x37, 0x2e, 0x31,
481 0x2f, 0x93, 0x8c, 0x08, 0x00, 0x01 ]);
482
483 assert!(msg.is_ok());
484 let msg = msg.unwrap();
485 assert_eq!(msg.magic, 0xd9b4bef9);
486 if let NetworkMessage::Version(version_msg) = msg.payload {
487 assert_eq!(version_msg.version, 70015);
488 assert_eq!(version_msg.services, ServiceFlags::NETWORK | ServiceFlags::BLOOM | ServiceFlags::WITNESS | ServiceFlags::NETWORK_LIMITED);
489 assert_eq!(version_msg.timestamp, 1548554224);
490 assert_eq!(version_msg.nonce, 13952548347456104954);
491 assert_eq!(version_msg.user_agent, "/Satoshi:0.17.1/");
492 assert_eq!(version_msg.start_height, 560275);
493 assert_eq!(version_msg.relay, true);
494 } else {
495 panic!("Wrong message type");
496 }
497 }
498
499 #[test]
500 fn deserialize_partial_message_test() {
501 let data = [ 0xf9, 0xbe, 0xb4, 0xd9, 0x76, 0x65, 0x72, 0x73,
502 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
503 0x66, 0x00, 0x00, 0x00, 0xbe, 0x61, 0xb8, 0x27,
504 0x7f, 0x11, 0x01, 0x00, 0x0d, 0x04, 0x00, 0x00,
505 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x4d, 0x5c,
506 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
508 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
509 0x5b, 0xf0, 0x8c, 0x80, 0xb4, 0xbd, 0x0d, 0x04,
510 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
511 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
512 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513 0xfa, 0xa9, 0x95, 0x59, 0xcc, 0x68, 0xa1, 0xc1,
514 0x10, 0x2f, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68,
515 0x69, 0x3a, 0x30, 0x2e, 0x31, 0x37, 0x2e, 0x31,
516 0x2f, 0x93, 0x8c, 0x08, 0x00, 0x01, 0, 0 ];
517 let msg = deserialize_partial::<RawNetworkMessage>(&data);
518 assert!(msg.is_ok());
519
520 let (msg, consumed) = msg.unwrap();
521 assert_eq!(consumed, data.to_vec().len() - 2);
522 assert_eq!(msg.magic, 0xd9b4bef9);
523 if let NetworkMessage::Version(version_msg) = msg.payload {
524 assert_eq!(version_msg.version, 70015);
525 assert_eq!(version_msg.services, ServiceFlags::NETWORK | ServiceFlags::BLOOM | ServiceFlags::WITNESS | ServiceFlags::NETWORK_LIMITED);
526 assert_eq!(version_msg.timestamp, 1548554224);
527 assert_eq!(version_msg.nonce, 13952548347456104954);
528 assert_eq!(version_msg.user_agent, "/Satoshi:0.17.1/");
529 assert_eq!(version_msg.start_height, 560275);
530 assert_eq!(version_msg.relay, true);
531 } else {
532 panic!("Wrong message type");
533 }
534 }
535}