freenet_test_network/
peer.rs

1use crate::{process::PeerProcess, remote::PeerLocation, Result};
2use std::net::UdpSocket;
3use std::path::{Path, PathBuf};
4
5/// Represents a single peer in the test network
6pub struct TestPeer {
7    pub(crate) id: String,
8    pub(crate) is_gateway: bool,
9    pub(crate) ws_port: u16,
10    pub(crate) network_port: u16,
11    pub(crate) network_address: String,
12    pub(crate) data_dir: PathBuf,
13    pub(crate) process: Box<dyn PeerProcess + Send>,
14    pub(crate) public_key_path: Option<PathBuf>,
15    pub(crate) location: PeerLocation,
16}
17
18impl TestPeer {
19    /// Get the WebSocket URL for connecting to this peer
20    pub fn ws_url(&self) -> String {
21        format!("ws://127.0.0.1:{}/v1/contract/command", self.ws_port)
22    }
23
24    /// Get the peer's identifier
25    pub fn id(&self) -> &str {
26        &self.id
27    }
28
29    /// Check if this is a gateway peer
30    pub fn is_gateway(&self) -> bool {
31        self.is_gateway
32    }
33
34    /// Get the peer's network address
35    pub fn network_address(&self) -> &str {
36        &self.network_address
37    }
38
39    /// Get the root data directory for this peer
40    pub fn data_dir_path(&self) -> &Path {
41        &self.data_dir
42    }
43
44    /// Get the path to this peer's log file
45    pub fn log_path(&self) -> PathBuf {
46        self.process.log_path()
47    }
48
49    /// Read logs from this peer (fetches from Docker if needed)
50    pub fn read_logs(&self) -> Result<Vec<crate::logs::LogEntry>> {
51        self.process.read_logs()
52    }
53
54    /// Check if the peer process is still running
55    pub fn is_running(&self) -> bool {
56        self.process.is_running()
57    }
58
59    /// Kill the peer process
60    pub fn kill(&mut self) -> Result<()> {
61        self.process.kill()
62    }
63
64    /// Get the peer's location (local or remote)
65    pub fn location(&self) -> &PeerLocation {
66        &self.location
67    }
68}
69
70/// Get a free port by binding to port 0 and letting the OS assign one
71pub(crate) fn get_free_port() -> Result<u16> {
72    // Use UDP to mirror the freenet transport listener and avoid conflicts with UDP-only bindings.
73    let socket = UdpSocket::bind("127.0.0.1:0")?;
74    Ok(socket.local_addr()?.port())
75}