From dac97072a572fb2f802ec724e550867d1a176d13 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 25 May 2023 10:08:55 +1000 Subject: [PATCH 1/7] Add BorrowMut to prelude We already have `Borrow`, add `BorrowMut`. --- bitcoin/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bitcoin/src/lib.rs b/bitcoin/src/lib.rs index af6e9ed2..99f2ef02 100644 --- a/bitcoin/src/lib.rs +++ b/bitcoin/src/lib.rs @@ -172,13 +172,13 @@ mod io_extras { #[rustfmt::skip] mod prelude { #[cfg(all(not(feature = "std"), not(test)))] - pub use alloc::{string::{String, ToString}, vec::Vec, boxed::Box, borrow::{Borrow, Cow, ToOwned}, slice, rc}; + pub use alloc::{string::{String, ToString}, vec::Vec, boxed::Box, borrow::{Borrow, BorrowMut, Cow, ToOwned}, slice, rc}; #[cfg(all(not(feature = "std"), not(test), any(not(rust_v_1_60), target_has_atomic = "ptr")))] pub use alloc::sync; #[cfg(any(feature = "std", test))] - pub use std::{string::{String, ToString}, vec::Vec, boxed::Box, borrow::{Borrow, Cow, ToOwned}, slice, rc, sync}; + pub use std::{string::{String, ToString}, vec::Vec, boxed::Box, borrow::{Borrow, BorrowMut, Cow, ToOwned}, slice, rc, sync}; #[cfg(all(not(feature = "std"), not(test)))] pub use alloc::collections::{BTreeMap, BTreeSet, btree_map, BinaryHeap}; From 1bac1fd51888dc0d0ca705e028cf7450588a10d5 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 25 May 2023 09:14:42 +1000 Subject: [PATCH 2/7] Rename the network module to p2p The `network` module deals with data types and logic related to internetworking bitcoind nodes, this is commonly referred to as the p2p layer. Rename the `network` module to `p2p` and fix all the paths. --- bitcoin/examples/handshake.rs | 2 +- bitcoin/src/address.rs | 4 ++-- bitcoin/src/bip32.rs | 4 ++-- bitcoin/src/blockdata/constants.rs | 4 ++-- bitcoin/src/blockdata/transaction.rs | 4 ++-- bitcoin/src/consensus/encode.rs | 4 ++-- bitcoin/src/consensus/params.rs | 2 +- bitcoin/src/crypto/key.rs | 4 ++-- bitcoin/src/crypto/sighash.rs | 2 +- bitcoin/src/lib.rs | 4 ++-- bitcoin/src/{network => p2p}/address.rs | 4 ++-- bitcoin/src/{network => p2p}/constants.rs | 12 ++++++------ bitcoin/src/{network => p2p}/message.rs | 18 +++++++++--------- .../src/{network => p2p}/message_blockdata.rs | 2 +- bitcoin/src/{network => p2p}/message_bloom.rs | 0 .../{network => p2p}/message_compact_blocks.rs | 0 bitcoin/src/{network => p2p}/message_filter.rs | 0 .../src/{network => p2p}/message_network.rs | 6 +++--- bitcoin/src/{network => p2p}/mod.rs | 5 ++--- bitcoin/src/psbt/mod.rs | 2 +- fuzz/fuzz_targets/bitcoin/deser_net_msg.rs | 2 +- .../fuzz_targets/bitcoin/deserialize_script.rs | 2 +- 22 files changed, 43 insertions(+), 44 deletions(-) rename bitcoin/src/{network => p2p}/address.rs (99%) rename bitcoin/src/{network => p2p}/constants.rs (98%) rename bitcoin/src/{network => p2p}/message.rs (98%) rename bitcoin/src/{network => p2p}/message_blockdata.rs (99%) rename bitcoin/src/{network => p2p}/message_bloom.rs (100%) rename bitcoin/src/{network => p2p}/message_compact_blocks.rs (100%) rename bitcoin/src/{network => p2p}/message_filter.rs (100%) rename bitcoin/src/{network => p2p}/message_network.rs (97%) rename bitcoin/src/{network => p2p}/mod.rs (86%) diff --git a/bitcoin/examples/handshake.rs b/bitcoin/examples/handshake.rs index b3f98d18..12da7e59 100644 --- a/bitcoin/examples/handshake.rs +++ b/bitcoin/examples/handshake.rs @@ -6,7 +6,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; use std::{env, process}; use bitcoin::consensus::{encode, Decodable}; -use bitcoin::network::{address, constants, message, message_network}; +use bitcoin::p2p::{address, constants, message, message_network}; use bitcoin::secp256k1; use bitcoin::secp256k1::rand::Rng; diff --git a/bitcoin/src/address.rs b/bitcoin/src/address.rs index afa42dea..41345867 100644 --- a/bitcoin/src/address.rs +++ b/bitcoin/src/address.rs @@ -46,7 +46,7 @@ use crate::blockdata::script::witness_version::{self, WitnessVersion}; use crate::blockdata::script::{self, Script, ScriptBuf}; use crate::crypto::key::{PublicKey, TapTweak, TweakedPublicKey, UntweakedPublicKey}; use crate::hash_types::{PubkeyHash, ScriptHash}; -use crate::network::constants::Network; +use crate::p2p::constants::Network; use crate::prelude::*; use crate::taproot::TapNodeHash; @@ -996,7 +996,7 @@ mod tests { use super::*; use crate::crypto::key::PublicKey; - use crate::network::constants::Network::{Bitcoin, Testnet}; + use crate::p2p::constants::Network::{Bitcoin, Testnet}; fn roundtrips(addr: &Address) { assert_eq!( diff --git a/bitcoin/src/bip32.rs b/bitcoin/src/bip32.rs index a1513a72..79cdc6b8 100644 --- a/bitcoin/src/bip32.rs +++ b/bitcoin/src/bip32.rs @@ -23,7 +23,7 @@ use crate::crypto::key::{self, KeyPair, PrivateKey, PublicKey}; use crate::hash_types::XpubIdentifier; use crate::internal_macros::impl_bytes_newtype; use crate::io::Write; -use crate::network::constants::Network; +use crate::p2p::constants::Network; use crate::prelude::*; /// A chain code @@ -866,7 +866,7 @@ mod tests { use super::ChildNumber::{Hardened, Normal}; use super::*; use crate::internal_macros::hex; - use crate::network::constants::Network::{self, Bitcoin}; + use crate::p2p::constants::Network::{self, Bitcoin}; #[test] fn test_parse_derivation_path() { diff --git a/bitcoin/src/blockdata/constants.rs b/bitcoin/src/blockdata/constants.rs index 8a368d45..07a424e6 100644 --- a/bitcoin/src/blockdata/constants.rs +++ b/bitcoin/src/blockdata/constants.rs @@ -20,7 +20,7 @@ use crate::blockdata::script; use crate::blockdata::transaction::{OutPoint, Sequence, Transaction, TxIn, TxOut}; use crate::blockdata::witness::Witness; use crate::internal_macros::impl_bytes_newtype; -use crate::network::constants::Network; +use crate::p2p::constants::Network; use crate::pow::CompactTarget; use crate::Amount; @@ -198,7 +198,7 @@ mod test { use crate::blockdata::locktime::absolute; use crate::consensus::encode::serialize; use crate::internal_macros::hex; - use crate::network::constants::Network; + use crate::p2p::constants::Network; #[test] fn bitcoin_genesis_first_transaction() { diff --git a/bitcoin/src/blockdata/transaction.rs b/bitcoin/src/blockdata/transaction.rs index edd0c223..d3327fc7 100644 --- a/bitcoin/src/blockdata/transaction.rs +++ b/bitcoin/src/blockdata/transaction.rs @@ -68,7 +68,7 @@ impl OutPoint { /// /// ```rust /// use bitcoin::constants::genesis_block; - /// use bitcoin::network::constants::Network; + /// use bitcoin::p2p::constants::Network; /// /// let block = genesis_block(Network::Bitcoin); /// let tx = &block.txdata[0]; @@ -1508,7 +1508,7 @@ mod tests { #[test] fn test_is_coinbase() { use crate::blockdata::constants; - use crate::network::constants::Network; + use crate::p2p::constants::Network; let genesis = constants::genesis_block(Network::Bitcoin); assert!(genesis.txdata[0].is_coinbase()); diff --git a/bitcoin/src/consensus/encode.rs b/bitcoin/src/consensus/encode.rs index 7f5ab21e..297d1c08 100644 --- a/bitcoin/src/consensus/encode.rs +++ b/bitcoin/src/consensus/encode.rs @@ -26,7 +26,7 @@ use crate::blockdata::transaction::{Transaction, TxIn, TxOut}; use crate::hash_types::{BlockHash, FilterHash, FilterHeader, TxMerkleNode}; use crate::io::{self, Cursor, Read}; #[cfg(feature = "std")] -use crate::network::{ +use crate::p2p::{ address::{AddrV2Message, Address}, message_blockdata::Inventory, }; @@ -836,7 +836,7 @@ mod tests { use super::*; use crate::consensus::{deserialize_partial, Decodable, Encodable}; #[cfg(feature = "std")] - use crate::network::{message_blockdata::Inventory, Address}; + use crate::p2p::{message_blockdata::Inventory, Address}; #[test] fn serialize_int_test() { diff --git a/bitcoin/src/consensus/params.rs b/bitcoin/src/consensus/params.rs index cd9cb5bc..36861564 100644 --- a/bitcoin/src/consensus/params.rs +++ b/bitcoin/src/consensus/params.rs @@ -6,7 +6,7 @@ //! chains (such as mainnet, testnet). //! -use crate::network::constants::Network; +use crate::p2p::constants::Network; use crate::pow::Work; /// Parameters that influence chain consensus. diff --git a/bitcoin/src/crypto/key.rs b/bitcoin/src/crypto/key.rs index e870592c..5e08c7e5 100644 --- a/bitcoin/src/crypto/key.rs +++ b/bitcoin/src/crypto/key.rs @@ -18,7 +18,7 @@ pub use secp256k1::{self, constants, KeyPair, Parity, Secp256k1, Verification, X use crate::crypto::ecdsa; use crate::hash_types::{PubkeyHash, WPubkeyHash}; -use crate::network::constants::Network; +use crate::p2p::constants::Network; use crate::prelude::*; use crate::taproot::{TapNodeHash, TapTweakHash}; use crate::{base58, io}; @@ -741,7 +741,7 @@ mod tests { use super::*; use crate::address::Address; use crate::io; - use crate::network::constants::Network::{Bitcoin, Testnet}; + use crate::p2p::constants::Network::{Bitcoin, Testnet}; #[test] fn test_key_derivation() { diff --git a/bitcoin/src/crypto/sighash.rs b/bitcoin/src/crypto/sighash.rs index ec4a2ad7..eb537479 100644 --- a/bitcoin/src/crypto/sighash.rs +++ b/bitcoin/src/crypto/sighash.rs @@ -1120,7 +1120,7 @@ mod tests { use crate::crypto::key::PublicKey; use crate::crypto::sighash::{LegacySighash, TapSighash}; use crate::internal_macros::hex; - use crate::network::constants::Network; + use crate::p2p::constants::Network; use crate::taproot::TapLeafHash; extern crate serde_json; diff --git a/bitcoin/src/lib.rs b/bitcoin/src/lib.rs index 99f2ef02..4bcc0783 100644 --- a/bitcoin/src/lib.rs +++ b/bitcoin/src/lib.rs @@ -92,7 +92,7 @@ mod parse; mod serde_utils; #[macro_use] -pub mod network; +pub mod p2p; pub mod address; pub mod amount; pub mod base58; @@ -146,7 +146,7 @@ pub use crate::hash_types::{ BlockHash, PubkeyHash, ScriptHash, Txid, WPubkeyHash, WScriptHash, Wtxid, }; pub use crate::merkle_tree::MerkleBlock; -pub use crate::network::constants::Network; +pub use crate::p2p::constants::Network; pub use crate::pow::{CompactTarget, Target, Work}; pub use crate::psbt::Psbt; diff --git a/bitcoin/src/network/address.rs b/bitcoin/src/p2p/address.rs similarity index 99% rename from bitcoin/src/network/address.rs rename to bitcoin/src/p2p/address.rs index f20907c3..5696026b 100644 --- a/bitcoin/src/network/address.rs +++ b/bitcoin/src/p2p/address.rs @@ -11,7 +11,7 @@ use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSoc use crate::consensus::encode::{self, Decodable, Encodable, ReadExt, VarInt, WriteExt}; use crate::io; -use crate::network::constants::ServiceFlags; +use crate::p2p::constants::ServiceFlags; use crate::prelude::*; /// A message which can be sent on the Bitcoin network @@ -311,7 +311,7 @@ mod test { use super::{AddrV2, AddrV2Message, Address}; use crate::consensus::encode::{deserialize, serialize}; use crate::internal_macros::hex; - use crate::network::constants::ServiceFlags; + use crate::p2p::constants::ServiceFlags; #[test] fn serialize_address_test() { diff --git a/bitcoin/src/network/constants.rs b/bitcoin/src/p2p/constants.rs similarity index 98% rename from bitcoin/src/network/constants.rs rename to bitcoin/src/p2p/constants.rs index 1b4d172f..7e86ebaa 100644 --- a/bitcoin/src/network/constants.rs +++ b/bitcoin/src/p2p/constants.rs @@ -16,7 +16,7 @@ //! # Example: encoding a network's magic bytes //! //! ```rust -//! use bitcoin::network::constants::Network; +//! use bitcoin::p2p::constants::Network; //! use bitcoin::consensus::encode::serialize; //! //! let network = Network::Bitcoin; @@ -82,7 +82,7 @@ impl Network { /// # Examples /// /// ```rust - /// use bitcoin::network::constants::{Network, Magic}; + /// use bitcoin::p2p::constants::{Network, Magic}; /// use std::convert::TryFrom; /// /// assert_eq!(Ok(Network::Bitcoin), Network::try_from(Magic::from_bytes([0xF9, 0xBE, 0xB4, 0xD9]))); @@ -96,7 +96,7 @@ impl Network { /// # Examples /// /// ```rust - /// use bitcoin::network::constants::{Network, Magic}; + /// use bitcoin::p2p::constants::{Network, Magic}; /// /// let network = Network::Bitcoin; /// assert_eq!(network.magic(), Magic::from_bytes([0xF9, 0xBE, 0xB4, 0xD9])); @@ -148,7 +148,7 @@ impl Network { /// # Examples /// /// ```rust - /// use bitcoin::network::constants::Network; + /// use bitcoin::p2p::constants::Network; /// use bitcoin::blockdata::constants::ChainHash; /// /// let network = Network::Bitcoin; @@ -161,7 +161,7 @@ impl Network { /// # Examples /// /// ```rust - /// use bitcoin::network::constants::Network; + /// use bitcoin::p2p::constants::Network; /// use bitcoin::blockdata::constants::ChainHash; /// use std::convert::TryFrom; /// @@ -723,7 +723,7 @@ mod tests { #[derive(Serialize, Deserialize, PartialEq, Debug)] #[serde(crate = "actual_serde")] struct T { - #[serde(with = "crate::network::constants::as_core_arg")] + #[serde(with = "crate::p2p::constants::as_core_arg")] pub network: Network, } diff --git a/bitcoin/src/network/message.rs b/bitcoin/src/p2p/message.rs similarity index 98% rename from bitcoin/src/network/message.rs rename to bitcoin/src/p2p/message.rs index 75d22de6..71bec7c4 100644 --- a/bitcoin/src/network/message.rs +++ b/bitcoin/src/p2p/message.rs @@ -16,9 +16,9 @@ use crate::blockdata::{block, transaction}; use crate::consensus::encode::{self, CheckedData, Decodable, Encodable, VarInt}; use crate::io; use crate::merkle_tree::MerkleBlock; -use crate::network::address::{AddrV2Message, Address}; -use crate::network::constants::Magic; -use crate::network::{ +use crate::p2p::address::{AddrV2Message, Address}; +use crate::p2p::constants::Magic; +use crate::p2p::{ message_blockdata, message_bloom, message_compact_blocks, message_filter, message_network, }; use crate::prelude::*; @@ -549,12 +549,12 @@ mod test { use crate::blockdata::transaction::Transaction; use crate::consensus::encode::{deserialize, deserialize_partial, serialize}; use crate::internal_macros::hex; - use crate::network::address::{AddrV2, AddrV2Message, Address}; - use crate::network::constants::{Magic, Network, ServiceFlags}; - use crate::network::message_blockdata::{GetBlocksMessage, GetHeadersMessage, Inventory}; - use crate::network::message_bloom::{BloomFlags, FilterAdd, FilterLoad}; - use crate::network::message_compact_blocks::{GetBlockTxn, SendCmpct}; - use crate::network::message_filter::{ + use crate::p2p::address::{AddrV2, AddrV2Message, Address}; + use crate::p2p::constants::{Magic, Network, ServiceFlags}; + use crate::p2p::message_blockdata::{GetBlocksMessage, GetHeadersMessage, Inventory}; + use crate::p2p::message_bloom::{BloomFlags, FilterAdd, FilterLoad}; + use crate::p2p::message_compact_blocks::{GetBlockTxn, SendCmpct}; + use crate::p2p::message_filter::{ CFCheckpt, CFHeaders, CFilter, GetCFCheckpt, GetCFHeaders, GetCFilters, }; diff --git a/bitcoin/src/network/message_blockdata.rs b/bitcoin/src/p2p/message_blockdata.rs similarity index 99% rename from bitcoin/src/network/message_blockdata.rs rename to bitcoin/src/p2p/message_blockdata.rs index 64273b7b..2a69f1e8 100644 --- a/bitcoin/src/network/message_blockdata.rs +++ b/bitcoin/src/p2p/message_blockdata.rs @@ -12,7 +12,7 @@ use crate::consensus::encode::{self, Decodable, Encodable}; use crate::hash_types::{BlockHash, Txid, Wtxid}; use crate::internal_macros::impl_consensus_encoding; use crate::io; -use crate::network::constants; +use crate::p2p::constants; use crate::prelude::*; /// An inventory item. diff --git a/bitcoin/src/network/message_bloom.rs b/bitcoin/src/p2p/message_bloom.rs similarity index 100% rename from bitcoin/src/network/message_bloom.rs rename to bitcoin/src/p2p/message_bloom.rs diff --git a/bitcoin/src/network/message_compact_blocks.rs b/bitcoin/src/p2p/message_compact_blocks.rs similarity index 100% rename from bitcoin/src/network/message_compact_blocks.rs rename to bitcoin/src/p2p/message_compact_blocks.rs diff --git a/bitcoin/src/network/message_filter.rs b/bitcoin/src/p2p/message_filter.rs similarity index 100% rename from bitcoin/src/network/message_filter.rs rename to bitcoin/src/p2p/message_filter.rs diff --git a/bitcoin/src/network/message_network.rs b/bitcoin/src/p2p/message_network.rs similarity index 97% rename from bitcoin/src/network/message_network.rs rename to bitcoin/src/p2p/message_network.rs index b49974f5..996aad66 100644 --- a/bitcoin/src/network/message_network.rs +++ b/bitcoin/src/p2p/message_network.rs @@ -11,8 +11,8 @@ use hashes::sha256d; use crate::consensus::{encode, Decodable, Encodable, ReadExt}; use crate::internal_macros::impl_consensus_encoding; use crate::io; -use crate::network::address::Address; -use crate::network::constants::{self, ServiceFlags}; +use crate::p2p::address::Address; +use crate::p2p::constants::{self, ServiceFlags}; use crate::prelude::*; /// Some simple messages @@ -146,7 +146,7 @@ mod tests { use super::{Reject, RejectReason, VersionMessage}; use crate::consensus::encode::{deserialize, serialize}; use crate::internal_macros::hex; - use crate::network::constants::ServiceFlags; + use crate::p2p::constants::ServiceFlags; #[test] fn version_message_test() { diff --git a/bitcoin/src/network/mod.rs b/bitcoin/src/p2p/mod.rs similarity index 86% rename from bitcoin/src/network/mod.rs rename to bitcoin/src/p2p/mod.rs index 2e379686..afe4eff9 100644 --- a/bitcoin/src/network/mod.rs +++ b/bitcoin/src/p2p/mod.rs @@ -1,10 +1,9 @@ // SPDX-License-Identifier: CC0-1.0 -//! Bitcoin network support. +//! Bitcoin p2p network types. //! //! This module defines support for (de)serialization and network transport -//! of Bitcoin data and network messages. -//! +//! of Bitcoin data and Bitcoin p2p network messages. pub mod constants; diff --git a/bitcoin/src/psbt/mod.rs b/bitcoin/src/psbt/mod.rs index ee378360..1caa20c6 100644 --- a/bitcoin/src/psbt/mod.rs +++ b/bitcoin/src/psbt/mod.rs @@ -823,7 +823,7 @@ mod tests { use crate::blockdata::transaction::{OutPoint, Sequence, Transaction, TxIn, TxOut}; use crate::blockdata::witness::Witness; use crate::internal_macros::hex; - use crate::network::constants::Network::Bitcoin; + use crate::p2p::constants::Network::Bitcoin; use crate::psbt::map::{Input, Output}; use crate::psbt::raw; use crate::psbt::serialize::{Deserialize, Serialize}; diff --git a/fuzz/fuzz_targets/bitcoin/deser_net_msg.rs b/fuzz/fuzz_targets/bitcoin/deser_net_msg.rs index 883431c1..906bcee9 100644 --- a/fuzz/fuzz_targets/bitcoin/deser_net_msg.rs +++ b/fuzz/fuzz_targets/bitcoin/deser_net_msg.rs @@ -1,7 +1,7 @@ use honggfuzz::fuzz; fn do_test(data: &[u8]) { - let _: Result = + let _: Result = bitcoin::consensus::encode::deserialize(data); } diff --git a/fuzz/fuzz_targets/bitcoin/deserialize_script.rs b/fuzz/fuzz_targets/bitcoin/deserialize_script.rs index 1020e0b0..1cc035d2 100644 --- a/fuzz/fuzz_targets/bitcoin/deserialize_script.rs +++ b/fuzz/fuzz_targets/bitcoin/deserialize_script.rs @@ -1,7 +1,7 @@ use bitcoin::address::Address; use bitcoin::blockdata::script; use bitcoin::consensus::encode; -use bitcoin::network::constants::Network; +use bitcoin::p2p::constants::Network; use honggfuzz::fuzz; fn do_test(data: &[u8]) { From 4330722d62fb81f9528074b41d9b3f88b70c43a3 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Wed, 31 May 2023 16:31:33 +1000 Subject: [PATCH 3/7] Move p2p::constants::PROTOCOL_VERSION to p2p module The `PROTOCOL_VERSION` const is a p2p layer constant. It can live in the `mod.rs` file of the `p2p` module. This is a straight code move, the `PROTOCOL_VERSION` replaces the current re-export. --- bitcoin/src/p2p/constants.rs | 17 ----------------- bitcoin/src/p2p/message_blockdata.rs | 7 +++---- bitcoin/src/p2p/message_network.rs | 6 +++--- bitcoin/src/p2p/mod.rs | 17 +++++++++++++++++ 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/bitcoin/src/p2p/constants.rs b/bitcoin/src/p2p/constants.rs index 7e86ebaa..90c0e591 100644 --- a/bitcoin/src/p2p/constants.rs +++ b/bitcoin/src/p2p/constants.rs @@ -42,23 +42,6 @@ use crate::error::impl_std_error; use crate::io; use crate::prelude::{String, ToOwned}; -/// Version of the protocol as appearing in network message headers -/// This constant is used to signal to other peers which features you support. -/// Increasing it implies that your software also supports every feature prior to this version. -/// Doing so without support may lead to you incorrectly banning other peers or other peers banning you. -/// These are the features required for each version: -/// 70016 - Support receiving `wtxidrelay` message between `version` and `verack` message -/// 70015 - Support receiving invalid compact blocks from a peer without banning them -/// 70014 - Support compact block messages `sendcmpct`, `cmpctblock`, `getblocktxn` and `blocktxn` -/// 70013 - Support `feefilter` message -/// 70012 - Support `sendheaders` message and announce new blocks via headers rather than inv -/// 70011 - Support NODE_BLOOM service flag and don't support bloom filter messages if it is not set -/// 70002 - Support `reject` message -/// 70001 - Support bloom filter messages `filterload`, `filterclear` `filteradd`, `merkleblock` and FILTERED_BLOCK inventory type -/// 60002 - Support `mempool` message -/// 60001 - Support `pong` message and nonce in `ping` message -pub const PROTOCOL_VERSION: u32 = 70001; - /// The cryptocurrency network to act on. #[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] diff --git a/bitcoin/src/p2p/message_blockdata.rs b/bitcoin/src/p2p/message_blockdata.rs index 2a69f1e8..3a563097 100644 --- a/bitcoin/src/p2p/message_blockdata.rs +++ b/bitcoin/src/p2p/message_blockdata.rs @@ -11,9 +11,8 @@ use hashes::{sha256d, Hash as _}; use crate::consensus::encode::{self, Decodable, Encodable}; use crate::hash_types::{BlockHash, Txid, Wtxid}; use crate::internal_macros::impl_consensus_encoding; -use crate::io; -use crate::p2p::constants; use crate::prelude::*; +use crate::{io, p2p}; /// An inventory item. #[derive(PartialEq, Eq, Clone, Debug, Copy, Hash, PartialOrd, Ord)] @@ -128,7 +127,7 @@ pub struct GetHeadersMessage { impl GetBlocksMessage { /// Construct a new `getblocks` message pub fn new(locator_hashes: Vec, stop_hash: BlockHash) -> GetBlocksMessage { - GetBlocksMessage { version: constants::PROTOCOL_VERSION, locator_hashes, stop_hash } + GetBlocksMessage { version: p2p::PROTOCOL_VERSION, locator_hashes, stop_hash } } } @@ -137,7 +136,7 @@ impl_consensus_encoding!(GetBlocksMessage, version, locator_hashes, stop_hash); impl GetHeadersMessage { /// Construct a new `getheaders` message pub fn new(locator_hashes: Vec, stop_hash: BlockHash) -> GetHeadersMessage { - GetHeadersMessage { version: constants::PROTOCOL_VERSION, locator_hashes, stop_hash } + GetHeadersMessage { version: p2p::PROTOCOL_VERSION, locator_hashes, stop_hash } } } diff --git a/bitcoin/src/p2p/message_network.rs b/bitcoin/src/p2p/message_network.rs index 996aad66..a0ab6cb4 100644 --- a/bitcoin/src/p2p/message_network.rs +++ b/bitcoin/src/p2p/message_network.rs @@ -10,10 +10,10 @@ use hashes::sha256d; use crate::consensus::{encode, Decodable, Encodable, ReadExt}; use crate::internal_macros::impl_consensus_encoding; -use crate::io; use crate::p2p::address::Address; -use crate::p2p::constants::{self, ServiceFlags}; +use crate::p2p::constants::ServiceFlags; use crate::prelude::*; +use crate::{io, p2p}; /// Some simple messages @@ -54,7 +54,7 @@ impl VersionMessage { start_height: i32, ) -> VersionMessage { VersionMessage { - version: constants::PROTOCOL_VERSION, + version: p2p::PROTOCOL_VERSION, services, timestamp, receiver, diff --git a/bitcoin/src/p2p/mod.rs b/bitcoin/src/p2p/mod.rs index afe4eff9..9e2a1c1a 100644 --- a/bitcoin/src/p2p/mod.rs +++ b/bitcoin/src/p2p/mod.rs @@ -25,3 +25,20 @@ pub mod message_filter; pub mod message_network; pub use self::constants::Magic; + +/// Version of the protocol as appearing in network message headers +/// This constant is used to signal to other peers which features you support. +/// Increasing it implies that your software also supports every feature prior to this version. +/// Doing so without support may lead to you incorrectly banning other peers or other peers banning you. +/// These are the features required for each version: +/// 70016 - Support receiving `wtxidrelay` message between `version` and `verack` message +/// 70015 - Support receiving invalid compact blocks from a peer without banning them +/// 70014 - Support compact block messages `sendcmpct`, `cmpctblock`, `getblocktxn` and `blocktxn` +/// 70013 - Support `feefilter` message +/// 70012 - Support `sendheaders` message and announce new blocks via headers rather than inv +/// 70011 - Support NODE_BLOOM service flag and don't support bloom filter messages if it is not set +/// 70002 - Support `reject` message +/// 70001 - Support bloom filter messages `filterload`, `filterclear` `filteradd`, `merkleblock` and FILTERED_BLOCK inventory type +/// 60002 - Support `mempool` message +/// 60001 - Support `pong` message and nonce in `ping` message +pub const PROTOCOL_VERSION: u32 = 70001; From 99d8ae11739f4192db8535b04f890d711a318044 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Wed, 31 May 2023 16:35:01 +1000 Subject: [PATCH 4/7] Improve rustdocs on PROTOCOL_VERSION --- bitcoin/src/p2p/mod.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bitcoin/src/p2p/mod.rs b/bitcoin/src/p2p/mod.rs index 9e2a1c1a..95184ccf 100644 --- a/bitcoin/src/p2p/mod.rs +++ b/bitcoin/src/p2p/mod.rs @@ -26,10 +26,12 @@ pub mod message_network; pub use self::constants::Magic; -/// Version of the protocol as appearing in network message headers -/// This constant is used to signal to other peers which features you support. -/// Increasing it implies that your software also supports every feature prior to this version. -/// Doing so without support may lead to you incorrectly banning other peers or other peers banning you. +/// Version of the protocol as appearing in network message headers. +/// +/// This constant is used to signal to other peers which features you support. Increasing it implies +/// that your software also supports every feature prior to this version. Doing so without support +/// may lead to you incorrectly banning other peers or other peers banning you. +/// /// These are the features required for each version: /// 70016 - Support receiving `wtxidrelay` message between `version` and `verack` message /// 70015 - Support receiving invalid compact blocks from a peer without banning them From d9d5a4ed4ff2cc8a1b100f91544649d231de6f80 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Wed, 31 May 2023 16:41:20 +1000 Subject: [PATCH 5/7] Move p2p::constants::ServiceFlags to p2p module The `ServiceFlags` type is used by the p2p layer. It can live in the `mod.rs` file of the `p2p` module. Done in preparation for removing the `p2p::constants` module. This is a straight code move, the `ServiceFlags` replaces the current re-export. --- bitcoin/examples/handshake.rs | 8 +- bitcoin/src/p2p/address.rs | 4 +- bitcoin/src/p2p/constants.rs | 153 +--------------------- bitcoin/src/p2p/message.rs | 3 +- bitcoin/src/p2p/message_network.rs | 4 +- bitcoin/src/p2p/mod.rs | 197 +++++++++++++++++++++++++++++ 6 files changed, 210 insertions(+), 159 deletions(-) diff --git a/bitcoin/examples/handshake.rs b/bitcoin/examples/handshake.rs index 12da7e59..d62d1699 100644 --- a/bitcoin/examples/handshake.rs +++ b/bitcoin/examples/handshake.rs @@ -6,7 +6,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; use std::{env, process}; use bitcoin::consensus::{encode, Decodable}; -use bitcoin::p2p::{address, constants, message, message_network}; +use bitcoin::p2p::{self, address, constants, message, message_network}; use bitcoin::secp256k1; use bitcoin::secp256k1::rand::Rng; @@ -75,16 +75,16 @@ fn build_version_message(address: SocketAddr) -> message::NetworkMessage { let my_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0); // "bitfield of features to be enabled for this connection" - let services = constants::ServiceFlags::NONE; + let services = p2p::ServiceFlags::NONE; // "standard UNIX timestamp in seconds" let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time error").as_secs(); // "The network address of the node receiving this message" - let addr_recv = address::Address::new(&address, constants::ServiceFlags::NONE); + let addr_recv = address::Address::new(&address, p2p::ServiceFlags::NONE); // "The network address of the node emitting this message" - let addr_from = address::Address::new(&my_address, constants::ServiceFlags::NONE); + let addr_from = address::Address::new(&my_address, p2p::ServiceFlags::NONE); // "Node random nonce, randomly generated every time a version packet is sent. This nonce is used to detect connections to self." let nonce: u64 = secp256k1::rand::thread_rng().gen(); diff --git a/bitcoin/src/p2p/address.rs b/bitcoin/src/p2p/address.rs index 5696026b..58678bc9 100644 --- a/bitcoin/src/p2p/address.rs +++ b/bitcoin/src/p2p/address.rs @@ -11,7 +11,7 @@ use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSoc use crate::consensus::encode::{self, Decodable, Encodable, ReadExt, VarInt, WriteExt}; use crate::io; -use crate::p2p::constants::ServiceFlags; +use crate::p2p::ServiceFlags; use crate::prelude::*; /// A message which can be sent on the Bitcoin network @@ -311,7 +311,7 @@ mod test { use super::{AddrV2, AddrV2Message, Address}; use crate::consensus::encode::{deserialize, serialize}; use crate::internal_macros::hex; - use crate::p2p::constants::ServiceFlags; + use crate::p2p::ServiceFlags; #[test] fn serialize_address_test() { diff --git a/bitcoin/src/p2p/constants.rs b/bitcoin/src/p2p/constants.rs index 90c0e591..2dce6961 100644 --- a/bitcoin/src/p2p/constants.rs +++ b/bitcoin/src/p2p/constants.rs @@ -27,9 +27,9 @@ use core::borrow::{Borrow, BorrowMut}; use core::convert::TryFrom; +use core::fmt; use core::fmt::Display; use core::str::FromStr; -use core::{fmt, ops}; use hex::FromHex; use internals::{debug_from_display, write_err}; @@ -423,161 +423,14 @@ impl fmt::Display for UnknownMagic { } impl_std_error!(UnknownMagic); -/// Flags to indicate which network services a node supports. -#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct ServiceFlags(u64); - -impl ServiceFlags { - /// NONE means no services supported. - pub const NONE: ServiceFlags = ServiceFlags(0); - - /// NETWORK means that the node is capable of serving the complete block chain. It is currently - /// set by all Bitcoin Core non pruned nodes, and is unset by SPV clients or other light - /// clients. - pub const NETWORK: ServiceFlags = ServiceFlags(1 << 0); - - /// GETUTXO means the node is capable of responding to the getutxo protocol request. Bitcoin - /// Core does not support this but a patch set called Bitcoin XT does. - /// See BIP 64 for details on how this is implemented. - pub const GETUTXO: ServiceFlags = ServiceFlags(1 << 1); - - /// BLOOM means the node is capable and willing to handle bloom-filtered connections. Bitcoin - /// Core nodes used to support this by default, without advertising this bit, but no longer do - /// as of protocol version 70011 (= NO_BLOOM_VERSION) - pub const BLOOM: ServiceFlags = ServiceFlags(1 << 2); - - /// WITNESS indicates that a node can be asked for blocks and transactions including witness - /// data. - pub const WITNESS: ServiceFlags = ServiceFlags(1 << 3); - - /// COMPACT_FILTERS means the node will service basic block filter requests. - /// See BIP157 and BIP158 for details on how this is implemented. - pub const COMPACT_FILTERS: ServiceFlags = ServiceFlags(1 << 6); - - /// NETWORK_LIMITED means the same as NODE_NETWORK with the limitation of only serving the last - /// 288 (2 day) blocks. - /// See BIP159 for details on how this is implemented. - pub const NETWORK_LIMITED: ServiceFlags = ServiceFlags(1 << 10); - - // NOTE: When adding new flags, remember to update the Display impl accordingly. - - /// Add [ServiceFlags] together. - /// - /// Returns itself. - pub fn add(&mut self, other: ServiceFlags) -> ServiceFlags { - self.0 |= other.0; - *self - } - - /// Remove [ServiceFlags] from this. - /// - /// Returns itself. - pub fn remove(&mut self, other: ServiceFlags) -> ServiceFlags { - self.0 ^= other.0; - *self - } - - /// Check whether [ServiceFlags] are included in this one. - pub fn has(self, flags: ServiceFlags) -> bool { (self.0 | flags.0) == self.0 } - - /// Gets the integer representation of this [`ServiceFlags`]. - pub fn to_u64(self) -> u64 { self.0 } -} - -impl fmt::LowerHex for ServiceFlags { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(&self.0, f) } -} - -impl fmt::UpperHex for ServiceFlags { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::UpperHex::fmt(&self.0, f) } -} - -impl fmt::Display for ServiceFlags { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut flags = *self; - if flags == ServiceFlags::NONE { - return write!(f, "ServiceFlags(NONE)"); - } - let mut first = true; - macro_rules! write_flag { - ($f:ident) => { - if flags.has(ServiceFlags::$f) { - if !first { - write!(f, "|")?; - } - first = false; - write!(f, stringify!($f))?; - flags.remove(ServiceFlags::$f); - } - }; - } - write!(f, "ServiceFlags(")?; - write_flag!(NETWORK); - write_flag!(GETUTXO); - write_flag!(BLOOM); - write_flag!(WITNESS); - write_flag!(COMPACT_FILTERS); - write_flag!(NETWORK_LIMITED); - // If there are unknown flags left, we append them in hex. - if flags != ServiceFlags::NONE { - if !first { - write!(f, "|")?; - } - write!(f, "0x{:x}", flags)?; - } - write!(f, ")") - } -} - -impl From for ServiceFlags { - fn from(f: u64) -> Self { ServiceFlags(f) } -} - -impl From for u64 { - fn from(flags: ServiceFlags) -> Self { flags.0 } -} - -impl ops::BitOr for ServiceFlags { - type Output = Self; - - fn bitor(mut self, rhs: Self) -> Self { self.add(rhs) } -} - -impl ops::BitOrAssign for ServiceFlags { - fn bitor_assign(&mut self, rhs: Self) { self.add(rhs); } -} - -impl ops::BitXor for ServiceFlags { - type Output = Self; - - fn bitxor(mut self, rhs: Self) -> Self { self.remove(rhs) } -} - -impl ops::BitXorAssign for ServiceFlags { - fn bitxor_assign(&mut self, rhs: Self) { self.remove(rhs); } -} - -impl Encodable for ServiceFlags { - #[inline] - fn consensus_encode(&self, w: &mut W) -> Result { - self.0.consensus_encode(w) - } -} - -impl Decodable for ServiceFlags { - #[inline] - fn consensus_decode(r: &mut R) -> Result { - Ok(ServiceFlags(Decodable::consensus_decode(r)?)) - } -} - #[cfg(test)] mod tests { use std::convert::TryFrom; use std::str::FromStr; - use super::{Magic, Network, ServiceFlags}; + use super::{Magic, Network}; use crate::consensus::encode::{deserialize, serialize}; + use crate::p2p::ServiceFlags; #[test] fn serialize_test() { diff --git a/bitcoin/src/p2p/message.rs b/bitcoin/src/p2p/message.rs index 71bec7c4..098c5e73 100644 --- a/bitcoin/src/p2p/message.rs +++ b/bitcoin/src/p2p/message.rs @@ -550,13 +550,14 @@ mod test { use crate::consensus::encode::{deserialize, deserialize_partial, serialize}; use crate::internal_macros::hex; use crate::p2p::address::{AddrV2, AddrV2Message, Address}; - use crate::p2p::constants::{Magic, Network, ServiceFlags}; + use crate::p2p::constants::{Magic, Network}; use crate::p2p::message_blockdata::{GetBlocksMessage, GetHeadersMessage, Inventory}; use crate::p2p::message_bloom::{BloomFlags, FilterAdd, FilterLoad}; use crate::p2p::message_compact_blocks::{GetBlockTxn, SendCmpct}; use crate::p2p::message_filter::{ CFCheckpt, CFHeaders, CFilter, GetCFCheckpt, GetCFHeaders, GetCFilters, }; + use crate::p2p::ServiceFlags; fn hash(slice: [u8; 32]) -> Hash { Hash::from_slice(&slice).unwrap() } diff --git a/bitcoin/src/p2p/message_network.rs b/bitcoin/src/p2p/message_network.rs index a0ab6cb4..fad323f6 100644 --- a/bitcoin/src/p2p/message_network.rs +++ b/bitcoin/src/p2p/message_network.rs @@ -11,7 +11,7 @@ use hashes::sha256d; use crate::consensus::{encode, Decodable, Encodable, ReadExt}; use crate::internal_macros::impl_consensus_encoding; use crate::p2p::address::Address; -use crate::p2p::constants::ServiceFlags; +use crate::p2p::ServiceFlags; use crate::prelude::*; use crate::{io, p2p}; @@ -146,7 +146,7 @@ mod tests { use super::{Reject, RejectReason, VersionMessage}; use crate::consensus::encode::{deserialize, serialize}; use crate::internal_macros::hex; - use crate::p2p::constants::ServiceFlags; + use crate::p2p::ServiceFlags; #[test] fn version_message_test() { diff --git a/bitcoin/src/p2p/mod.rs b/bitcoin/src/p2p/mod.rs index 95184ccf..f46733f7 100644 --- a/bitcoin/src/p2p/mod.rs +++ b/bitcoin/src/p2p/mod.rs @@ -24,7 +24,11 @@ pub mod message_filter; #[cfg(feature = "std")] pub mod message_network; +use core::{fmt, ops}; + pub use self::constants::Magic; +use crate::consensus::encode::{self, Decodable, Encodable}; +use crate::io; /// Version of the protocol as appearing in network message headers. /// @@ -44,3 +48,196 @@ pub use self::constants::Magic; /// 60002 - Support `mempool` message /// 60001 - Support `pong` message and nonce in `ping` message pub const PROTOCOL_VERSION: u32 = 70001; + +/// Flags to indicate which network services a node supports. +#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ServiceFlags(u64); + +impl ServiceFlags { + /// NONE means no services supported. + pub const NONE: ServiceFlags = ServiceFlags(0); + + /// NETWORK means that the node is capable of serving the complete block chain. It is currently + /// set by all Bitcoin Core non pruned nodes, and is unset by SPV clients or other light + /// clients. + pub const NETWORK: ServiceFlags = ServiceFlags(1 << 0); + + /// GETUTXO means the node is capable of responding to the getutxo protocol request. Bitcoin + /// Core does not support this but a patch set called Bitcoin XT does. + /// See BIP 64 for details on how this is implemented. + pub const GETUTXO: ServiceFlags = ServiceFlags(1 << 1); + + /// BLOOM means the node is capable and willing to handle bloom-filtered connections. Bitcoin + /// Core nodes used to support this by default, without advertising this bit, but no longer do + /// as of protocol version 70011 (= NO_BLOOM_VERSION) + pub const BLOOM: ServiceFlags = ServiceFlags(1 << 2); + + /// WITNESS indicates that a node can be asked for blocks and transactions including witness + /// data. + pub const WITNESS: ServiceFlags = ServiceFlags(1 << 3); + + /// COMPACT_FILTERS means the node will service basic block filter requests. + /// See BIP157 and BIP158 for details on how this is implemented. + pub const COMPACT_FILTERS: ServiceFlags = ServiceFlags(1 << 6); + + /// NETWORK_LIMITED means the same as NODE_NETWORK with the limitation of only serving the last + /// 288 (2 day) blocks. + /// See BIP159 for details on how this is implemented. + pub const NETWORK_LIMITED: ServiceFlags = ServiceFlags(1 << 10); + + // NOTE: When adding new flags, remember to update the Display impl accordingly. + + /// Add [ServiceFlags] together. + /// + /// Returns itself. + pub fn add(&mut self, other: ServiceFlags) -> ServiceFlags { + self.0 |= other.0; + *self + } + + /// Remove [ServiceFlags] from this. + /// + /// Returns itself. + pub fn remove(&mut self, other: ServiceFlags) -> ServiceFlags { + self.0 ^= other.0; + *self + } + + /// Check whether [ServiceFlags] are included in this one. + pub fn has(self, flags: ServiceFlags) -> bool { (self.0 | flags.0) == self.0 } + + /// Gets the integer representation of this [`ServiceFlags`]. + pub fn to_u64(self) -> u64 { self.0 } +} + +impl fmt::LowerHex for ServiceFlags { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(&self.0, f) } +} + +impl fmt::UpperHex for ServiceFlags { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::UpperHex::fmt(&self.0, f) } +} + +impl fmt::Display for ServiceFlags { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut flags = *self; + if flags == ServiceFlags::NONE { + return write!(f, "ServiceFlags(NONE)"); + } + let mut first = true; + macro_rules! write_flag { + ($f:ident) => { + if flags.has(ServiceFlags::$f) { + if !first { + write!(f, "|")?; + } + first = false; + write!(f, stringify!($f))?; + flags.remove(ServiceFlags::$f); + } + }; + } + write!(f, "ServiceFlags(")?; + write_flag!(NETWORK); + write_flag!(GETUTXO); + write_flag!(BLOOM); + write_flag!(WITNESS); + write_flag!(COMPACT_FILTERS); + write_flag!(NETWORK_LIMITED); + // If there are unknown flags left, we append them in hex. + if flags != ServiceFlags::NONE { + if !first { + write!(f, "|")?; + } + write!(f, "0x{:x}", flags)?; + } + write!(f, ")") + } +} + +impl From for ServiceFlags { + fn from(f: u64) -> Self { ServiceFlags(f) } +} + +impl From for u64 { + fn from(flags: ServiceFlags) -> Self { flags.0 } +} + +impl ops::BitOr for ServiceFlags { + type Output = Self; + + fn bitor(mut self, rhs: Self) -> Self { self.add(rhs) } +} + +impl ops::BitOrAssign for ServiceFlags { + fn bitor_assign(&mut self, rhs: Self) { self.add(rhs); } +} + +impl ops::BitXor for ServiceFlags { + type Output = Self; + + fn bitxor(mut self, rhs: Self) -> Self { self.remove(rhs) } +} + +impl ops::BitXorAssign for ServiceFlags { + fn bitxor_assign(&mut self, rhs: Self) { self.remove(rhs); } +} + +impl Encodable for ServiceFlags { + #[inline] + fn consensus_encode(&self, w: &mut W) -> Result { + self.0.consensus_encode(w) + } +} + +impl Decodable for ServiceFlags { + #[inline] + fn consensus_decode(r: &mut R) -> Result { + Ok(ServiceFlags(Decodable::consensus_decode(r)?)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn service_flags_test() { + let all = [ + ServiceFlags::NETWORK, + ServiceFlags::GETUTXO, + ServiceFlags::BLOOM, + ServiceFlags::WITNESS, + ServiceFlags::COMPACT_FILTERS, + ServiceFlags::NETWORK_LIMITED, + ]; + + let mut flags = ServiceFlags::NONE; + for f in all.iter() { + assert!(!flags.has(*f)); + } + + flags |= ServiceFlags::WITNESS; + assert_eq!(flags, ServiceFlags::WITNESS); + + let mut flags2 = flags | ServiceFlags::GETUTXO; + for f in all.iter() { + assert_eq!(flags2.has(*f), *f == ServiceFlags::WITNESS || *f == ServiceFlags::GETUTXO); + } + + flags2 ^= ServiceFlags::WITNESS; + assert_eq!(flags2, ServiceFlags::GETUTXO); + + flags2 |= ServiceFlags::COMPACT_FILTERS; + flags2 ^= ServiceFlags::GETUTXO; + assert_eq!(flags2, ServiceFlags::COMPACT_FILTERS); + + // Test formatting. + assert_eq!("ServiceFlags(NONE)", ServiceFlags::NONE.to_string()); + assert_eq!("ServiceFlags(WITNESS)", ServiceFlags::WITNESS.to_string()); + let flag = ServiceFlags::WITNESS | ServiceFlags::BLOOM | ServiceFlags::NETWORK; + assert_eq!("ServiceFlags(NETWORK|BLOOM|WITNESS)", flag.to_string()); + let flag = ServiceFlags::WITNESS | 0xf0.into(); + assert_eq!("ServiceFlags(WITNESS|COMPACT_FILTERS|0xb0)", flag.to_string()); + } +} From 0f78943ef079dbc9ea70b4a204fa09f8c11691b6 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Fri, 9 Jun 2023 16:12:31 +1000 Subject: [PATCH 6/7] 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. --- bitcoin/src/p2p/constants.rs | 186 ++--------------------------------- bitcoin/src/p2p/message.rs | 6 +- bitcoin/src/p2p/mod.rs | 176 ++++++++++++++++++++++++++++++++- 3 files changed, 185 insertions(+), 183 deletions(-) diff --git a/bitcoin/src/p2p/constants.rs b/bitcoin/src/p2p/constants.rs index 2dce6961..33cd8ab0 100644 --- a/bitcoin/src/p2p/constants.rs +++ b/bitcoin/src/p2p/constants.rs @@ -25,21 +25,18 @@ //! assert_eq!(&bytes[..], &[0xF9, 0xBE, 0xB4, 0xD9]); //! ``` -use core::borrow::{Borrow, BorrowMut}; use core::convert::TryFrom; use core::fmt; use core::fmt::Display; use core::str::FromStr; -use hex::FromHex; -use internals::{debug_from_display, write_err}; +use internals::write_err; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use crate::consensus::encode::{self, Decodable, Encodable}; use crate::constants::ChainHash; use crate::error::impl_std_error; -use crate::io; +use crate::p2p::Magic; use crate::prelude::{String, ToOwned}; /// The cryptocurrency network to act on. @@ -65,7 +62,8 @@ impl Network { /// # Examples /// /// ```rust - /// use bitcoin::p2p::constants::{Network, Magic}; + /// use bitcoin::p2p::Magic; + /// use bitcoin::Network; /// use std::convert::TryFrom; /// /// assert_eq!(Ok(Network::Bitcoin), Network::try_from(Magic::from_bytes([0xF9, 0xBE, 0xB4, 0xD9]))); @@ -79,7 +77,8 @@ impl Network { /// # Examples /// /// ```rust - /// use bitcoin::p2p::constants::{Network, Magic}; + /// use bitcoin::p2p::Magic; + /// use bitcoin::Network; /// /// let network = Network::Bitcoin; /// assert_eq!(network.magic(), Magic::from_bytes([0xF9, 0xBE, 0xB4, 0xD9])); @@ -271,164 +270,9 @@ impl TryFrom 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 { - 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 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 for Network { - type Error = UnknownMagic; - - fn try_from(magic: Magic) -> Result { - 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(&self, writer: &mut W) -> Result { - self.0.consensus_encode(writer) - } -} - -impl Decodable for Magic { - fn consensus_decode(reader: &mut R) -> Result { - 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)] mod tests { - use std::convert::TryFrom; - use std::str::FromStr; - - use super::{Magic, Network}; + use super::Network; use crate::consensus::encode::{deserialize, serialize}; 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] fn from_to_core_arg() { let expected_pairs = [ diff --git a/bitcoin/src/p2p/message.rs b/bitcoin/src/p2p/message.rs index 098c5e73..3bd5aed4 100644 --- a/bitcoin/src/p2p/message.rs +++ b/bitcoin/src/p2p/message.rs @@ -17,9 +17,9 @@ use crate::consensus::encode::{self, CheckedData, Decodable, Encodable, VarInt}; use crate::io; use crate::merkle_tree::MerkleBlock; use crate::p2p::address::{AddrV2Message, Address}; -use crate::p2p::constants::Magic; use crate::p2p::{ message_blockdata, message_bloom, message_compact_blocks, message_filter, message_network, + Magic, }; use crate::prelude::*; @@ -550,14 +550,14 @@ mod test { use crate::consensus::encode::{deserialize, deserialize_partial, serialize}; use crate::internal_macros::hex; 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_bloom::{BloomFlags, FilterAdd, FilterLoad}; use crate::p2p::message_compact_blocks::{GetBlockTxn, SendCmpct}; use crate::p2p::message_filter::{ 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() } diff --git a/bitcoin/src/p2p/mod.rs b/bitcoin/src/p2p/mod.rs index f46733f7..df6f89ed 100644 --- a/bitcoin/src/p2p/mod.rs +++ b/bitcoin/src/p2p/mod.rs @@ -24,11 +24,18 @@ pub mod message_filter; #[cfg(feature = "std")] pub mod message_network; +use core::convert::TryFrom; +use core::str::FromStr; 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::error::impl_std_error; 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. /// @@ -196,6 +203,157 @@ impl Decodable for ServiceFlags { 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 { + 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 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 for Network { + type Error = UnknownMagic; + + fn try_from(magic: Magic) -> Result { + 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(&self, writer: &mut W) -> Result { + self.0.consensus_encode(writer) + } +} + +impl Decodable for Magic { + fn consensus_decode(reader: &mut R) -> Result { + 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)] mod tests { @@ -240,4 +398,20 @@ mod tests { let flag = ServiceFlags::WITNESS | 0xf0.into(); 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); + } + } } From d4e8f49fc30d038520b46e08646c8a1f4cee9e1b Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Fri, 9 Jun 2023 16:18:39 +1000 Subject: [PATCH 7/7] Move p2p::constants::Network to crate root The `Network` type is not a p2p construct, it is more general, used throughout the codebase to define _which_ Bitcoin network we are operating on. --- bitcoin/examples/handshake.rs | 6 ++--- bitcoin/src/address.rs | 4 ++-- bitcoin/src/bip32.rs | 4 ++-- bitcoin/src/blockdata/constants.rs | 4 ++-- bitcoin/src/blockdata/transaction.rs | 4 ++-- bitcoin/src/consensus/params.rs | 2 +- bitcoin/src/crypto/key.rs | 4 ++-- bitcoin/src/crypto/sighash.rs | 2 +- bitcoin/src/lib.rs | 3 ++- bitcoin/src/{p2p/constants.rs => network.rs} | 23 +++++++------------ bitcoin/src/p2p/message.rs | 2 +- bitcoin/src/p2p/mod.rs | 5 +--- bitcoin/src/psbt/mod.rs | 2 +- .../bitcoin/deserialize_script.rs | 2 +- 14 files changed, 29 insertions(+), 38 deletions(-) rename bitcoin/src/{p2p/constants.rs => network.rs} (94%) diff --git a/bitcoin/examples/handshake.rs b/bitcoin/examples/handshake.rs index d62d1699..9a3bb462 100644 --- a/bitcoin/examples/handshake.rs +++ b/bitcoin/examples/handshake.rs @@ -6,7 +6,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; use std::{env, process}; use bitcoin::consensus::{encode, Decodable}; -use bitcoin::p2p::{self, address, constants, message, message_network}; +use bitcoin::p2p::{self, address, message, message_network}; use bitcoin::secp256k1; use bitcoin::secp256k1::rand::Rng; @@ -29,7 +29,7 @@ fn main() { let version_message = build_version_message(address); let first_message = - message::RawNetworkMessage::new(constants::Network::Bitcoin.magic(), version_message); + message::RawNetworkMessage::new(bitcoin::Network::Bitcoin.magic(), version_message); if let Ok(mut stream) = TcpStream::connect(address) { // Send the message @@ -47,7 +47,7 @@ fn main() { println!("Received version message: {:?}", reply.payload()); let second_message = message::RawNetworkMessage::new( - constants::Network::Bitcoin.magic(), + bitcoin::Network::Bitcoin.magic(), message::NetworkMessage::Verack, ); diff --git a/bitcoin/src/address.rs b/bitcoin/src/address.rs index 41345867..ced80341 100644 --- a/bitcoin/src/address.rs +++ b/bitcoin/src/address.rs @@ -46,7 +46,7 @@ use crate::blockdata::script::witness_version::{self, WitnessVersion}; use crate::blockdata::script::{self, Script, ScriptBuf}; use crate::crypto::key::{PublicKey, TapTweak, TweakedPublicKey, UntweakedPublicKey}; use crate::hash_types::{PubkeyHash, ScriptHash}; -use crate::p2p::constants::Network; +use crate::network::Network; use crate::prelude::*; use crate::taproot::TapNodeHash; @@ -996,7 +996,7 @@ mod tests { use super::*; use crate::crypto::key::PublicKey; - use crate::p2p::constants::Network::{Bitcoin, Testnet}; + use crate::network::Network::{Bitcoin, Testnet}; fn roundtrips(addr: &Address) { assert_eq!( diff --git a/bitcoin/src/bip32.rs b/bitcoin/src/bip32.rs index 79cdc6b8..78be0174 100644 --- a/bitcoin/src/bip32.rs +++ b/bitcoin/src/bip32.rs @@ -23,7 +23,7 @@ use crate::crypto::key::{self, KeyPair, PrivateKey, PublicKey}; use crate::hash_types::XpubIdentifier; use crate::internal_macros::impl_bytes_newtype; use crate::io::Write; -use crate::p2p::constants::Network; +use crate::network::Network; use crate::prelude::*; /// A chain code @@ -866,7 +866,7 @@ mod tests { use super::ChildNumber::{Hardened, Normal}; use super::*; use crate::internal_macros::hex; - use crate::p2p::constants::Network::{self, Bitcoin}; + use crate::network::Network::{self, Bitcoin}; #[test] fn test_parse_derivation_path() { diff --git a/bitcoin/src/blockdata/constants.rs b/bitcoin/src/blockdata/constants.rs index 07a424e6..c97a5692 100644 --- a/bitcoin/src/blockdata/constants.rs +++ b/bitcoin/src/blockdata/constants.rs @@ -20,7 +20,7 @@ use crate::blockdata::script; use crate::blockdata::transaction::{OutPoint, Sequence, Transaction, TxIn, TxOut}; use crate::blockdata::witness::Witness; use crate::internal_macros::impl_bytes_newtype; -use crate::p2p::constants::Network; +use crate::network::Network; use crate::pow::CompactTarget; use crate::Amount; @@ -198,7 +198,7 @@ mod test { use crate::blockdata::locktime::absolute; use crate::consensus::encode::serialize; use crate::internal_macros::hex; - use crate::p2p::constants::Network; + use crate::network::Network; #[test] fn bitcoin_genesis_first_transaction() { diff --git a/bitcoin/src/blockdata/transaction.rs b/bitcoin/src/blockdata/transaction.rs index d3327fc7..ce782d14 100644 --- a/bitcoin/src/blockdata/transaction.rs +++ b/bitcoin/src/blockdata/transaction.rs @@ -68,7 +68,7 @@ impl OutPoint { /// /// ```rust /// use bitcoin::constants::genesis_block; - /// use bitcoin::p2p::constants::Network; + /// use bitcoin::Network; /// /// let block = genesis_block(Network::Bitcoin); /// let tx = &block.txdata[0]; @@ -1508,7 +1508,7 @@ mod tests { #[test] fn test_is_coinbase() { use crate::blockdata::constants; - use crate::p2p::constants::Network; + use crate::network::Network; let genesis = constants::genesis_block(Network::Bitcoin); assert!(genesis.txdata[0].is_coinbase()); diff --git a/bitcoin/src/consensus/params.rs b/bitcoin/src/consensus/params.rs index 36861564..12eb1f5e 100644 --- a/bitcoin/src/consensus/params.rs +++ b/bitcoin/src/consensus/params.rs @@ -6,7 +6,7 @@ //! chains (such as mainnet, testnet). //! -use crate::p2p::constants::Network; +use crate::network::Network; use crate::pow::Work; /// Parameters that influence chain consensus. diff --git a/bitcoin/src/crypto/key.rs b/bitcoin/src/crypto/key.rs index 5e08c7e5..fcfe14e7 100644 --- a/bitcoin/src/crypto/key.rs +++ b/bitcoin/src/crypto/key.rs @@ -18,7 +18,7 @@ pub use secp256k1::{self, constants, KeyPair, Parity, Secp256k1, Verification, X use crate::crypto::ecdsa; use crate::hash_types::{PubkeyHash, WPubkeyHash}; -use crate::p2p::constants::Network; +use crate::network::Network; use crate::prelude::*; use crate::taproot::{TapNodeHash, TapTweakHash}; use crate::{base58, io}; @@ -741,7 +741,7 @@ mod tests { use super::*; use crate::address::Address; use crate::io; - use crate::p2p::constants::Network::{Bitcoin, Testnet}; + use crate::network::Network::{Bitcoin, Testnet}; #[test] fn test_key_derivation() { diff --git a/bitcoin/src/crypto/sighash.rs b/bitcoin/src/crypto/sighash.rs index eb537479..fcefe767 100644 --- a/bitcoin/src/crypto/sighash.rs +++ b/bitcoin/src/crypto/sighash.rs @@ -1120,7 +1120,7 @@ mod tests { use crate::crypto::key::PublicKey; use crate::crypto::sighash::{LegacySighash, TapSighash}; use crate::internal_macros::hex; - use crate::p2p::constants::Network; + use crate::network::Network; use crate::taproot::TapLeafHash; extern crate serde_json; diff --git a/bitcoin/src/lib.rs b/bitcoin/src/lib.rs index 4bcc0783..0665662a 100644 --- a/bitcoin/src/lib.rs +++ b/bitcoin/src/lib.rs @@ -106,6 +106,7 @@ pub(crate) mod crypto; pub mod error; pub mod hash_types; pub mod merkle_tree; +pub mod network; pub mod policy; pub mod pow; pub mod psbt; @@ -146,7 +147,7 @@ pub use crate::hash_types::{ BlockHash, PubkeyHash, ScriptHash, Txid, WPubkeyHash, WScriptHash, Wtxid, }; pub use crate::merkle_tree::MerkleBlock; -pub use crate::p2p::constants::Network; +pub use crate::network::Network; pub use crate::pow::{CompactTarget, Target, Work}; pub use crate::psbt::Psbt; diff --git a/bitcoin/src/p2p/constants.rs b/bitcoin/src/network.rs similarity index 94% rename from bitcoin/src/p2p/constants.rs rename to bitcoin/src/network.rs index 33cd8ab0..9e128d4e 100644 --- a/bitcoin/src/p2p/constants.rs +++ b/bitcoin/src/network.rs @@ -1,22 +1,15 @@ // SPDX-License-Identifier: CC0-1.0 -//! Bitcoin network constants. +//! Bitcoin network. //! -//! This module provides various constants relating to the Bitcoin network -//! protocol, such as protocol versioning and magic header bytes. -//! -//! The [`Network`][1] type implements the [`Decodable`][2] and -//! [`Encodable`][3] traits and encodes the magic bytes of the given -//! network. -//! -//! [1]: enum.Network.html -//! [2]: ../../consensus/encode/trait.Decodable.html -//! [3]: ../../consensus/encode/trait.Encodable.html +//! The term "network" is overloaded, here [`Network`] refers to the specific +//! Bitcoin network we are operating on e.g., signet, regtest. The terms +//! "network" and "chain" are often used interchangeably for this concept. //! //! # Example: encoding a network's magic bytes //! //! ```rust -//! use bitcoin::p2p::constants::Network; +//! use bitcoin::Network; //! use bitcoin::consensus::encode::serialize; //! //! let network = Network::Bitcoin; @@ -130,7 +123,7 @@ impl Network { /// # Examples /// /// ```rust - /// use bitcoin::p2p::constants::Network; + /// use bitcoin::Network; /// use bitcoin::blockdata::constants::ChainHash; /// /// let network = Network::Bitcoin; @@ -143,7 +136,7 @@ impl Network { /// # Examples /// /// ```rust - /// use bitcoin::p2p::constants::Network; + /// use bitcoin::Network; /// use bitcoin::blockdata::constants::ChainHash; /// use std::convert::TryFrom; /// @@ -387,7 +380,7 @@ mod tests { #[derive(Serialize, Deserialize, PartialEq, Debug)] #[serde(crate = "actual_serde")] struct T { - #[serde(with = "crate::p2p::constants::as_core_arg")] + #[serde(with = "crate::network::as_core_arg")] pub network: Network, } diff --git a/bitcoin/src/p2p/message.rs b/bitcoin/src/p2p/message.rs index 3bd5aed4..8b048af2 100644 --- a/bitcoin/src/p2p/message.rs +++ b/bitcoin/src/p2p/message.rs @@ -549,8 +549,8 @@ mod test { use crate::blockdata::transaction::Transaction; use crate::consensus::encode::{deserialize, deserialize_partial, serialize}; use crate::internal_macros::hex; + use crate::network::Network; use crate::p2p::address::{AddrV2, AddrV2Message, Address}; - use crate::p2p::constants::Network; use crate::p2p::message_blockdata::{GetBlocksMessage, GetHeadersMessage, Inventory}; use crate::p2p::message_bloom::{BloomFlags, FilterAdd, FilterLoad}; use crate::p2p::message_compact_blocks::{GetBlockTxn, SendCmpct}; diff --git a/bitcoin/src/p2p/mod.rs b/bitcoin/src/p2p/mod.rs index df6f89ed..f4b7698c 100644 --- a/bitcoin/src/p2p/mod.rs +++ b/bitcoin/src/p2p/mod.rs @@ -5,8 +5,6 @@ //! This module defines support for (de)serialization and network transport //! of Bitcoin data and Bitcoin p2p network messages. -pub mod constants; - #[cfg(feature = "std")] pub mod address; #[cfg(feature = "std")] @@ -33,9 +31,8 @@ use internals::{debug_from_display, write_err}; use crate::consensus::encode::{self, Decodable, Encodable}; use crate::error::impl_std_error; -use crate::io; -use crate::p2p::constants::Network; use crate::prelude::{Borrow, BorrowMut, String, ToOwned}; +use crate::{io, Network}; /// Version of the protocol as appearing in network message headers. /// diff --git a/bitcoin/src/psbt/mod.rs b/bitcoin/src/psbt/mod.rs index 1caa20c6..df9f6c90 100644 --- a/bitcoin/src/psbt/mod.rs +++ b/bitcoin/src/psbt/mod.rs @@ -823,7 +823,7 @@ mod tests { use crate::blockdata::transaction::{OutPoint, Sequence, Transaction, TxIn, TxOut}; use crate::blockdata::witness::Witness; use crate::internal_macros::hex; - use crate::p2p::constants::Network::Bitcoin; + use crate::network::Network::Bitcoin; use crate::psbt::map::{Input, Output}; use crate::psbt::raw; use crate::psbt::serialize::{Deserialize, Serialize}; diff --git a/fuzz/fuzz_targets/bitcoin/deserialize_script.rs b/fuzz/fuzz_targets/bitcoin/deserialize_script.rs index 1cc035d2..a32f01f0 100644 --- a/fuzz/fuzz_targets/bitcoin/deserialize_script.rs +++ b/fuzz/fuzz_targets/bitcoin/deserialize_script.rs @@ -1,7 +1,7 @@ use bitcoin::address::Address; use bitcoin::blockdata::script; use bitcoin::consensus::encode; -use bitcoin::p2p::constants::Network; +use bitcoin::Network; use honggfuzz::fuzz; fn do_test(data: &[u8]) {