bitcoin_peers_crawler/
lib.rs

1//! Bitcoin network peer discovery.
2//!
3//! This crate provides a high-performance, concurrent crawler for discovering peers on the bitcoin network.
4//!
5//! # Features
6//!
7//! * **Concurrent Crawling**: Efficiently crawls multiple peers simultaneously.
8//! * **Streaming Results**: Returns discovered peers as they're found via an async channel interface.
9//! * **Resource Control**: Configurable limits on concurrent connections and timeouts.
10//!
11//! # Quick Start
12//!
13//! ```
14//! use bitcoin::Network;
15//! use bitcoin::p2p::address::AddrV2;
16//! use bitcoin_peers_crawler::{Crawler, CrawlerBuilder, Peer};
17//! use tokio::time::{timeout, Duration};
18//! use std::net::Ipv4Addr;
19//!
20//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
21//! // Build a crawler with custom configuration.
22//! let crawler = CrawlerBuilder::new(Network::Bitcoin)
23//!     .with_max_concurrent_tasks(16)  // Increase concurrency
24//!     .build();
25//!
26//! // Create a seed peer to start crawling from.
27//! let seed = Peer::new(
28//!     AddrV2::Ipv4(Ipv4Addr::new(127, 0, 0, 1)),
29//!     8333,
30//! );
31//!
32//! // Start crawling from the seed peer.
33//! let mut receiver = crawler.crawl(seed).await?;
34//!
35//! // Collect peers for 30 seconds.
36//! let mut discovered_peers = Vec::new();
37//! let duration = Duration::from_secs(30);
38//!
39//! if let Ok(result) = timeout(duration, async {
40//!     while let Some(msg) = receiver.recv().await {
41//!         match msg {
42//!             bitcoin_peers_crawler::CrawlerMessage::Listening(peer) => {
43//!                 discovered_peers.push(peer);
44//!             }
45//!             _ => {} // Ignore non-listening peers
46//!         }
47//!     }
48//! }).await {
49//!     result;
50//! }
51//!
52//! println!("Discovered {} peers", discovered_peers.len());
53//! # Ok(())
54//! # }
55//! ```
56//!
57//! # Configuration
58//!
59//! The [`CrawlerBuilder`] provides fine-grained control over crawler behavior:
60//!
61//! ```no_run
62//! use bitcoin::Network;
63//! use bitcoin_peers_crawler::{CrawlerBuilder, TransportPolicy};
64//!
65//! let crawler = CrawlerBuilder::new(Network::Bitcoin)
66//!     .with_max_concurrent_tasks(32)     // Aggressive concurrency
67//!     .with_transport_policy(TransportPolicy::V2Required)  // Require encrypted connections
68//!     .with_protocol_version(70016)      // Minimum protocol version
69//!     .build();
70//! ```
71//!
72//! # Example: Finding V2-Capable Peers
73//!
74//! ```no_run
75//! use bitcoin::Network;
76//! use bitcoin::p2p::address::AddrV2;
77//! use bitcoin::p2p::ServiceFlags;
78//! use bitcoin_peers_crawler::{CrawlerBuilder, CrawlerMessage, Peer, PeerServices};
79//! use std::net::Ipv4Addr;
80//!
81//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
82//! let crawler = CrawlerBuilder::new(Network::Bitcoin).build();
83//!
84//! // Start from a known peer
85//! let seed = Peer::new(
86//!     AddrV2::Ipv4(Ipv4Addr::new(127, 0, 0, 1)),
87//!     8333,
88//! );
89//! let mut receiver = crawler.crawl(seed).await?;
90//!
91//! let mut v2_peers = Vec::new();
92//! while let Some(msg) = receiver.recv().await {
93//!     if let CrawlerMessage::Listening(peer) = msg {
94//!         // Check if peer advertises v2 transport support.
95//!         if let PeerServices::Known(flags) = peer.services {
96//!             if flags.has(ServiceFlags::P2P_V2) {
97//!                 v2_peers.push(peer);
98//!             }
99//!         }
100//!         
101//!         if v2_peers.len() >= 100 {
102//!             break;  // Found enough v2-capable peers
103//!         }
104//!     }
105//! }
106//! # Ok(())
107//! # }
108//! ```
109
110mod builder;
111mod connection;
112mod crawler;
113mod session;
114
115pub use builder::{CrawlerBuilder, CrawlerBuilderError};
116pub use crawler::{Crawler, CrawlerMessage};
117
118// Re-exports.
119pub use bitcoin_peers_connection::{
120    ConnectionError, Peer, PeerProtocolVersion, PeerServices, TransportPolicy, UserAgent,
121};