cuprate_test_utils/
test_netzone.rs

1//! Test net zone.
2//!
3//! This module contains a test network zone, this network zone use channels as the network layer to simulate p2p
4//! communication.
5//!
6use std::{
7    fmt::Formatter,
8    io::Error,
9    net::{Ipv4Addr, SocketAddr},
10    pin::Pin,
11};
12
13use borsh::{BorshDeserialize, BorshSerialize};
14use futures::Stream;
15use tokio::io::{DuplexStream, ReadHalf, WriteHalf};
16use tokio_util::codec::{FramedRead, FramedWrite};
17
18use cuprate_wire::{
19    network_address::{NetworkAddress, NetworkAddressIncorrectZone},
20    MoneroWireCodec,
21};
22
23use cuprate_p2p_core::{NetZoneAddress, NetworkZone};
24
25/// An address on the test network
26#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq, BorshSerialize, BorshDeserialize)]
27pub struct TestNetZoneAddr(pub u32);
28
29impl NetZoneAddress for TestNetZoneAddr {
30    type BanID = Self;
31
32    fn set_port(&mut self, _: u16) {}
33
34    fn make_canonical(&mut self) {}
35
36    fn ban_id(&self) -> Self::BanID {
37        *self
38    }
39
40    fn should_add_to_peer_list(&self) -> bool {
41        true
42    }
43}
44
45impl std::fmt::Display for TestNetZoneAddr {
46    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
47        f.write_str(format!("test client, id: {}", self.0).as_str())
48    }
49}
50
51impl From<TestNetZoneAddr> for NetworkAddress {
52    fn from(value: TestNetZoneAddr) -> Self {
53        Self::Clear(SocketAddr::new(Ipv4Addr::from(value.0).into(), 18080))
54    }
55}
56
57impl TryFrom<NetworkAddress> for TestNetZoneAddr {
58    type Error = NetworkAddressIncorrectZone;
59
60    fn try_from(value: NetworkAddress) -> Result<Self, Self::Error> {
61        match value {
62            NetworkAddress::Clear(soc) => match soc {
63                SocketAddr::V4(v4) => Ok(Self(u32::from_be_bytes(v4.ip().octets()))),
64                SocketAddr::V6(_) => panic!("None v4 address in test code"),
65            },
66        }
67    }
68}
69
70/// TODO
71#[derive(Debug, Clone, Copy, Eq, PartialEq)]
72pub struct TestNetZone<const CHECK_NODE_ID: bool>;
73
74#[async_trait::async_trait]
75impl<const CHECK_NODE_ID: bool> NetworkZone for TestNetZone<CHECK_NODE_ID> {
76    const NAME: &'static str = "Testing";
77    const CHECK_NODE_ID: bool = CHECK_NODE_ID;
78
79    type Addr = TestNetZoneAddr;
80    type Stream = FramedRead<ReadHalf<DuplexStream>, MoneroWireCodec>;
81    type Sink = FramedWrite<WriteHalf<DuplexStream>, MoneroWireCodec>;
82    type Listener = Pin<
83        Box<
84            dyn Stream<Item = Result<(Option<Self::Addr>, Self::Stream, Self::Sink), Error>>
85                + Send
86                + 'static,
87        >,
88    >;
89    type ServerCfg = ();
90
91    async fn connect_to_peer(_: Self::Addr) -> Result<(Self::Stream, Self::Sink), Error> {
92        unimplemented!()
93    }
94
95    async fn incoming_connection_listener(
96        _: Self::ServerCfg,
97        _: u16,
98    ) -> Result<Self::Listener, Error> {
99        unimplemented!()
100    }
101}