mirror of
https://github.com/hinto-janai/cuprate.git
synced 2025-01-10 21:04:59 +00:00
Boog900
ecd077b402
* init config * split sections * finish initial config. * fix clap * misc changes * fix doc * fix test & clippy * fix test 2 * try fix windows * testing * testing 2 * fix windows test * fix windows: the remix. * review comments * fix imports * rename & fix default config file * fix cargo hack * enable serde on `cuprate-helper` * changes from matrix chats * fix ci * fix doc * fix doc test * move Cuprated.toml * remove default.rs * `size` -> `bytes` * `addressbook_path` -> `address_book_path` * fix config output * fix ci * Update binaries/cuprated/src/config/args.rs Co-authored-by: hinto-janai <hinto.janai@protonmail.com> --------- Co-authored-by: hinto-janai <hinto.janai@protonmail.com>
96 lines
3.4 KiB
Rust
96 lines
3.4 KiB
Rust
//! Cuprate Address Book
|
|
//!
|
|
//! This module holds the logic for persistent peer storage.
|
|
//! Cuprates address book is modeled as a [`tower::Service`]
|
|
//! The request is [`AddressBookRequest`](cuprate_p2p_core::services::AddressBookRequest) and the response is
|
|
//! [`AddressBookResponse`](cuprate_p2p_core::services::AddressBookResponse).
|
|
//!
|
|
//! Cuprate, like monerod, actually has multiple address books, one
|
|
//! for each [`NetworkZone`]. This is to reduce the possibility of
|
|
//! clear net peers getting linked to their dark counterparts
|
|
//! and so peers will only get told about peers they can
|
|
//! connect to.
|
|
use std::{io::ErrorKind, path::PathBuf, time::Duration};
|
|
|
|
use cuprate_p2p_core::{NetZoneAddress, NetworkZone};
|
|
|
|
mod book;
|
|
mod peer_list;
|
|
mod store;
|
|
|
|
/// The address book config.
|
|
#[derive(Debug, Clone)]
|
|
pub struct AddressBookConfig {
|
|
/// The maximum number of white peers in the peer list.
|
|
///
|
|
/// White peers are peers we have connected to before.
|
|
pub max_white_list_length: usize,
|
|
/// The maximum number of gray peers in the peer list.
|
|
///
|
|
/// Gray peers are peers we are yet to make a connection to.
|
|
pub max_gray_list_length: usize,
|
|
/// The location to store the peer store files.
|
|
pub peer_store_directory: PathBuf,
|
|
/// The amount of time between saving the address book to disk.
|
|
pub peer_save_period: Duration,
|
|
}
|
|
|
|
/// Possible errors when dealing with the address book.
|
|
/// This is boxed when returning an error in the [`tower::Service`].
|
|
#[derive(Debug, thiserror::Error, Eq, PartialEq)]
|
|
pub enum AddressBookError {
|
|
/// The peer is already connected.
|
|
#[error("Peer is already connected")]
|
|
PeerAlreadyConnected,
|
|
/// The peer is not in the address book for this zone.
|
|
#[error("Peer was not found in book")]
|
|
PeerNotFound,
|
|
/// Immutable peer data was changed.
|
|
#[error("Immutable peer data was changed: {0}")]
|
|
PeersDataChanged(&'static str),
|
|
/// The peer is banned.
|
|
#[error("The peer is banned")]
|
|
PeerIsBanned,
|
|
/// The channel to the address book has closed unexpectedly.
|
|
#[error("The address books channel has closed.")]
|
|
AddressBooksChannelClosed,
|
|
/// The address book task has exited.
|
|
#[error("The address book task has exited.")]
|
|
AddressBookTaskExited,
|
|
}
|
|
|
|
/// Initializes the P2P address book for a specific network zone.
|
|
pub async fn init_address_book<Z: BorshNetworkZone>(
|
|
cfg: AddressBookConfig,
|
|
) -> Result<book::AddressBook<Z>, std::io::Error> {
|
|
let (white_list, gray_list) = match store::read_peers_from_disk::<Z>(&cfg).await {
|
|
Ok(res) => res,
|
|
Err(e) if e.kind() == ErrorKind::NotFound => (vec![], vec![]),
|
|
Err(e) => {
|
|
tracing::error!("Failed to open peer list, {}", e);
|
|
panic!("{e}");
|
|
}
|
|
};
|
|
|
|
let address_book = book::AddressBook::<Z>::new(cfg, white_list, gray_list, Vec::new());
|
|
|
|
Ok(address_book)
|
|
}
|
|
|
|
use sealed::BorshNetworkZone;
|
|
mod sealed {
|
|
use super::*;
|
|
|
|
/// An internal trait for the address book for a [`NetworkZone`] that adds the requirement of [`borsh`] traits
|
|
/// onto the network address.
|
|
pub trait BorshNetworkZone: NetworkZone<Addr = Self::BorshAddr> {
|
|
type BorshAddr: NetZoneAddress + borsh::BorshDeserialize + borsh::BorshSerialize;
|
|
}
|
|
|
|
impl<T: NetworkZone> BorshNetworkZone for T
|
|
where
|
|
T::Addr: borsh::BorshDeserialize + borsh::BorshSerialize,
|
|
{
|
|
type BorshAddr = T::Addr;
|
|
}
|
|
}
|