diff --git a/Cargo.toml b/Cargo.toml index 46461d2..ec4ea5e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://forgejo.fireturlte.net" [workspace.dependencies] lazy-supplements.path = "lazy-supplements" lazy-supplements-migration.path = "lazy-supplements-migration" -libp2p = { version = "0.55.0", features = ["noise", "ping", "tcp", "tokio", "yamux" ] } +libp2p = { version = "0.55.0", features = ["macros", "mdns", "noise", "ping", "tcp", "tokio", "yamux" ] } [workspace.dependencies.sea-orm-migration] version = "1.1.0" diff --git a/lazy-supplements/src/cli/node.rs b/lazy-supplements/src/cli/node.rs index 3529b91..2f17414 100644 --- a/lazy-supplements/src/cli/node.rs +++ b/lazy-supplements/src/cli/node.rs @@ -53,7 +53,10 @@ impl JoinNodeArgs { loop{ match swarm.select_next_some().await { SwarmEvent::NewListenAddr { address, .. } => println!("Listening on {address:?}"), - SwarmEvent::Behaviour(event) => println!("{event:?}"), + SwarmEvent::Behaviour(event) => { + println!("{event:?}"); + event.run().await; + }, _ => {} } } diff --git a/lazy-supplements/src/cli/server.rs b/lazy-supplements/src/cli/server.rs index 247fd7f..0a65dc5 100644 --- a/lazy-supplements/src/cli/server.rs +++ b/lazy-supplements/src/cli/server.rs @@ -18,7 +18,10 @@ impl ServerArgs { loop{ match swarm.select_next_some().await { SwarmEvent::NewListenAddr { address, .. } => println!("Listening on {address:?}"), - SwarmEvent::Behaviour(event) => println!("{event:?}"), + SwarmEvent::Behaviour(event) => { + println!("{event:?}"); + event.run().await; + }, _ => {} } } diff --git a/lazy-supplements/src/config/node.rs b/lazy-supplements/src/config/node.rs index f2887c4..ef45285 100644 --- a/lazy-supplements/src/config/node.rs +++ b/lazy-supplements/src/config/node.rs @@ -8,7 +8,7 @@ use tokio::{fs::File, io::{AsyncReadExt, AsyncWriteExt}}; use tracing_subscriber::EnvFilter; -use crate::{cli::ConfigArgs, error::Error, global::DEFAULT_DATABASE_FILE_PATH}; +use crate::{cli::ConfigArgs, error::Error, global::DEFAULT_DATABASE_FILE_PATH, p2p}; use super::{PartialConfig, DEFAULT_LISTEN_IPS, DEFAULT_PORT}; @@ -33,7 +33,7 @@ pub struct NodeConfig { } impl NodeConfig { - pub async fn try_into_swarm (self) -> Result, Error> { + pub async fn try_into_swarm (self) -> Result, Error> { let _ = tracing_subscriber::fmt() .with_env_filter(EnvFilter::from_default_env()) .try_init(); @@ -44,7 +44,7 @@ impl NodeConfig { noise::Config::new, yamux::Config::default, )? - .with_behaviour(|_| ping::Behaviour::default())? + .with_behaviour(|keypair| p2p::Behaviour::try_from(keypair).unwrap())? .build(); swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?; Ok(swarm) diff --git a/lazy-supplements/src/global/mod.rs b/lazy-supplements/src/global/mod.rs index 459310e..c51d2db 100644 --- a/lazy-supplements/src/global/mod.rs +++ b/lazy-supplements/src/global/mod.rs @@ -1,8 +1,9 @@ -use std::{net::{IpAddr, Ipv4Addr}, path::PathBuf, sync::LazyLock}; +use std::{collections::HashMap, net::{IpAddr, Ipv4Addr}, path::PathBuf, sync::LazyLock}; use crate::config::{NodeConfig, RawNodeConfig}; +use libp2p::{Multiaddr, PeerId}; use sea_orm::DatabaseConnection; -use tokio::sync::OnceCell; +use tokio::sync::{OnceCell, RwLock}; mod database; @@ -53,10 +54,12 @@ pub static DEFAULT_DATABASE_FILE_PATH: LazyLock = LazyLock::new(|| { pub static GLOBAL: Global = Global{ node_config: OnceCell::const_new(), database: OnceCell::const_new(), + peers: OnceCell::const_new(), }; pub struct Global { pub node_config: OnceCell, pub database: OnceCell, + pub peers: OnceCell>> } #[cfg(test)] @@ -69,6 +72,17 @@ impl Global { pub async fn get_or_try_init_node_config(&self, config: NodeConfig) -> &NodeConfig { self.node_config.get_or_init(|| async {config}).await } + pub async fn get_or_init_peers(&self) -> &RwLock> { + self.peers.get_or_init(|| async { + RwLock::new(HashMap::new()) + }).await + } + pub async fn read_peers(&self) -> tokio::sync::RwLockReadGuard<'_, HashMap>{ + self.get_or_init_peers().await.read().await + } + pub async fn write_peers(&self) -> tokio::sync::RwLockWriteGuard<'_, HashMap>{ + self.get_or_init_peers().await.write().await + } } pub static DEFAULT_RAW_NODE_CONFIG: LazyLock = LazyLock::new(|| { diff --git a/lazy-supplements/src/lib.rs b/lazy-supplements/src/lib.rs index 636048c..5c5f70a 100644 --- a/lazy-supplements/src/lib.rs +++ b/lazy-supplements/src/lib.rs @@ -3,5 +3,6 @@ pub mod config; pub mod entity; pub mod error; pub mod global; +pub mod p2p; #[cfg(any(test, feature="test"))] pub mod tests; diff --git a/lazy-supplements/src/p2p/mod.rs b/lazy-supplements/src/p2p/mod.rs new file mode 100644 index 0000000..a64add5 --- /dev/null +++ b/lazy-supplements/src/p2p/mod.rs @@ -0,0 +1,60 @@ +use libp2p::{ identity::Keypair, mdns, ping, swarm}; + +use crate::error::Error; + +#[derive(swarm::NetworkBehaviour)] +#[behaviour(to_swarm = "Event")] +pub struct Behaviour { + pub mdns: mdns::tokio::Behaviour, + pub ping: ping::Behaviour, +} + +impl TryFrom<&Keypair> for Behaviour { + type Error = Error; + fn try_from(keypair: &Keypair) -> Result { + Ok(Self { + mdns: mdns::tokio::Behaviour::new( + mdns::Config::default(), + keypair.public().into(), + )?, + ping: libp2p::ping::Behaviour::new(ping::Config::new()), + }) + } +} + +#[derive(Debug)] +pub enum Event { + Mdns(mdns::Event), + Ping(ping::Event), +} + +impl Event { + pub async fn run(self) { + match self { + Self::Mdns(x) => { + match x { + mdns::Event::Discovered(e) => { + for peer in e { + let mut peers = crate::global::GLOBAL.write_peers().await; + peers.insert(peer.0, peer.1); + } + let peers = crate::global::GLOBAL.read_peers().await; + println!("Peers: {peers:?}"); + }, + _ => {}, + } + }, + _ => {} + } + } +} +impl From for Event { + fn from(event: mdns::Event) -> Self { + Self::Mdns(event) + } +} +impl From for Event { + fn from(event: ping::Event) -> Self { + Self::Ping(event) + } +} \ No newline at end of file