Remove all `p2p` dependency from `network`

Motivated by moving the `p2p` module to its own crate. `TryFrom` and
`From` are already implement for converting to and from
`Network`/`Magic`. The methods related to `Magic` are removed from
`Network`, as well as any reference to `p2p` in the documentation, as
`bitcoin` would no longer depend on `p2p`.

The deser roundtrip test are relocated to `p2p/mod.rs`
This commit is contained in:
rustaceanrob 2025-05-27 10:23:00 +01:00
parent 3c8eeeb42a
commit cbe04b00c6
No known key found for this signature in database
GPG Key ID: F4DD8F8486EC0F1F
4 changed files with 37 additions and 79 deletions

View File

@ -4,7 +4,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use std::{env, process}; use std::{env, process};
use bitcoin::consensus::{encode, Decodable}; use bitcoin::consensus::{encode, Decodable};
use bitcoin::p2p::{self, address, message, message_network}; use bitcoin::p2p::{self, address, message, message_network, Magic};
use bitcoin::secp256k1::rand::Rng; use bitcoin::secp256k1::rand::Rng;
fn main() { fn main() {
@ -26,7 +26,7 @@ fn main() {
let version_message = build_version_message(address); let version_message = build_version_message(address);
let first_message = let first_message =
message::RawNetworkMessage::new(bitcoin::Network::Bitcoin.magic(), version_message); message::RawNetworkMessage::new(Magic::BITCOIN, version_message);
if let Ok(mut stream) = TcpStream::connect(address) { if let Ok(mut stream) = TcpStream::connect(address) {
// Send the message // Send the message
@ -44,7 +44,7 @@ fn main() {
println!("Received version message: {:?}", reply.payload()); println!("Received version message: {:?}", reply.payload());
let second_message = message::RawNetworkMessage::new( let second_message = message::RawNetworkMessage::new(
bitcoin::Network::Bitcoin.magic(), Magic::BITCOIN,
message::NetworkMessage::Verack, message::NetworkMessage::Verack,
); );

View File

@ -5,18 +5,6 @@
//! The term "network" is overloaded, here [`Network`] refers to the specific //! The term "network" is overloaded, here [`Network`] refers to the specific
//! Bitcoin network we are operating on e.g., signet, regtest. The terms //! Bitcoin network we are operating on e.g., signet, regtest. The terms
//! "network" and "chain" are often used interchangeably for this concept. //! "network" and "chain" are often used interchangeably for this concept.
//!
//! # Example: encoding a network's magic bytes
//!
//! ```rust
//! use bitcoin::Network;
//! use bitcoin::consensus::encode::serialize;
//!
//! let network = Network::Bitcoin;
//! let bytes = serialize(&network.magic());
//!
//! assert_eq!(&bytes[..], &[0xF9, 0xBE, 0xB4, 0xD9]);
//! ```
pub mod params; pub mod params;
@ -28,7 +16,6 @@ use internals::write_err;
use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer}; use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
use crate::constants::ChainHash; use crate::constants::ChainHash;
use crate::p2p::Magic;
use crate::prelude::{String, ToOwned}; use crate::prelude::{String, ToOwned};
#[rustfmt::skip] // Keep public re-exports separate. #[rustfmt::skip] // Keep public re-exports separate.
@ -124,33 +111,6 @@ impl<'de> Deserialize<'de> for Network {
} }
impl Network { impl Network {
/// Constructs a new `Network` from the magic bytes.
///
/// # Examples
///
/// ```rust
/// use bitcoin::p2p::Magic;
/// use bitcoin::Network;
///
/// assert_eq!(Ok(Network::Bitcoin), Network::try_from(Magic::from_bytes([0xF9, 0xBE, 0xB4, 0xD9])));
/// assert_eq!(None, Network::from_magic(Magic::from_bytes([0xFF, 0xFF, 0xFF, 0xFF])));
/// ```
pub fn from_magic(magic: Magic) -> Option<Network> { Network::try_from(magic).ok() }
/// Return the network magic bytes, which should be encoded little-endian
/// at the start of every message
///
/// # Examples
///
/// ```rust
/// use bitcoin::p2p::Magic;
/// use bitcoin::Network;
///
/// let network = Network::Bitcoin;
/// assert_eq!(network.magic(), Magic::from_bytes([0xF9, 0xBE, 0xB4, 0xD9]));
/// ```
pub fn magic(self) -> Magic { Magic::from(self) }
/// Converts a `Network` to its equivalent `bitcoind -chain` argument name. /// Converts a `Network` to its equivalent `bitcoind -chain` argument name.
/// ///
/// ```bash /// ```bash
@ -363,34 +323,6 @@ impl TryFrom<ChainHash> for Network {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{Network, TestnetVersion}; use super::{Network, TestnetVersion};
use crate::consensus::encode::{deserialize, serialize};
#[test]
fn serialize_deserialize() {
assert_eq!(serialize(&Network::Bitcoin.magic()), &[0xf9, 0xbe, 0xb4, 0xd9]);
assert_eq!(
serialize(&Network::Testnet(TestnetVersion::V3).magic()),
&[0x0b, 0x11, 0x09, 0x07]
);
assert_eq!(
serialize(&Network::Testnet(TestnetVersion::V4).magic()),
&[0x1c, 0x16, 0x3f, 0x28]
);
assert_eq!(serialize(&Network::Signet.magic()), &[0x0a, 0x03, 0xcf, 0x40]);
assert_eq!(serialize(&Network::Regtest.magic()), &[0xfa, 0xbf, 0xb5, 0xda]);
assert_eq!(deserialize(&[0xf9, 0xbe, 0xb4, 0xd9]).ok(), Some(Network::Bitcoin.magic()));
assert_eq!(
deserialize(&[0x0b, 0x11, 0x09, 0x07]).ok(),
Some(Network::Testnet(TestnetVersion::V3).magic())
);
assert_eq!(
deserialize(&[0x1c, 0x16, 0x3f, 0x28]).ok(),
Some(Network::Testnet(TestnetVersion::V4).magic())
);
assert_eq!(deserialize(&[0x0a, 0x03, 0xcf, 0x40]).ok(), Some(Network::Signet.magic()));
assert_eq!(deserialize(&[0xfa, 0xbf, 0xb5, 0xda]).ok(), Some(Network::Regtest.magic()));
}
#[test] #[test]
fn string() { fn string() {

View File

@ -12,14 +12,12 @@
//! //!
//! ``` //! ```
//! use bitcoin::network::Params; //! use bitcoin::network::Params;
//! use bitcoin::{p2p, Script, ScriptBuf, Network, Target}; //! use bitcoin::{Script, ScriptBuf, Network, Target};
//! //!
//! const POW_TARGET_SPACING: u64 = 120; // Two minutes. //! const POW_TARGET_SPACING: u64 = 120; // Two minutes.
//! const MAGIC: [u8; 4] = [1, 2, 3, 4];
//! //!
//! pub struct CustomParams { //! pub struct CustomParams {
//! params: Params, //! params: Params,
//! magic: [u8; 4],
//! challenge_script: ScriptBuf, //! challenge_script: ScriptBuf,
//! } //! }
//! //!
@ -34,14 +32,10 @@
//! //!
//! Self { //! Self {
//! params, //! params,
//! magic: MAGIC,
//! challenge_script, //! challenge_script,
//! } //! }
//! } //! }
//! //!
//! /// Returns the custom magic bytes.
//! pub fn magic(&self) -> p2p::Magic { p2p::Magic::from_bytes(self.magic) }
//!
//! /// Returns the custom signet challenge script. //! /// Returns the custom signet challenge script.
//! pub fn challenge_script(&self) -> &Script { &self.challenge_script } //! pub fn challenge_script(&self) -> &Script { &self.challenge_script }
//! } //! }
@ -61,7 +55,6 @@
//! # let _ = target.difficulty(signet); //! # let _ = target.difficulty(signet);
//! # //! #
//! # let custom = CustomParams::new(); //! # let custom = CustomParams::new();
//! # let _ = custom.magic();
//! # let _ = custom.challenge_script(); //! # let _ = custom.challenge_script();
//! # let _ = target.difficulty(custom); //! # let _ = target.difficulty(custom);
//! # } //! # }

View File

@ -395,6 +395,39 @@ impl std::error::Error for UnknownMagicError {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::consensus::encode::{deserialize, serialize};
#[test]
fn serialize_deserialize() {
assert_eq!(serialize(&Magic::BITCOIN), &[0xf9, 0xbe, 0xb4, 0xd9]);
let magic: Magic = Network::Bitcoin.into();
assert_eq!(serialize(&magic), &[0xf9, 0xbe, 0xb4, 0xd9]);
assert_eq!(serialize(&Magic::TESTNET3), &[0x0b, 0x11, 0x09, 0x07]);
let magic: Magic = Network::Testnet(TestnetVersion::V3).into();
assert_eq!(serialize(&magic), &[0x0b, 0x11, 0x09, 0x07]);
assert_eq!(serialize(&Magic::TESTNET4), &[0x1c, 0x16, 0x3f, 0x28]);
let magic: Magic = Network::Testnet(TestnetVersion::V4).into();
assert_eq!(serialize(&magic), &[0x1c, 0x16, 0x3f, 0x28]);
assert_eq!(serialize(&Magic::SIGNET), &[0x0a, 0x03, 0xcf, 0x40]);
let magic: Magic = Network::Signet.into();
assert_eq!(serialize(&magic), &[0x0a, 0x03, 0xcf, 0x40]);
assert_eq!(serialize(&Magic::REGTEST), &[0xfa, 0xbf, 0xb5, 0xda]);
let magic: Magic = Network::Regtest.into();
assert_eq!(serialize(&magic), &[0xfa, 0xbf, 0xb5, 0xda]);
assert_eq!(deserialize::<Magic>(&[0xf9, 0xbe, 0xb4, 0xd9]).ok(), Some(Network::Bitcoin.into()));
assert_eq!(
deserialize::<Magic>(&[0x0b, 0x11, 0x09, 0x07]).ok(),
Some(Network::Testnet(TestnetVersion::V3).into())
);
assert_eq!(
deserialize::<Magic>(&[0x1c, 0x16, 0x3f, 0x28]).ok(),
Some(Network::Testnet(TestnetVersion::V4).into())
);
assert_eq!(deserialize::<Magic>(&[0x0a, 0x03, 0xcf, 0x40]).ok(), Some(Network::Signet.into()));
assert_eq!(deserialize::<Magic>(&[0xfa, 0xbf, 0xb5, 0xda]).ok(), Some(Network::Regtest.into()));
}
#[test] #[test]
fn service_flags_test() { fn service_flags_test() {