Move p2p::constants::Magic to p2p module
In preparation for removing the `p2p::constants` module; move the `p2p::constants::Magic` type to the `p2p` module.
This commit is contained in:
parent
d9d5a4ed4f
commit
0f78943ef0
|
@ -25,21 +25,18 @@
|
||||||
//! assert_eq!(&bytes[..], &[0xF9, 0xBE, 0xB4, 0xD9]);
|
//! assert_eq!(&bytes[..], &[0xF9, 0xBE, 0xB4, 0xD9]);
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use core::borrow::{Borrow, BorrowMut};
|
|
||||||
use core::convert::TryFrom;
|
use core::convert::TryFrom;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::fmt::Display;
|
use core::fmt::Display;
|
||||||
use core::str::FromStr;
|
use core::str::FromStr;
|
||||||
|
|
||||||
use hex::FromHex;
|
use internals::write_err;
|
||||||
use internals::{debug_from_display, write_err};
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::consensus::encode::{self, Decodable, Encodable};
|
|
||||||
use crate::constants::ChainHash;
|
use crate::constants::ChainHash;
|
||||||
use crate::error::impl_std_error;
|
use crate::error::impl_std_error;
|
||||||
use crate::io;
|
use crate::p2p::Magic;
|
||||||
use crate::prelude::{String, ToOwned};
|
use crate::prelude::{String, ToOwned};
|
||||||
|
|
||||||
/// The cryptocurrency network to act on.
|
/// The cryptocurrency network to act on.
|
||||||
|
@ -65,7 +62,8 @@ impl Network {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use bitcoin::p2p::constants::{Network, Magic};
|
/// use bitcoin::p2p::Magic;
|
||||||
|
/// use bitcoin::Network;
|
||||||
/// use std::convert::TryFrom;
|
/// use std::convert::TryFrom;
|
||||||
///
|
///
|
||||||
/// assert_eq!(Ok(Network::Bitcoin), Network::try_from(Magic::from_bytes([0xF9, 0xBE, 0xB4, 0xD9])));
|
/// assert_eq!(Ok(Network::Bitcoin), Network::try_from(Magic::from_bytes([0xF9, 0xBE, 0xB4, 0xD9])));
|
||||||
|
@ -79,7 +77,8 @@ impl Network {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use bitcoin::p2p::constants::{Network, Magic};
|
/// use bitcoin::p2p::Magic;
|
||||||
|
/// use bitcoin::Network;
|
||||||
///
|
///
|
||||||
/// let network = Network::Bitcoin;
|
/// let network = Network::Bitcoin;
|
||||||
/// assert_eq!(network.magic(), Magic::from_bytes([0xF9, 0xBE, 0xB4, 0xD9]));
|
/// assert_eq!(network.magic(), Magic::from_bytes([0xF9, 0xBE, 0xB4, 0xD9]));
|
||||||
|
@ -271,164 +270,9 @@ impl TryFrom<ChainHash> for Network {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Network magic bytes to identify the cryptocurrency network the message was intended for.
|
|
||||||
#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
|
|
||||||
pub struct Magic([u8; 4]);
|
|
||||||
|
|
||||||
impl Magic {
|
|
||||||
/// Bitcoin mainnet network magic bytes.
|
|
||||||
pub const BITCOIN: Self = Self([0xF9, 0xBE, 0xB4, 0xD9]);
|
|
||||||
/// Bitcoin testnet network magic bytes.
|
|
||||||
pub const TESTNET: Self = Self([0x0B, 0x11, 0x09, 0x07]);
|
|
||||||
/// Bitcoin signet network magic bytes.
|
|
||||||
pub const SIGNET: Self = Self([0x0A, 0x03, 0xCF, 0x40]);
|
|
||||||
/// Bitcoin regtest network magic bytes.
|
|
||||||
pub const REGTEST: Self = Self([0xFA, 0xBF, 0xB5, 0xDA]);
|
|
||||||
|
|
||||||
/// Create network magic from bytes.
|
|
||||||
pub fn from_bytes(bytes: [u8; 4]) -> Magic { Magic(bytes) }
|
|
||||||
|
|
||||||
/// Get network magic bytes.
|
|
||||||
pub fn to_bytes(self) -> [u8; 4] { self.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An error in parsing magic bytes.
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub struct ParseMagicError {
|
|
||||||
/// The error that occurred when parsing the string.
|
|
||||||
error: hex::HexToArrayError,
|
|
||||||
/// The byte string that failed to parse.
|
|
||||||
magic: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for Magic {
|
|
||||||
type Err = ParseMagicError;
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Magic, Self::Err> {
|
|
||||||
match <[u8; 4]>::from_hex(s) {
|
|
||||||
Ok(magic) => Ok(Magic::from_bytes(magic)),
|
|
||||||
Err(e) => Err(ParseMagicError { error: e, magic: s.to_owned() }),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Network> for Magic {
|
|
||||||
fn from(network: Network) -> Magic {
|
|
||||||
match network {
|
|
||||||
// Note: new network entries must explicitly be matched in `try_from` below.
|
|
||||||
Network::Bitcoin => Magic::BITCOIN,
|
|
||||||
Network::Testnet => Magic::TESTNET,
|
|
||||||
Network::Signet => Magic::SIGNET,
|
|
||||||
Network::Regtest => Magic::REGTEST,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Error in creating a Network from Magic bytes.
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub struct UnknownMagic(Magic);
|
|
||||||
|
|
||||||
impl TryFrom<Magic> for Network {
|
|
||||||
type Error = UnknownMagic;
|
|
||||||
|
|
||||||
fn try_from(magic: Magic) -> Result<Self, Self::Error> {
|
|
||||||
match magic {
|
|
||||||
// Note: any new network entries must be matched against here.
|
|
||||||
Magic::BITCOIN => Ok(Network::Bitcoin),
|
|
||||||
Magic::TESTNET => Ok(Network::Testnet),
|
|
||||||
Magic::SIGNET => Ok(Network::Signet),
|
|
||||||
Magic::REGTEST => Ok(Network::Regtest),
|
|
||||||
_ => Err(UnknownMagic(magic)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Magic {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
||||||
hex::fmt_hex_exact!(f, 4, &self.0, hex::Case::Lower)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug_from_display!(Magic);
|
|
||||||
|
|
||||||
impl fmt::LowerHex for Magic {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
||||||
hex::fmt_hex_exact!(f, 4, &self.0, hex::Case::Lower)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::UpperHex for Magic {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
||||||
hex::fmt_hex_exact!(f, 4, &self.0, hex::Case::Upper)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Encodable for Magic {
|
|
||||||
fn consensus_encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
|
|
||||||
self.0.consensus_encode(writer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decodable for Magic {
|
|
||||||
fn consensus_decode<R: io::Read + ?Sized>(reader: &mut R) -> Result<Self, encode::Error> {
|
|
||||||
Ok(Magic(Decodable::consensus_decode(reader)?))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsRef<[u8]> for Magic {
|
|
||||||
fn as_ref(&self) -> &[u8] { &self.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsRef<[u8; 4]> for Magic {
|
|
||||||
fn as_ref(&self) -> &[u8; 4] { &self.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsMut<[u8]> for Magic {
|
|
||||||
fn as_mut(&mut self) -> &mut [u8] { &mut self.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsMut<[u8; 4]> for Magic {
|
|
||||||
fn as_mut(&mut self) -> &mut [u8; 4] { &mut self.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Borrow<[u8]> for Magic {
|
|
||||||
fn borrow(&self) -> &[u8] { &self.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Borrow<[u8; 4]> for Magic {
|
|
||||||
fn borrow(&self) -> &[u8; 4] { &self.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BorrowMut<[u8]> for Magic {
|
|
||||||
fn borrow_mut(&mut self) -> &mut [u8] { &mut self.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BorrowMut<[u8; 4]> for Magic {
|
|
||||||
fn borrow_mut(&mut self) -> &mut [u8; 4] { &mut self.0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for ParseMagicError {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
||||||
write_err!(f, "failed to parse {} as network magic", self.magic; self.error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl_std_error!(ParseMagicError, error);
|
|
||||||
|
|
||||||
impl fmt::Display for UnknownMagic {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
||||||
write!(f, "unknown network magic {}", self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl_std_error!(UnknownMagic);
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::convert::TryFrom;
|
use super::Network;
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use super::{Magic, Network};
|
|
||||||
use crate::consensus::encode::{deserialize, serialize};
|
use crate::consensus::encode::{deserialize, serialize};
|
||||||
use crate::p2p::ServiceFlags;
|
use crate::p2p::ServiceFlags;
|
||||||
|
|
||||||
|
@ -522,22 +366,6 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn magic_from_str() {
|
|
||||||
let known_network_magic_strs = [
|
|
||||||
("f9beb4d9", Network::Bitcoin),
|
|
||||||
("0b110907", Network::Testnet),
|
|
||||||
("fabfb5da", Network::Regtest),
|
|
||||||
("0a03cf40", Network::Signet),
|
|
||||||
];
|
|
||||||
|
|
||||||
for (magic_str, network) in &known_network_magic_strs {
|
|
||||||
let magic: Magic = Magic::from_str(magic_str).unwrap();
|
|
||||||
assert_eq!(Network::try_from(magic).unwrap(), *network);
|
|
||||||
assert_eq!(&magic.to_string(), magic_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_to_core_arg() {
|
fn from_to_core_arg() {
|
||||||
let expected_pairs = [
|
let expected_pairs = [
|
||||||
|
|
|
@ -17,9 +17,9 @@ use crate::consensus::encode::{self, CheckedData, Decodable, Encodable, VarInt};
|
||||||
use crate::io;
|
use crate::io;
|
||||||
use crate::merkle_tree::MerkleBlock;
|
use crate::merkle_tree::MerkleBlock;
|
||||||
use crate::p2p::address::{AddrV2Message, Address};
|
use crate::p2p::address::{AddrV2Message, Address};
|
||||||
use crate::p2p::constants::Magic;
|
|
||||||
use crate::p2p::{
|
use crate::p2p::{
|
||||||
message_blockdata, message_bloom, message_compact_blocks, message_filter, message_network,
|
message_blockdata, message_bloom, message_compact_blocks, message_filter, message_network,
|
||||||
|
Magic,
|
||||||
};
|
};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
@ -550,14 +550,14 @@ mod test {
|
||||||
use crate::consensus::encode::{deserialize, deserialize_partial, serialize};
|
use crate::consensus::encode::{deserialize, deserialize_partial, serialize};
|
||||||
use crate::internal_macros::hex;
|
use crate::internal_macros::hex;
|
||||||
use crate::p2p::address::{AddrV2, AddrV2Message, Address};
|
use crate::p2p::address::{AddrV2, AddrV2Message, Address};
|
||||||
use crate::p2p::constants::{Magic, Network};
|
use crate::p2p::constants::Network;
|
||||||
use crate::p2p::message_blockdata::{GetBlocksMessage, GetHeadersMessage, Inventory};
|
use crate::p2p::message_blockdata::{GetBlocksMessage, GetHeadersMessage, Inventory};
|
||||||
use crate::p2p::message_bloom::{BloomFlags, FilterAdd, FilterLoad};
|
use crate::p2p::message_bloom::{BloomFlags, FilterAdd, FilterLoad};
|
||||||
use crate::p2p::message_compact_blocks::{GetBlockTxn, SendCmpct};
|
use crate::p2p::message_compact_blocks::{GetBlockTxn, SendCmpct};
|
||||||
use crate::p2p::message_filter::{
|
use crate::p2p::message_filter::{
|
||||||
CFCheckpt, CFHeaders, CFilter, GetCFCheckpt, GetCFHeaders, GetCFilters,
|
CFCheckpt, CFHeaders, CFilter, GetCFCheckpt, GetCFHeaders, GetCFilters,
|
||||||
};
|
};
|
||||||
use crate::p2p::ServiceFlags;
|
use crate::p2p::{Magic, ServiceFlags};
|
||||||
|
|
||||||
fn hash(slice: [u8; 32]) -> Hash { Hash::from_slice(&slice).unwrap() }
|
fn hash(slice: [u8; 32]) -> Hash { Hash::from_slice(&slice).unwrap() }
|
||||||
|
|
||||||
|
|
|
@ -24,11 +24,18 @@ pub mod message_filter;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub mod message_network;
|
pub mod message_network;
|
||||||
|
|
||||||
|
use core::convert::TryFrom;
|
||||||
|
use core::str::FromStr;
|
||||||
use core::{fmt, ops};
|
use core::{fmt, ops};
|
||||||
|
|
||||||
pub use self::constants::Magic;
|
use hex::FromHex;
|
||||||
|
use internals::{debug_from_display, write_err};
|
||||||
|
|
||||||
use crate::consensus::encode::{self, Decodable, Encodable};
|
use crate::consensus::encode::{self, Decodable, Encodable};
|
||||||
|
use crate::error::impl_std_error;
|
||||||
use crate::io;
|
use crate::io;
|
||||||
|
use crate::p2p::constants::Network;
|
||||||
|
use crate::prelude::{Borrow, BorrowMut, String, ToOwned};
|
||||||
|
|
||||||
/// Version of the protocol as appearing in network message headers.
|
/// Version of the protocol as appearing in network message headers.
|
||||||
///
|
///
|
||||||
|
@ -196,6 +203,157 @@ impl Decodable for ServiceFlags {
|
||||||
Ok(ServiceFlags(Decodable::consensus_decode(r)?))
|
Ok(ServiceFlags(Decodable::consensus_decode(r)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// Network magic bytes to identify the cryptocurrency network the message was intended for.
|
||||||
|
#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
|
||||||
|
pub struct Magic([u8; 4]);
|
||||||
|
|
||||||
|
impl Magic {
|
||||||
|
/// Bitcoin mainnet network magic bytes.
|
||||||
|
pub const BITCOIN: Self = Self([0xF9, 0xBE, 0xB4, 0xD9]);
|
||||||
|
/// Bitcoin testnet network magic bytes.
|
||||||
|
pub const TESTNET: Self = Self([0x0B, 0x11, 0x09, 0x07]);
|
||||||
|
/// Bitcoin signet network magic bytes.
|
||||||
|
pub const SIGNET: Self = Self([0x0A, 0x03, 0xCF, 0x40]);
|
||||||
|
/// Bitcoin regtest network magic bytes.
|
||||||
|
pub const REGTEST: Self = Self([0xFA, 0xBF, 0xB5, 0xDA]);
|
||||||
|
|
||||||
|
/// Create network magic from bytes.
|
||||||
|
pub fn from_bytes(bytes: [u8; 4]) -> Magic { Magic(bytes) }
|
||||||
|
|
||||||
|
/// Get network magic bytes.
|
||||||
|
pub fn to_bytes(self) -> [u8; 4] { self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An error in parsing magic bytes.
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
|
pub struct ParseMagicError {
|
||||||
|
/// The error that occurred when parsing the string.
|
||||||
|
error: hex::HexToArrayError,
|
||||||
|
/// The byte string that failed to parse.
|
||||||
|
magic: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Magic {
|
||||||
|
type Err = ParseMagicError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Magic, Self::Err> {
|
||||||
|
match <[u8; 4]>::from_hex(s) {
|
||||||
|
Ok(magic) => Ok(Magic::from_bytes(magic)),
|
||||||
|
Err(e) => Err(ParseMagicError { error: e, magic: s.to_owned() }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Network> for Magic {
|
||||||
|
fn from(network: Network) -> Magic {
|
||||||
|
match network {
|
||||||
|
// Note: new network entries must explicitly be matched in `try_from` below.
|
||||||
|
Network::Bitcoin => Magic::BITCOIN,
|
||||||
|
Network::Testnet => Magic::TESTNET,
|
||||||
|
Network::Signet => Magic::SIGNET,
|
||||||
|
Network::Regtest => Magic::REGTEST,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Error in creating a Network from Magic bytes.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct UnknownMagic(Magic);
|
||||||
|
|
||||||
|
impl TryFrom<Magic> for Network {
|
||||||
|
type Error = UnknownMagic;
|
||||||
|
|
||||||
|
fn try_from(magic: Magic) -> Result<Self, Self::Error> {
|
||||||
|
match magic {
|
||||||
|
// Note: any new network entries must be matched against here.
|
||||||
|
Magic::BITCOIN => Ok(Network::Bitcoin),
|
||||||
|
Magic::TESTNET => Ok(Network::Testnet),
|
||||||
|
Magic::SIGNET => Ok(Network::Signet),
|
||||||
|
Magic::REGTEST => Ok(Network::Regtest),
|
||||||
|
_ => Err(UnknownMagic(magic)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Magic {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
hex::fmt_hex_exact!(f, 4, &self.0, hex::Case::Lower)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug_from_display!(Magic);
|
||||||
|
|
||||||
|
impl fmt::LowerHex for Magic {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
hex::fmt_hex_exact!(f, 4, &self.0, hex::Case::Lower)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::UpperHex for Magic {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
hex::fmt_hex_exact!(f, 4, &self.0, hex::Case::Upper)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodable for Magic {
|
||||||
|
fn consensus_encode<W: io::Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
|
||||||
|
self.0.consensus_encode(writer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for Magic {
|
||||||
|
fn consensus_decode<R: io::Read + ?Sized>(reader: &mut R) -> Result<Self, encode::Error> {
|
||||||
|
Ok(Magic(Decodable::consensus_decode(reader)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<[u8]> for Magic {
|
||||||
|
fn as_ref(&self) -> &[u8] { &self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<[u8; 4]> for Magic {
|
||||||
|
fn as_ref(&self) -> &[u8; 4] { &self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsMut<[u8]> for Magic {
|
||||||
|
fn as_mut(&mut self) -> &mut [u8] { &mut self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsMut<[u8; 4]> for Magic {
|
||||||
|
fn as_mut(&mut self) -> &mut [u8; 4] { &mut self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Borrow<[u8]> for Magic {
|
||||||
|
fn borrow(&self) -> &[u8] { &self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Borrow<[u8; 4]> for Magic {
|
||||||
|
fn borrow(&self) -> &[u8; 4] { &self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BorrowMut<[u8]> for Magic {
|
||||||
|
fn borrow_mut(&mut self) -> &mut [u8] { &mut self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BorrowMut<[u8; 4]> for Magic {
|
||||||
|
fn borrow_mut(&mut self) -> &mut [u8; 4] { &mut self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ParseMagicError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
write_err!(f, "failed to parse {} as network magic", self.magic; self.error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl_std_error!(ParseMagicError, error);
|
||||||
|
|
||||||
|
impl fmt::Display for UnknownMagic {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
write!(f, "unknown network magic {}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl_std_error!(UnknownMagic);
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
@ -240,4 +398,20 @@ mod tests {
|
||||||
let flag = ServiceFlags::WITNESS | 0xf0.into();
|
let flag = ServiceFlags::WITNESS | 0xf0.into();
|
||||||
assert_eq!("ServiceFlags(WITNESS|COMPACT_FILTERS|0xb0)", flag.to_string());
|
assert_eq!("ServiceFlags(WITNESS|COMPACT_FILTERS|0xb0)", flag.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn magic_from_str() {
|
||||||
|
let known_network_magic_strs = [
|
||||||
|
("f9beb4d9", Network::Bitcoin),
|
||||||
|
("0b110907", Network::Testnet),
|
||||||
|
("fabfb5da", Network::Regtest),
|
||||||
|
("0a03cf40", Network::Signet),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (magic_str, network) in &known_network_magic_strs {
|
||||||
|
let magic: Magic = Magic::from_str(magic_str).unwrap();
|
||||||
|
assert_eq!(Network::try_from(magic).unwrap(), *network);
|
||||||
|
assert_eq!(&magic.to_string(), magic_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue