bitcoincash/network/
message.rs

1// Written in 2014 by Andrew Poelstra <apoelstra@wpsoftware.net>
2// SPDX-License-Identifier: CC0-1.0
3
4//! Bitcoin network messages.
5//!
6//! This module defines the `NetworkMessage` and `RawNetworkMessage` types that
7//! are used for (de)serializing Bitcoin objects for transmission on the network.
8//!
9
10use crate::prelude::*;
11
12use core::{fmt, iter};
13use core::convert::TryFrom;
14
15use crate::io;
16use io::Read as _;
17use crate::blockdata::block;
18use crate::blockdata::transaction;
19use crate::network::address::{Address, AddrV2Message};
20use crate::network::{message_network, message_bloom};
21use crate::network::message_blockdata;
22use crate::network::message_filter;
23use crate::network::message_compact_blocks;
24use crate::consensus::encode::{CheckedData, Decodable, Encodable, VarInt};
25use crate::consensus::{encode, serialize};
26use crate::util::merkleblock::MerkleBlock;
27
28/// The maximum number of [super::message_blockdata::Inventory] items in an `inv` message.
29///
30/// This limit is not currently enforced by this implementation.
31pub const MAX_INV_SIZE: usize = 50_000;
32
33/// Maximum size, in bytes, of an encoded message
34/// This by neccessity should be larger tham `MAX_VEC_SIZE`
35pub const MAX_MSG_SIZE: usize = 5_000_000;
36
37/// Serializer for command string
38#[derive(PartialEq, Eq, Clone, Debug)]
39pub struct CommandString(Cow<'static, str>);
40
41impl CommandString {
42    /// Convert from various string types into a [CommandString].
43    ///
44    /// Supported types are:
45    /// - `&'static str`
46    /// - `String`
47    ///
48    /// Returns an error if and only if the string is
49    /// larger than 12 characters in length.
50    #[deprecated(note = "Use `TryFrom::try_from` or `CommandString::try_from_static`", since = "0.29.0")]
51    pub fn try_from<S: Into<Cow<'static, str>>>(s: S) -> Result<CommandString, CommandStringError> {
52        Self::try_from_static_cow(s.into())
53    }
54
55    /// Convert `&'static str` to `CommandString`
56    ///
57    /// This is more efficient for string literals than non-static conversions because it avoids
58    /// allocation.
59    ///
60    /// # Errors
61    ///
62    /// Returns an error if and only if the string is
63    /// larger than 12 characters in length.
64    pub fn try_from_static(s: &'static str) -> Result<CommandString, CommandStringError> {
65        Self::try_from_static_cow(s.into())
66    }
67
68    fn try_from_static_cow(cow: Cow<'static, str>) -> Result<CommandString, CommandStringError> {
69        if cow.len() > 12 {
70            Err(CommandStringError { cow })
71        } else {
72            Ok(CommandString(cow))
73        }
74    }
75}
76
77impl TryFrom<String> for CommandString {
78    type Error = CommandStringError;
79
80    fn try_from(value: String) -> Result<Self, Self::Error> {
81        Self::try_from_static_cow(value.into())
82    }
83}
84
85impl TryFrom<Box<str>> for CommandString {
86    type Error = CommandStringError;
87
88    fn try_from(value: Box<str>) -> Result<Self, Self::Error> {
89        Self::try_from_static_cow(String::from(value).into())
90    }
91}
92
93impl<'a> TryFrom<&'a str> for CommandString {
94    type Error = CommandStringError;
95
96    fn try_from(value: &'a str) -> Result<Self, Self::Error> {
97        Self::try_from_static_cow(value.to_owned().into())
98    }
99}
100
101impl core::str::FromStr for CommandString {
102    type Err = CommandStringError;
103
104    fn from_str(s: &str) -> Result<Self, Self::Err> {
105        Self::try_from_static_cow(s.to_owned().into())
106    }
107}
108
109impl fmt::Display for CommandString {
110    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111        f.write_str(self.0.as_ref())
112    }
113}
114
115impl AsRef<str> for CommandString {
116    fn as_ref(&self) -> &str {
117        self.0.as_ref()
118    }
119}
120
121impl Encodable for CommandString {
122    #[inline]
123    fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
124        let mut rawbytes = [0u8; 12];
125        let strbytes = self.0.as_bytes();
126        debug_assert!(strbytes.len() <= 12);
127        rawbytes[..strbytes.len()].copy_from_slice(strbytes);
128        rawbytes.consensus_encode(w)
129    }
130}
131
132impl Decodable for CommandString {
133    #[inline]
134    fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
135        let rawbytes: [u8; 12] = Decodable::consensus_decode(r)?;
136        let rv = iter::FromIterator::from_iter(
137            rawbytes
138                .iter()
139                .filter_map(|&u| if u > 0 { Some(u as char) } else { None })
140        );
141        Ok(CommandString(rv))
142    }
143}
144
145/// Error returned when a command string is invalid.
146///
147/// This is currently returned for command strings longer than 12.
148#[derive(Clone, Debug)]
149pub struct CommandStringError {
150    cow: Cow<'static, str>,
151}
152
153impl fmt::Display for CommandStringError {
154    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
155        write!(f, "the command string '{}' has length {} which is larger than 12", self.cow, self.cow.len())
156    }
157}
158
159#[cfg(feature = "std")]
160#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
161impl std::error::Error for CommandStringError {
162    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
163        None
164    }
165}
166
167/// A Network message
168#[derive(Clone, Debug, PartialEq, Eq)]
169pub struct RawNetworkMessage {
170    /// Magic bytes to identify the network these messages are meant for
171    pub magic: u32,
172    /// The actual message data
173    pub payload: NetworkMessage
174}
175
176/// A Network message payload. Proper documentation is available on at
177/// [Bitcoin Wiki: Protocol Specification](https://en.bitcoin.it/wiki/Protocol_specification)
178#[derive(Clone, PartialEq, Eq, Debug)]
179pub enum NetworkMessage {
180    /// `version`
181    Version(message_network::VersionMessage),
182    /// `verack`
183    Verack,
184    /// `addr`
185    Addr(Vec<(u32, Address)>),
186    /// `inv`
187    Inv(Vec<message_blockdata::Inventory>),
188    /// `getdata`
189    GetData(Vec<message_blockdata::Inventory>),
190    /// `notfound`
191    NotFound(Vec<message_blockdata::Inventory>),
192    /// `getblocks`
193    GetBlocks(message_blockdata::GetBlocksMessage),
194    /// `getheaders`
195    GetHeaders(message_blockdata::GetHeadersMessage),
196    /// `mempool`
197    MemPool,
198    /// tx
199    Tx(transaction::Transaction),
200    /// `block`
201    Block(block::Block),
202    /// `headers`
203    Headers(Vec<block::BlockHeader>),
204    /// `sendheaders`
205    SendHeaders,
206    /// `getaddr`
207    GetAddr,
208    // TODO: checkorder,
209    // TODO: submitorder,
210    // TODO: reply,
211    /// `ping`
212    Ping(u64),
213    /// `pong`
214    Pong(u64),
215    /// `merkleblock`
216    MerkleBlock(MerkleBlock),
217    /// BIP 37 `filterload`
218    FilterLoad(message_bloom::FilterLoad),
219    /// BIP 37 `filteradd`
220    FilterAdd(message_bloom::FilterAdd),
221    /// BIP 37 `filterclear`
222    FilterClear,
223    /// BIP157 getcfilters
224    GetCFilters(message_filter::GetCFilters),
225    /// BIP157 cfilter
226    CFilter(message_filter::CFilter),
227    /// BIP157 getcfheaders
228    GetCFHeaders(message_filter::GetCFHeaders),
229    /// BIP157 cfheaders
230    CFHeaders(message_filter::CFHeaders),
231    /// BIP157 getcfcheckpt
232    GetCFCheckpt(message_filter::GetCFCheckpt),
233    /// BIP157 cfcheckpt
234    CFCheckpt(message_filter::CFCheckpt),
235    /// BIP152 sendcmpct
236    SendCmpct(message_compact_blocks::SendCmpct),
237    /// BIP152 cmpctblock
238    CmpctBlock(message_compact_blocks::CmpctBlock),
239    /// BIP152 getblocktxn
240    GetBlockTxn(message_compact_blocks::GetBlockTxn),
241    /// BIP152 blocktxn
242    BlockTxn(message_compact_blocks::BlockTxn),
243    /// `alert`
244    Alert(Vec<u8>),
245    /// `reject`
246    Reject(message_network::Reject),
247    /// `feefilter`
248    FeeFilter(i64),
249    /// `wtxidrelay`
250    WtxidRelay,
251    /// `addrv2`
252    AddrV2(Vec<AddrV2Message>),
253    /// `sendaddrv2`
254    SendAddrV2,
255
256    /// Any other message.
257    Unknown {
258        /// The command of this message.
259        command: CommandString,
260        /// The payload of this message.
261        payload: Vec<u8>,
262    }
263}
264
265impl NetworkMessage {
266    /// Return the message command as a static string reference.
267    ///
268    /// This returns `"unknown"` for [NetworkMessage::Unknown],
269    /// regardless of the actual command in the unknown message.
270    /// Use the [Self::command] method to get the command for unknown messages.
271    pub fn cmd(&self) -> &'static str {
272        match *self {
273            NetworkMessage::Version(_) => "version",
274            NetworkMessage::Verack     => "verack",
275            NetworkMessage::Addr(_)    => "addr",
276            NetworkMessage::Inv(_)     => "inv",
277            NetworkMessage::GetData(_) => "getdata",
278            NetworkMessage::NotFound(_) => "notfound",
279            NetworkMessage::GetBlocks(_) => "getblocks",
280            NetworkMessage::GetHeaders(_) => "getheaders",
281            NetworkMessage::MemPool    => "mempool",
282            NetworkMessage::Tx(_)      => "tx",
283            NetworkMessage::Block(_)   => "block",
284            NetworkMessage::Headers(_) => "headers",
285            NetworkMessage::SendHeaders => "sendheaders",
286            NetworkMessage::GetAddr    => "getaddr",
287            NetworkMessage::Ping(_)    => "ping",
288            NetworkMessage::Pong(_)    => "pong",
289            NetworkMessage::MerkleBlock(_) => "merkleblock",
290            NetworkMessage::FilterLoad(_) => "filterload",
291            NetworkMessage::FilterAdd(_)    => "filteradd",
292            NetworkMessage::FilterClear    => "filterclear",
293            NetworkMessage::GetCFilters(_) => "getcfilters",
294            NetworkMessage::CFilter(_) => "cfilter",
295            NetworkMessage::GetCFHeaders(_) => "getcfheaders",
296            NetworkMessage::CFHeaders(_) => "cfheaders",
297            NetworkMessage::GetCFCheckpt(_) => "getcfcheckpt",
298            NetworkMessage::CFCheckpt(_) => "cfcheckpt",
299            NetworkMessage::SendCmpct(_) => "sendcmpct",
300            NetworkMessage::CmpctBlock(_) => "cmpctblock",
301            NetworkMessage::GetBlockTxn(_) => "getblocktxn",
302            NetworkMessage::BlockTxn(_) => "blocktxn",
303            NetworkMessage::Alert(_)    => "alert",
304            NetworkMessage::Reject(_)    => "reject",
305            NetworkMessage::FeeFilter(_) => "feefilter",
306            NetworkMessage::WtxidRelay => "wtxidrelay",
307            NetworkMessage::AddrV2(_) => "addrv2",
308            NetworkMessage::SendAddrV2 => "sendaddrv2",
309            NetworkMessage::Unknown { .. } => "unknown",
310        }
311    }
312
313    /// Return the CommandString for the message command.
314    pub fn command(&self) -> CommandString {
315        match *self {
316            NetworkMessage::Unknown { command: ref c, .. } => c.clone(),
317            _ => CommandString::try_from_static(self.cmd()).expect("cmd returns valid commands")
318        }
319    }
320}
321
322impl RawNetworkMessage {
323    /// Return the message command as a static string reference.
324    ///
325    /// This returns `"unknown"` for [NetworkMessage::Unknown],
326    /// regardless of the actual command in the unknown message.
327    /// Use the [Self::command] method to get the command for unknown messages.
328    pub fn cmd(&self) -> &'static str {
329        self.payload.cmd()
330    }
331
332    /// Return the CommandString for the message command.
333    pub fn command(&self) -> CommandString {
334        self.payload.command()
335    }
336}
337
338struct HeaderSerializationWrapper<'a>(&'a Vec<block::BlockHeader>);
339
340impl<'a> Encodable for HeaderSerializationWrapper<'a> {
341    #[inline]
342    fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
343        let mut len = 0;
344        len += VarInt(self.0.len() as u64).consensus_encode(w)?;
345        for header in self.0.iter() {
346            len += header.consensus_encode(w)?;
347            len += 0u8.consensus_encode(w)?;
348        }
349        Ok(len)
350    }
351}
352
353impl Encodable for RawNetworkMessage {
354    fn consensus_encode<W: io::Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
355        let mut len = 0;
356        len += self.magic.consensus_encode(w)?;
357        len += self.command().consensus_encode(w)?;
358        len += CheckedData(match self.payload {
359            NetworkMessage::Version(ref dat) => serialize(dat),
360            NetworkMessage::Addr(ref dat)    => serialize(dat),
361            NetworkMessage::Inv(ref dat)     => serialize(dat),
362            NetworkMessage::GetData(ref dat) => serialize(dat),
363            NetworkMessage::NotFound(ref dat) => serialize(dat),
364            NetworkMessage::GetBlocks(ref dat) => serialize(dat),
365            NetworkMessage::GetHeaders(ref dat) => serialize(dat),
366            NetworkMessage::Tx(ref dat)      => serialize(dat),
367            NetworkMessage::Block(ref dat)   => serialize(dat),
368            NetworkMessage::Headers(ref dat) => serialize(&HeaderSerializationWrapper(dat)),
369            NetworkMessage::Ping(ref dat)    => serialize(dat),
370            NetworkMessage::Pong(ref dat)    => serialize(dat),
371            NetworkMessage::MerkleBlock(ref dat)    => serialize(dat),
372            NetworkMessage::FilterLoad(ref dat)    => serialize(dat),
373            NetworkMessage::FilterAdd(ref dat)    => serialize(dat),
374            NetworkMessage::GetCFilters(ref dat) => serialize(dat),
375            NetworkMessage::CFilter(ref dat) => serialize(dat),
376            NetworkMessage::GetCFHeaders(ref dat) => serialize(dat),
377            NetworkMessage::CFHeaders(ref dat) => serialize(dat),
378            NetworkMessage::GetCFCheckpt(ref dat) => serialize(dat),
379            NetworkMessage::CFCheckpt(ref dat) => serialize(dat),
380            NetworkMessage::SendCmpct(ref dat) => serialize(dat),
381            NetworkMessage::CmpctBlock(ref dat) => serialize(dat),
382            NetworkMessage::GetBlockTxn(ref dat) => serialize(dat),
383            NetworkMessage::BlockTxn(ref dat) => serialize(dat),
384            NetworkMessage::Alert(ref dat)    => serialize(dat),
385            NetworkMessage::Reject(ref dat) => serialize(dat),
386            NetworkMessage::FeeFilter(ref data) => serialize(data),
387            NetworkMessage::AddrV2(ref dat) => serialize(dat),
388            NetworkMessage::Verack
389            | NetworkMessage::SendHeaders
390            | NetworkMessage::MemPool
391            | NetworkMessage::GetAddr
392            | NetworkMessage::WtxidRelay
393            | NetworkMessage::FilterClear
394            | NetworkMessage::SendAddrV2 => vec![],
395            NetworkMessage::Unknown { payload: ref data, .. } => serialize(data),
396        }).consensus_encode(w)?;
397        Ok(len)
398    }
399}
400
401struct HeaderDeserializationWrapper(Vec<block::BlockHeader>);
402
403impl Decodable for HeaderDeserializationWrapper {
404    #[inline]
405    fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
406        let len = VarInt::consensus_decode(r)?.0;
407        // should be above usual number of items to avoid
408        // allocation
409        let mut ret = Vec::with_capacity(core::cmp::min(1024 * 16, len as usize));
410        for _ in 0..len {
411            ret.push(Decodable::consensus_decode(r)?);
412            if u8::consensus_decode(r)? != 0u8 {
413                return Err(encode::Error::ParseFailed("Headers message should not contain transactions"));
414            }
415        }
416        Ok(HeaderDeserializationWrapper(ret))
417    }
418
419    #[inline]
420    fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
421        Self::consensus_decode_from_finite_reader(r.take(MAX_MSG_SIZE as u64).by_ref())
422    }
423}
424
425impl Decodable for RawNetworkMessage {
426    fn consensus_decode_from_finite_reader<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
427        let magic = Decodable::consensus_decode_from_finite_reader(r)?;
428        let cmd = CommandString::consensus_decode_from_finite_reader(r)?;
429        let raw_payload = CheckedData::consensus_decode_from_finite_reader(r)?.0;
430
431        let mut mem_d = io::Cursor::new(raw_payload);
432        let payload = match &cmd.0[..] {
433            "version" => NetworkMessage::Version(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
434            "verack"  => NetworkMessage::Verack,
435            "addr"    => NetworkMessage::Addr(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
436            "inv"     => NetworkMessage::Inv(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
437            "getdata" => NetworkMessage::GetData(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
438            "notfound" => NetworkMessage::NotFound(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
439            "getblocks" => NetworkMessage::GetBlocks(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
440            "getheaders" => NetworkMessage::GetHeaders(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
441            "mempool" => NetworkMessage::MemPool,
442            "block"   => NetworkMessage::Block(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
443            "headers" => NetworkMessage::Headers(
444                HeaderDeserializationWrapper::consensus_decode_from_finite_reader(&mut mem_d)?.0
445            ),
446            "sendheaders" => NetworkMessage::SendHeaders,
447            "getaddr" => NetworkMessage::GetAddr,
448            "ping"    => NetworkMessage::Ping(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
449            "pong"    => NetworkMessage::Pong(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
450            "merkleblock" => NetworkMessage::MerkleBlock(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
451            "filterload" => NetworkMessage::FilterLoad(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
452            "filteradd" => NetworkMessage::FilterAdd(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
453            "filterclear" => NetworkMessage::FilterClear,
454            "tx"      => NetworkMessage::Tx(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
455            "getcfilters" => NetworkMessage::GetCFilters(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
456            "cfilter" => NetworkMessage::CFilter(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
457            "getcfheaders" => NetworkMessage::GetCFHeaders(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
458            "cfheaders" => NetworkMessage::CFHeaders(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
459            "getcfcheckpt" => NetworkMessage::GetCFCheckpt(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
460            "cfcheckpt" => NetworkMessage::CFCheckpt(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
461            "reject" => NetworkMessage::Reject(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
462            "alert"   => NetworkMessage::Alert(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
463            "feefilter" => NetworkMessage::FeeFilter(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
464            "sendcmpct" => NetworkMessage::SendCmpct(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
465            "cmpctblock" => NetworkMessage::CmpctBlock(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
466            "getblocktxn" => NetworkMessage::GetBlockTxn(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
467            "blocktxn" => NetworkMessage::BlockTxn(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
468            "wtxidrelay" => NetworkMessage::WtxidRelay,
469            "addrv2" => NetworkMessage::AddrV2(Decodable::consensus_decode_from_finite_reader(&mut mem_d)?),
470            "sendaddrv2" => NetworkMessage::SendAddrV2,
471            _ => NetworkMessage::Unknown {
472                command: cmd,
473                payload: mem_d.into_inner(),
474            }
475        };
476        Ok(RawNetworkMessage {
477            magic,
478            payload,
479        })
480    }
481
482    #[inline]
483    fn consensus_decode<R: io::Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
484        Self::consensus_decode_from_finite_reader(r.take(MAX_MSG_SIZE as u64).by_ref())
485    }
486}
487
488#[cfg(test)]
489mod test {
490    use std::net::Ipv4Addr;
491    use super::{RawNetworkMessage, NetworkMessage, CommandString};
492    use crate::network::constants::ServiceFlags;
493    use crate::consensus::encode::{deserialize, deserialize_partial, serialize};
494    use crate::hashes::hex::FromHex;
495    use crate::hashes::sha256d::Hash;
496    use crate::hashes::Hash as HashTrait;
497    use crate::network::address::{Address, AddrV2, AddrV2Message};
498    use super::message_network::{Reject, RejectReason, VersionMessage};
499    use crate::network::message_blockdata::{Inventory, GetBlocksMessage, GetHeadersMessage};
500    use crate::blockdata::block::{Block, BlockHeader};
501    use crate::network::message_filter::{GetCFilters, CFilter, GetCFHeaders, CFHeaders, GetCFCheckpt, CFCheckpt};
502    use crate::blockdata::transaction::Transaction;
503    use crate::blockdata::script::Script;
504    use crate::network::message_bloom::{FilterAdd, FilterLoad, BloomFlags};
505    use crate::MerkleBlock;
506    use crate::network::message_compact_blocks::{GetBlockTxn, SendCmpct};
507    use crate::util::bip152::BlockTransactionsRequest;
508
509    fn hash(slice: [u8;32]) -> Hash {
510        Hash::from_slice(&slice).unwrap()
511    }
512
513    #[test]
514    fn full_round_ser_der_raw_network_message_test() {
515        // TODO: Impl Rand traits here to easily generate random values.
516        let version_msg: VersionMessage = deserialize(&Vec::from_hex("721101000100000000000000e6e0845300000000010000000000000000000000000000000000ffff0000000000000100000000000000fd87d87eeb4364f22cf54dca59412db7208d47d920cffce83ee8102f5361746f7368693a302e392e39392f2c9f040001").unwrap()).unwrap();
517        let tx: Transaction = deserialize(&Vec::from_hex("0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000").unwrap()).unwrap();
518        let block: Block = deserialize(&include_bytes!("../../test_data/testnet_block_000000000000045e0b1660b6445b5e5c5ab63c9a4f956be7e1e69be04fa4497b.raw")[..]).unwrap();
519        let header: BlockHeader = deserialize(&Vec::from_hex("010000004ddccd549d28f385ab457e98d1b11ce80bfea2c5ab93015ade4973e400000000bf4473e53794beae34e64fccc471dace6ae544180816f89591894e0f417a914cd74d6e49ffff001d323b3a7b").unwrap()).unwrap();
520        let script: Script = deserialize(&Vec::from_hex("1976a91431a420903c05a0a7de2de40c9f02ebedbacdc17288ac").unwrap()).unwrap();
521        let merkle_block: MerkleBlock = deserialize(&Vec::from_hex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101").unwrap()).unwrap();
522        let cmptblock = deserialize(&Vec::from_hex("00000030d923ad36ff2d955abab07f8a0a6e813bc6e066b973e780c5e36674cad5d1cd1f6e265f2a17a0d35cbe701fe9d06e2c6324cfe135f6233e8b767bfa3fb4479b71115dc562ffff7f2006000000000000000000000000010002000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0302ee00ffffffff0100f9029500000000015100000000").unwrap()).unwrap();
523        let blocktxn = deserialize(&Vec::from_hex("2e93c0cff39ff605020072d96bc3a8d20b8447e294d08092351c8583e08d9b5a01020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0402dc0000ffffffff0200f90295000000001976a9142b4569203694fc997e13f2c0a1383b9e16c77a0d88ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000").unwrap()).unwrap();
524
525
526        let msgs = vec![
527            NetworkMessage::Version(version_msg),
528            NetworkMessage::Verack,
529            NetworkMessage::Addr(vec![(45, Address::new(&([123,255,000,100], 833).into(), ServiceFlags::NETWORK))]),
530            NetworkMessage::Inv(vec![Inventory::Block(hash([8u8; 32]).into())]),
531            NetworkMessage::GetData(vec![Inventory::Transaction(hash([45u8; 32]).into())]),
532            NetworkMessage::NotFound(vec![Inventory::Error]),
533            NetworkMessage::GetBlocks(GetBlocksMessage::new(vec![hash([1u8; 32]).into(), hash([4u8; 32]).into()], hash([5u8; 32]).into())),
534            NetworkMessage::GetHeaders(GetHeadersMessage::new(vec![hash([10u8; 32]).into(), hash([40u8; 32]).into()], hash([50u8; 32]).into())),
535            NetworkMessage::MemPool,
536            NetworkMessage::Tx(tx),
537            NetworkMessage::Block(block),
538            NetworkMessage::Headers(vec![header]),
539            NetworkMessage::SendHeaders,
540            NetworkMessage::GetAddr,
541            NetworkMessage::Ping(15),
542            NetworkMessage::Pong(23),
543            NetworkMessage::MerkleBlock(merkle_block),
544            NetworkMessage::FilterLoad(FilterLoad {filter: Vec::from_hex("03614e9b050000000000000001").unwrap(), hash_funcs: 1, tweak: 2, flags: BloomFlags::All}),
545            NetworkMessage::FilterAdd(FilterAdd {data: script.as_bytes().to_vec()}),
546            NetworkMessage::FilterAdd(FilterAdd {data: hash([29u8; 32]).to_vec()}),
547            NetworkMessage::FilterClear,
548            NetworkMessage::GetCFilters(GetCFilters{filter_type: 2, start_height: 52, stop_hash: hash([42u8; 32]).into()}),
549            NetworkMessage::CFilter(CFilter{filter_type: 7, block_hash: hash([25u8; 32]).into(), filter: vec![1,2,3]}),
550            NetworkMessage::GetCFHeaders(GetCFHeaders{filter_type: 4, start_height: 102, stop_hash: hash([47u8; 32]).into()}),
551            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()]}),
552            NetworkMessage::GetCFCheckpt(GetCFCheckpt{filter_type: 17, stop_hash: hash([25u8; 32]).into()}),
553            NetworkMessage::CFCheckpt(CFCheckpt{filter_type: 27, stop_hash: hash([77u8; 32]).into(), filter_headers: vec![hash([3u8; 32]).into(), hash([99u8; 32]).into()]}),
554            NetworkMessage::Alert(vec![45,66,3,2,6,8,9,12,3,130]),
555            NetworkMessage::Reject(Reject{message: "Test reject".into(), ccode: RejectReason::Duplicate, reason: "Cause".into(), hash: hash([255u8; 32])}),
556            NetworkMessage::FeeFilter(1000),
557            NetworkMessage::WtxidRelay,
558            NetworkMessage::AddrV2(vec![AddrV2Message{ addr: AddrV2::Ipv4(Ipv4Addr::new(127, 0, 0, 1)), port: 0, services: ServiceFlags::NONE, time: 0 }]),
559            NetworkMessage::SendAddrV2,
560            NetworkMessage::CmpctBlock(cmptblock),
561            NetworkMessage::GetBlockTxn(GetBlockTxn { txs_request: BlockTransactionsRequest { block_hash: hash([11u8; 32]).into(), indexes: vec![0, 1, 2, 3, 10, 3002] } }),
562            NetworkMessage::BlockTxn(blocktxn),
563            NetworkMessage::SendCmpct(SendCmpct{send_compact: true, version: 8333}),
564        ];
565
566        for msg in msgs {
567            let raw_msg = RawNetworkMessage {magic: 57, payload: msg};
568            assert_eq!(deserialize::<RawNetworkMessage>(&serialize(&raw_msg)).unwrap(), raw_msg);
569        }
570
571    }
572
573    #[test]
574    fn commandstring_test() {
575        // Test converting.
576        assert_eq!(CommandString::try_from_static("AndrewAndrew").unwrap().as_ref(), "AndrewAndrew");
577        assert!(CommandString::try_from_static("AndrewAndrewA").is_err());
578
579        // Test serializing.
580        let cs = CommandString("Andrew".into());
581        assert_eq!(serialize(&cs), vec![0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0, 0]);
582
583        // Test deserializing
584        let cs: Result<CommandString, _> = deserialize(&[0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0, 0]);
585        assert!(cs.is_ok());
586        assert_eq!(cs.as_ref().unwrap().to_string(), "Andrew".to_owned());
587        assert_eq!(cs.unwrap(), CommandString::try_from_static("Andrew").unwrap());
588
589        let short_cs: Result<CommandString, _> = deserialize(&[0x41u8, 0x6e, 0x64, 0x72, 0x65, 0x77, 0, 0, 0, 0, 0]);
590        assert!(short_cs.is_err());
591    }
592
593    #[test]
594    fn serialize_verack_test() {
595        assert_eq!(serialize(&RawNetworkMessage { magic: 0xd9b4bef9, payload: NetworkMessage::Verack }),
596                             vec![0xf9, 0xbe, 0xb4, 0xd9, 0x76, 0x65, 0x72, 0x61,
597                                  0x63, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598                                  0x00, 0x00, 0x00, 0x00, 0x5d, 0xf6, 0xe0, 0xe2]);
599    }
600
601    #[test]
602    fn serialize_ping_test() {
603        assert_eq!(serialize(&RawNetworkMessage { magic: 0xd9b4bef9, payload: NetworkMessage::Ping(100) }),
604                             vec![0xf9, 0xbe, 0xb4, 0xd9, 0x70, 0x69, 0x6e, 0x67,
605                                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606                                  0x08, 0x00, 0x00, 0x00, 0x24, 0x67, 0xf1, 0x1d,
607                                  0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
608    }
609
610
611    #[test]
612    fn serialize_mempool_test() {
613        assert_eq!(serialize(&RawNetworkMessage { magic: 0xd9b4bef9, payload: NetworkMessage::MemPool }),
614                             vec![0xf9, 0xbe, 0xb4, 0xd9, 0x6d, 0x65, 0x6d, 0x70,
615                                  0x6f, 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
616                                  0x00, 0x00, 0x00, 0x00, 0x5d, 0xf6, 0xe0, 0xe2]);
617    }
618
619    #[test]
620    fn serialize_getaddr_test() {
621        assert_eq!(serialize(&RawNetworkMessage { magic: 0xd9b4bef9, payload: NetworkMessage::GetAddr }),
622                             vec![0xf9, 0xbe, 0xb4, 0xd9, 0x67, 0x65, 0x74, 0x61,
623                                  0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00,
624                                  0x00, 0x00, 0x00, 0x00, 0x5d, 0xf6, 0xe0, 0xe2]);
625    }
626
627    #[test]
628    fn deserialize_getaddr_test() {
629        let msg = deserialize(
630            &[0xf9, 0xbe, 0xb4, 0xd9, 0x67, 0x65, 0x74, 0x61,
631                0x64, 0x64, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00,
632                0x00, 0x00, 0x00, 0x00, 0x5d, 0xf6, 0xe0, 0xe2]);
633        let preimage = RawNetworkMessage { magic: 0xd9b4bef9, payload: NetworkMessage::GetAddr };
634        assert!(msg.is_ok());
635        let msg : RawNetworkMessage = msg.unwrap();
636        assert_eq!(preimage.magic, msg.magic);
637        assert_eq!(preimage.payload, msg.payload);
638    }
639
640    #[test]
641    fn deserialize_version_test() {
642        let msg = deserialize::<RawNetworkMessage>(
643            &[  0xf9, 0xbe, 0xb4, 0xd9, 0x76, 0x65, 0x72, 0x73,
644                0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
645                0x66, 0x00, 0x00, 0x00, 0xbe, 0x61, 0xb8, 0x27,
646                0x7f, 0x11, 0x01, 0x00, 0x0d, 0x04, 0x00, 0x00,
647                0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x4d, 0x5c,
648                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
651                0x5b, 0xf0, 0x8c, 0x80, 0xb4, 0xbd, 0x0d, 0x04,
652                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
654                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
655                0xfa, 0xa9, 0x95, 0x59, 0xcc, 0x68, 0xa1, 0xc1,
656                0x10, 0x2f, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68,
657                0x69, 0x3a, 0x30, 0x2e, 0x31, 0x37, 0x2e, 0x31,
658                0x2f, 0x93, 0x8c, 0x08, 0x00, 0x01 ]);
659
660        assert!(msg.is_ok());
661        let msg = msg.unwrap();
662        assert_eq!(msg.magic, 0xd9b4bef9);
663        if let NetworkMessage::Version(version_msg) = msg.payload {
664            assert_eq!(version_msg.version, 70015);
665            assert_eq!(version_msg.services, ServiceFlags::NETWORK | ServiceFlags::BLOOM | ServiceFlags::WITNESS | ServiceFlags::NETWORK_LIMITED);
666            assert_eq!(version_msg.timestamp, 1548554224);
667            assert_eq!(version_msg.nonce, 13952548347456104954);
668            assert_eq!(version_msg.user_agent, "/Satoshi:0.17.1/");
669            assert_eq!(version_msg.start_height, 560275);
670            assert!(version_msg.relay);
671        } else {
672            panic!("Wrong message type");
673        }
674    }
675
676    #[test]
677    fn deserialize_partial_message_test() {
678        let data = [  0xf9, 0xbe, 0xb4, 0xd9, 0x76, 0x65, 0x72, 0x73,
679            0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
680            0x66, 0x00, 0x00, 0x00, 0xbe, 0x61, 0xb8, 0x27,
681            0x7f, 0x11, 0x01, 0x00, 0x0d, 0x04, 0x00, 0x00,
682            0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x4d, 0x5c,
683            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
684            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
685            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
686            0x5b, 0xf0, 0x8c, 0x80, 0xb4, 0xbd, 0x0d, 0x04,
687            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
690            0xfa, 0xa9, 0x95, 0x59, 0xcc, 0x68, 0xa1, 0xc1,
691            0x10, 0x2f, 0x53, 0x61, 0x74, 0x6f, 0x73, 0x68,
692            0x69, 0x3a, 0x30, 0x2e, 0x31, 0x37, 0x2e, 0x31,
693            0x2f, 0x93, 0x8c, 0x08, 0x00, 0x01, 0, 0 ];
694        let msg = deserialize_partial::<RawNetworkMessage>(&data);
695        assert!(msg.is_ok());
696
697        let (msg, consumed) = msg.unwrap();
698        assert_eq!(consumed, data.to_vec().len() - 2);
699        assert_eq!(msg.magic, 0xd9b4bef9);
700        if let NetworkMessage::Version(version_msg) = msg.payload {
701            assert_eq!(version_msg.version, 70015);
702            assert_eq!(version_msg.services, ServiceFlags::NETWORK | ServiceFlags::BLOOM | ServiceFlags::WITNESS | ServiceFlags::NETWORK_LIMITED);
703            assert_eq!(version_msg.timestamp, 1548554224);
704            assert_eq!(version_msg.nonce, 13952548347456104954);
705            assert_eq!(version_msg.user_agent, "/Satoshi:0.17.1/");
706            assert_eq!(version_msg.start_height, 560275);
707            assert!(version_msg.relay);
708        } else {
709            panic!("Wrong message type");
710        }
711    }
712}