1use super::*;
20use async_trait::async_trait;
21use std::collections::{HashMap, HashSet};
22use std::sync::Arc;
23use std::time::{Duration, Instant};
24use tokio::sync::RwLock;
25
26#[derive(Debug)]
28pub struct EigenTrustEngine {
29 local_trust: Arc<RwLock<HashMap<(NodeId, NodeId), LocalTrustData>>>,
31
32 global_trust: Arc<RwLock<HashMap<NodeId, f64>>>,
34
35 pre_trusted_nodes: Arc<RwLock<HashSet<NodeId>>>,
37
38 node_stats: Arc<RwLock<HashMap<NodeId, NodeStatistics>>>,
40
41 alpha: f64,
43
44 decay_rate: f64,
46
47 last_update: RwLock<Instant>,
49
50 update_interval: Duration,
52
53 trust_cache: Arc<RwLock<HashMap<NodeId, f64>>>,
55}
56
57#[derive(Debug, Clone)]
59struct LocalTrustData {
60 value: f64,
62 interactions: u64,
64 last_interaction: Instant,
66}
67
68#[derive(Debug, Clone, Default)]
70pub struct NodeStatistics {
71 pub uptime: u64,
73 pub correct_responses: u64,
75 pub failed_responses: u64,
77 pub storage_contributed: u64,
79 pub bandwidth_contributed: u64,
81 pub compute_contributed: u64,
83}
84
85#[derive(Debug, Clone)]
87pub enum NodeStatisticsUpdate {
88 Uptime(u64),
89 CorrectResponse,
90 FailedResponse,
91 StorageContributed(u64),
92 BandwidthContributed(u64),
93 ComputeContributed(u64),
94}
95
96impl EigenTrustEngine {
97 pub fn new(pre_trusted_nodes: HashSet<NodeId>) -> Self {
99 let mut initial_cache = HashMap::new();
100 for node in &pre_trusted_nodes {
102 initial_cache.insert(node.clone(), 0.9);
103 }
104
105 Self {
106 local_trust: Arc::new(RwLock::new(HashMap::new())),
107 global_trust: Arc::new(RwLock::new(HashMap::new())),
108 pre_trusted_nodes: Arc::new(RwLock::new(pre_trusted_nodes)),
109 node_stats: Arc::new(RwLock::new(HashMap::new())),
110 alpha: 0.15,
111 decay_rate: 0.99,
112 last_update: RwLock::new(Instant::now()),
113 update_interval: Duration::from_secs(300), trust_cache: Arc::new(RwLock::new(initial_cache)),
115 }
116 }
117
118 pub fn start_background_updates(self: Arc<Self>) {
120 tokio::spawn(async move {
121 loop {
122 tokio::time::sleep(self.update_interval).await;
123 let _ = self.compute_global_trust().await;
124 }
125 });
126 }
127
128 pub async fn update_local_trust(&self, from: &NodeId, to: &NodeId, success: bool) {
130 let key = (from.clone(), to.clone());
131 let new_value = if success { 1.0 } else { 0.0 };
132
133 let mut trust_map = self.local_trust.write().await;
134 trust_map
135 .entry(key)
136 .and_modify(|data| {
137 data.value = 0.9 * data.value + 0.1 * new_value;
139 data.interactions += 1;
140 data.last_interaction = Instant::now();
141 })
142 .or_insert(LocalTrustData {
143 value: new_value,
144 interactions: 1,
145 last_interaction: Instant::now(),
146 });
147 }
148
149 pub async fn update_node_stats(&self, node_id: &NodeId, stats_update: NodeStatisticsUpdate) {
151 let mut stats = self.node_stats.write().await;
152 let node_stats = stats.entry(node_id.clone()).or_default();
153
154 match stats_update {
155 NodeStatisticsUpdate::Uptime(seconds) => node_stats.uptime += seconds,
156 NodeStatisticsUpdate::CorrectResponse => node_stats.correct_responses += 1,
157 NodeStatisticsUpdate::FailedResponse => node_stats.failed_responses += 1,
158 NodeStatisticsUpdate::StorageContributed(gb) => node_stats.storage_contributed += gb,
159 NodeStatisticsUpdate::BandwidthContributed(gb) => {
160 node_stats.bandwidth_contributed += gb
161 }
162 NodeStatisticsUpdate::ComputeContributed(cycles) => {
163 node_stats.compute_contributed += cycles
164 }
165 }
166 }
167
168 pub async fn compute_global_trust(&self) -> HashMap<NodeId, f64> {
170 let local_trust = self.local_trust.read().await;
172 let node_stats = self.node_stats.read().await;
173 let pre_trusted = self.pre_trusted_nodes.read().await;
174
175 let nodes: Vec<NodeId> = local_trust
176 .keys()
177 .flat_map(|(from, to)| vec![from.clone(), to.clone()])
178 .chain(node_stats.keys().cloned())
179 .collect::<HashSet<_>>()
180 .into_iter()
181 .collect();
182
183 if nodes.is_empty() {
184 return HashMap::new();
185 }
186
187 let mut trust_vector: HashMap<NodeId, f64> = HashMap::new();
189 for node in &nodes {
190 trust_vector.insert(node.clone(), 1.0 / nodes.len() as f64);
191 }
192
193 for _ in 0..50 {
195 let mut new_trust = HashMap::new();
196
197 for node in &nodes {
198 let mut trust_sum = 0.0;
199
200 for other in &nodes {
201 if let Some(local_trust_val) =
202 self.get_normalized_trust(&local_trust, other, node)
203 {
204 trust_sum += local_trust_val * trust_vector.get(other).unwrap_or(&0.0);
205 }
206 }
207
208 let pre_trust = if pre_trusted.contains(node) {
210 1.0 / pre_trusted.len().max(1) as f64
211 } else {
212 0.0
213 };
214
215 let new_value = (1.0 - self.alpha) * trust_sum + self.alpha * pre_trust;
216 new_trust.insert(node.clone(), new_value);
217 }
218
219 let diff: f64 = trust_vector
221 .iter()
222 .map(|(node, old_trust)| (old_trust - new_trust.get(node).unwrap_or(&0.0)).abs())
223 .sum();
224
225 trust_vector = new_trust;
226
227 if diff < 0.001 {
228 break;
229 }
230 }
231
232 for (node, trust) in trust_vector.iter_mut() {
234 if let Some(stats) = node_stats.get(node) {
235 let factor = self.compute_multi_factor_adjustment(stats);
236 *trust *= factor;
237 }
238 }
239
240 let last_update = self.last_update.read().await;
242 let elapsed = last_update.elapsed().as_secs() as f64 / 3600.0; for (_, trust) in trust_vector.iter_mut() {
245 *trust *= self.decay_rate.powf(elapsed);
246 }
247
248 let total_trust: f64 = trust_vector.values().sum();
250 if total_trust > 0.0 {
251 for (_, trust) in trust_vector.iter_mut() {
252 *trust /= total_trust;
253 }
254 }
255
256 let mut global_trust = self.global_trust.write().await;
258 let mut trust_cache = self.trust_cache.write().await;
259
260 for (node, trust) in &trust_vector {
261 global_trust.insert(node.clone(), *trust);
262 trust_cache.insert(node.clone(), *trust);
263 }
264
265 *self.last_update.write().await = Instant::now();
267
268 trust_vector
269 }
270
271 fn compute_multi_factor_adjustment(&self, stats: &NodeStatistics) -> f64 {
273 let response_rate = if stats.correct_responses + stats.failed_responses > 0 {
274 stats.correct_responses as f64
275 / (stats.correct_responses + stats.failed_responses) as f64
276 } else {
277 0.5
278 };
279
280 let storage_factor = (1.0 + stats.storage_contributed as f64).ln() / 10.0;
282 let bandwidth_factor = (1.0 + stats.bandwidth_contributed as f64).ln() / 10.0;
283 let compute_factor = (1.0 + stats.compute_contributed as f64).ln() / 10.0;
284 let uptime_factor = (stats.uptime as f64 / 86400.0).min(1.0); 0.4 * response_rate
288 + 0.2 * uptime_factor
289 + 0.15 * storage_factor
290 + 0.15 * bandwidth_factor
291 + 0.1 * compute_factor
292 }
293
294 fn get_normalized_trust(
296 &self,
297 local_trust: &HashMap<(NodeId, NodeId), LocalTrustData>,
298 from: &NodeId,
299 to: &NodeId,
300 ) -> Option<f64> {
301 let key = (from.clone(), to.clone());
302 let trust_data = local_trust.get(&key)?;
303
304 let total_outgoing: f64 = local_trust
306 .iter()
307 .filter(|((f, _), _)| f == from)
308 .map(|(_, data)| data.value.max(0.0))
309 .sum();
310
311 if total_outgoing > 0.0 {
312 Some(trust_data.value.max(0.0) / total_outgoing)
313 } else {
314 None
315 }
316 }
317
318 pub async fn add_pre_trusted(&self, node_id: NodeId) {
320 let mut pre_trusted = self.pre_trusted_nodes.write().await;
321 pre_trusted.insert(node_id.clone());
322
323 let mut cache = self.trust_cache.write().await;
325 cache.insert(node_id, 0.9);
326 }
327
328 pub async fn remove_pre_trusted(&self, node_id: &NodeId) {
330 let mut pre_trusted = self.pre_trusted_nodes.write().await;
331 pre_trusted.remove(node_id);
332 }
333
334 pub async fn get_trust_async(&self, node_id: &NodeId) -> f64 {
336 let cache = self.trust_cache.read().await;
337 cache.get(node_id).copied().unwrap_or(0.5)
338 }
339}
340
341impl TrustProvider for EigenTrustEngine {
342 fn get_trust(&self, node: &NodeId) -> f64 {
343 if let Ok(cache) = self.trust_cache.try_read() {
346 cache.get(node).copied().unwrap_or(0.5)
347 } else {
348 0.5
350 }
351 }
352
353 fn update_trust(&self, from: &NodeId, to: &NodeId, success: bool) {
354 let local_trust = self.local_trust.clone();
356 let from = from.clone();
357 let to = to.clone();
358
359 tokio::spawn(async move {
360 let key = (from, to);
361 let new_value = if success { 1.0 } else { 0.0 };
362
363 let mut trust_map = local_trust.write().await;
364 trust_map
365 .entry(key)
366 .and_modify(|data| {
367 data.value = 0.9 * data.value + 0.1 * new_value;
368 data.interactions += 1;
369 data.last_interaction = Instant::now();
370 })
371 .or_insert(LocalTrustData {
372 value: new_value,
373 interactions: 1,
374 last_interaction: Instant::now(),
375 });
376 });
377 }
378
379 fn get_global_trust(&self) -> HashMap<NodeId, f64> {
380 if let Ok(cache) = self.trust_cache.try_read() {
382 cache.clone()
383 } else {
384 HashMap::new()
385 }
386 }
387
388 fn remove_node(&self, node: &NodeId) {
389 let node_id = node.clone();
391 let local_trust = self.local_trust.clone();
392 let trust_cache = self.trust_cache.clone();
393
394 tokio::spawn(async move {
395 let mut trust_map = local_trust.write().await;
397 trust_map.retain(|(from, to), _| from != &node_id && to != &node_id);
398
399 let mut cache = trust_cache.write().await;
401 cache.remove(&node_id);
402 });
403 }
404}
405
406pub struct TrustBasedRoutingStrategy {
408 trust_engine: Arc<EigenTrustEngine>,
410
411 local_id: NodeId,
413
414 min_trust_threshold: f64,
416}
417
418impl TrustBasedRoutingStrategy {
419 pub fn new(trust_engine: Arc<EigenTrustEngine>, local_id: NodeId) -> Self {
421 Self {
422 trust_engine,
423 local_id,
424 min_trust_threshold: 0.3,
425 }
426 }
427}
428
429#[async_trait]
430impl RoutingStrategy for TrustBasedRoutingStrategy {
431 async fn find_path(&self, target: &NodeId) -> Result<Vec<NodeId>> {
432 let trust_scores = self.trust_engine.get_global_trust();
434
435 let mut trusted_nodes: Vec<(NodeId, f64)> = trust_scores
437 .into_iter()
438 .filter(|(id, trust)| {
439 id != &self.local_id && id != target && *trust >= self.min_trust_threshold
440 })
441 .collect();
442
443 trusted_nodes.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
445
446 let path: Vec<NodeId> = trusted_nodes
448 .into_iter()
449 .take(3) .map(|(id, _)| id)
451 .chain(std::iter::once(target.clone()))
452 .collect();
453
454 if path.len() == 1 {
455 Err(AdaptiveNetworkError::Routing(
457 "No trusted path found".to_string(),
458 ))
459 } else {
460 Ok(path)
461 }
462 }
463
464 fn route_score(&self, neighbor: &NodeId, _target: &NodeId) -> f64 {
465 self.trust_engine.get_trust(neighbor)
466 }
467
468 fn update_metrics(&mut self, path: &[NodeId], success: bool) {
469 if path.len() >= 2 {
471 for window in path.windows(2) {
472 self.trust_engine
473 .update_trust(&window[0], &window[1], success);
474 }
475 }
476 }
477}
478
479pub struct MockTrustProvider {
481 trust_scores: Arc<RwLock<HashMap<NodeId, f64>>>,
482}
483
484impl Default for MockTrustProvider {
485 fn default() -> Self {
486 Self::new()
487 }
488}
489
490impl MockTrustProvider {
491 pub fn new() -> Self {
492 Self {
493 trust_scores: Arc::new(RwLock::new(HashMap::new())),
494 }
495 }
496}
497
498impl TrustProvider for MockTrustProvider {
499 fn get_trust(&self, node: &NodeId) -> f64 {
500 self.trust_scores
501 .blocking_read()
502 .get(node)
503 .copied()
504 .unwrap_or(0.5)
505 }
506
507 fn update_trust(&self, _from: &NodeId, to: &NodeId, success: bool) {
508 let mut scores = self.trust_scores.blocking_write();
509 let current = scores.get(to).copied().unwrap_or(0.5);
510 let new_score = if success {
511 (current + 0.1).min(1.0)
512 } else {
513 (current - 0.1).max(0.0)
514 };
515 scores.insert(to.clone(), new_score);
516 }
517
518 fn get_global_trust(&self) -> HashMap<NodeId, f64> {
519 self.trust_scores.blocking_read().clone()
520 }
521
522 fn remove_node(&self, node: &NodeId) {
523 self.trust_scores.blocking_write().remove(node);
524 }
525}
526
527#[cfg(test)]
528mod tests {
529 use super::*;
530
531 #[tokio::test]
532 async fn test_eigentrust_basic() {
533 use rand::RngCore;
534
535 let mut hash_pre = [0u8; 32];
536 rand::thread_rng().fill_bytes(&mut hash_pre);
537 let pre_trusted = HashSet::from([NodeId::from_bytes(hash_pre)]);
538
539 let engine = EigenTrustEngine::new(pre_trusted.clone());
540
541 let mut hash1 = [0u8; 32];
543 rand::thread_rng().fill_bytes(&mut hash1);
544 let node1 = NodeId { hash: hash1 };
545
546 let mut hash2 = [0u8; 32];
547 rand::thread_rng().fill_bytes(&mut hash2);
548 let node2 = NodeId { hash: hash2 };
549
550 let pre_trusted_node = pre_trusted.iter().next().unwrap();
551
552 engine
553 .update_local_trust(pre_trusted_node, &node1, true)
554 .await;
555 engine.update_local_trust(&node1, &node2, true).await;
556 engine.update_local_trust(&node2, &node1, false).await;
557
558 let global_trust = engine.compute_global_trust().await;
560
561 let pre_trust = global_trust.get(pre_trusted_node).unwrap_or(&0.0);
563 let node1_trust = global_trust.get(&node1).unwrap_or(&0.0);
564
565 assert!(pre_trust > node1_trust);
566 }
567
568 #[tokio::test]
569 async fn test_trust_normalization() {
570 use rand::RngCore;
571
572 let engine = EigenTrustEngine::new(HashSet::new());
573
574 let mut hash1 = [0u8; 32];
575 rand::thread_rng().fill_bytes(&mut hash1);
576 let node1 = NodeId { hash: hash1 };
577
578 let mut hash2 = [0u8; 32];
579 rand::thread_rng().fill_bytes(&mut hash2);
580 let node2 = NodeId { hash: hash2 };
581
582 let mut hash3 = [0u8; 32];
583 rand::thread_rng().fill_bytes(&mut hash3);
584 let node3 = NodeId { hash: hash3 };
585
586 engine.update_local_trust(&node1, &node2, true).await;
587 engine.update_local_trust(&node1, &node3, true).await;
588
589 let local_trust = engine.local_trust.read().await;
591 let trust2 = engine.get_normalized_trust(&local_trust, &node1, &node2);
592 let trust3 = engine.get_normalized_trust(&local_trust, &node1, &node3);
593
594 assert_eq!(trust2, Some(0.5));
595 assert_eq!(trust3, Some(0.5));
596 }
597
598 #[tokio::test]
599 async fn test_multi_factor_trust() {
600 use rand::RngCore;
601
602 let engine = Arc::new(EigenTrustEngine::new(HashSet::new()));
603
604 let mut hash = [0u8; 32];
605 rand::thread_rng().fill_bytes(&mut hash);
606 let node = NodeId { hash };
607
608 engine
610 .update_node_stats(&node, NodeStatisticsUpdate::Uptime(3600))
611 .await;
612 engine
613 .update_node_stats(&node, NodeStatisticsUpdate::CorrectResponse)
614 .await;
615 engine
616 .update_node_stats(&node, NodeStatisticsUpdate::CorrectResponse)
617 .await;
618 engine
619 .update_node_stats(&node, NodeStatisticsUpdate::FailedResponse)
620 .await;
621 engine
622 .update_node_stats(&node, NodeStatisticsUpdate::StorageContributed(100))
623 .await;
624
625 let mut hash2 = [0u8; 32];
627 rand::thread_rng().fill_bytes(&mut hash2);
628 let other = NodeId { hash: hash2 };
629
630 engine.update_local_trust(&other, &node, true).await;
631
632 let global_trust = engine.compute_global_trust().await;
634
635 let trust = global_trust.get(&node).unwrap_or(&0.0);
637 assert!(*trust > 0.0);
638 }
639
640 #[tokio::test]
641 async fn test_trust_decay() {
642 use rand::RngCore;
643
644 let mut engine = EigenTrustEngine::new(HashSet::new());
645 engine.decay_rate = 0.5; let mut hash1 = [0u8; 32];
648 rand::thread_rng().fill_bytes(&mut hash1);
649 let node1 = NodeId { hash: hash1 };
650
651 let mut hash2 = [0u8; 32];
652 rand::thread_rng().fill_bytes(&mut hash2);
653 let node2 = NodeId { hash: hash2 };
654
655 engine.update_local_trust(&node1, &node2, true).await;
656
657 let trust1 = engine.compute_global_trust().await;
659 let initial_trust = trust1.get(&node2).copied().unwrap_or(0.0);
660
661 *engine.last_update.write().await = Instant::now() - Duration::from_secs(3600);
663
664 let trust2 = engine.compute_global_trust().await;
666 let decayed_trust = trust2.get(&node2).copied().unwrap_or(0.0);
667
668 assert!(decayed_trust < initial_trust);
669 assert!((decayed_trust - initial_trust * 0.5).abs() < 0.1); }
671
672 #[tokio::test]
673 async fn test_trust_based_routing() {
674 use rand::RngCore;
675
676 let mut hash_pre = [0u8; 32];
678 rand::thread_rng().fill_bytes(&mut hash_pre);
679 let pre_trusted_id = NodeId::from_bytes(hash_pre);
680
681 let engine = Arc::new(EigenTrustEngine::new(HashSet::from([
682 pre_trusted_id.clone()
683 ])));
684
685 let mut hash_local = [0u8; 32];
687 rand::thread_rng().fill_bytes(&mut hash_local);
688 let local_id = NodeId::from_bytes(hash_local);
689
690 let mut hash_target = [0u8; 32];
691 rand::thread_rng().fill_bytes(&mut hash_target);
692 let target_id = NodeId::from_bytes(hash_target);
693
694 engine
696 .update_local_trust(&pre_trusted_id, &local_id, true)
697 .await;
698 engine.update_local_trust(&local_id, &target_id, true).await;
699
700 engine.compute_global_trust().await;
702
703 let strategy = TrustBasedRoutingStrategy::new(engine.clone(), local_id);
705
706 let result = strategy.find_path(&target_id).await;
708
709 assert!(result.is_ok());
711 let path = result.unwrap();
712 assert!(path.contains(&target_id));
713 }
714}