Skip to main content

firecloud_net/
provider.rs

1//! Storage provider information and discovery
2
3use libp2p::{Multiaddr, PeerId};
4use serde::{Deserialize, Serialize};
5
6/// Information about a storage provider node
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct ProviderInfo {
9    /// Peer ID of the provider
10    pub peer_id: PeerId,
11    /// Available storage space in bytes
12    pub available_space: u64,
13    /// Listen addresses for connections
14    pub listen_addrs: Vec<Multiaddr>,
15    /// Provider reputation score (0.0 - 1.0)
16    pub reputation: f64,
17    /// Last announcement timestamp
18    pub last_seen: u64,
19}
20
21impl ProviderInfo {
22    /// Create new provider info
23    pub fn new(peer_id: PeerId, available_space: u64, listen_addrs: Vec<Multiaddr>) -> Self {
24        Self {
25            peer_id,
26            available_space,
27            listen_addrs,
28            reputation: 1.0, // Start with perfect reputation
29            last_seen: std::time::SystemTime::now()
30                .duration_since(std::time::UNIX_EPOCH)
31                .unwrap()
32                .as_secs(),
33        }
34    }
35
36    /// Check if provider info is still fresh (within 10 minutes)
37    pub fn is_fresh(&self) -> bool {
38        let now = std::time::SystemTime::now()
39            .duration_since(std::time::UNIX_EPOCH)
40            .unwrap()
41            .as_secs();
42        now - self.last_seen < 600 // 10 minutes
43    }
44}
45
46/// Storage provider discovery result
47#[derive(Debug)]
48pub struct ProviderDiscovery {
49    /// List of available providers
50    pub providers: Vec<ProviderInfo>,
51    /// Total available space across all providers
52    pub total_space: u64,
53}
54
55impl ProviderDiscovery {
56    /// Create new discovery result
57    pub fn new(providers: Vec<ProviderInfo>) -> Self {
58        let total_space = providers.iter().map(|p| p.available_space).sum();
59        Self {
60            providers,
61            total_space,
62        }
63    }
64
65    /// Get best providers sorted by latency and space
66    pub fn best_providers(&self, count: usize) -> Vec<ProviderInfo> {
67        let mut providers = self.providers.clone();
68        
69        // Sort by: reputation (desc) -> available_space (desc)
70        providers.sort_by(|a, b| {
71            b.reputation
72                .partial_cmp(&a.reputation)
73                .unwrap()
74                .then(b.available_space.cmp(&a.available_space))
75        });
76
77        providers.into_iter().take(count).collect()
78    }
79
80    /// Check if we have enough providers for reliable storage
81    pub fn has_sufficient_providers(&self, min_required: usize) -> bool {
82        self.providers.len() >= min_required
83    }
84}