mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Update to libp2p 0.54
This is the same libp2p Substrate uses as of https://github.com/paritytech/polkadot-sdk/pull/6248.
This commit is contained in:
524
Cargo.lock
generated
524
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -35,7 +35,7 @@ tributary-sdk = { path = "../../tributary-sdk" }
|
|||||||
|
|
||||||
futures-util = { version = "0.3", default-features = false, features = ["std"] }
|
futures-util = { version = "0.3", default-features = false, features = ["std"] }
|
||||||
tokio = { version = "1", default-features = false, features = ["sync"] }
|
tokio = { version = "1", default-features = false, features = ["sync"] }
|
||||||
libp2p = { version = "0.52", default-features = false, features = ["tokio", "tcp", "noise", "yamux", "ping", "request-response", "gossipsub", "macros"] }
|
libp2p = { version = "0.54", default-features = false, features = ["tokio", "tcp", "noise", "yamux", "ping", "request-response", "gossipsub", "macros"] }
|
||||||
|
|
||||||
log = { version = "0.4", default-features = false, features = ["std"] }
|
log = { version = "0.4", default-features = false, features = ["std"] }
|
||||||
serai-task = { path = "../../../common/task", version = "0.1" }
|
serai-task = { path = "../../../common/task", version = "0.1" }
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ use serai_client::primitives::PublicKey as Public;
|
|||||||
|
|
||||||
use futures_util::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
|
use futures_util::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
|
||||||
use libp2p::{
|
use libp2p::{
|
||||||
core::UpgradeInfo,
|
core::upgrade::{UpgradeInfo, InboundConnectionUpgrade, OutboundConnectionUpgrade},
|
||||||
InboundUpgrade, OutboundUpgrade,
|
|
||||||
identity::{self, PeerId},
|
identity::{self, PeerId},
|
||||||
noise,
|
noise,
|
||||||
};
|
};
|
||||||
@@ -119,12 +118,18 @@ impl UpgradeInfo for OnlyValidators {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: 'static + Send + Unpin + AsyncRead + AsyncWrite> InboundUpgrade<S> for OnlyValidators {
|
impl<S: 'static + Send + Unpin + AsyncRead + AsyncWrite> InboundConnectionUpgrade<S>
|
||||||
|
for OnlyValidators
|
||||||
|
{
|
||||||
type Output = (PeerId, noise::Output<S>);
|
type Output = (PeerId, noise::Output<S>);
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
type Future = Pin<Box<dyn Send + Future<Output = Result<Self::Output, Self::Error>>>>;
|
type Future = Pin<Box<dyn Send + Future<Output = Result<Self::Output, Self::Error>>>>;
|
||||||
|
|
||||||
fn upgrade_inbound(self, socket: S, info: Self::Info) -> Self::Future {
|
fn upgrade_inbound(
|
||||||
|
self,
|
||||||
|
socket: S,
|
||||||
|
info: <Self as UpgradeInfo>::Info,
|
||||||
|
) -> <Self as InboundConnectionUpgrade<S>>::Future {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let (dialer_noise_peer_id, mut socket) = noise::Config::new(&self.noise_keypair)
|
let (dialer_noise_peer_id, mut socket) = noise::Config::new(&self.noise_keypair)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -147,12 +152,18 @@ impl<S: 'static + Send + Unpin + AsyncRead + AsyncWrite> InboundUpgrade<S> for O
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: 'static + Send + Unpin + AsyncRead + AsyncWrite> OutboundUpgrade<S> for OnlyValidators {
|
impl<S: 'static + Send + Unpin + AsyncRead + AsyncWrite> OutboundConnectionUpgrade<S>
|
||||||
|
for OnlyValidators
|
||||||
|
{
|
||||||
type Output = (PeerId, noise::Output<S>);
|
type Output = (PeerId, noise::Output<S>);
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
type Future = Pin<Box<dyn Send + Future<Output = Result<Self::Output, Self::Error>>>>;
|
type Future = Pin<Box<dyn Send + Future<Output = Result<Self::Output, Self::Error>>>>;
|
||||||
|
|
||||||
fn upgrade_outbound(self, socket: S, info: Self::Info) -> Self::Future {
|
fn upgrade_outbound(
|
||||||
|
self,
|
||||||
|
socket: S,
|
||||||
|
info: <Self as UpgradeInfo>::Info,
|
||||||
|
) -> <Self as OutboundConnectionUpgrade<S>>::Future {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
let (listener_noise_peer_id, mut socket) = noise::Config::new(&self.noise_keypair)
|
let (listener_noise_peer_id, mut socket) = noise::Config::new(&self.noise_keypair)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ mod ping;
|
|||||||
|
|
||||||
/// The request-response messages and behavior
|
/// The request-response messages and behavior
|
||||||
mod reqres;
|
mod reqres;
|
||||||
use reqres::{RequestId, Request, Response};
|
use reqres::{InboundRequestId, Request, Response};
|
||||||
|
|
||||||
/// The gossip messages and behavior
|
/// The gossip messages and behavior
|
||||||
mod gossip;
|
mod gossip;
|
||||||
@@ -66,14 +66,6 @@ use dial::DialTask;
|
|||||||
|
|
||||||
const PORT: u16 = 30563; // 5132 ^ (('c' << 8) | 'o')
|
const PORT: u16 = 30563; // 5132 ^ (('c' << 8) | 'o')
|
||||||
|
|
||||||
// usize::max, manually implemented, as max isn't a const fn
|
|
||||||
const MAX_LIBP2P_MESSAGE_SIZE: usize =
|
|
||||||
if gossip::MAX_LIBP2P_GOSSIP_MESSAGE_SIZE > reqres::MAX_LIBP2P_REQRES_MESSAGE_SIZE {
|
|
||||||
gossip::MAX_LIBP2P_GOSSIP_MESSAGE_SIZE
|
|
||||||
} else {
|
|
||||||
reqres::MAX_LIBP2P_REQRES_MESSAGE_SIZE
|
|
||||||
};
|
|
||||||
|
|
||||||
fn peer_id_from_public(public: PublicKey) -> PeerId {
|
fn peer_id_from_public(public: PublicKey) -> PeerId {
|
||||||
// 0 represents the identity Multihash, that no hash was performed
|
// 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
|
// It's an internal constant so we can't refer to the constant inside libp2p
|
||||||
@@ -143,9 +135,9 @@ struct Libp2pInner {
|
|||||||
signed_cosigns: Mutex<mpsc::UnboundedReceiver<SignedCosign>>,
|
signed_cosigns: Mutex<mpsc::UnboundedReceiver<SignedCosign>>,
|
||||||
signed_cosigns_send: mpsc::UnboundedSender<SignedCosign>,
|
signed_cosigns_send: mpsc::UnboundedSender<SignedCosign>,
|
||||||
|
|
||||||
heartbeat_requests: Mutex<mpsc::UnboundedReceiver<(RequestId, ValidatorSet, [u8; 32])>>,
|
heartbeat_requests: Mutex<mpsc::UnboundedReceiver<(InboundRequestId, ValidatorSet, [u8; 32])>>,
|
||||||
notable_cosign_requests: Mutex<mpsc::UnboundedReceiver<(RequestId, [u8; 32])>>,
|
notable_cosign_requests: Mutex<mpsc::UnboundedReceiver<(InboundRequestId, [u8; 32])>>,
|
||||||
inbound_request_responses: mpsc::UnboundedSender<(RequestId, Response)>,
|
inbound_request_responses: mpsc::UnboundedSender<(InboundRequestId, Response)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The libp2p-backed P2P implementation.
|
/// The libp2p-backed P2P implementation.
|
||||||
@@ -176,19 +168,9 @@ impl Libp2p {
|
|||||||
Ok(OnlyValidators { serai_key: serai_key.clone(), noise_keypair: noise_keypair.clone() })
|
Ok(OnlyValidators { serai_key: serai_key.clone(), noise_keypair: noise_keypair.clone() })
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_yamux = || {
|
|
||||||
let mut config = yamux::Config::default();
|
|
||||||
// 1 MiB default + max message size
|
|
||||||
config.set_max_buffer_size((1024 * 1024) + MAX_LIBP2P_MESSAGE_SIZE);
|
|
||||||
// 256 KiB default + max message size
|
|
||||||
config
|
|
||||||
.set_receive_window_size(((256 * 1024) + MAX_LIBP2P_MESSAGE_SIZE).try_into().unwrap());
|
|
||||||
config
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut swarm = SwarmBuilder::with_existing_identity(identity::Keypair::generate_ed25519())
|
let mut swarm = SwarmBuilder::with_existing_identity(identity::Keypair::generate_ed25519())
|
||||||
.with_tokio()
|
.with_tokio()
|
||||||
.with_tcp(TcpConfig::default().nodelay(true), new_only_validators, new_yamux)
|
.with_tcp(TcpConfig::default().nodelay(true), new_only_validators, yamux::Config::default)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.with_behaviour(|_| Behavior {
|
.with_behaviour(|_| Behavior {
|
||||||
allow_list: allow_block_list::Behaviour::default(),
|
allow_list: allow_block_list::Behaviour::default(),
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use futures_util::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
|
|||||||
use libp2p::request_response::{
|
use libp2p::request_response::{
|
||||||
self, Codec as CodecTrait, Event as GenericEvent, Config, Behaviour, ProtocolSupport,
|
self, Codec as CodecTrait, Event as GenericEvent, Config, Behaviour, ProtocolSupport,
|
||||||
};
|
};
|
||||||
pub use request_response::{RequestId, Message};
|
pub use request_response::{InboundRequestId, Message};
|
||||||
|
|
||||||
use serai_cosign::SignedCosign;
|
use serai_cosign::SignedCosign;
|
||||||
|
|
||||||
@@ -129,7 +129,6 @@ pub(crate) type Event = GenericEvent<Request, Response>;
|
|||||||
|
|
||||||
pub(crate) type Behavior = Behaviour<Codec>;
|
pub(crate) type Behavior = Behaviour<Codec>;
|
||||||
pub(crate) fn new_behavior() -> Behavior {
|
pub(crate) fn new_behavior() -> Behavior {
|
||||||
let mut config = Config::default();
|
let config = Config::default().with_request_timeout(Duration::from_secs(5));
|
||||||
config.set_request_timeout(Duration::from_secs(5));
|
|
||||||
Behavior::new([(PROTOCOL, ProtocolSupport::Full)], config)
|
Behavior::new([(PROTOCOL, ProtocolSupport::Full)], config)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use serai_cosign::SignedCosign;
|
|||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
use libp2p::{
|
use libp2p::{
|
||||||
identity::PeerId,
|
identity::PeerId,
|
||||||
request_response::{RequestId, ResponseChannel},
|
request_response::{InboundRequestId, OutboundRequestId, ResponseChannel},
|
||||||
swarm::{dial_opts::DialOpts, SwarmEvent, Swarm},
|
swarm::{dial_opts::DialOpts, SwarmEvent, Swarm},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -65,12 +65,12 @@ pub(crate) struct SwarmTask {
|
|||||||
tributary_gossip: mpsc::UnboundedSender<([u8; 32], Vec<u8>)>,
|
tributary_gossip: mpsc::UnboundedSender<([u8; 32], Vec<u8>)>,
|
||||||
|
|
||||||
outbound_requests: mpsc::UnboundedReceiver<(PeerId, Request, oneshot::Sender<Response>)>,
|
outbound_requests: mpsc::UnboundedReceiver<(PeerId, Request, oneshot::Sender<Response>)>,
|
||||||
outbound_request_responses: HashMap<RequestId, oneshot::Sender<Response>>,
|
outbound_request_responses: HashMap<OutboundRequestId, oneshot::Sender<Response>>,
|
||||||
|
|
||||||
inbound_request_response_channels: HashMap<RequestId, ResponseChannel<Response>>,
|
inbound_request_response_channels: HashMap<InboundRequestId, ResponseChannel<Response>>,
|
||||||
heartbeat_requests: mpsc::UnboundedSender<(RequestId, ValidatorSet, [u8; 32])>,
|
heartbeat_requests: mpsc::UnboundedSender<(InboundRequestId, ValidatorSet, [u8; 32])>,
|
||||||
notable_cosign_requests: mpsc::UnboundedSender<(RequestId, [u8; 32])>,
|
notable_cosign_requests: mpsc::UnboundedSender<(InboundRequestId, [u8; 32])>,
|
||||||
inbound_request_responses: mpsc::UnboundedReceiver<(RequestId, Response)>,
|
inbound_request_responses: mpsc::UnboundedReceiver<(InboundRequestId, Response)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SwarmTask {
|
impl SwarmTask {
|
||||||
@@ -222,24 +222,20 @@ impl SwarmTask {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SwarmEvent::Behaviour(
|
SwarmEvent::Behaviour(event) => {
|
||||||
BehaviorEvent::AllowList(event) | BehaviorEvent::ConnectionLimits(event)
|
match event {
|
||||||
) => {
|
BehaviorEvent::AllowList(event) | BehaviorEvent::ConnectionLimits(event) => {
|
||||||
// This *is* an exhaustive match as these events are empty enums
|
// This *is* an exhaustive match as these events are empty enums
|
||||||
match event {}
|
match event {}
|
||||||
}
|
}
|
||||||
SwarmEvent::Behaviour(
|
BehaviorEvent::Ping(ping::Event { peer: _, connection, result, }) => {
|
||||||
BehaviorEvent::Ping(ping::Event { peer: _, connection, result, })
|
|
||||||
) => {
|
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
self.swarm.close_connection(connection);
|
self.swarm.close_connection(connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SwarmEvent::Behaviour(BehaviorEvent::Reqres(event)) => {
|
BehaviorEvent::Reqres(event) => self.handle_reqres(event),
|
||||||
self.handle_reqres(event)
|
BehaviorEvent::Gossip(event) => self.handle_gossip(event),
|
||||||
}
|
}
|
||||||
SwarmEvent::Behaviour(BehaviorEvent::Gossip(event)) => {
|
|
||||||
self.handle_gossip(event)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't handle any of these
|
// We don't handle any of these
|
||||||
@@ -250,7 +246,14 @@ impl SwarmTask {
|
|||||||
SwarmEvent::ExpiredListenAddr { .. } |
|
SwarmEvent::ExpiredListenAddr { .. } |
|
||||||
SwarmEvent::ListenerClosed { .. } |
|
SwarmEvent::ListenerClosed { .. } |
|
||||||
SwarmEvent::ListenerError { .. } |
|
SwarmEvent::ListenerError { .. } |
|
||||||
SwarmEvent::Dialing { .. } => {}
|
SwarmEvent::Dialing { .. } |
|
||||||
|
SwarmEvent::NewExternalAddrCandidate { .. } |
|
||||||
|
SwarmEvent::ExternalAddrConfirmed { .. } |
|
||||||
|
SwarmEvent::ExternalAddrExpired { .. } |
|
||||||
|
SwarmEvent::NewExternalAddrOfPeer { .. } => {}
|
||||||
|
|
||||||
|
// Requires as SwarmEvent is non-exhaustive
|
||||||
|
_ => log::warn!("unhandled SwarmEvent: {event:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,9 +324,9 @@ impl SwarmTask {
|
|||||||
|
|
||||||
outbound_requests: mpsc::UnboundedReceiver<(PeerId, Request, oneshot::Sender<Response>)>,
|
outbound_requests: mpsc::UnboundedReceiver<(PeerId, Request, oneshot::Sender<Response>)>,
|
||||||
|
|
||||||
heartbeat_requests: mpsc::UnboundedSender<(RequestId, ValidatorSet, [u8; 32])>,
|
heartbeat_requests: mpsc::UnboundedSender<(InboundRequestId, ValidatorSet, [u8; 32])>,
|
||||||
notable_cosign_requests: mpsc::UnboundedSender<(RequestId, [u8; 32])>,
|
notable_cosign_requests: mpsc::UnboundedSender<(InboundRequestId, [u8; 32])>,
|
||||||
inbound_request_responses: mpsc::UnboundedReceiver<(RequestId, Response)>,
|
inbound_request_responses: mpsc::UnboundedReceiver<(InboundRequestId, Response)>,
|
||||||
) {
|
) {
|
||||||
tokio::spawn(
|
tokio::spawn(
|
||||||
SwarmTask {
|
SwarmTask {
|
||||||
|
|||||||
Reference in New Issue
Block a user