Skip to main content

monacoin/network/
message.rs

1// Rust Bitcoin Library
2// Written in 2014 by
3//     Andrew Poelstra <apoelstra@wpsoftware.net>
4//
5// To the extent possible under law, the author(s) have dedicated all
6// copyright and related and neighboring rights to this software to
7// the public domain worldwide. This software is distributed without
8// any warranty.
9//
10// You should have received a copy of the CC0 Public Domain Dedication
11// along with this software.
12// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
13//
14
15//! Network message
16//!
17//! This module defines the `Message` traits which are used
18//! for (de)serializing Bitcoin objects for transmission on the network. It
19//! also defines (de)serialization routines for many primitives.
20//!
21
22use 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/// Serializer for command string
37#[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)]
96/// A Network message
97pub struct RawNetworkMessage {
98    /// Magic bytes to identify the network these messages are meant for
99    pub magic: u32,
100    /// The actual message data
101    pub payload: NetworkMessage
102}
103
104#[derive(Clone, PartialEq, Eq, Debug)]
105/// A Network message payload. Proper documentation is available on at
106/// [Bitcoin Wiki: Protocol Specification](https://en.bitcoin.it/wiki/Protocol_specification)
107pub enum NetworkMessage {
108    /// `version`
109    Version(message_network::VersionMessage),
110    /// `verack`
111    Verack,
112    /// `addr`
113    Addr(Vec<(u32, Address)>),
114    /// `inv`
115    Inv(Vec<message_blockdata::Inventory>),
116    /// `getdata`
117    GetData(Vec<message_blockdata::Inventory>),
118    /// `notfound`
119    NotFound(Vec<message_blockdata::Inventory>),
120    /// `getblocks`
121    GetBlocks(message_blockdata::GetBlocksMessage),
122    /// `getheaders`
123    GetHeaders(message_blockdata::GetHeadersMessage),
124    /// `mempool`
125    MemPool,
126    /// tx
127    Tx(transaction::Transaction),
128    /// `block`
129    Block(block::Block),
130    /// `headers`
131    Headers(Vec<block::BlockHeader>),
132    /// `sendheaders`
133    SendHeaders,
134    /// `getaddr`
135    GetAddr,
136    // TODO: checkorder,
137    // TODO: submitorder,
138    // TODO: reply,
139    /// `ping`
140    Ping(u64),
141    /// `pong`
142    Pong(u64),
143    // TODO: bloom filtering
144    /// BIP157 getcfilters
145    GetCFilters(message_filter::GetCFilters),
146    /// BIP157 cfilter
147    CFilter(message_filter::CFilter),
148    /// BIP157 getcfheaders
149    GetCFHeaders(message_filter::GetCFHeaders),
150    /// BIP157 cfheaders
151    CFHeaders(message_filter::CFHeaders),
152    /// BIP157 getcfcheckpt
153    GetCFCheckpt(message_filter::GetCFCheckpt),
154    /// BIP157 cfcheckpt
155    CFCheckpt(message_filter::CFCheckpt),
156    /// `alert`
157    Alert(Vec<u8>),
158    /// `reject`
159    Reject(message_network::Reject)
160}
161
162impl NetworkMessage {
163    /// Return the message command. This is useful for debug outputs.
164    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    /// Return the CommandString for the message command.
194    pub fn command(&self) -> CommandString {
195        self.cmd().into()
196    }
197}
198
199impl RawNetworkMessage {
200    /// Return the message command. This is useful for debug outputs.
201    pub fn cmd(&self) -> &'static str {
202        self.payload.cmd()
203    }
204
205    /// Return the CommandString for the message command.
206    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        // TODO: Impl Rand traits here to easily generate random values.
356        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        // Test oversized one.
401        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}