cuprate-hinto-janai/p2p/src/address_book.rs
Boog900 a187d9a357
initial p2p code (#8)
* init

* save

* use macro to create the levin body enum

* add protocol docs and cargo fmt

* add response validation

* add client functionality to connection + fmt

* Add new cuprate-common crate
this crate will hold stuff needed across cuprate crates

+ init handshaker

* add stagenet & testnet hardforks + tests

+ cargo fmt

* split peer and protocol into separate crates
+ add sync state watcher

* finish initial sync states and add some tests

* save

* add initial address book

* cargo fmt

* save

* add pruning module to cuprate-common

* more address book updates
- added an address book client
- add some more address book requests
- add "NetZone"

* lots of changes

* cargo fmt

* combine p2p into one crate
they were all linked anyway

* cargo fmt

* turn the handshaker into a statemachine

* cargo fmt

* reduce the amt of copies when decoding

+ remove reliance on monero-rs

* update time_from_timestamp func

* cargo fmt
+ change qr code link
+ remove clippy.toml
2023-04-24 22:37:40 +01:00

120 lines
3.7 KiB
Rust

mod addr_book_client;
pub(crate) mod address_book;
pub use addr_book_client::start_address_book;
use monero_wire::{messages::PeerListEntryBase, network_address::NetZone, NetworkAddress};
const MAX_WHITE_LIST_PEERS: usize = 1000;
const MAX_GRAY_LIST_PEERS: usize = 5000;
#[derive(Debug, thiserror::Error)]
pub enum AddressBookError {
#[error("Peer was not found in book")]
PeerNotFound,
#[error("The peer list is empty")]
PeerListEmpty,
#[error("Peer sent an address out of it's net-zone")]
PeerSentAnAddressOutOfZone,
#[error("The address books channel has closed.")]
AddressBooksChannelClosed,
#[error("Peer Store Error: {0}")]
PeerStoreError(&'static str),
}
#[derive(Debug)]
pub enum AddressBookRequest {
HandleNewPeerList(Vec<PeerListEntryBase>, NetZone),
SetPeerSeen(NetworkAddress, i64),
BanPeer(NetworkAddress, chrono::NaiveDateTime),
AddPeerToAnchor(NetworkAddress),
RemovePeerFromAnchor(NetworkAddress),
UpdatePeerInfo(PeerListEntryBase),
GetRandomGrayPeer(NetZone),
GetRandomWhitePeer(NetZone),
}
impl std::fmt::Display for AddressBookRequest {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::HandleNewPeerList(_, _) => f.write_str("HandleNewPeerList"),
Self::SetPeerSeen(_, _) => f.write_str("SetPeerSeen"),
Self::BanPeer(_, _) => f.write_str("BanPeer"),
Self::AddPeerToAnchor(_) => f.write_str("AddPeerToAnchor"),
Self::RemovePeerFromAnchor(_) => f.write_str("RemovePeerFromAnchor"),
Self::UpdatePeerInfo(_) => f.write_str("UpdatePeerInfo"),
Self::GetRandomGrayPeer(_) => f.write_str("GetRandomGrayPeer"),
Self::GetRandomWhitePeer(_) => f.write_str("GetRandomWhitePeer"),
}
}
}
impl AddressBookRequest {
pub fn get_zone(&self) -> NetZone {
match self {
Self::HandleNewPeerList(_, zone) => *zone,
Self::SetPeerSeen(peer, _) => peer.get_zone(),
Self::BanPeer(peer, _) => peer.get_zone(),
Self::AddPeerToAnchor(peer) => peer.get_zone(),
Self::RemovePeerFromAnchor(peer) => peer.get_zone(),
Self::UpdatePeerInfo(peer) => peer.adr.get_zone(),
Self::GetRandomGrayPeer(zone) => *zone,
Self::GetRandomWhitePeer(zone) => *zone,
}
}
}
#[derive(Debug)]
pub enum AddressBookResponse {
Ok,
Peer(PeerListEntryBase),
}
#[derive(Debug, Clone)]
pub struct AddressBookConfig {
max_white_peers: usize,
max_gray_peers: usize,
}
impl Default for AddressBookConfig {
fn default() -> Self {
AddressBookConfig {
max_white_peers: MAX_WHITE_LIST_PEERS,
max_gray_peers: MAX_GRAY_LIST_PEERS,
}
}
}
#[async_trait::async_trait]
pub trait AddressBookStore: Clone {
type Error: Into<AddressBookError>;
/// Loads the peers from the peer store.
/// returns (in order):
/// the white list,
/// the gray list,
/// the anchor list,
/// the ban list
async fn load_peers(
&mut self,
zone: NetZone,
) -> Result<
(
Vec<PeerListEntryBase>, // white list
Vec<PeerListEntryBase>, // gray list
Vec<NetworkAddress>, // anchor list
Vec<(NetworkAddress, chrono::NaiveDateTime)>, // ban list
),
Self::Error,
>;
async fn save_peers(
&mut self,
zone: NetZone,
white: Vec<PeerListEntryBase>,
gray: Vec<PeerListEntryBase>,
anchor: Vec<NetworkAddress>,
bans: Vec<(NetworkAddress, chrono::NaiveDateTime)>, // ban lists
) -> Result<(), Self::Error>;
}