saorsa_core/adaptive/
mod.rs

1// Copyright 2024 Saorsa Labs Limited
2//
3// This software is dual-licensed under:
4// - GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later)
5// - Commercial License
6//
7// For AGPL-3.0 license, see LICENSE-AGPL-3.0
8// For commercial licensing, contact: saorsalabs@gmail.com
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under these licenses is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
14//! Adaptive P2P Network Implementation
15//!
16//! This module implements the adaptive P2P network architecture described in the
17//! network documentation, combining multiple distributed systems technologies:
18//! - Secure Kademlia (S/Kademlia) as the foundational DHT layer
19//! - Hyperbolic geometry routing for efficient greedy routing
20//! - Self-Organizing Maps (SOM) for content and capability clustering
21//! - EigenTrust++ for decentralized reputation management
22//! - Adaptive GossipSub for scalable message propagation
23//! - Machine learning systems for routing optimization, caching, and churn prediction
24
25#![allow(missing_docs)]
26
27use async_trait::async_trait;
28use serde::{Deserialize, Serialize};
29
30pub mod beta_distribution;
31pub mod churn;
32pub mod churn_prediction;
33pub mod client;
34pub mod coordinator;
35pub mod coordinator_extensions;
36pub mod dht_integration;
37pub mod eviction;
38pub mod gossip;
39pub mod hyperbolic;
40pub mod hyperbolic_enhanced;
41pub mod hyperbolic_greedy;
42// Use crate-level PQC identity instead of local Ed25519 variant
43pub mod learning;
44pub mod monitoring;
45pub mod multi_armed_bandit;
46pub mod performance;
47pub mod q_learning_cache;
48pub mod replication;
49pub mod retrieval;
50pub mod routing;
51pub mod security;
52pub mod som;
53pub mod storage;
54pub mod transport;
55pub mod trust;
56
57// Re-export commonly used types
58pub use crate::identity::NodeIdentity;
59pub use churn::{ChurnConfig, ChurnHandler, NodeMonitor, NodeState, RecoveryManager};
60pub use client::{
61    AdaptiveP2PClient, Client, ClientConfig, ClientProfile, NetworkStats as ClientNetworkStats,
62};
63pub use coordinator::{NetworkConfig, NetworkCoordinator};
64pub use dht_integration::{AdaptiveDHT, KademliaRoutingStrategy};
65pub use eviction::{
66    AdaptiveStrategy, CacheState, EvictionStrategy, EvictionStrategyType, FIFOStrategy,
67    LFUStrategy, LRUStrategy,
68};
69pub use gossip::AdaptiveGossipSub;
70pub use hyperbolic::{HyperbolicRoutingStrategy, HyperbolicSpace};
71pub use hyperbolic_enhanced::{
72    EnhancedHyperbolicCoordinate, EnhancedHyperbolicRoutingStrategy, EnhancedHyperbolicSpace,
73};
74pub use hyperbolic_greedy::{
75    Embedding, EmbeddingConfig, HyperbolicGreedyRouter, embed_snapshot, greedy_next,
76};
77pub use learning::{ChurnPredictor, QLearnCacheManager, ThompsonSampling};
78pub use monitoring::{
79    Alert, AlertManager, DashboardData, MonitoringConfig, MonitoringSystem, NetworkHealth,
80};
81pub use multi_armed_bandit::{
82    MABConfig, MABRoutingStrategy, MultiArmedBandit, RouteDecision, RouteId,
83};
84pub use performance::{
85    BatchProcessor, ConcurrencyLimiter, ConnectionPool, OptimizedSerializer, PerformanceCache,
86    PerformanceConfig,
87};
88pub use q_learning_cache::{
89    AccessInfo, CacheAction, CacheStatistics, QLearnCacheManager as QLearningCacheManager,
90    QLearningConfig, StateVector,
91};
92pub use replication::{ReplicaInfo, ReplicationManager, ReplicationStrategy};
93pub use retrieval::{RetrievalManager, RetrievalStrategy};
94pub use routing::AdaptiveRouter;
95pub use security::{
96    BlacklistManager, EclipseDetector, RateLimiter, SecurityAuditor, SecurityConfig,
97    SecurityManager,
98};
99pub use som::{FeatureExtractor, GridSize, SOMRoutingStrategy, SelfOrganizingMap, SomConfig};
100pub use storage::{ChunkManager, ContentStore, ReplicationConfig, StorageConfig};
101pub use transport::{ConnectionInfo, Transport, TransportManager, TransportProtocol};
102pub use trust::{
103    EigenTrustEngine, MockTrustProvider, NodeStatistics, NodeStatisticsUpdate,
104    TrustBasedRoutingStrategy,
105};
106
107/// Result type for adaptive network operations
108pub type Result<T> = std::result::Result<T, AdaptiveNetworkError>;
109
110/// Core error type for the adaptive network
111#[derive(Debug, thiserror::Error)]
112pub enum AdaptiveNetworkError {
113    #[error("Routing error: {0}")]
114    Routing(String),
115
116    #[error("Trust calculation error: {0}")]
117    Trust(String),
118
119    #[error("Learning system error: {0}")]
120    Learning(String),
121
122    #[error("Gossip error: {0}")]
123    Gossip(String),
124
125    #[error("Network error: {0}")]
126    Network(#[from] std::io::Error),
127
128    #[error("IO error: {0}")]
129    Io(std::io::Error),
130
131    #[error("Serialization error: {0}")]
132    Serialization(#[from] bincode::Error),
133
134    #[error("Other error: {0}")]
135    Other(String),
136}
137
138impl From<anyhow::Error> for AdaptiveNetworkError {
139    fn from(e: anyhow::Error) -> Self {
140        AdaptiveNetworkError::Io(std::io::Error::other(e.to_string()))
141    }
142}
143
144impl From<crate::error::P2PError> for AdaptiveNetworkError {
145    fn from(e: crate::error::P2PError) -> Self {
146        AdaptiveNetworkError::Network(std::io::Error::other(e.to_string()))
147    }
148}
149
150/// Content hash type used throughout the network
151#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
152pub struct ContentHash(pub [u8; 32]);
153
154impl ContentHash {
155    /// Create from bytes
156    pub fn from(data: &[u8]) -> Self {
157        let mut hash = [0u8; 32];
158        if data.len() >= 32 {
159            hash.copy_from_slice(&data[..32]);
160        } else {
161            let hashed = blake3::hash(data);
162            hash.copy_from_slice(hashed.as_bytes());
163        }
164        Self(hash)
165    }
166}
167
168/// Network message type
169#[derive(Debug, Clone, Serialize, Deserialize)]
170pub struct NetworkMessage {
171    /// Message ID
172    pub id: String,
173    /// Sender node ID
174    pub sender: NodeId,
175    /// Message content
176    pub content: Vec<u8>,
177    /// Message type
178    pub msg_type: ContentType,
179    /// Timestamp (Unix timestamp in seconds)
180    pub timestamp: u64,
181}
182
183/// Node ID type alias
184pub type NodeId = crate::peer_record::UserId;
185
186/// Node descriptor containing all information about a peer
187#[derive(Debug, Clone)]
188pub struct NodeDescriptor {
189    pub id: NodeId,
190    // PQC-only: ML-DSA public key
191    pub public_key: crate::quantum_crypto::ant_quic_integration::MlDsaPublicKey,
192    pub addresses: Vec<String>,
193    pub hyperbolic: Option<HyperbolicCoordinate>,
194    pub som_position: Option<[f64; 4]>,
195    pub trust: f64,
196    pub capabilities: NodeCapabilities,
197}
198
199/// Hyperbolic coordinate in Poincaré disk model
200#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
201pub struct HyperbolicCoordinate {
202    pub r: f64,     // Radial coordinate [0, 1)
203    pub theta: f64, // Angular coordinate [0, 2π)
204}
205
206/// Node capabilities for resource discovery
207#[derive(Debug, Clone, Serialize, Deserialize)]
208pub struct NodeCapabilities {
209    pub storage: u64,   // GB available
210    pub compute: u64,   // Benchmark score
211    pub bandwidth: u64, // Mbps available
212}
213
214/// Core trait for adaptive P2P network nodes
215#[async_trait]
216pub trait AdaptiveNetworkNode: Send + Sync {
217    /// Join the network using bootstrap nodes
218    async fn join(&mut self, bootstrap: Vec<NodeDescriptor>) -> Result<()>;
219
220    /// Store data with adaptive replication
221    async fn store(&self, data: Vec<u8>) -> Result<ContentHash>;
222
223    /// Retrieve data using parallel strategies
224    async fn retrieve(&self, hash: &ContentHash) -> Result<Vec<u8>>;
225
226    /// Publish a message to a gossip topic
227    async fn publish(&self, topic: &str, message: Vec<u8>) -> Result<()>;
228
229    /// Subscribe to a gossip topic
230    async fn subscribe(
231        &self,
232        topic: &str,
233    ) -> Result<Box<dyn futures::Stream<Item = Vec<u8>> + Send>>;
234
235    /// Get current node information
236    async fn node_info(&self) -> Result<NodeDescriptor>;
237
238    /// Get network statistics
239    async fn network_stats(&self) -> Result<NetworkStats>;
240
241    /// Gracefully shutdown the node
242    async fn shutdown(self) -> Result<()>;
243}
244
245/// Network statistics for monitoring
246#[derive(Debug, Clone, Serialize, Deserialize)]
247pub struct NetworkStats {
248    pub connected_peers: usize,
249    pub routing_success_rate: f64,
250    pub average_trust_score: f64,
251    pub cache_hit_rate: f64,
252    pub churn_rate: f64,
253    pub total_storage: u64,
254    pub total_bandwidth: u64,
255}
256
257/// Routing strategy trait for different routing algorithms
258#[async_trait]
259pub trait RoutingStrategy: Send + Sync {
260    /// Find a path to the target node
261    async fn find_path(&self, target: &NodeId) -> Result<Vec<NodeId>>;
262
263    /// Calculate routing score for a neighbor towards a target
264    fn route_score(&self, neighbor: &NodeId, target: &NodeId) -> f64;
265
266    /// Update routing metrics based on success/failure
267    fn update_metrics(&mut self, path: &[NodeId], success: bool);
268
269    /// Find closest nodes to a content hash
270    async fn find_closest_nodes(
271        &self,
272        content_hash: &ContentHash,
273        _count: usize,
274    ) -> Result<Vec<NodeId>> {
275        // Default implementation uses node ID from content hash
276        let target = NodeId {
277            hash: content_hash.0,
278        };
279        self.find_path(&target).await
280    }
281}
282
283/// Trust provider trait for reputation queries
284pub trait TrustProvider: Send + Sync {
285    /// Get trust score for a node
286    fn get_trust(&self, node: &NodeId) -> f64;
287
288    /// Update trust based on interaction
289    fn update_trust(&self, from: &NodeId, to: &NodeId, success: bool);
290
291    /// Get global trust vector
292    fn get_global_trust(&self) -> std::collections::HashMap<NodeId, f64>;
293
294    /// Remove a node from the trust system
295    fn remove_node(&self, node: &NodeId);
296
297    /// Get trust score (alias for get_trust)
298    fn get_trust_score(&self, node: &NodeId) -> f64 {
299        self.get_trust(node)
300    }
301}
302
303/// Learning system trait for adaptive behavior
304#[async_trait]
305pub trait LearningSystem: Send + Sync {
306    /// Select optimal strategy based on context
307    async fn select_strategy(&self, context: &LearningContext) -> StrategyChoice;
308
309    /// Update learning model with outcome
310    async fn update(
311        &mut self,
312        context: &LearningContext,
313        choice: &StrategyChoice,
314        outcome: &Outcome,
315    );
316
317    /// Get current model performance metrics
318    async fn metrics(&self) -> LearningMetrics;
319}
320
321/// Context for learning decisions
322#[derive(Debug, Clone, Serialize, Deserialize)]
323pub struct LearningContext {
324    pub content_type: ContentType,
325    pub network_conditions: NetworkConditions,
326    pub historical_performance: Vec<f64>,
327}
328
329/// Content type classification
330#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
331pub enum ContentType {
332    DHTLookup,
333    DataRetrieval,
334    ComputeRequest,
335    RealtimeMessage,
336    DiscoveryProbe,
337}
338
339/// Current network conditions
340#[derive(Debug, Clone, Serialize, Deserialize)]
341pub struct NetworkConditions {
342    pub connected_peers: usize,
343    pub avg_latency_ms: f64,
344    pub churn_rate: f64,
345}
346
347/// Strategy choice made by learning system
348#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
349pub enum StrategyChoice {
350    Kademlia,
351    Hyperbolic,
352    TrustPath,
353    SOMRegion,
354}
355
356/// Outcome of a strategy choice
357#[derive(Debug, Clone, Serialize, Deserialize)]
358pub struct Outcome {
359    pub success: bool,
360    pub latency_ms: u64,
361    pub hops: usize,
362}
363
364/// Learning system performance metrics
365#[derive(Debug, Clone, Serialize, Deserialize)]
366pub struct LearningMetrics {
367    pub total_decisions: u64,
368    pub success_rate: f64,
369    pub avg_latency_ms: f64,
370    pub strategy_performance: std::collections::HashMap<StrategyChoice, f64>,
371}
372
373#[cfg(test)]
374mod timestamp_tests;
375
376#[cfg(test)]
377mod tests {
378    use super::*;
379
380    #[test]
381    fn test_content_hash_serialization() {
382        let hash = ContentHash([42u8; 32]);
383        let serialized = bincode::serialize(&hash).unwrap();
384        let deserialized: ContentHash = bincode::deserialize(&serialized).unwrap();
385        assert_eq!(hash, deserialized);
386    }
387
388    #[test]
389    fn test_hyperbolic_coordinate_bounds() {
390        let coord = HyperbolicCoordinate {
391            r: 0.5,
392            theta: std::f64::consts::PI,
393        };
394        assert!(coord.r >= 0.0 && coord.r < 1.0);
395        assert!(coord.theta >= 0.0 && coord.theta < 2.0 * std::f64::consts::PI);
396    }
397}