diff --git a/Cargo.lock b/Cargo.lock index 802c5f00..eb3c9b4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8327,6 +8327,7 @@ dependencies = [ "parity-scale-codec", "rand_core", "schnorr-signatures", + "schnorrkel", "serai-client", "serai-cosign", "serai-db", diff --git a/coordinator/cosign/src/lib.rs b/coordinator/cosign/src/lib.rs index faa449dd..3d2ab5ab 100644 --- a/coordinator/cosign/src/lib.rs +++ b/coordinator/cosign/src/lib.rs @@ -29,7 +29,7 @@ pub use delay::BROADCAST_FREQUENCY; use delay::LatestCosignedBlockNumber; /// The schnorrkel context to used when signing a cosign. -pub const COSIGN_CONTEXT: &[u8] = b"serai-cosign"; +pub const COSIGN_CONTEXT: &[u8] = b"/serai/coordinator/cosign"; /// A 'global session', defined as all validator sets used for cosigning at a given moment. /// diff --git a/coordinator/src/p2p/authenticate.rs b/coordinator/src/p2p/authenticate.rs index 99d98515..ffa8a33b 100644 --- a/coordinator/src/p2p/authenticate.rs +++ b/coordinator/src/p2p/authenticate.rs @@ -12,7 +12,12 @@ use serai_client::primitives::PublicKey as Public; use tokio::sync::RwLock; use futures_util::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; -use libp2p::{core::UpgradeInfo, InboundUpgrade, OutboundUpgrade, identity::PeerId, noise}; +use libp2p::{ + core::UpgradeInfo, + InboundUpgrade, OutboundUpgrade, + identity::{self, PeerId}, + noise, +}; use crate::p2p::{validators::Validators, peer_id_from_public}; @@ -21,7 +26,7 @@ const PROTOCOL: &str = "/serai/coordinator/validators"; struct OnlyValidators { validators: Arc>, serai_key: Zeroizing, - our_peer_id: PeerId, + noise_keypair: identity::Keypair, } impl OnlyValidators { @@ -112,33 +117,35 @@ impl OnlyValidators { } impl UpgradeInfo for OnlyValidators { - type Info = &'static str; - type InfoIter = [&'static str; 1]; - fn protocol_info(&self) -> [&'static str; 1] { - [PROTOCOL] + type Info = ::Info; + type InfoIter = ::InfoIter; + fn protocol_info(&self) -> Self::InfoIter { + // A keypair only causes an error if its sign operation fails, which is only possible with RSA, + // which isn't used within this codebase + noise::Config::new(&self.noise_keypair).unwrap().protocol_info() } } -impl InboundUpgrade<(PeerId, noise::Output)> - for OnlyValidators -{ +impl InboundUpgrade for OnlyValidators { type Output = (PeerId, noise::Output); type Error = io::Error; type Future = Pin>>>; - fn upgrade_inbound( - self, - (dialer_noise_peer_id, mut socket): (PeerId, noise::Output), - _: Self::Info, - ) -> Self::Future { + fn upgrade_inbound(self, socket: S, info: Self::Info) -> Self::Future { Box::pin(async move { + let (dialer_noise_peer_id, mut socket) = noise::Config::new(&self.noise_keypair) + .unwrap() + .upgrade_inbound(socket, info) + .await + .map_err(io::Error::other)?; + let (our_challenge, dialer_challenge) = OnlyValidators::challenges(&mut socket).await?; let dialer_serai_validator = self .authenticate( &mut socket, dialer_noise_peer_id, dialer_challenge, - self.our_peer_id, + PeerId::from_public_key(&self.noise_keypair.public()), our_challenge, ) .await?; @@ -147,24 +154,24 @@ impl InboundUpgrade<(PeerId, } } -impl OutboundUpgrade<(PeerId, noise::Output)> - for OnlyValidators -{ +impl OutboundUpgrade for OnlyValidators { type Output = (PeerId, noise::Output); type Error = io::Error; type Future = Pin>>>; - fn upgrade_outbound( - self, - (listener_noise_peer_id, mut socket): (PeerId, noise::Output), - _: Self::Info, - ) -> Self::Future { + fn upgrade_outbound(self, socket: S, info: Self::Info) -> Self::Future { Box::pin(async move { + let (listener_noise_peer_id, mut socket) = noise::Config::new(&self.noise_keypair) + .unwrap() + .upgrade_outbound(socket, info) + .await + .map_err(io::Error::other)?; + let (our_challenge, listener_challenge) = OnlyValidators::challenges(&mut socket).await?; let listener_serai_validator = self .authenticate( &mut socket, - self.our_peer_id, + PeerId::from_public_key(&self.noise_keypair.public()), our_challenge, listener_noise_peer_id, listener_challenge, diff --git a/coordinator/src/p2p/mod.rs b/coordinator/src/p2p/mod.rs index dbecc7c7..71984b8c 100644 --- a/coordinator/src/p2p/mod.rs +++ b/coordinator/src/p2p/mod.rs @@ -100,6 +100,7 @@ impl SwarmTask { biased; // Refresh the instance of validators we use to track peers/share with authenticate + // TODO: Move this to a task () = tokio::time::sleep(time_till_refresh_validators) => { const TIME_BETWEEN_REFRESH_VALIDATORS: Duration = Duration::from_secs(60); const MAX_TIME_BETWEEN_REFRESH_VALIDATORS: Duration = Duration::from_secs(5 * 60); diff --git a/substrate/node/src/rpc.rs b/substrate/node/src/rpc.rs index b818c798..63330419 100644 --- a/substrate/node/src/rpc.rs +++ b/substrate/node/src/rpc.rs @@ -65,7 +65,7 @@ where let validators = client.runtime_api().validators(latest_block, network).map_err(|_| { jsonrpsee::core::Error::to_call_error(std::io::Error::other(format!( "couldn't get validators from the latest block, which is likely a fatal bug. {}", - "please report this at https://github.com/serai-dex/serai", + "please report this at https://github.com/serai-dex/serai/issues", ))) })?; // Always return the protocol's bootnodes