//! Device registry and management. //! //! Supports all device types: //! - Data center servers //! - Desktop workstations //! - Laptops //! - Mobile devices (iOS, Android) //! - Browsers (WebGPU, WASM) //! - IoT devices use crate::error::ComputeError; use crate::processor::{GenericProcessor, Processor, ProcessorId, ProcessorType}; use crate::{NodeId, ProcessorInfo}; use parking_lot::RwLock; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::sync::Arc; /// Unique device identifier. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct DeviceId(pub [u8; 32]); impl DeviceId { /// Creates a new random device ID. pub fn new() -> Self { use rand::Rng; let mut bytes = [0u8; 32]; rand::thread_rng().fill(&mut bytes); DeviceId(bytes) } /// Creates from bytes. pub fn from_bytes(bytes: [u8; 32]) -> Self { DeviceId(bytes) } } impl Default for DeviceId { fn default() -> Self { Self::new() } } impl std::fmt::Display for DeviceId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "dev_{}", hex::encode(&self.0[..8])) } } /// Device type classification. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum DeviceType { /// Data center server. DataCenter, /// Desktop workstation. Desktop, /// Laptop. Laptop, /// Mobile phone. Mobile, /// Tablet. Tablet, /// IoT device. IoT, /// Browser (WebGPU/WASM). Browser, /// Edge server. Edge, } impl DeviceType { /// Returns typical reliability score (0-100). pub fn reliability(&self) -> u32 { match self { DeviceType::DataCenter => 99, DeviceType::Edge => 95, DeviceType::Desktop => 80, DeviceType::Laptop => 60, DeviceType::Mobile => 40, DeviceType::Tablet => 50, DeviceType::IoT => 70, DeviceType::Browser => 30, } } /// Returns typical availability hours per day. pub fn availability_hours(&self) -> f32 { match self { DeviceType::DataCenter => 24.0, DeviceType::Edge => 24.0, DeviceType::Desktop => 8.0, DeviceType::Laptop => 6.0, DeviceType::Mobile => 4.0, DeviceType::Tablet => 4.0, DeviceType::IoT => 24.0, DeviceType::Browser => 2.0, } } } /// Device capabilities. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct DeviceCapabilities { /// Device type. pub device_type: DeviceType, /// Available processors. pub processors: Vec, /// Total memory (GB). pub memory_gb: f32, /// Network bandwidth (Mbps). pub bandwidth_mbps: f32, /// Storage available (GB). pub storage_gb: f32, /// Battery powered. pub battery_powered: bool, /// Supports background execution. pub background_execution: bool, } /// Device information. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct DeviceInfo { /// Device ID. pub id: DeviceId, /// Device type. pub device_type: DeviceType, /// Owner address. pub owner: [u8; 32], /// Capabilities. pub capabilities: DeviceCapabilities, /// Current status. pub status: DeviceStatus, /// Reputation score (0-100). pub reputation: u32, /// Total earnings (atomic SYNOR). pub earnings: u64, /// Geographic region. pub region: String, } /// Device status. #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum DeviceStatus { /// Online and available. Online, /// Online but busy. Busy, /// Idle but available. Idle, /// On battery (reduced capacity). OnBattery, /// Offline. Offline, /// Maintenance. Maintenance, } /// Device registry managing all devices and processors. pub struct DeviceRegistry { /// Registered devices. devices: RwLock>, /// Node to device mapping. node_devices: RwLock>>, /// All processors (across all nodes). processors: RwLock>>, /// Processor to node mapping. processor_nodes: RwLock>, /// Next processor ID. next_processor_id: std::sync::atomic::AtomicU64, } impl DeviceRegistry { /// Creates a new device registry. pub fn new() -> Self { Self { devices: RwLock::new(HashMap::new()), node_devices: RwLock::new(HashMap::new()), processors: RwLock::new(HashMap::new()), processor_nodes: RwLock::new(HashMap::new()), next_processor_id: std::sync::atomic::AtomicU64::new(0), } } /// Registers a device. pub fn register_device(&self, device: DeviceInfo) -> Result { let id = device.id; self.devices.write().insert(id, device); Ok(id) } /// Unregisters a device. pub fn unregister_device(&self, device_id: DeviceId) -> Result<(), ComputeError> { self.devices.write().remove(&device_id); Ok(()) } /// Gets a device by ID. pub fn get_device(&self, device_id: DeviceId) -> Option { self.devices.read().get(&device_id).cloned() } /// Registers a processor for a node. pub fn register_processor( &self, node_id: NodeId, info: ProcessorInfo, ) -> Result<(), ComputeError> { let processor_id = info.id; // Create a generic processor from the info let processor: Arc = Arc::new(GenericProcessor::new( processor_id, info.processor_type, info.capabilities, )); self.processors.write().insert(processor_id, processor); self.processor_nodes.write().insert(processor_id, node_id); Ok(()) } /// Unregisters all processors for a node. pub fn unregister_node(&self, node_id: NodeId) -> Result<(), ComputeError> { let mut processors = self.processors.write(); let mut processor_nodes = self.processor_nodes.write(); // Find and remove all processors for this node let to_remove: Vec<_> = processor_nodes .iter() .filter(|(_, n)| **n == node_id) .map(|(p, _)| *p) .collect(); for proc_id in to_remove { processors.remove(&proc_id); processor_nodes.remove(&proc_id); } Ok(()) } /// Gets a processor by ID. pub fn get_processor(&self, processor_id: ProcessorId) -> Result, ComputeError> { self.processors .read() .get(&processor_id) .cloned() .ok_or(ComputeError::ProcessorNotFound(processor_id)) } /// Gets all processors. pub fn all_processors(&self) -> Vec> { self.processors.read().values().cloned().collect() } /// Gets processors of a specific type. pub fn processors_by_type(&self, proc_type: ProcessorType) -> Vec> { self.processors .read() .values() .filter(|p| p.processor_type() == proc_type) .cloned() .collect() } /// Gets the next processor ID. pub fn next_processor_id(&self) -> ProcessorId { ProcessorId(self.next_processor_id.fetch_add(1, std::sync::atomic::Ordering::SeqCst)) } /// Gets total number of devices. pub fn device_count(&self) -> usize { self.devices.read().len() } /// Gets total number of processors. pub fn processor_count(&self) -> usize { self.processors.read().len() } /// Gets devices by type. pub fn devices_by_type(&self, device_type: DeviceType) -> Vec { self.devices .read() .values() .filter(|d| d.device_type == device_type) .cloned() .collect() } /// Gets online devices. pub fn online_devices(&self) -> Vec { self.devices .read() .values() .filter(|d| d.status == DeviceStatus::Online || d.status == DeviceStatus::Idle) .cloned() .collect() } /// Updates device status. pub fn update_device_status( &self, device_id: DeviceId, status: DeviceStatus, ) -> Result<(), ComputeError> { if let Some(device) = self.devices.write().get_mut(&device_id) { device.status = status; Ok(()) } else { Err(ComputeError::Internal(format!("Device not found: {}", device_id))) } } } impl Default for DeviceRegistry { fn default() -> Self { Self::new() } } #[cfg(test)] mod tests { use super::*; use crate::processor::{CpuVariant, AvxSupport}; #[test] fn test_device_id() { let id1 = DeviceId::new(); let id2 = DeviceId::new(); assert_ne!(id1.0, id2.0); } #[test] fn test_device_registry() { let registry = DeviceRegistry::new(); let device = DeviceInfo { id: DeviceId::new(), device_type: DeviceType::Desktop, owner: [1u8; 32], capabilities: DeviceCapabilities { device_type: DeviceType::Desktop, processors: vec![ProcessorType::Cpu(CpuVariant::X86_64 { avx: AvxSupport::Avx512, })], memory_gb: 64.0, bandwidth_mbps: 1000.0, storage_gb: 1000.0, battery_powered: false, background_execution: true, }, status: DeviceStatus::Online, reputation: 100, earnings: 0, region: "us-east".to_string(), }; let device_id = device.id; registry.register_device(device).unwrap(); assert_eq!(registry.device_count(), 1); assert!(registry.get_device(device_id).is_some()); registry.unregister_device(device_id).unwrap(); assert_eq!(registry.device_count(), 0); } #[test] fn test_device_type_properties() { assert_eq!(DeviceType::DataCenter.reliability(), 99); assert_eq!(DeviceType::Mobile.reliability(), 40); assert_eq!(DeviceType::DataCenter.availability_hours(), 24.0); assert_eq!(DeviceType::Browser.availability_hours(), 2.0); } }