bitcoin_peers_connection/lib.rs
1//! Bitcoin peer connection and transport handling.
2//!
3//! This crate provides a robust implementation of the bitcoin peer-to-peer network protocol,
4//! supporting both the legacy v1 transport and the modern encrypted v2 transport (BIP-324).
5//! It handles the complete connection lifecycle including handshake, feature negotiation,
6//! and message serialization,
7//!
8//! # Features
9//!
10//! * **Dual Transport Support**: Seamlessly handles both v1 (legacy) and v2 (BIP-324 encrypted) transports.
11//! * **Feature Negotiation**: Automatic negotiation of protocol features like compact blocks and address relay.
12//! * **Split Architecture**: Connections can be split into separate sender/receiver halves for concurrent use.
13//!
14//! # Quick Start
15//!
16//! ```
17//! use bitcoin::Network;
18//! use bitcoin_peers_connection::{
19//! futures::Connection, ConnectionConfiguration, Peer, PeerProtocolVersion,
20//! TransportPolicy, FeaturePreferences
21//! };
22//! use bitcoin::p2p::address::AddrV2;
23//! use bitcoin::p2p::message::NetworkMessage;
24//! use std::net::Ipv4Addr;
25//!
26//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
27//! // Create a peer address.
28//! let peer = Peer::new(
29//! AddrV2::Ipv4(Ipv4Addr::new(127, 0, 0, 1)),
30//! 8333,
31//! );
32//!
33//! // Configure connection for a non-listening client.
34//! let config = ConnectionConfiguration::non_listening(
35//! PeerProtocolVersion::Known(70016), // Local protocol version
36//! TransportPolicy::V2Preferred, // Try v2, fallback to v1
37//! FeaturePreferences::default(), // Default features
38//! None, // No custom user agent
39//! );
40//!
41//! // Establish connection with automatic handshake.
42//! let mut connection = Connection::connect(peer, Network::Bitcoin, config).await?;
43//!
44//! // Send and receive messages.
45//! connection.write(NetworkMessage::GetAddr).await?;
46//! let message = connection.read().await?;
47//! # Ok(())
48//! # }
49//! ```
50//!
51//! # Architecture
52//!
53//! The crate is organized into several key modules:
54//!
55//! * **Connection Layer**: High-level API for establishing and managing connections.
56//! * **Transport Layer**: Lower level message serialization and encryption (v1 and v2).
57//!
58//! # Connection
59//!
60//! * [`futures::Connection`] - The main async connection type that handles both sending and receiving.
61//! * [`futures::ConnectionWriter`] / [`futures::ConnectionReader`] - Split connection for concurrent operations.
62//!
63//! ## Split Connection for Concurrent Operations
64//!
65//! ```
66//! # use bitcoin::Network;
67//! # use bitcoin_peers_connection::{futures::Connection, ConnectionConfiguration, Peer, PeerProtocolVersion, TransportPolicy, FeaturePreferences};
68//! # use bitcoin::p2p::message::NetworkMessage;
69//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
70//! # let peer = Peer::new(bitcoin::p2p::address::AddrV2::Ipv4(std::net::Ipv4Addr::new(127, 0, 0, 1)), 8333);
71//! # let config = ConnectionConfiguration::non_listening(
72//! # PeerProtocolVersion::Known(70016),
73//! # TransportPolicy::V2Preferred,
74//! # FeaturePreferences::default(),
75//! # None,
76//! # );
77//! let connection = Connection::connect(peer, Network::Bitcoin, config).await?;
78//! let (mut receiver, mut sender) = connection.into_split();
79//!
80//! // Can now send and receive concurrently from different tasks.
81//! tokio::spawn(async move {
82//! sender.write(NetworkMessage::Ping(42)).await.unwrap();
83//! });
84//!
85//! let message = receiver.read().await?;
86//! # Ok(())
87//! # }
88//! ```
89//!
90//! ## Accepting Inbound Connections
91//!
92//! ```
93//! # use bitcoin::Network;
94//! # use bitcoin_peers_connection::{futures::Connection, ConnectionConfiguration, PeerProtocolVersion, TransportPolicy, FeaturePreferences, UserAgent};
95//! # use tokio::net::TcpListener;
96//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
97//! // Configure for a listening node with custom user agent.
98//! let config = ConnectionConfiguration::non_listening(
99//! PeerProtocolVersion::Known(70016),
100//! TransportPolicy::V2Preferred,
101//! FeaturePreferences::default(),
102//! Some(UserAgent::from_name_version("MyNode", "0.1.0")),
103//! );
104//!
105//! // Accept incoming connections.
106//! let listener = TcpListener::bind("0.0.0.0:8333").await?;
107//! let (stream, _addr) = listener.accept().await?;
108//! let connection = Connection::accept(stream, Network::Bitcoin, config).await?;
109//! # Ok(())
110//! # }
111//! ````
112//!
113//! # Transport
114//!
115//! * [`transport::Transport`] - Lower-level transport abstraction over both v1 and v2.
116
117pub mod connection;
118mod peer;
119pub mod transport;
120mod user_agent;
121
122pub use connection::{
123 futures, ConnectionConfiguration, ConnectionError, FeaturePreferences, TransportPolicy,
124};
125pub use peer::{Peer, PeerProtocolVersion, PeerServices};
126pub use user_agent::{UserAgent, UserAgentError};