use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::net::SocketAddr;
use std::time::{SystemTime, UNIX_EPOCH};
#[derive(Debug, Clone)]
pub struct NetworkDiscovery {
pub known_organisms: HashMap<String, OrganismNode>,
pub topology: NetworkTopology,
pub discovery_metrics: DiscoveryMetrics,
pub config: NetworkConfig,
}
#[derive(Debug, Clone)]
pub struct NetworkTopology {
pub nodes: HashMap<String, NetworkNode>,
pub connections: HashMap<String, NetworkConnection>,
pub clusters: HashMap<String, NetworkCluster>,
pub metrics: TopologyMetrics,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OrganismNode {
pub organism_id: String,
pub address: SocketAddr,
pub capabilities: NodeCapabilities,
pub status: NodeStatus,
pub last_seen: u64,
pub connection_quality: f64,
pub trust_level: f64,
pub performance: NodePerformance,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NetworkNode {
pub node_id: String,
pub address: SocketAddr,
pub organisms: Vec<String>,
pub node_type: NodeType,
pub capabilities: NodeCapabilities,
pub status: NodeStatus,
pub resource_usage: ResourceUsage,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NetworkConnection {
pub connection_id: String,
pub source_node: String,
pub target_node: String,
pub connection_type: ConnectionType,
pub quality: ConnectionQuality,
pub established_at: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NetworkCluster {
pub cluster_id: String,
pub members: Vec<String>,
pub purpose: String,
pub coordinator: Option<String>,
pub health: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NodeCapabilities {
pub max_organisms: usize,
pub max_connections: usize,
pub protocols: Vec<String>,
pub computing_power: f64,
pub memory_capacity: u64,
pub bandwidth: u64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum NodeStatus {
Online,
Offline,
Connecting,
Disconnecting,
Maintenance,
Degraded,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NodeType {
Full,
Relay,
Gateway,
Bootstrap,
Archive,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ConnectionType {
Direct,
Relayed,
Gateway,
Cluster,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConnectionQuality {
pub rtt: f64,
pub packet_loss: f64,
pub bandwidth: u64,
pub reliability: f64,
pub stability: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NodePerformance {
pub messages_per_second: f64,
pub avg_response_time: f64,
pub uptime: f64,
pub error_rate: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceUsage {
pub cpu_usage: f64,
pub memory_usage: f64,
pub network_usage: f64,
pub storage_usage: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NetworkConfig {
pub discovery_interval: u64,
pub max_discovery_attempts: u32,
pub connection_timeout: u64,
pub heartbeat_interval: u64,
pub trust_threshold: f64,
pub default_port: u16,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DiscoveryMetrics {
pub total_discovered: usize,
pub active_connections: usize,
pub failed_connections: u64,
pub avg_discovery_time: f64,
pub network_coverage: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TopologyMetrics {
pub total_nodes: usize,
pub total_connections: usize,
pub network_diameter: usize,
pub clustering_coefficient: f64,
pub network_density: f64,
}
impl NetworkDiscovery {
pub fn new() -> Result<Self, NetworkError> {
Ok(NetworkDiscovery {
known_organisms: HashMap::new(),
topology: NetworkTopology::new(),
discovery_metrics: DiscoveryMetrics::new(),
config: NetworkConfig::default(),
})
}
pub async fn discover_organisms(&mut self) -> Result<Vec<String>, NetworkError> {
let mut discovered = Vec::new();
for i in 0..rand::random::<usize>() % 5 + 1 {
let organism_id = format!("discovered_tron_{}", i);
let address = format!("127.0.0.1:{}", 8000 + i).parse().unwrap();
let organism_node = OrganismNode {
organism_id: organism_id.clone(),
address,
capabilities: NodeCapabilities::default(),
status: NodeStatus::Online,
last_seen: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
connection_quality: 0.8,
trust_level: 0.5,
performance: NodePerformance::default(),
};
self.known_organisms.insert(organism_id.clone(), organism_node);
discovered.push(organism_id);
}
self.discovery_metrics.total_discovered = self.known_organisms.len();
Ok(discovered)
}
pub async fn connect_to_organism(&mut self, organism_id: &str) -> Result<(), NetworkError> {
if let Some(organism) = self.known_organisms.get_mut(organism_id) {
if organism.status == NodeStatus::Offline {
return Err(NetworkError::OrganismOffline(organism_id.to_string()));
}
organism.status = NodeStatus::Connecting;
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
organism.status = NodeStatus::Online;
organism.connection_quality = 0.9;
organism.last_seen = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
self.discovery_metrics.active_connections += 1;
Ok(())
} else {
Err(NetworkError::OrganismNotFound(organism_id.to_string()))
}
}
pub fn update_topology(&mut self) {
self.topology.update_from_organisms(&self.known_organisms);
self.topology.calculate_metrics();
}
pub fn get_network_stats(&self) -> NetworkStats {
NetworkStats {
total_organisms: self.known_organisms.len(),
online_organisms: self.known_organisms.values()
.filter(|o| o.status == NodeStatus::Online)
.count(),
total_nodes: self.topology.nodes.len(),
total_connections: self.topology.connections.len(),
network_health: self.calculate_network_health(),
average_connection_quality: self.calculate_average_connection_quality(),
}
}
fn calculate_network_health(&self) -> f64 {
if self.known_organisms.is_empty() {
return 0.0;
}
let total_quality: f64 = self.known_organisms.values()
.map(|o| o.connection_quality)
.sum();
let online_count = self.known_organisms.values()
.filter(|o| o.status == NodeStatus::Online)
.count();
let availability = online_count as f64 / self.known_organisms.len() as f64;
let average_quality = total_quality / self.known_organisms.len() as f64;
(availability + average_quality) / 2.0
}
fn calculate_average_connection_quality(&self) -> f64 {
if self.known_organisms.is_empty() {
return 0.0;
}
let total_quality: f64 = self.known_organisms.values()
.map(|o| o.connection_quality)
.sum();
total_quality / self.known_organisms.len() as f64
}
}
impl NetworkTopology {
pub fn new() -> Self {
NetworkTopology {
nodes: HashMap::new(),
connections: HashMap::new(),
clusters: HashMap::new(),
metrics: TopologyMetrics::new(),
}
}
pub fn update_from_organisms(&mut self, organisms: &HashMap<String, OrganismNode>) {
for (organism_id, organism) in organisms {
let node = NetworkNode {
node_id: organism_id.clone(),
address: organism.address,
organisms: vec![organism_id.clone()],
node_type: NodeType::Full,
capabilities: organism.capabilities.clone(),
status: organism.status.clone(),
resource_usage: ResourceUsage::default(),
};
self.nodes.insert(organism_id.clone(), node);
}
self.create_connections();
}
fn create_connections(&mut self) {
let node_ids: Vec<String> = self.nodes.keys().cloned().collect();
for i in 0..node_ids.len() {
for j in i + 1..node_ids.len() {
let connection_id = format!("conn_{}_{}", i, j);
let connection = NetworkConnection {
connection_id: connection_id.clone(),
source_node: node_ids[i].clone(),
target_node: node_ids[j].clone(),
connection_type: ConnectionType::Direct,
quality: ConnectionQuality::default(),
established_at: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
};
self.connections.insert(connection_id, connection);
}
}
}
pub fn calculate_metrics(&mut self) {
self.metrics.total_nodes = self.nodes.len();
self.metrics.total_connections = self.connections.len();
let max_connections = if self.nodes.len() > 1 {
self.nodes.len() * (self.nodes.len() - 1) / 2
} else {
1
};
self.metrics.network_density = self.connections.len() as f64 / max_connections as f64;
self.metrics.clustering_coefficient = 0.7;
self.metrics.network_diameter = (self.nodes.len() as f64).sqrt() as usize;
}
}
impl Default for NodeCapabilities {
fn default() -> Self {
NodeCapabilities {
max_organisms: 100,
max_connections: 1000,
protocols: vec!["genesis-neural".to_string()],
computing_power: 1.0,
memory_capacity: 1_000_000_000, bandwidth: 100_000_000, }
}
}
impl Default for NodePerformance {
fn default() -> Self {
NodePerformance {
messages_per_second: 1000.0,
avg_response_time: 10.0,
uptime: 99.9,
error_rate: 0.001,
}
}
}
impl Default for ResourceUsage {
fn default() -> Self {
ResourceUsage {
cpu_usage: 25.0,
memory_usage: 30.0,
network_usage: 15.0,
storage_usage: 10.0,
}
}
}
impl Default for ConnectionQuality {
fn default() -> Self {
ConnectionQuality {
rtt: 10.0,
packet_loss: 0.001,
bandwidth: 100_000_000,
reliability: 0.999,
stability: 0.95,
}
}
}
impl Default for NetworkConfig {
fn default() -> Self {
NetworkConfig {
discovery_interval: 30,
max_discovery_attempts: 3,
connection_timeout: 10,
heartbeat_interval: 5,
trust_threshold: 0.7,
default_port: 8000,
}
}
}
impl DiscoveryMetrics {
fn new() -> Self {
DiscoveryMetrics {
total_discovered: 0,
active_connections: 0,
failed_connections: 0,
avg_discovery_time: 0.0,
network_coverage: 0.0,
}
}
}
impl TopologyMetrics {
fn new() -> Self {
TopologyMetrics {
total_nodes: 0,
total_connections: 0,
network_diameter: 0,
clustering_coefficient: 0.0,
network_density: 0.0,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NetworkStats {
pub total_organisms: usize,
pub online_organisms: usize,
pub total_nodes: usize,
pub total_connections: usize,
pub network_health: f64,
pub average_connection_quality: f64,
}
#[derive(Debug, thiserror::Error)]
pub enum NetworkError {
#[error("Organism not found: {0}")]
OrganismNotFound(String),
#[error("Organism offline: {0}")]
OrganismOffline(String),
#[error("Connection failed: {0}")]
ConnectionFailed(String),
#[error("Discovery failed: {0}")]
DiscoveryFailed(String),
#[error("Network timeout")]
NetworkTimeout,
#[error("Invalid address: {0}")]
InvalidAddress(String),
#[error("Protocol not supported: {0}")]
ProtocolNotSupported(String),
#[error("Network overloaded")]
NetworkOverloaded,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_network_discovery_creation() {
let discovery = NetworkDiscovery::new().unwrap();
assert_eq!(discovery.known_organisms.len(), 0);
assert_eq!(discovery.topology.nodes.len(), 0);
}
#[tokio::test]
async fn test_organism_discovery() {
let mut discovery = NetworkDiscovery::new().unwrap();
let discovered = discovery.discover_organisms().await.unwrap();
assert!(discovered.len() > 0);
assert_eq!(discovery.known_organisms.len(), discovered.len());
for organism_id in &discovered {
assert!(discovery.known_organisms.contains_key(organism_id));
}
}
#[tokio::test]
async fn test_organism_connection() {
let mut discovery = NetworkDiscovery::new().unwrap();
let discovered = discovery.discover_organisms().await.unwrap();
if let Some(organism_id) = discovered.first() {
let result = discovery.connect_to_organism(organism_id).await;
assert!(result.is_ok());
assert_eq!(discovery.known_organisms[organism_id].status, NodeStatus::Online);
}
}
#[test]
fn test_topology_update() {
let mut discovery = NetworkDiscovery::new().unwrap();
let organism1 = OrganismNode {
organism_id: "tron_1".to_string(),
address: "127.0.0.1:8000".parse().unwrap(),
capabilities: NodeCapabilities::default(),
status: NodeStatus::Online,
last_seen: 0,
connection_quality: 0.8,
trust_level: 0.7,
performance: NodePerformance::default(),
};
discovery.known_organisms.insert("tron_1".to_string(), organism1);
discovery.update_topology();
assert_eq!(discovery.topology.nodes.len(), 1);
}
#[test]
fn test_network_stats() {
let mut discovery = NetworkDiscovery::new().unwrap();
for i in 0..3 {
let organism = OrganismNode {
organism_id: format!("tron_{}", i),
address: format!("127.0.0.1:{}", 8000 + i).parse().unwrap(),
capabilities: NodeCapabilities::default(),
status: NodeStatus::Online,
last_seen: 0,
connection_quality: 0.8,
trust_level: 0.7,
performance: NodePerformance::default(),
};
discovery.known_organisms.insert(format!("tron_{}", i), organism);
}
let stats = discovery.get_network_stats();
assert_eq!(stats.total_organisms, 3);
assert_eq!(stats.online_organisms, 3);
assert!(stats.network_health > 0.0);
}
}