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