pub mod address_db;
pub mod ban_list_merging;
pub mod ban_list_signing;
pub mod bandwidth_protection;
pub mod chain_access;
pub mod connection_manager;
pub mod dns_seeds;
pub mod dos_protection;
#[cfg(feature = "erlay")]
pub mod erlay;
pub mod ibd_protection;
pub mod inventory;
pub mod lan_discovery;
pub mod lan_security;
pub mod message_bridge;
pub mod module_registry_extensions;
pub mod network_manager;
pub mod peer;
pub mod peer_manager;
pub mod peer_scoring;
pub mod protocol;
pub mod protocol_adapter;
pub mod protocol_extensions;
pub mod relay;
pub mod replay_protection;
pub mod tcp_transport;
pub mod transport;
#[cfg(feature = "quinn")]
pub mod quinn_transport;
#[cfg(feature = "iroh")]
pub mod iroh_transport;
#[cfg(feature = "utxo-commitments")]
pub mod utxo_commitments_client;
pub mod compact_blocks;
mod background_tasks;
pub mod bip157_handler;
pub mod filter_service;
mod getdata_serve;
mod handlers;
mod network_message_dispatch;
mod peer_connections;
mod startup;
mod wire_dispatch;
pub mod bip70_handler;
#[cfg(feature = "dandelion")]
pub mod dandelion; #[cfg(feature = "fibre")]
pub mod fibre; pub mod package_relay; pub mod package_relay_handler; #[cfg(feature = "stratum-v2")]
pub mod stratum_v2;
#[cfg(feature = "stratum-v2")]
pub(crate) mod stratum_v2_listener;
pub mod txhash;
use std::net::SocketAddr;
use tokio::sync::mpsc;
pub use connection_manager::{ConnectionManager, NetworkIO};
pub use network_manager::NetworkManager;
pub use peer_manager::{PeerByteRateLimiter, PeerManager, PeerRateLimiter};
pub use transport::{TransportAddr, TransportPreference};
#[derive(Debug, Clone)]
pub enum NetworkMessage {
PeerConnected(TransportAddr),
PeerDisconnected(TransportAddr),
BlockReceived(Vec<u8>),
TransactionReceived(Vec<u8>),
InventoryReceived(Vec<u8>),
#[cfg(feature = "utxo-commitments")]
UTXOSetReceived(Vec<u8>, SocketAddr), #[cfg(feature = "utxo-commitments")]
FilteredBlockReceived(Vec<u8>, SocketAddr), #[cfg(feature = "utxo-commitments")]
GetUTXOSetReceived(Vec<u8>, SocketAddr), #[cfg(feature = "utxo-commitments")]
GetFilteredBlockReceived(Vec<u8>, SocketAddr), #[cfg(feature = "stratum-v2")]
StratumV2MessageReceived(Vec<u8>, SocketAddr), RawMessageReceived(Vec<u8>, SocketAddr), HeadersReceived(Vec<u8>, SocketAddr), GetCfiltersReceived(Vec<u8>, SocketAddr), GetCfheadersReceived(Vec<u8>, SocketAddr), GetCfcheckptReceived(Vec<u8>, SocketAddr), PkgTxnReceived(Vec<u8>, SocketAddr), SendPkgTxnReceived(Vec<u8>, SocketAddr), GetModuleReceived(Vec<u8>, SocketAddr), ModuleReceived(Vec<u8>, SocketAddr), GetModuleByHashReceived(Vec<u8>, SocketAddr), ModuleByHashReceived(Vec<u8>, SocketAddr), GetModuleListReceived(Vec<u8>, SocketAddr), ModuleListReceived(Vec<u8>, SocketAddr), GetPaymentRequestReceived(Vec<u8>, SocketAddr), PaymentRequestReceived(Vec<u8>, SocketAddr), PaymentReceived(Vec<u8>, SocketAddr), PaymentACKReceived(Vec<u8>, SocketAddr), #[cfg(feature = "ctv")]
PaymentProofReceived(Vec<u8>, SocketAddr), SettlementNotificationReceived(Vec<u8>, SocketAddr), MeshPacketReceived(Vec<u8>, SocketAddr), }
#[cfg(test)]
mod tests {
mod bandwidth_protection_tests;
mod concurrency_stress_tests;
use super::*;
#[tokio::test]
async fn test_peer_manager_creation() {
let _addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let manager = PeerManager::new(10);
assert_eq!(manager.peer_count(), 0);
assert!(manager.can_accept_peer());
}
#[tokio::test]
async fn test_peer_manager_add_peer() {
let manager = PeerManager::new(2);
let _addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let (_tx, _rx): (mpsc::UnboundedSender<NetworkMessage>, _) = mpsc::unbounded_channel();
assert_eq!(manager.peer_count(), 0);
assert!(manager.can_accept_peer());
}
#[tokio::test]
async fn test_peer_manager_max_peers() {
let manager = PeerManager::new(1);
let _addr1: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let _addr2: std::net::SocketAddr = "127.0.0.1:8081".parse().unwrap();
assert_eq!(manager.peer_count(), 0);
assert!(manager.can_accept_peer());
assert_eq!(manager.peer_count(), 0);
}
#[tokio::test]
async fn test_peer_manager_remove_peer() {
let mut manager = PeerManager::new(10);
let addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
assert_eq!(manager.peer_count(), 0);
let transport_addr = TransportAddr::Tcp(addr);
let removed_peer = manager.remove_peer(&transport_addr);
assert!(removed_peer.is_none());
assert_eq!(manager.peer_count(), 0);
}
#[tokio::test]
async fn test_peer_manager_get_peer() {
let manager = PeerManager::new(10);
let addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
assert_eq!(manager.peer_count(), 0);
let transport_addr = TransportAddr::Tcp(addr);
let retrieved_peer = manager.get_peer(&transport_addr);
assert!(retrieved_peer.is_none());
}
#[tokio::test]
async fn test_peer_manager_peer_addresses() {
let manager = PeerManager::new(10);
let _addr1: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let _addr2: std::net::SocketAddr = "127.0.0.1:8081".parse().unwrap();
assert_eq!(manager.peer_count(), 0);
let addresses = manager.peer_addresses();
assert_eq!(addresses.len(), 0);
}
#[tokio::test]
async fn test_connection_manager_creation() {
let addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let manager = ConnectionManager::new(addr);
assert_eq!(manager.listen_addr(), addr);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_network_manager_creation() {
let addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let manager = NetworkManager::new(addr);
assert_eq!(manager.peer_count(), 0);
assert_eq!(manager.peer_addresses().len(), 0);
}
#[tokio::test]
async fn test_network_manager_with_config() {
let addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let manager = NetworkManager::with_config(
addr,
5,
crate::network::transport::TransportPreference::TCP_ONLY,
None,
);
let peer_manager = manager.peer_manager().await;
assert_eq!(peer_manager.peer_count(), 0);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_network_manager_peer_count() {
let addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let manager = NetworkManager::new(addr);
assert_eq!(manager.peer_count(), 0);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_network_manager_peer_addresses() {
let addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let manager = NetworkManager::new(addr);
assert_eq!(manager.peer_count(), 0);
let addresses = manager.peer_addresses();
assert_eq!(addresses.len(), 0);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_network_manager_broadcast() {
let addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let manager = NetworkManager::new(addr);
assert_eq!(manager.peer_count(), 0);
let message = b"test message".to_vec();
let result = manager.broadcast(message).await;
assert!(result.is_ok());
}
#[tokio::test(flavor = "multi_thread")]
async fn test_network_manager_send_to_peer() {
let addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let manager = NetworkManager::new(addr);
assert_eq!(manager.peer_count(), 0);
let peer_addr = "127.0.0.1:8081".parse().unwrap();
let message = b"test message".to_vec();
let result = manager.send_to_peer(peer_addr, message).await;
assert!(result.is_err()); }
#[tokio::test]
async fn test_network_manager_send_to_nonexistent_peer() {
let addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let manager = NetworkManager::new(addr);
let peer_addr = "127.0.0.1:8081".parse().unwrap();
let message = b"test message".to_vec();
let result = manager.send_to_peer(peer_addr, message).await;
assert!(result.is_err()); }
#[tokio::test]
async fn test_network_message_peer_connected() {
let socket_addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let transport_addr = TransportAddr::Tcp(socket_addr);
let message = NetworkMessage::PeerConnected(transport_addr.clone());
match message {
NetworkMessage::PeerConnected(addr) => {
assert_eq!(addr, transport_addr);
}
_ => panic!("Expected PeerConnected message"),
}
}
#[tokio::test]
async fn test_network_message_peer_disconnected() {
let socket_addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let transport_addr = TransportAddr::Tcp(socket_addr);
let message = NetworkMessage::PeerDisconnected(transport_addr.clone());
match message {
NetworkMessage::PeerDisconnected(addr) => {
assert_eq!(addr, transport_addr);
}
_ => panic!("Expected PeerDisconnected message"),
}
}
#[tokio::test]
async fn test_network_message_block_received() {
let data = b"block data".to_vec();
let message = NetworkMessage::BlockReceived(data.clone());
match message {
NetworkMessage::BlockReceived(msg_data) => {
assert_eq!(msg_data, data);
}
_ => panic!("Expected BlockReceived message"),
}
}
#[tokio::test]
async fn test_network_message_transaction_received() {
let data = b"tx data".to_vec();
let message = NetworkMessage::TransactionReceived(data.clone());
match message {
NetworkMessage::TransactionReceived(msg_data) => {
assert_eq!(msg_data, data);
}
_ => panic!("Expected TransactionReceived message"),
}
}
#[tokio::test]
async fn test_network_message_inventory_received() {
let data = b"inv data".to_vec();
let message = NetworkMessage::InventoryReceived(data.clone());
match message {
NetworkMessage::InventoryReceived(msg_data) => {
assert_eq!(msg_data, data);
}
_ => panic!("Expected InventoryReceived message"),
}
}
#[tokio::test(flavor = "multi_thread")]
async fn test_network_manager_peer_manager_access() {
let addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let manager = NetworkManager::new(addr);
{
let peer_manager = manager.peer_manager().await;
assert_eq!(peer_manager.peer_count(), 0);
}
assert_eq!(manager.peer_count(), 0);
}
#[tokio::test]
async fn test_network_manager_transport_preference() {
let addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let manager = NetworkManager::new(addr);
assert_eq!(
manager.transport_preference(),
TransportPreference::TCP_ONLY
);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_block_request_completion_direct() {
use crate::storage::hashing::double_sha256;
use blvm_protocol::genesis;
let genesis = genesis::mainnet_genesis();
let mut header_bytes = Vec::with_capacity(80);
header_bytes.extend_from_slice(&(genesis.header.version as i32).to_le_bytes());
header_bytes.extend_from_slice(&genesis.header.prev_block_hash);
header_bytes.extend_from_slice(&genesis.header.merkle_root);
header_bytes.extend_from_slice(&(genesis.header.timestamp as u32).to_le_bytes());
header_bytes.extend_from_slice(&(genesis.header.bits as u32).to_le_bytes());
header_bytes.extend_from_slice(&(genesis.header.nonce as u32).to_le_bytes());
let block_hash = double_sha256(&header_bytes);
let mut hash_array = [0u8; 32];
hash_array.copy_from_slice(&block_hash);
let addr: std::net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
let network = NetworkManager::with_config(addr, 5, TransportPreference::TCP_ONLY, None);
let peer_addr: std::net::SocketAddr = "127.0.0.1:18444".parse().unwrap();
let block_rx = network.register_block_request(peer_addr, hash_array);
let empty_witnesses: Vec<Vec<blvm_protocol::segwit::Witness>> =
(0..genesis.transactions.len()).map(|_| vec![]).collect();
let ok = network.complete_block_request(
peer_addr,
hash_array,
genesis.clone(),
empty_witnesses.clone(),
);
assert!(
ok,
"complete_block_request should find matching pending request"
);
let (received, witnesses) =
tokio::time::timeout(std::time::Duration::from_secs(1), block_rx)
.await
.expect("block rx should complete within 1s")
.expect("block channel should not be closed");
assert_eq!(received.header.merkle_root, genesis.header.merkle_root);
assert_eq!(witnesses.len(), genesis.transactions.len());
}
}