2025-01-07 16:34:19 -05:00
|
|
|
use core::future::Future;
|
2025-01-04 22:21:23 -05:00
|
|
|
use std::{
|
2025-01-04 23:28:29 -05:00
|
|
|
sync::Arc,
|
2025-01-04 22:21:23 -05:00
|
|
|
collections::{HashSet, HashMap},
|
|
|
|
|
};
|
2025-01-03 13:04:27 -05:00
|
|
|
|
2025-01-04 22:21:23 -05:00
|
|
|
use serai_client::primitives::{NetworkId, PublicKey};
|
|
|
|
|
|
2025-01-07 16:34:19 -05:00
|
|
|
use tokio::sync::RwLock;
|
2025-01-07 15:36:06 -05:00
|
|
|
|
2025-01-07 16:34:19 -05:00
|
|
|
use serai_task::ContinuallyRan;
|
2025-01-05 01:23:28 -05:00
|
|
|
|
2025-01-07 16:34:19 -05:00
|
|
|
use libp2p::{multihash::Multihash, identity::PeerId, swarm::NetworkBehaviour};
|
2025-01-04 22:21:23 -05:00
|
|
|
|
|
|
|
|
/// A struct to sync the validators from the Serai node in order to keep track of them.
|
|
|
|
|
mod validators;
|
2025-01-05 00:29:11 -05:00
|
|
|
use validators::{Validators, update_shared_validators};
|
2025-01-04 22:21:23 -05:00
|
|
|
|
|
|
|
|
/// The authentication protocol upgrade to limit the P2P network to active validators.
|
|
|
|
|
mod authenticate;
|
|
|
|
|
|
|
|
|
|
/// The dial task, to find new peers to connect to
|
|
|
|
|
mod dial;
|
|
|
|
|
|
|
|
|
|
/// The request-response messages and behavior
|
2025-01-03 13:04:27 -05:00
|
|
|
mod reqres;
|
|
|
|
|
use reqres::{Request, Response};
|
|
|
|
|
|
2025-01-04 22:21:23 -05:00
|
|
|
/// The gossip messages and behavior
|
2025-01-03 13:04:27 -05:00
|
|
|
mod gossip;
|
|
|
|
|
|
2025-01-04 22:21:23 -05:00
|
|
|
/// The heartbeat task, effecting sync of Tributaries
|
2025-01-03 13:04:27 -05:00
|
|
|
mod heartbeat;
|
|
|
|
|
|
2025-01-07 16:34:19 -05:00
|
|
|
/// The swarm task, running it and dispatching to/from it
|
|
|
|
|
mod swarm;
|
|
|
|
|
|
2025-01-04 22:21:23 -05:00
|
|
|
const PORT: u16 = 30563; // 5132 ^ (('c' << 8) | 'o')
|
|
|
|
|
|
|
|
|
|
fn peer_id_from_public(public: PublicKey) -> PeerId {
|
|
|
|
|
// 0 represents the identity Multihash, that no hash was performed
|
|
|
|
|
// It's an internal constant so we can't refer to the constant inside libp2p
|
|
|
|
|
PeerId::from_multihash(Multihash::wrap(0, &public.0).unwrap()).unwrap()
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-03 13:04:27 -05:00
|
|
|
struct Peer;
|
|
|
|
|
impl Peer {
|
|
|
|
|
async fn send(&self, request: Request) -> Result<Response, tokio::time::error::Elapsed> {
|
|
|
|
|
(async move { todo!("TODO") }).await
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-04 22:21:23 -05:00
|
|
|
#[derive(Clone)]
|
|
|
|
|
struct Peers {
|
|
|
|
|
peers: Arc<RwLock<HashMap<NetworkId, HashSet<PeerId>>>>,
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-03 13:04:27 -05:00
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
|
struct P2p;
|
|
|
|
|
impl P2p {
|
|
|
|
|
async fn peers(&self, set: NetworkId) -> Vec<Peer> {
|
|
|
|
|
(async move { todo!("TODO") }).await
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
|
|
|
|
impl tributary::P2p for P2p {
|
|
|
|
|
async fn broadcast(&self, genesis: [u8; 32], msg: Vec<u8>) {
|
|
|
|
|
todo!("TODO")
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-04 22:21:23 -05:00
|
|
|
|
|
|
|
|
#[derive(NetworkBehaviour)]
|
|
|
|
|
struct Behavior {
|
|
|
|
|
reqres: reqres::Behavior,
|
|
|
|
|
gossip: gossip::Behavior,
|
|
|
|
|
}
|
2025-01-04 23:28:29 -05:00
|
|
|
|
2025-01-07 16:34:19 -05:00
|
|
|
struct UpdateSharedValidatorsTask {
|
2025-01-04 23:28:29 -05:00
|
|
|
validators: Arc<RwLock<Validators>>,
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-07 16:34:19 -05:00
|
|
|
impl ContinuallyRan for UpdateSharedValidatorsTask {
|
|
|
|
|
// Only run every minute, not the default of every five seconds
|
|
|
|
|
const DELAY_BETWEEN_ITERATIONS: u64 = 60;
|
|
|
|
|
const MAX_DELAY_BETWEEN_ITERATIONS: u64 = 5 * 60;
|
2025-01-05 01:23:28 -05:00
|
|
|
|
2025-01-07 16:34:19 -05:00
|
|
|
fn run_iteration(&mut self) -> impl Send + Future<Output = Result<bool, String>> {
|
|
|
|
|
async move {
|
|
|
|
|
update_shared_validators(&self.validators).await.map_err(|e| format!("{e:?}"))?;
|
|
|
|
|
Ok(true)
|
2025-01-04 23:28:29 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|