bitcoin/p2p/
mod.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Bitcoin p2p network types.
4//!
5//! This module defines support for (de)serialization and network transport
6//! of Bitcoin data and Bitcoin p2p network messages.
7
8#[cfg(feature = "std")]
9pub mod address;
10#[cfg(feature = "std")]
11pub mod message;
12#[cfg(feature = "std")]
13pub mod message_blockdata;
14#[cfg(feature = "std")]
15pub mod message_bloom;
16#[cfg(feature = "std")]
17pub mod message_compact_blocks;
18#[cfg(feature = "std")]
19pub mod message_filter;
20#[cfg(feature = "std")]
21pub mod message_network;
22
23use core::str::FromStr;
24use core::{fmt, ops};
25
26use hex::FromHex;
27use internals::{debug_from_display, write_err};
28use io::{Read, Write};
29
30use crate::consensus::encode::{self, Decodable, Encodable};
31use crate::consensus::Params;
32use crate::prelude::*;
33use crate::network::Network;
34
35#[rustfmt::skip]
36#[doc(inline)]
37#[cfg(feature = "std")]
38pub use self::address::Address;
39
40/// Version of the protocol as appearing in network message headers.
41///
42/// This constant is used to signal to other peers which features you support. Increasing it implies
43/// that your software also supports every feature prior to this version. Doing so without support
44/// may lead to you incorrectly banning other peers or other peers banning you.
45///
46/// These are the features required for each version:
47/// 70016 - Support receiving `wtxidrelay` message between `version` and `verack` message
48/// 70015 - Support receiving invalid compact blocks from a peer without banning them
49/// 70014 - Support compact block messages `sendcmpct`, `cmpctblock`, `getblocktxn` and `blocktxn`
50/// 70013 - Support `feefilter` message
51/// 70012 - Support `sendheaders` message and announce new blocks via headers rather than inv
52/// 70011 - Support NODE_BLOOM service flag and don't support bloom filter messages if it is not set
53/// 70002 - Support `reject` message
54/// 70001 - Support bloom filter messages `filterload`, `filterclear` `filteradd`, `merkleblock` and FILTERED_BLOCK inventory type
55/// 60002 - Support `mempool` message
56/// 60001 - Support `pong` message and nonce in `ping` message
57pub const PROTOCOL_VERSION: u32 = 70001;
58
59/// Flags to indicate which network services a node supports.
60#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
61pub struct ServiceFlags(u64);
62
63impl ServiceFlags {
64    /// NONE means no services supported.
65    pub const NONE: ServiceFlags = ServiceFlags(0);
66
67    /// NETWORK means that the node is capable of serving the complete block chain. It is currently
68    /// set by all Bitcoin Core non pruned nodes, and is unset by SPV clients or other light
69    /// clients.
70    pub const NETWORK: ServiceFlags = ServiceFlags(1 << 0);
71
72    /// GETUTXO means the node is capable of responding to the getutxo protocol request.  Bitcoin
73    /// Core does not support this but a patch set called Bitcoin XT does.
74    /// See BIP 64 for details on how this is implemented.
75    pub const GETUTXO: ServiceFlags = ServiceFlags(1 << 1);
76
77    /// BLOOM means the node is capable and willing to handle bloom-filtered connections.  Bitcoin
78    /// Core nodes used to support this by default, without advertising this bit, but no longer do
79    /// as of protocol version 70011 (= NO_BLOOM_VERSION)
80    pub const BLOOM: ServiceFlags = ServiceFlags(1 << 2);
81
82    /// WITNESS indicates that a node can be asked for blocks and transactions including witness
83    /// data.
84    pub const WITNESS: ServiceFlags = ServiceFlags(1 << 3);
85
86    /// COMPACT_FILTERS means the node will service basic block filter requests.
87    /// See BIP157 and BIP158 for details on how this is implemented.
88    pub const COMPACT_FILTERS: ServiceFlags = ServiceFlags(1 << 6);
89
90    /// NETWORK_LIMITED means the same as NODE_NETWORK with the limitation of only serving the last
91    /// 288 (2 day) blocks.
92    /// See BIP159 for details on how this is implemented.
93    pub const NETWORK_LIMITED: ServiceFlags = ServiceFlags(1 << 10);
94
95    /// P2P_V2 indicates that the node supports the P2P v2 encrypted transport protocol.
96    /// See BIP324 for details on how this is implemented.
97    pub const P2P_V2: ServiceFlags = ServiceFlags(1 << 11);
98
99    // NOTE: When adding new flags, remember to update the Display impl accordingly.
100
101    /// Add [ServiceFlags] together.
102    ///
103    /// Returns itself.
104    pub fn add(&mut self, other: ServiceFlags) -> ServiceFlags {
105        self.0 |= other.0;
106        *self
107    }
108
109    /// Remove [ServiceFlags] from this.
110    ///
111    /// Returns itself.
112    pub fn remove(&mut self, other: ServiceFlags) -> ServiceFlags {
113        self.0 ^= other.0;
114        *self
115    }
116
117    /// Check whether [ServiceFlags] are included in this one.
118    pub fn has(self, flags: ServiceFlags) -> bool { (self.0 | flags.0) == self.0 }
119
120    /// Gets the integer representation of this [`ServiceFlags`].
121    pub fn to_u64(self) -> u64 { self.0 }
122}
123
124impl fmt::LowerHex for ServiceFlags {
125    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(&self.0, f) }
126}
127
128impl fmt::UpperHex for ServiceFlags {
129    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::UpperHex::fmt(&self.0, f) }
130}
131
132impl fmt::Display for ServiceFlags {
133    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134        let mut flags = *self;
135        if flags == ServiceFlags::NONE {
136            return write!(f, "ServiceFlags(NONE)");
137        }
138        let mut first = true;
139        macro_rules! write_flag {
140            ($f:ident) => {
141                if flags.has(ServiceFlags::$f) {
142                    if !first {
143                        write!(f, "|")?;
144                    }
145                    first = false;
146                    write!(f, stringify!($f))?;
147                    flags.remove(ServiceFlags::$f);
148                }
149            };
150        }
151        write!(f, "ServiceFlags(")?;
152        write_flag!(NETWORK);
153        write_flag!(GETUTXO);
154        write_flag!(BLOOM);
155        write_flag!(WITNESS);
156        write_flag!(COMPACT_FILTERS);
157        write_flag!(NETWORK_LIMITED);
158        write_flag!(P2P_V2);
159        // If there are unknown flags left, we append them in hex.
160        if flags != ServiceFlags::NONE {
161            if !first {
162                write!(f, "|")?;
163            }
164            write!(f, "0x{:x}", flags)?;
165        }
166        write!(f, ")")
167    }
168}
169
170impl From<u64> for ServiceFlags {
171    fn from(f: u64) -> Self { ServiceFlags(f) }
172}
173
174impl From<ServiceFlags> for u64 {
175    fn from(flags: ServiceFlags) -> Self { flags.0 }
176}
177
178impl ops::BitOr for ServiceFlags {
179    type Output = Self;
180
181    fn bitor(mut self, rhs: Self) -> Self { self.add(rhs) }
182}
183
184impl ops::BitOrAssign for ServiceFlags {
185    fn bitor_assign(&mut self, rhs: Self) { self.add(rhs); }
186}
187
188impl ops::BitXor for ServiceFlags {
189    type Output = Self;
190
191    fn bitxor(mut self, rhs: Self) -> Self { self.remove(rhs) }
192}
193
194impl ops::BitXorAssign for ServiceFlags {
195    fn bitxor_assign(&mut self, rhs: Self) { self.remove(rhs); }
196}
197
198impl Encodable for ServiceFlags {
199    #[inline]
200    fn consensus_encode<W: Write + ?Sized>(&self, w: &mut W) -> Result<usize, io::Error> {
201        self.0.consensus_encode(w)
202    }
203}
204
205impl Decodable for ServiceFlags {
206    #[inline]
207    fn consensus_decode<R: Read + ?Sized>(r: &mut R) -> Result<Self, encode::Error> {
208        Ok(ServiceFlags(Decodable::consensus_decode(r)?))
209    }
210}
211/// Network magic bytes to identify the cryptocurrency network the message was intended for.
212#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
213pub struct Magic([u8; 4]);
214
215impl Magic {
216    /// Bitcoin mainnet network magic bytes.
217    pub const BITCOIN: Self = Self([0xF9, 0xBE, 0xB4, 0xD9]);
218    /// Bitcoin testnet3 network magic bytes.
219    #[deprecated(since = "0.32.4", note = "Use TESTNET3 instead")]
220    pub const TESTNET: Self = Self([0x0B, 0x11, 0x09, 0x07]);
221    /// Bitcoin testnet3 network magic bytes.
222    pub const TESTNET3: Self = Self([0x0B, 0x11, 0x09, 0x07]);
223    /// Bitcoin testnet4 network magic bytes.
224    pub const TESTNET4: Self = Self([0x1c, 0x16, 0x3f, 0x28]);
225    /// Bitcoin signet network magic bytes.
226    pub const SIGNET: Self = Self([0x0A, 0x03, 0xCF, 0x40]);
227    /// Bitcoin regtest network magic bytes.
228    pub const REGTEST: Self = Self([0xFA, 0xBF, 0xB5, 0xDA]);
229
230    /// Create network magic from bytes.
231    pub fn from_bytes(bytes: [u8; 4]) -> Magic { Magic(bytes) }
232
233    /// Get network magic bytes.
234    pub fn to_bytes(self) -> [u8; 4] { self.0 }
235
236    /// Returns the magic bytes for the network defined by `params`.
237    pub fn from_params(params: impl AsRef<Params>) -> Self {
238        params.as_ref().network.into()
239    }
240}
241
242impl FromStr for Magic {
243    type Err = ParseMagicError;
244
245    fn from_str(s: &str) -> Result<Magic, Self::Err> {
246        match <[u8; 4]>::from_hex(s) {
247            Ok(magic) => Ok(Magic::from_bytes(magic)),
248            Err(e) => Err(ParseMagicError { error: e, magic: s.to_owned() }),
249        }
250    }
251}
252
253impl From<Network> for Magic {
254    fn from(network: Network) -> Magic {
255        match network {
256            // Note: new network entries must explicitly be matched in `try_from` below.
257            Network::Bitcoin => Magic::BITCOIN,
258            Network::Testnet => Magic::TESTNET3,
259            Network::Testnet4 => Magic::TESTNET4,
260            Network::Signet => Magic::SIGNET,
261            Network::Regtest => Magic::REGTEST,
262        }
263    }
264}
265
266impl TryFrom<Magic> for Network {
267    type Error = UnknownMagicError;
268
269    fn try_from(magic: Magic) -> Result<Self, Self::Error> {
270        match magic {
271            // Note: any new network entries must be matched against here.
272            Magic::BITCOIN => Ok(Network::Bitcoin),
273            Magic::TESTNET3 => Ok(Network::Testnet),
274            Magic::TESTNET4 => Ok(Network::Testnet4),
275            Magic::SIGNET => Ok(Network::Signet),
276            Magic::REGTEST => Ok(Network::Regtest),
277            _ => Err(UnknownMagicError(magic)),
278        }
279    }
280}
281
282impl fmt::Display for Magic {
283    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
284        hex::fmt_hex_exact!(f, 4, &self.0, hex::Case::Lower)?;
285        Ok(())
286    }
287}
288debug_from_display!(Magic);
289
290impl fmt::LowerHex for Magic {
291    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
292        hex::fmt_hex_exact!(f, 4, &self.0, hex::Case::Lower)?;
293        Ok(())
294    }
295}
296
297impl fmt::UpperHex for Magic {
298    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
299        hex::fmt_hex_exact!(f, 4, &self.0, hex::Case::Upper)?;
300        Ok(())
301    }
302}
303
304impl Encodable for Magic {
305    fn consensus_encode<W: Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
306        self.0.consensus_encode(writer)
307    }
308}
309
310impl Decodable for Magic {
311    fn consensus_decode<R: Read + ?Sized>(reader: &mut R) -> Result<Self, encode::Error> {
312        Ok(Magic(Decodable::consensus_decode(reader)?))
313    }
314}
315
316impl AsRef<[u8]> for Magic {
317    fn as_ref(&self) -> &[u8] { &self.0 }
318}
319
320impl AsRef<[u8; 4]> for Magic {
321    fn as_ref(&self) -> &[u8; 4] { &self.0 }
322}
323
324impl AsMut<[u8]> for Magic {
325    fn as_mut(&mut self) -> &mut [u8] { &mut self.0 }
326}
327
328impl AsMut<[u8; 4]> for Magic {
329    fn as_mut(&mut self) -> &mut [u8; 4] { &mut self.0 }
330}
331
332impl Borrow<[u8]> for Magic {
333    fn borrow(&self) -> &[u8] { &self.0 }
334}
335
336impl Borrow<[u8; 4]> for Magic {
337    fn borrow(&self) -> &[u8; 4] { &self.0 }
338}
339
340impl BorrowMut<[u8]> for Magic {
341    fn borrow_mut(&mut self) -> &mut [u8] { &mut self.0 }
342}
343
344impl BorrowMut<[u8; 4]> for Magic {
345    fn borrow_mut(&mut self) -> &mut [u8; 4] { &mut self.0 }
346}
347
348/// An error in parsing magic bytes.
349#[derive(Debug, Clone, PartialEq, Eq)]
350#[non_exhaustive]
351pub struct ParseMagicError {
352    /// The error that occurred when parsing the string.
353    error: hex::HexToArrayError,
354    /// The byte string that failed to parse.
355    magic: String,
356}
357
358impl fmt::Display for ParseMagicError {
359    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
360        write_err!(f, "failed to parse {} as network magic", self.magic; self.error)
361    }
362}
363
364#[cfg(feature = "std")]
365impl std::error::Error for ParseMagicError {
366    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.error) }
367}
368
369/// Error in creating a Network from Magic bytes.
370#[derive(Debug, Clone, PartialEq, Eq)]
371#[non_exhaustive]
372pub struct UnknownMagicError(Magic);
373
374impl fmt::Display for UnknownMagicError {
375    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
376        write!(f, "unknown network magic {}", self.0)
377    }
378}
379
380#[cfg(feature = "std")]
381impl std::error::Error for UnknownMagicError {
382    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None }
383}
384
385#[cfg(test)]
386mod tests {
387    use super::*;
388
389    #[test]
390    fn service_flags_test() {
391        let all = [
392            ServiceFlags::NETWORK,
393            ServiceFlags::GETUTXO,
394            ServiceFlags::BLOOM,
395            ServiceFlags::WITNESS,
396            ServiceFlags::COMPACT_FILTERS,
397            ServiceFlags::NETWORK_LIMITED,
398        ];
399
400        let mut flags = ServiceFlags::NONE;
401        for f in all.iter() {
402            assert!(!flags.has(*f));
403        }
404
405        flags |= ServiceFlags::WITNESS;
406        assert_eq!(flags, ServiceFlags::WITNESS);
407
408        let mut flags2 = flags | ServiceFlags::GETUTXO;
409        for f in all.iter() {
410            assert_eq!(flags2.has(*f), *f == ServiceFlags::WITNESS || *f == ServiceFlags::GETUTXO);
411        }
412
413        flags2 ^= ServiceFlags::WITNESS;
414        assert_eq!(flags2, ServiceFlags::GETUTXO);
415
416        flags2 |= ServiceFlags::COMPACT_FILTERS;
417        flags2 ^= ServiceFlags::GETUTXO;
418        assert_eq!(flags2, ServiceFlags::COMPACT_FILTERS);
419
420        // Test formatting.
421        assert_eq!("ServiceFlags(NONE)", ServiceFlags::NONE.to_string());
422        assert_eq!("ServiceFlags(WITNESS)", ServiceFlags::WITNESS.to_string());
423        let flag = ServiceFlags::WITNESS | ServiceFlags::BLOOM | ServiceFlags::NETWORK;
424        assert_eq!("ServiceFlags(NETWORK|BLOOM|WITNESS)", flag.to_string());
425        let flag = ServiceFlags::WITNESS | 0xf0.into();
426        assert_eq!("ServiceFlags(WITNESS|COMPACT_FILTERS|0xb0)", flag.to_string());
427    }
428
429    #[test]
430    fn magic_from_str() {
431        let known_network_magic_strs = [
432            ("f9beb4d9", Network::Bitcoin),
433            ("0b110907", Network::Testnet),
434            ("1c163f28", Network::Testnet4),
435            ("fabfb5da", Network::Regtest),
436            ("0a03cf40", Network::Signet),
437        ];
438
439        for (magic_str, network) in &known_network_magic_strs {
440            let magic: Magic = Magic::from_str(magic_str).unwrap();
441            assert_eq!(Network::try_from(magic).unwrap(), *network);
442            assert_eq!(&magic.to_string(), magic_str);
443        }
444    }
445}