use crate::network::bandwidth_protection::{BandwidthProtectionManager, ServiceType};
use crate::network::ibd_protection::IbdProtectionManager;
use std::net::SocketAddr;
use std::sync::Arc;
use tokio::time::{sleep, Duration};
fn create_test_manager() -> Arc<BandwidthProtectionManager> {
let ibd_protection = Arc::new(IbdProtectionManager::new());
Arc::new(BandwidthProtectionManager::new(ibd_protection))
}
#[tokio::test]
async fn test_filter_service_bandwidth_limit() {
let manager = create_test_manager();
let peer_addr: SocketAddr = "127.0.0.1:8333".parse().unwrap();
let result = manager
.check_service_request(ServiceType::Filters, peer_addr)
.await;
assert!(result.is_ok());
assert!(result.unwrap(), "First filter request should be allowed");
let limit_bytes = 5 * 1024 * 1024 * 1024;
manager
.record_service_bandwidth(ServiceType::Filters, peer_addr, limit_bytes)
.await;
let result = manager
.check_service_request(ServiceType::Filters, peer_addr)
.await;
assert!(result.is_ok());
assert!(
!result.unwrap(),
"Request should be rejected after limit exceeded"
);
}
#[tokio::test]
async fn test_filter_service_rate_limit() {
let manager = create_test_manager();
let peer_addr: SocketAddr = "127.0.0.1:8333".parse().unwrap();
for i in 0..50 {
let result = manager
.check_service_request(ServiceType::Filters, peer_addr)
.await;
assert!(result.is_ok());
assert!(result.unwrap(), "Request {i} should be allowed");
manager
.record_service_request(ServiceType::Filters, peer_addr)
.await;
}
let result = manager
.check_service_request(ServiceType::Filters, peer_addr)
.await;
assert!(result.is_ok());
assert!(
!result.unwrap(),
"51st request should be rejected (rate limit)"
);
}
#[tokio::test]
async fn test_per_ip_bandwidth_limit() {
let manager = create_test_manager();
let peer1: SocketAddr = "127.0.0.1:8333".parse().unwrap();
let peer2: SocketAddr = "127.0.0.1:8334".parse().unwrap();
let result1 = manager
.check_service_request(ServiceType::Filters, peer1)
.await;
assert!(result1.is_ok());
assert!(result1.unwrap());
let result2 = manager
.check_service_request(ServiceType::Filters, peer2)
.await;
assert!(result2.is_ok());
assert!(result2.unwrap());
let limit_bytes = 10 * 1024 * 1024 * 1024; manager
.record_service_bandwidth(ServiceType::Filters, peer1, limit_bytes)
.await;
let result = manager
.check_service_request(ServiceType::Filters, peer2)
.await;
assert!(result.is_ok());
assert!(
!result.unwrap(),
"peer2 should be rejected (IP limit exceeded)"
);
}
#[tokio::test]
async fn test_per_subnet_bandwidth_limit() {
let manager = create_test_manager();
let peer1: SocketAddr = "192.168.1.1:8333".parse().unwrap();
let peer2: SocketAddr = "192.168.1.2:8333".parse().unwrap();
let peer3: SocketAddr = "192.168.1.3:8333".parse().unwrap();
for peer in &[peer1, peer2, peer3] {
let result = manager
.check_service_request(ServiceType::Filters, *peer)
.await;
assert!(result.is_ok());
assert!(result.unwrap());
}
let limit_bytes = 50 * 1024 * 1024 * 1024; manager
.record_service_bandwidth(ServiceType::Filters, peer1, limit_bytes)
.await;
for peer in &[peer2, peer3] {
let result = manager
.check_service_request(ServiceType::Filters, *peer)
.await;
assert!(result.is_ok());
assert!(!result.unwrap(), "Peer from same subnet should be rejected");
}
}
#[tokio::test]
async fn test_utxo_set_very_restrictive_limit() {
let manager = create_test_manager();
let peer_addr: SocketAddr = "127.0.0.1:8333".parse().unwrap();
let result = manager
.check_service_request(ServiceType::UtxoSet, peer_addr)
.await;
assert!(result.is_ok());
assert!(result.unwrap());
manager
.record_service_request(ServiceType::UtxoSet, peer_addr)
.await;
let result = manager
.check_service_request(ServiceType::UtxoSet, peer_addr)
.await;
assert!(result.is_ok());
assert!(
!result.unwrap(),
"Second UTXO set request should be rejected (rate limit)"
);
}
#[tokio::test]
async fn test_cpu_time_limit() {
let manager = create_test_manager();
assert!(
manager.check_cpu_time_limit(ServiceType::Filters, 50),
"50ms should be within limit"
);
assert!(
manager.check_cpu_time_limit(ServiceType::Filters, 100),
"100ms should be at limit"
);
assert!(
!manager.check_cpu_time_limit(ServiceType::Filters, 101),
"101ms should exceed limit"
);
assert!(
manager.check_cpu_time_limit(ServiceType::PackageRelay, 1000),
"Package relay should have no CPU limit"
);
}
#[tokio::test]
async fn test_different_services_independent_limits() {
let manager = create_test_manager();
let peer_addr: SocketAddr = "127.0.0.1:8333".parse().unwrap();
let filter_limit = 5 * 1024 * 1024 * 1024;
manager
.record_service_bandwidth(ServiceType::Filters, peer_addr, filter_limit)
.await;
let result = manager
.check_service_request(ServiceType::Filters, peer_addr)
.await;
assert!(result.is_ok());
assert!(!result.unwrap(), "Filter service should be blocked");
let result = manager
.check_service_request(ServiceType::PackageRelay, peer_addr)
.await;
assert!(result.is_ok());
assert!(
result.unwrap(),
"Package relay should still work (different service)"
);
}
#[tokio::test]
async fn test_attack_scenario_multiple_peers_same_ip() {
let manager = create_test_manager();
let peers: Vec<SocketAddr> = (8333..8353)
.map(|port| format!("127.0.0.1:{port}").parse().unwrap())
.collect();
for peer in &peers {
let result = manager
.check_service_request(ServiceType::Filters, *peer)
.await;
assert!(result.is_ok());
assert!(result.unwrap());
}
let bytes_per_peer = 2 * 1024 * 1024 * 1024; for peer in &peers[..5] {
manager
.record_service_bandwidth(ServiceType::Filters, *peer, bytes_per_peer)
.await;
}
for peer in &peers[5..] {
let result = manager
.check_service_request(ServiceType::Filters, *peer)
.await;
assert!(result.is_ok());
assert!(
!result.unwrap(),
"Peer from same IP should be blocked (IP limit)"
);
}
}
#[tokio::test]
async fn test_attack_scenario_rapid_requests() {
let manager = create_test_manager();
let peer_addr: SocketAddr = "127.0.0.1:8333".parse().unwrap();
let mut allowed = 0;
for _ in 0..60 {
let result = manager
.check_service_request(ServiceType::Filters, peer_addr)
.await;
if result.is_ok() && result.unwrap() {
allowed += 1;
manager
.record_service_request(ServiceType::Filters, peer_addr)
.await;
} else {
break; }
}
assert_eq!(allowed, 50, "Should allow exactly 50 requests per hour");
}
#[tokio::test]
async fn test_legitimate_use_not_blocked() {
let manager = create_test_manager();
let peer_addr: SocketAddr = "127.0.0.1:8333".parse().unwrap();
let moderate_bytes = 100 * 1024 * 1024; manager
.record_service_bandwidth(ServiceType::Filters, peer_addr, moderate_bytes)
.await;
let result = manager
.check_service_request(ServiceType::Filters, peer_addr)
.await;
assert!(result.is_ok());
assert!(result.unwrap(), "Legitimate moderate use should be allowed");
}
#[tokio::test]
async fn test_package_relay_limits() {
let manager = create_test_manager();
let peer_addr: SocketAddr = "127.0.0.1:8333".parse().unwrap();
let limit_bytes = 10 * 1024 * 1024 * 1024; manager
.record_service_bandwidth(ServiceType::PackageRelay, peer_addr, limit_bytes)
.await;
let result = manager
.check_service_request(ServiceType::PackageRelay, peer_addr)
.await;
assert!(result.is_ok());
assert!(
!result.unwrap(),
"Should be blocked after package relay limit"
);
}
#[tokio::test]
async fn test_module_serving_limits() {
let manager = create_test_manager();
let peer_addr: SocketAddr = "127.0.0.1:8333".parse().unwrap();
let limit_bytes = 100 * 1024 * 1024 * 1024; manager
.record_service_bandwidth(ServiceType::ModuleServing, peer_addr, limit_bytes)
.await;
let result = manager
.check_service_request(ServiceType::ModuleServing, peer_addr)
.await;
assert!(result.is_ok());
assert!(
!result.unwrap(),
"Should be blocked after module serving limit"
);
}
#[tokio::test]
async fn test_window_reset() {
let manager = create_test_manager();
let peer_addr: SocketAddr = "127.0.0.1:8333".parse().unwrap();
let hourly_limit = 1024 * 1024 * 1024; manager
.record_service_bandwidth(ServiceType::Filters, peer_addr, hourly_limit)
.await;
let result = manager
.check_service_request(ServiceType::Filters, peer_addr)
.await;
assert!(result.is_ok());
assert!(!result.unwrap());
}
#[tokio::test]
async fn test_multiple_services_same_peer() {
let manager = create_test_manager();
let peer_addr: SocketAddr = "127.0.0.1:8333".parse().unwrap();
let services = [
ServiceType::Filters,
ServiceType::PackageRelay,
ServiceType::FilteredBlocks,
];
for service in &services {
let result = manager.check_service_request(*service, peer_addr).await;
assert!(result.is_ok());
assert!(result.unwrap(), "Service {service:?} should be allowed");
}
let filter_limit = 5 * 1024 * 1024 * 1024;
manager
.record_service_bandwidth(ServiceType::Filters, peer_addr, filter_limit)
.await;
let result = manager
.check_service_request(ServiceType::Filters, peer_addr)
.await;
assert!(result.is_ok());
assert!(!result.unwrap(), "Filter service should be blocked");
for service in &[ServiceType::PackageRelay, ServiceType::FilteredBlocks] {
let result = manager.check_service_request(*service, peer_addr).await;
assert!(result.is_ok());
assert!(result.unwrap(), "Service {service:?} should still work");
}
}
#[tokio::test]
async fn test_concurrent_requests() {
let manager = Arc::clone(&create_test_manager());
let peer_addr: SocketAddr = "127.0.0.1:8333".parse().unwrap();
let mut handles = vec![];
for _ in 0..10 {
let manager_clone = Arc::clone(&manager);
let peer = peer_addr;
let handle = tokio::spawn(async move {
manager_clone
.check_service_request(ServiceType::Filters, peer)
.await
});
handles.push(handle);
}
let results = futures::future::join_all(handles).await;
for result in results {
assert!(result.is_ok(), "Concurrent request should complete");
let check_result = result.unwrap();
assert!(check_result.is_ok(), "Check should succeed");
}
}