Skip to main content

shadow_client/
node.rs

1//! Shadow Network node implementation
2
3use shadow_core::{PeerId, PeerInfo};
4use shadow_core::error::{Result, ShadowError};
5use crypto::Keypair;
6use dht::{DHTNode, NodeConfig as DHTConfig};
7use nat_traversal::{StunClient, types::NatInfo};
8use std::sync::Arc;
9use tokio::sync::RwLock;
10
11/// Shadow Network node
12pub struct ShadowNode {
13    /// Node keypair
14    keypair: Keypair,
15    /// Peer ID
16    peer_id: PeerId,
17    /// DHT node
18    dht: Arc<DHTNode>,
19    /// NAT information
20    nat_info: Arc<RwLock<Option<NatInfo>>>,
21}
22
23impl ShadowNode {
24    /// Create new shadow node
25    pub fn new(keypair: Keypair) -> Self {
26        // Use verify_key as peer ID
27        // The VerifyKey struct contains 32 bytes internally
28        let public_identity = keypair.public_identity();
29        // For now, use serialized verify_key
30        let serialized = bincode::serialize(&public_identity.verify_key).unwrap();
31        let mut peer_id_bytes = [0u8; 32];
32        peer_id_bytes.copy_from_slice(&serialized[..32.min(serialized.len())]);
33        let peer_id = PeerId::from_bytes(peer_id_bytes);
34        let dht = Arc::new(DHTNode::new(peer_id, DHTConfig::default()));
35
36        Self {
37            keypair,
38            peer_id,
39            dht,
40            nat_info: Arc::new(RwLock::new(None)),
41        }
42    }
43
44    /// Get peer ID
45    pub fn peer_id(&self) -> PeerId {
46        self.peer_id
47    }
48
49    /// Get keypair reference
50    pub fn keypair(&self) -> &Keypair {
51        &self.keypair
52    }
53
54    /// Get DHT node
55    pub fn dht(&self) -> &Arc<DHTNode> {
56        &self.dht
57    }
58
59    /// Start node services
60    pub async fn start(&self) -> Result<()> {
61        // Discover NAT type
62        let stun_client = StunClient::default();
63        match stun_client.discover_nat() {
64            Ok(info) => {
65                tracing::info!("NAT discovery: {:?}", info.nat_type);
66                *self.nat_info.write().await = Some(info);
67            }
68            Err(e) => {
69                tracing::warn!("NAT discovery failed: {}", e);
70            }
71        }
72
73        // Start DHT maintenance
74        let dht_clone = self.dht.clone();
75        tokio::spawn(async move {
76            dht_clone.start_maintenance().await;
77        });
78
79        Ok(())
80    }
81
82    /// Stop node services
83    pub async fn stop(&self) -> Result<()> {
84        Ok(())
85    }
86
87    /// Add peer to network
88    pub async fn add_peer(&self, peer: PeerInfo) -> Result<()> {
89        self.dht.add_peer(peer)?;
90        Ok(())
91    }
92
93    /// Get connected peers
94    pub fn get_peers(&self) -> Vec<PeerInfo> {
95        self.dht.all_peers()
96    }
97
98    /// Get NAT information
99    pub async fn nat_info(&self) -> Option<NatInfo> {
100        self.nat_info.read().await.clone()
101    }
102
103    /// Store data in DHT
104    pub async fn store_data(&self, key: [u8; 32], data: bytes::Bytes) -> Result<()> {
105        let peer_id_bytes = *self.peer_id.as_bytes();
106        self.dht.store_value(key, data, peer_id_bytes)?;
107        Ok(())
108    }
109
110    /// Retrieve data from DHT
111    pub async fn get_data(&self, key: &[u8; 32]) -> Option<bytes::Bytes> {
112        self.dht.get_value(key).map(|v| v.data)
113    }
114
115    /// Get node statistics
116    pub fn stats(&self) -> NodeStats {
117        let dht_stats = self.dht.stats();
118        
119        NodeStats {
120            peer_id: self.peer_id,
121            connected_peers: dht_stats.peer_count,
122            stored_values: dht_stats.value_count,
123            storage_bytes: dht_stats.storage_size,
124        }
125    }
126}
127
128/// Node handle for async operations
129pub struct NodeHandle {
130    node: Arc<ShadowNode>,
131}
132
133impl NodeHandle {
134    /// Create new node handle
135    pub fn new(node: ShadowNode) -> Self {
136        Self {
137            node: Arc::new(node),
138        }
139    }
140
141    /// Get node reference
142    pub fn node(&self) -> &Arc<ShadowNode> {
143        &self.node
144    }
145
146    /// Start node
147    pub async fn start(&self) -> Result<()> {
148        self.node.start().await
149    }
150
151    /// Stop node
152    pub async fn stop(&self) -> Result<()> {
153        self.node.stop().await
154    }
155}
156
157impl Clone for NodeHandle {
158    fn clone(&self) -> Self {
159        Self {
160            node: self.node.clone(),
161        }
162    }
163}
164
165/// Node statistics
166#[derive(Debug, Clone)]
167pub struct NodeStats {
168    pub peer_id: PeerId,
169    pub connected_peers: usize,
170    pub stored_values: usize,
171    pub storage_bytes: usize,
172}
173
174#[cfg(test)]
175mod tests {
176    use super::*;
177
178    #[test]
179    fn test_node_creation() {
180        let keypair = Keypair::generate();
181        let node = ShadowNode::new(keypair);
182        
183        assert_eq!(node.get_peers().len(), 0);
184    }
185
186    #[tokio::test]
187    async fn test_node_lifecycle() {
188        let keypair = Keypair::generate();
189        let node = NodeHandle::new(ShadowNode::new(keypair));
190        
191        // Start and stop should work
192        node.start().await.ok();
193        node.stop().await.ok();
194    }
195}