Files
cuprate-for-explorer/p2p/address-book/src/book/tests.rs
SyntheticBird 392653c659 Define Tor Zone, add onion addressing and more (#481)
* Define Tor Zone, add onion addressing, extend AddressBook, adapt `handle_timed_sync_request`, changes in cuprated + some cleanup

In `cuprated`:

- Added `Z: NetworkZone` as a generic requirement for `address_book_config`. Now takes the optional node address in argument.
- Added `tor_net_seed_nodes` fn for obtaining tor seed nodes.
- Added `CrossNetworkInternalPeerId::Tor(_)` variant and `From<InternalPeerId<OnionAddr>>`

In `cuprate-wire`:

- Added `src/network_address/onion_addr.rs` implementing `OnionAddr` type used by `Tor` network zone.
- Implemented parsing, formatting, conversion and validation of `OnionAddr`.
- Implemented 2 validation tests and 2 parsing tests for `OnionAddr`.
- Documented and cleaned up `src/network_address/epee_builder.rs`.
- Changed `u8` `type` field of `TaggedNetworkAddress` to `AddressType` enum equivalent to monerod's `address_type`.
- Added additional `host` and `port` fields to `AllFieldedNetworkAddress` collection type.
- Added `NetworkAddress:Tor` variant and added conversion to related functions.

In `cuprate-address-book`:

- Added `our_own_addr: Z::Addr` field to AddressBookConfig. This adds a `Z: NetworkZone` requirement to `AddressBookConfig`.
- Adapted code to the new generic requirement.
- Implemented handling of new `AddressBookRequest::OwnAddress` for querying the node self specified address for the zone.

In `cuprate-p2p`:

- If `Z::BROADCAST_OUR_OWN_ADDR` = `true`, `handle_timed_sync_request` will insert the node's address to the peerlist being sent.

In `cuprate-p2p-core`:

- Removed `#[async_trait::async_trait]` attribute to `impl NetworkZone for *`.
- Added `AddressBookRequest::OwnAddress` and `AddressBookResponse::OwnAddress(Option<Z::Addr>)`.
- Defined new `Tor` `NetworkZone`

* fmt

* fix typo and fmt

* final edits?

* fix test

* forgor
2025-06-05 20:54:19 +01:00

146 lines
4.6 KiB
Rust

use std::{path::PathBuf, time::Duration};
use futures::StreamExt;
use tokio::time::interval;
use cuprate_p2p_core::{handles::HandleBuilder, NetworkZone};
use cuprate_pruning::PruningSeed;
use super::{AddressBook, ConnectionPeerEntry, InternalPeerID};
use crate::{peer_list::tests::make_fake_peer_list, AddressBookConfig, AddressBookError};
use cuprate_test_utils::test_netzone::{TestNetZone, TestNetZoneAddr};
fn test_cfg<Z: NetworkZone>() -> AddressBookConfig<Z> {
AddressBookConfig {
max_white_list_length: 100,
max_gray_list_length: 500,
peer_store_directory: PathBuf::new(),
peer_save_period: Duration::from_secs(60),
our_own_address: None,
}
}
fn make_fake_address_book(numb_white: u32, numb_gray: u32) -> AddressBook<TestNetZone<true>> {
let white_list = make_fake_peer_list(0, numb_white);
let gray_list = make_fake_peer_list(numb_white, numb_gray);
AddressBook {
white_list,
gray_list,
anchor_list: Default::default(),
connected_peers: Default::default(),
connected_peers_ban_id: Default::default(),
banned_peers: Default::default(),
banned_peers_queue: Default::default(),
peer_save_task_handle: None,
peer_save_interval: interval(Duration::from_secs(60)),
cfg: test_cfg(),
}
}
#[tokio::test]
async fn take_random_peers() {
let mut address_book = make_fake_address_book(50, 250);
let peer = address_book.take_random_white_peer(None).unwrap();
assert!(!address_book.white_list.contains_peer(&peer.adr));
assert!(!address_book.gray_list.contains_peer(&peer.adr));
let peer = address_book.take_random_gray_peer(None).unwrap();
assert!(!address_book.white_list.contains_peer(&peer.adr));
assert!(!address_book.gray_list.contains_peer(&peer.adr));
}
#[tokio::test]
async fn get_white_peers() {
let address_book = make_fake_address_book(100, 0);
let peers = address_book.get_white_peers(50);
assert_eq!(peers.len(), 50);
let peers = address_book.get_white_peers(60);
assert_eq!(peers.len(), 60);
for window in peers.windows(2) {
assert_ne!(window[0], window[1]);
}
let address_book = make_fake_address_book(45, 0);
let peers = address_book.get_white_peers(50);
assert_eq!(peers.len(), 45);
let peers = address_book.get_white_peers(60);
assert_eq!(peers.len(), 45);
for window in peers.windows(2) {
assert_ne!(window[0], window[1]);
}
}
#[tokio::test]
async fn add_new_peer_already_connected() {
let mut address_book = make_fake_address_book(0, 0);
let (_, handle) = HandleBuilder::default().build();
address_book
.handle_new_connection(
InternalPeerID::KnownAddr(TestNetZoneAddr(1)),
ConnectionPeerEntry {
addr: None,
id: 0,
handle,
pruning_seed: PruningSeed::decompress(385).unwrap(),
rpc_port: 0,
rpc_credits_per_hash: 0,
},
)
.unwrap();
let (_, handle) = HandleBuilder::default().build();
assert_eq!(
address_book.handle_new_connection(
InternalPeerID::KnownAddr(TestNetZoneAddr(1)),
ConnectionPeerEntry {
addr: None,
id: 0,
handle,
pruning_seed: PruningSeed::decompress(385).unwrap(),
rpc_port: 0,
rpc_credits_per_hash: 0,
},
),
Err(AddressBookError::PeerAlreadyConnected)
);
}
#[tokio::test]
async fn banned_peer_removed_from_peer_lists() {
let mut address_book = make_fake_address_book(100, 0);
assert_eq!(address_book.banned_peers.len(), 0);
assert_eq!(address_book.white_list.len(), 100);
address_book.ban_peer(TestNetZoneAddr(1), Duration::from_secs(1));
assert_eq!(address_book.banned_peers.len(), 1);
assert_eq!(address_book.white_list.len(), 99);
address_book.ban_peer(TestNetZoneAddr(1), Duration::from_secs(1));
assert_eq!(address_book.banned_peers.len(), 1);
assert_eq!(address_book.white_list.len(), 99);
address_book.ban_peer(TestNetZoneAddr(1), Duration::from_secs(1));
assert_eq!(address_book.banned_peers.len(), 1);
assert_eq!(address_book.white_list.len(), 99);
address_book.ban_peer(TestNetZoneAddr(5), Duration::from_secs(100));
assert_eq!(address_book.banned_peers.len(), 2);
assert_eq!(address_book.white_list.len(), 98);
assert_eq!(
address_book
.banned_peers_queue
.next()
.await
.unwrap()
.into_inner(),
TestNetZoneAddr(1)
);
}