Skip to main content

pot_o_extensions/
peer_network.rs

1//! Peer network: local-only and optional VPN mesh for multi-node discovery.
2
3use async_trait::async_trait;
4use pot_o_core::TribeResult;
5use pot_o_mining::{Challenge, ProofPayload};
6use serde::{Deserialize, Serialize};
7
8// ---------------------------------------------------------------------------
9// Types
10// ---------------------------------------------------------------------------
11
12pub type NodeId = String;
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct PeerInfo {
16    pub node_id: NodeId,
17    pub address: String,
18    pub port: u16,
19    pub last_seen: chrono::DateTime<chrono::Utc>,
20    pub version: String,
21}
22
23#[derive(Debug, Clone, Default, Serialize, Deserialize)]
24pub struct NetworkState {
25    pub peers: Vec<PeerInfo>,
26    pub total_nodes: usize,
27    pub synced: bool,
28}
29
30// ---------------------------------------------------------------------------
31// Trait
32// ---------------------------------------------------------------------------
33
34/// How validator nodes discover and communicate with each other.
35#[async_trait]
36pub trait PeerNetwork: Send + Sync {
37    fn node_id(&self) -> &NodeId;
38    async fn discover_peers(&self) -> TribeResult<Vec<PeerInfo>>;
39    async fn broadcast_challenge(&self, challenge: &Challenge) -> TribeResult<()>;
40    async fn relay_proof(&self, proof: &ProofPayload) -> TribeResult<()>;
41    async fn sync_state(&self) -> TribeResult<NetworkState>;
42}
43
44// ---------------------------------------------------------------------------
45// LocalOnlyNetwork (implemented now)
46// ---------------------------------------------------------------------------
47
48pub struct LocalOnlyNetwork {
49    node_id: NodeId,
50}
51
52impl LocalOnlyNetwork {
53    pub fn new() -> Self {
54        Self {
55            node_id: uuid::Uuid::new_v4().to_string(),
56        }
57    }
58}
59
60impl Default for LocalOnlyNetwork {
61    fn default() -> Self {
62        Self::new()
63    }
64}
65
66#[async_trait]
67impl PeerNetwork for LocalOnlyNetwork {
68    fn node_id(&self) -> &NodeId {
69        &self.node_id
70    }
71
72    async fn discover_peers(&self) -> TribeResult<Vec<PeerInfo>> {
73        Ok(vec![]) // No peers in local-only mode
74    }
75
76    async fn broadcast_challenge(&self, _challenge: &Challenge) -> TribeResult<()> {
77        Ok(()) // No-op
78    }
79
80    async fn relay_proof(&self, _proof: &ProofPayload) -> TribeResult<()> {
81        Ok(()) // No-op
82    }
83
84    async fn sync_state(&self) -> TribeResult<NetworkState> {
85        Ok(NetworkState {
86            peers: vec![],
87            total_nodes: 1,
88            synced: true,
89        })
90    }
91}
92
93// ---------------------------------------------------------------------------
94// VpnMeshNetwork (stubbed for future WireGuard + mDNS)
95// ---------------------------------------------------------------------------
96
97#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct VpnMeshConfig {
99    pub wireguard_interface: String,
100    pub peer_addresses: Vec<String>,
101    pub mdns_enabled: bool,
102    pub gossip_port: u16,
103}
104
105pub struct VpnMeshNetwork {
106    pub node_id: NodeId,
107    pub config: VpnMeshConfig,
108}
109
110#[async_trait]
111impl PeerNetwork for VpnMeshNetwork {
112    fn node_id(&self) -> &NodeId {
113        &self.node_id
114    }
115
116    async fn discover_peers(&self) -> TribeResult<Vec<PeerInfo>> {
117        todo!("VPN mesh peer discovery via WireGuard + mDNS not yet implemented")
118    }
119
120    async fn broadcast_challenge(&self, _challenge: &Challenge) -> TribeResult<()> {
121        todo!("VPN mesh challenge broadcast not yet implemented")
122    }
123
124    async fn relay_proof(&self, _proof: &ProofPayload) -> TribeResult<()> {
125        todo!("VPN mesh proof relay not yet implemented")
126    }
127
128    async fn sync_state(&self) -> TribeResult<NetworkState> {
129        todo!("VPN mesh state sync not yet implemented")
130    }
131}