Merge pull request #4573 from nymtech/feature/axum-upgrade
upgraded axum and related deps to the most recent version
This commit is contained in:
Generated
+1267
-3132
File diff suppressed because it is too large
Load Diff
+7
-5
@@ -160,7 +160,8 @@ license = "Apache-2.0"
|
||||
[workspace.dependencies]
|
||||
anyhow = "1.0.71"
|
||||
async-trait = "0.1.68"
|
||||
axum = "0.6.20"
|
||||
axum = "0.7.5"
|
||||
axum-extra = "0.9.3"
|
||||
base64 = "0.21.4"
|
||||
bs58 = "0.5.0"
|
||||
bip39 = { version = "2.0.0", features = ["zeroize"] }
|
||||
@@ -171,15 +172,16 @@ dotenvy = "0.15.6"
|
||||
futures = "0.3.28"
|
||||
generic-array = "0.14.7"
|
||||
getrandom = "0.2.10"
|
||||
headers = "0.4.0"
|
||||
humantime-serde = "1.1.1"
|
||||
hyper = "0.14.27"
|
||||
hyper = "1.3.1"
|
||||
k256 = "0.13"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4"
|
||||
once_cell = "1.7.2"
|
||||
parking_lot = "0.12.1"
|
||||
rand = "0.8.5"
|
||||
reqwest = { version = "0.11.22", default-features = false }
|
||||
reqwest = { version = "0.12.4", default-features = false }
|
||||
schemars = "0.8.1"
|
||||
serde = "1.0.152"
|
||||
serde_json = "1.0.91"
|
||||
@@ -193,8 +195,8 @@ tokio-tungstenite = { version = "0.20.1" }
|
||||
tracing = "0.1.37"
|
||||
tungstenite = { version = "0.20.1", default-features = false }
|
||||
ts-rs = "7.0.0"
|
||||
utoipa = "3.5.0"
|
||||
utoipa-swagger-ui = "3.1.5"
|
||||
utoipa = "4.2.0"
|
||||
utoipa-swagger-ui = "6.0.0"
|
||||
url = "2.4"
|
||||
zeroize = "1.6.0"
|
||||
|
||||
|
||||
+2
-2
@@ -37,7 +37,7 @@ nym-config = { path = "../common/config" }
|
||||
nym-ephemera-common = { path = "../common/cosmwasm-smart-contracts/ephemera" }
|
||||
pretty_env_logger = "0.4"
|
||||
refinery = { version = "0.8.7", features = ["rusqlite"], optional = true }
|
||||
reqwest = { version = "0.11.22", default_features = false, features = ["rustls-tls", "json"] }
|
||||
reqwest = { version = "0.12.4", default_features = false, features = ["rustls-tls", "json"] }
|
||||
# Rocksdb kills compilation times and we're not currently using it. The reason
|
||||
# we comment it out is that rust-analyzer runs with --all-features
|
||||
#rocksdb = { version = "0.21.0", optional = true }
|
||||
@@ -46,7 +46,7 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
serde_derive = "1.0.149"
|
||||
serde_json = "1.0.91"
|
||||
thiserror = { workspace = true }
|
||||
tokio = { version = "1", features = ["macros", "net","rt-multi-thread"] }
|
||||
tokio = { version = "1", features = ["macros", "net", "rt-multi-thread"] }
|
||||
tokio-tungstenite = { workspace = true }
|
||||
tokio-util = { workspace = true, features = ["full"] }
|
||||
toml = "0.7.0"
|
||||
|
||||
+12
-5
@@ -5,7 +5,7 @@ use crate::config::Config;
|
||||
use crate::error::GatewayError;
|
||||
use crate::helpers::load_public_key;
|
||||
use ipnetwork::IpNetwork;
|
||||
use log::{debug, warn};
|
||||
use log::{debug, error, warn};
|
||||
use nym_bin_common::bin_info_owned;
|
||||
use nym_crypto::asymmetric::{encryption, identity};
|
||||
use nym_network_requester::RequestFilter;
|
||||
@@ -295,12 +295,19 @@ impl<'a> HttpApiBuilder<'a> {
|
||||
.ok()
|
||||
});
|
||||
|
||||
let bind_address = self.gateway_config.http.bind_address;
|
||||
let router = nym_node_http_api::NymNodeRouter::new(config, None, wg_state);
|
||||
|
||||
let server = router
|
||||
.build_server(&self.gateway_config.http.bind_address)?
|
||||
.with_task_client(task_client);
|
||||
tokio::spawn(async move { server.run().await });
|
||||
tokio::spawn(async move {
|
||||
let server = match router.build_server(&bind_address).await {
|
||||
Ok(server) => server.with_task_client(task_client),
|
||||
Err(err) => {
|
||||
error!("failed to create http server: {err}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
server.run().await
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
use crate::config::Config;
|
||||
use crate::error::MixnodeError;
|
||||
use crate::node::node_description::NodeDescription;
|
||||
use log::info;
|
||||
use log::{error, info};
|
||||
use nym_bin_common::bin_info_owned;
|
||||
use nym_crypto::asymmetric::{encryption, identity};
|
||||
use nym_node_http_api::api::api_requests;
|
||||
@@ -104,11 +104,17 @@ impl<'a> HttpApiBuilder<'a> {
|
||||
.with_landing_page_assets(self.mixnode_config.http.landing_page_assets_path.as_ref());
|
||||
|
||||
let router = nym_node_http_api::NymNodeRouter::new(config, None, None);
|
||||
let server = router
|
||||
// .with_merged(legacy::routes(self.legacy_mixnode, self.legacy_descriptor))
|
||||
.build_server(&bind_address)?
|
||||
.with_task_client(task_client);
|
||||
tokio::spawn(async move { server.run().await });
|
||||
|
||||
tokio::spawn(async move {
|
||||
let server = match router.build_server(&bind_address).await {
|
||||
Ok(server) => server.with_task_client(task_client),
|
||||
Err(err) => {
|
||||
error!("failed to create http server: {err}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
server.run().await
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ anyhow = "1.0"
|
||||
bip39 = { version = "2.0.0", features = ["zeroize"] }
|
||||
dirs = "4.0"
|
||||
eyre = "0.6.5"
|
||||
fix-path-env = { git = "https://github.com/tauri-apps/fix-path-env-rs", branch = "release"}
|
||||
fix-path-env = { git = "https://github.com/tauri-apps/fix-path-env-rs", branch = "release" }
|
||||
futures = "0.3"
|
||||
fern = { version = "0.6.1", features = ["colored"] }
|
||||
itertools = "0.10.5"
|
||||
@@ -31,7 +31,7 @@ log = { version = "0.4", features = ["serde"] }
|
||||
pretty_env_logger = "0.4.0"
|
||||
rand = "0.8"
|
||||
rand-07 = { package = "rand", version = "0.7.3" }
|
||||
reqwest = { version = "0.11.22", features = ["json", "socks"] }
|
||||
reqwest = { version = "0.12.4", features = ["json", "socks"] }
|
||||
rust-embed = { version = "6.4.2", features = ["include-exclude"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
@@ -46,17 +46,17 @@ tokio = { version = "1.24.1", features = ["sync", "time"] }
|
||||
url = "2.4"
|
||||
yaml-rust = "0.4"
|
||||
toml = "0.7"
|
||||
sentry = { version = "0.31.5", features = [ "anyhow" ] }
|
||||
sentry = { version = "0.31.5", features = ["anyhow"] }
|
||||
sentry-log = "0.31.5"
|
||||
dotenvy = "0.15.7"
|
||||
|
||||
nym-client-core = { path = "../../../common/client-core" }
|
||||
nym-api-requests = { path = "../../../nym-api/nym-api-requests" }
|
||||
nym-contracts-common = { path = "../../../common/cosmwasm-smart-contracts/contracts-common"}
|
||||
nym-contracts-common = { path = "../../../common/cosmwasm-smart-contracts/contracts-common" }
|
||||
nym-config = { path = "../../../common/config" }
|
||||
nym-crypto = { path = "../../../common/crypto" }
|
||||
nym-credential-storage = { path = "../../../common/credential-storage" }
|
||||
nym-bin-common = { path = "../../../common/bin-common"}
|
||||
nym-bin-common = { path = "../../../common/bin-common" }
|
||||
nym-socks5-client-core = { path = "../../../common/socks5-client-core" }
|
||||
nym-sphinx = { path = "../../../common/nymsphinx" }
|
||||
nym-task = { path = "../../../common/task" }
|
||||
|
||||
@@ -7,18 +7,16 @@ license.workspace = true
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
axum = { workspace = true, features = ["headers"] }
|
||||
# \/ will be needed once we update axum to 0.7
|
||||
#axum-extra = { version = "0.9.3", features = ["typed-header"] }
|
||||
#headers = "0.4"
|
||||
axum.workspace = true
|
||||
axum-extra = { workspace = true, features = ["typed-header"] }
|
||||
headers.workspace = true
|
||||
|
||||
# useful for `#[axum_macros::debug_handler]`
|
||||
#axum-macros = "0.3.8"
|
||||
hyper.workspace = true
|
||||
thiserror.workspace = true
|
||||
time = { workspace = true, features = ["serde"] }
|
||||
tokio = { workspace = true, features = ["macros"] }
|
||||
tower-http = { version = "0.4.4", features = ["fs"] }
|
||||
tower-http = { version = "0.5.2", features = ["fs"] }
|
||||
tracing.workspace = true
|
||||
utoipa = { workspace = true, features = ["axum_extras", "time"] }
|
||||
utoipa-swagger-ui = { workspace = true, features = ["axum"] }
|
||||
@@ -40,6 +38,7 @@ nym-wireguard = { path = "../../common/wireguard" }
|
||||
nym-wireguard-types = { path = "../../common/wireguard-types", features = ["verify"] }
|
||||
|
||||
[dev-dependencies]
|
||||
hyper.workspace = true
|
||||
dashmap.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::io;
|
||||
use std::net::SocketAddr;
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -9,7 +10,7 @@ pub enum NymNodeHttpError {
|
||||
#[error("failed to bind the HTTP API to {bind_address}: {source}")]
|
||||
HttpBindFailure {
|
||||
bind_address: SocketAddr,
|
||||
source: hyper::Error,
|
||||
source: io::Error,
|
||||
},
|
||||
|
||||
#[error("failed to use nym-node requests: {source}")]
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use axum::extract::connect_info::IntoMakeServiceWithConnectInfo;
|
||||
use axum::extract::ConnectInfo;
|
||||
use axum::middleware::AddExtension;
|
||||
use axum::serve::Serve;
|
||||
use axum::Router;
|
||||
use hyper::server::conn::AddrIncoming;
|
||||
use hyper::Server;
|
||||
use nym_task::TaskClient;
|
||||
use std::net::SocketAddr;
|
||||
use tracing::{debug, error, info};
|
||||
use tracing::{debug, error};
|
||||
|
||||
pub mod error;
|
||||
pub mod middleware;
|
||||
@@ -17,15 +18,18 @@ pub mod state;
|
||||
pub use error::NymNodeHttpError;
|
||||
pub use router::{api, landing_page, Config, NymNodeRouter};
|
||||
|
||||
// I guess this wasn't really meant to be extracted into separate type haha
|
||||
type InnerService = IntoMakeServiceWithConnectInfo<Router, SocketAddr>;
|
||||
type ConnectInfoExt = AddExtension<Router, ConnectInfo<SocketAddr>>;
|
||||
pub type ServeService = Serve<InnerService, ConnectInfoExt>;
|
||||
|
||||
pub struct NymNodeHTTPServer {
|
||||
task_client: Option<TaskClient>,
|
||||
inner: Server<AddrIncoming, IntoMakeServiceWithConnectInfo<Router, SocketAddr>>,
|
||||
inner: ServeService,
|
||||
}
|
||||
|
||||
impl NymNodeHTTPServer {
|
||||
pub(crate) fn new(
|
||||
inner: Server<AddrIncoming, IntoMakeServiceWithConnectInfo<Router, SocketAddr>>,
|
||||
) -> Self {
|
||||
pub(crate) fn new(inner: ServeService) -> Self {
|
||||
NymNodeHTTPServer {
|
||||
task_client: None,
|
||||
inner,
|
||||
@@ -38,9 +42,7 @@ impl NymNodeHTTPServer {
|
||||
self
|
||||
}
|
||||
|
||||
async fn run_server_forever(
|
||||
server: Server<AddrIncoming, IntoMakeServiceWithConnectInfo<Router, SocketAddr>>,
|
||||
) {
|
||||
async fn run_server_forever(server: ServeService) {
|
||||
if let Err(err) = server.await {
|
||||
error!("the HTTP server has terminated with the error: {err}");
|
||||
} else {
|
||||
@@ -49,7 +51,6 @@ impl NymNodeHTTPServer {
|
||||
}
|
||||
|
||||
pub async fn run(self) {
|
||||
info!("Started NymNodeHTTPServer on {}", self.inner.local_addr());
|
||||
if let Some(mut task_client) = self.task_client {
|
||||
tokio::select! {
|
||||
_ = task_client.recv_with_delay() => {
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use axum::{
|
||||
extract::ConnectInfo,
|
||||
http::{HeaderValue, Request},
|
||||
extract::{ConnectInfo, Request},
|
||||
http::{
|
||||
header::{HOST, USER_AGENT},
|
||||
HeaderValue,
|
||||
},
|
||||
middleware::Next,
|
||||
response::IntoResponse,
|
||||
};
|
||||
use colored::*;
|
||||
use hyper::header::{HOST, USER_AGENT};
|
||||
use std::net::SocketAddr;
|
||||
use tracing::info;
|
||||
|
||||
/// Simple logger for requests
|
||||
pub async fn logger<B>(
|
||||
pub async fn logger(
|
||||
ConnectInfo(addr): ConnectInfo<SocketAddr>,
|
||||
req: Request<B>,
|
||||
next: Next<B>,
|
||||
req: Request,
|
||||
next: Next,
|
||||
) -> impl IntoResponse {
|
||||
let method = req.method().to_string().green();
|
||||
let uri = req.uri().to_string().blue();
|
||||
|
||||
+3
-2
@@ -104,6 +104,7 @@ mod test {
|
||||
use crate::api::v1::gateway::client_interfaces::wireguard::{
|
||||
routes, WireguardAppState, WireguardAppStateInner,
|
||||
};
|
||||
use axum::body::to_bytes;
|
||||
use axum::body::Body;
|
||||
use axum::http::Request;
|
||||
use axum::http::StatusCode;
|
||||
@@ -203,7 +204,7 @@ mod test {
|
||||
nonce,
|
||||
gateway_data,
|
||||
wg_port: 8080,
|
||||
} = serde_json::from_slice(&hyper::body::to_bytes(response.into_body()).await.unwrap())
|
||||
} = serde_json::from_slice(&to_bytes(response.into_body(), usize::MAX).await.unwrap())
|
||||
.unwrap()
|
||||
else {
|
||||
panic!("invalid response")
|
||||
@@ -257,7 +258,7 @@ mod test {
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
|
||||
let clients: Vec<PeerPublicKey> =
|
||||
serde_json::from_slice(&hyper::body::to_bytes(response.into_body()).await.unwrap())
|
||||
serde_json::from_slice(&to_bytes(response.into_body(), usize::MAX).await.unwrap())
|
||||
.unwrap();
|
||||
|
||||
assert!(!clients.is_empty());
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
|
||||
use crate::state::metrics::MetricsAppState;
|
||||
use axum::extract::State;
|
||||
use axum::headers::authorization::Bearer;
|
||||
use axum::headers::Authorization;
|
||||
use axum::http::StatusCode;
|
||||
use axum::TypedHeader;
|
||||
use axum_extra::TypedHeader;
|
||||
use headers::authorization::Bearer;
|
||||
use headers::Authorization;
|
||||
use nym_metrics::metrics;
|
||||
|
||||
/// Returns `prometheus` compatible metrics
|
||||
|
||||
@@ -204,19 +204,22 @@ impl NymNodeRouter {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build_server(
|
||||
pub async fn build_server(
|
||||
self,
|
||||
bind_address: &SocketAddr,
|
||||
) -> Result<NymNodeHTTPServer, NymNodeHttpError> {
|
||||
let axum_server = axum::Server::try_bind(bind_address)
|
||||
let listener = tokio::net::TcpListener::bind(bind_address)
|
||||
.await
|
||||
.map_err(|source| NymNodeHttpError::HttpBindFailure {
|
||||
bind_address: *bind_address,
|
||||
source,
|
||||
})?
|
||||
.serve(
|
||||
self.inner
|
||||
.into_make_service_with_connect_info::<SocketAddr>(),
|
||||
);
|
||||
})?;
|
||||
|
||||
let axum_server = axum::serve(
|
||||
listener,
|
||||
self.inner
|
||||
.into_make_service_with_connect_info::<SocketAddr>(),
|
||||
);
|
||||
|
||||
Ok(NymNodeHTTPServer::new(axum_server))
|
||||
}
|
||||
|
||||
@@ -455,7 +455,7 @@ impl NymNode {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn build_http_server(&self) -> Result<NymNodeHTTPServer, NymNodeError> {
|
||||
pub(crate) async fn build_http_server(&self) -> Result<NymNodeHTTPServer, NymNodeError> {
|
||||
let host_details = sign_host_details(
|
||||
&self.config,
|
||||
self.x25519_sphinx_keys.public_key(),
|
||||
@@ -559,15 +559,23 @@ impl NymNode {
|
||||
.with_metrics_key(self.config.http.access_token.clone());
|
||||
|
||||
Ok(NymNodeRouter::new(config, Some(app_state), Some(wg_state))
|
||||
.build_server(&self.config.http.bind_address)?)
|
||||
.build_server(&self.config.http.bind_address)
|
||||
.await?)
|
||||
}
|
||||
|
||||
pub(crate) async fn run(self) -> Result<(), NymNodeError> {
|
||||
let mut task_manager = TaskManager::default().named("NymNode");
|
||||
let http_server = self
|
||||
.build_http_server()?
|
||||
.build_http_server()
|
||||
.await?
|
||||
.with_task_client(task_manager.subscribe_named("http-server"));
|
||||
tokio::spawn(async move { http_server.run().await });
|
||||
let bind_address = self.config.http.bind_address;
|
||||
tokio::spawn(async move {
|
||||
{
|
||||
info!("Started NymNodeHTTPServer on {bind_address}");
|
||||
http_server.run().await
|
||||
}
|
||||
});
|
||||
|
||||
match self.config.mode {
|
||||
NodeMode::Mixnode => {
|
||||
|
||||
@@ -32,7 +32,7 @@ itertools = "0.10"
|
||||
log = { version = "0.4", features = ["serde"] }
|
||||
once_cell = "1.7.2"
|
||||
pretty_env_logger = "0.4"
|
||||
reqwest = {version = "0.11.22", features = ["json"] }
|
||||
reqwest = { version = "0.12.4", features = ["json"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
serde_repr = "0.1"
|
||||
@@ -50,7 +50,7 @@ base64 = "0.13"
|
||||
zeroize = { version = "1.5", features = ["zeroize_derive", "serde"] }
|
||||
|
||||
cosmwasm-std = "1.3.0"
|
||||
cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch ="nym-temp/all-validator-features" }
|
||||
cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch = "nym-temp/all-validator-features" }
|
||||
|
||||
nym-validator-client = { path = "../../common/client-libs/validator-client" }
|
||||
nym-crypto = { path = "../../common/crypto", features = ["asymmetric"] }
|
||||
|
||||
@@ -9,7 +9,7 @@ license.workspace = true
|
||||
[dependencies]
|
||||
async-trait = { workspace = true }
|
||||
bip39 = { workspace = true }
|
||||
nym-client-core = { path = "../../../common/client-core", features = ["fs-surb-storage", "fs-gateways-storage"]}
|
||||
nym-client-core = { path = "../../../common/client-core", features = ["fs-surb-storage", "fs-gateways-storage"] }
|
||||
nym-crypto = { path = "../../../common/crypto" }
|
||||
nym-gateway-requests = { path = "../../../gateway/gateway-requests" }
|
||||
nym-bandwidth-controller = { path = "../../../common/bandwidth-controller" }
|
||||
@@ -48,7 +48,7 @@ tokio = { workspace = true, features = ["full"] }
|
||||
nym-bin-common = { path = "../../../common/bin-common" }
|
||||
|
||||
# extra dependencies for libp2p examples
|
||||
libp2p = { git = "https://github.com/ChainSafe/rust-libp2p.git", rev = "e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6", features = [ "identify", "macros", "ping", "tokio", "tcp", "dns", "websocket", "noise", "mplex", "yamux", "gossipsub" ]}
|
||||
#libp2p = { git = "https://github.com/ChainSafe/rust-libp2p.git", rev = "e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6", features = [ "identify", "macros", "ping", "tokio", "tcp", "dns", "websocket", "noise", "mplex", "yamux", "gossipsub" ]}
|
||||
tokio-stream = "0.1.12"
|
||||
tokio-util = { workspace = true, features = ["codec"] }
|
||||
parking_lot = "0.12"
|
||||
|
||||
@@ -45,127 +45,129 @@
|
||||
//! If a participant exits (Control-C or otherwise) the other peers will receive an mDNS expired
|
||||
//! event and remove the expired peer from the list of known peers.
|
||||
|
||||
use crate::rust_libp2p_nym::transport::NymTransport;
|
||||
use futures::{prelude::*, select};
|
||||
use libp2p::Multiaddr;
|
||||
use libp2p::{
|
||||
core::muxing::StreamMuxerBox,
|
||||
gossipsub, identity,
|
||||
swarm::NetworkBehaviour,
|
||||
swarm::{SwarmBuilder, SwarmEvent},
|
||||
PeerId, Transport,
|
||||
};
|
||||
use log::{error, info, LevelFilter};
|
||||
use nym_sdk::mixnet::MixnetClient;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
// use crate::rust_libp2p_nym::transport::NymTransport;
|
||||
// use futures::{prelude::*, select};
|
||||
// use libp2p::Multiaddr;
|
||||
// use libp2p::{
|
||||
// core::muxing::StreamMuxerBox,
|
||||
// gossipsub, identity,
|
||||
// swarm::NetworkBehaviour,
|
||||
// swarm::{SwarmBuilder, SwarmEvent},
|
||||
// PeerId, Transport,
|
||||
// };
|
||||
// use log::{error, info, LevelFilter};
|
||||
// use nym_sdk::mixnet::MixnetClient;
|
||||
// use std::collections::hash_map::DefaultHasher;
|
||||
use std::error::Error;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::time::Duration;
|
||||
use tokio::io;
|
||||
use tokio_util::codec;
|
||||
// use std::hash::{Hash, Hasher};
|
||||
// use std::time::Duration;
|
||||
// use tokio::io;
|
||||
// use tokio_util::codec;
|
||||
|
||||
#[path = "../libp2p_shared/lib.rs"]
|
||||
mod rust_libp2p_nym;
|
||||
|
||||
// We create a custom network behaviour that uses Gossipsub
|
||||
#[derive(NetworkBehaviour)]
|
||||
struct Behaviour {
|
||||
gossipsub: gossipsub::Behaviour,
|
||||
}
|
||||
// #[path = "../libp2p_shared/lib.rs"]
|
||||
// mod rust_libp2p_nym;
|
||||
//
|
||||
// // We create a custom network behaviour that uses Gossipsub
|
||||
// #[derive(NetworkBehaviour)]
|
||||
// struct Behaviour {
|
||||
// gossipsub: gossipsub::Behaviour,
|
||||
// }
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
pretty_env_logger::formatted_timed_builder()
|
||||
.filter_level(LevelFilter::Warn)
|
||||
.filter(Some("libp2p_chat"), LevelFilter::Info)
|
||||
.init();
|
||||
unimplemented!("temporarily disabled")
|
||||
|
||||
// Create a random PeerId
|
||||
let id_keys = identity::Keypair::generate_ed25519();
|
||||
let local_peer_id = PeerId::from(id_keys.public());
|
||||
info!("Local peer id: {local_peer_id}");
|
||||
|
||||
// To content-address message, we can take the hash of message and use it as an ID.
|
||||
let message_id_fn = |message: &gossipsub::Message| {
|
||||
let mut s = DefaultHasher::new();
|
||||
message.data.hash(&mut s);
|
||||
gossipsub::MessageId::from(s.finish().to_string())
|
||||
};
|
||||
|
||||
// Set a custom gossipsub configuration
|
||||
let gossipsub_config = gossipsub::ConfigBuilder::default()
|
||||
.heartbeat_interval(Duration::from_secs(10)) // This is set to aid debugging by not cluttering the log space
|
||||
.validation_mode(gossipsub::ValidationMode::Strict) // This sets the kind of message validation. The default is Strict (enforce message signing)
|
||||
.message_id_fn(message_id_fn) // content-address messages. No two messages of the same content will be propagated.
|
||||
.build()
|
||||
.expect("Valid config");
|
||||
|
||||
// build a gossipsub network behaviour
|
||||
let mut gossipsub = gossipsub::Behaviour::new(
|
||||
gossipsub::MessageAuthenticity::Signed(id_keys),
|
||||
gossipsub_config,
|
||||
)
|
||||
.expect("Correct configuration");
|
||||
// Create a Gossipsub topic
|
||||
let topic = gossipsub::IdentTopic::new("test-net");
|
||||
// subscribes to our topic
|
||||
gossipsub.subscribe(&topic)?;
|
||||
|
||||
let client = MixnetClient::connect_new().await.unwrap();
|
||||
info!("client address: {}", client.nym_address());
|
||||
|
||||
let local_key = identity::Keypair::generate_ed25519();
|
||||
let local_peer_id = PeerId::from(local_key.public());
|
||||
info!("Local peer id: {local_peer_id:?}");
|
||||
|
||||
let transport = NymTransport::new(client, local_key).await?;
|
||||
|
||||
let mut swarm = SwarmBuilder::with_tokio_executor(
|
||||
transport
|
||||
.map(|a, _| (a.0, StreamMuxerBox::new(a.1)))
|
||||
.boxed(),
|
||||
Behaviour { gossipsub },
|
||||
local_peer_id,
|
||||
)
|
||||
.build();
|
||||
|
||||
if let Some(addr) = std::env::args().nth(1) {
|
||||
let remote: Multiaddr = addr.parse()?;
|
||||
swarm.dial(remote)?;
|
||||
info!("Dialed {addr}")
|
||||
}
|
||||
|
||||
// Read full lines from stdin
|
||||
let mut stdin = codec::FramedRead::new(io::stdin(), codec::LinesCodec::new()).fuse();
|
||||
|
||||
info!("Enter messages via STDIN and they will be sent to connected peers using Gossipsub");
|
||||
|
||||
// Kick it off
|
||||
loop {
|
||||
select! {
|
||||
line = stdin.select_next_some() => {
|
||||
if let Err(e) = swarm
|
||||
.behaviour_mut().gossipsub
|
||||
.publish(topic.clone(), line.expect("Stdin not to close").as_bytes()) {
|
||||
error!("Publish error: {e:?}");
|
||||
}
|
||||
},
|
||||
event = swarm.select_next_some() => {
|
||||
match event {
|
||||
SwarmEvent::Behaviour(BehaviourEvent::Gossipsub(gossipsub::Event::Message {
|
||||
propagation_source: peer_id,
|
||||
message_id: id,
|
||||
message,
|
||||
})) => info!(
|
||||
"Got message: '{}' with id: {id} from peer: {peer_id}",
|
||||
String::from_utf8_lossy(&message.data),
|
||||
),
|
||||
SwarmEvent::NewListenAddr { address, .. } => {
|
||||
info!("Local node is listening on {address}");
|
||||
}
|
||||
other => {info!("other event: {:?}", other)}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// pretty_env_logger::formatted_timed_builder()
|
||||
// .filter_level(LevelFilter::Warn)
|
||||
// .filter(Some("libp2p_chat"), LevelFilter::Info)
|
||||
// .init();
|
||||
//
|
||||
// // Create a random PeerId
|
||||
// let id_keys = identity::Keypair::generate_ed25519();
|
||||
// let local_peer_id = PeerId::from(id_keys.public());
|
||||
// info!("Local peer id: {local_peer_id}");
|
||||
//
|
||||
// // To content-address message, we can take the hash of message and use it as an ID.
|
||||
// let message_id_fn = |message: &gossipsub::Message| {
|
||||
// let mut s = DefaultHasher::new();
|
||||
// message.data.hash(&mut s);
|
||||
// gossipsub::MessageId::from(s.finish().to_string())
|
||||
// };
|
||||
//
|
||||
// // Set a custom gossipsub configuration
|
||||
// let gossipsub_config = gossipsub::ConfigBuilder::default()
|
||||
// .heartbeat_interval(Duration::from_secs(10)) // This is set to aid debugging by not cluttering the log space
|
||||
// .validation_mode(gossipsub::ValidationMode::Strict) // This sets the kind of message validation. The default is Strict (enforce message signing)
|
||||
// .message_id_fn(message_id_fn) // content-address messages. No two messages of the same content will be propagated.
|
||||
// .build()
|
||||
// .expect("Valid config");
|
||||
//
|
||||
// // build a gossipsub network behaviour
|
||||
// let mut gossipsub = gossipsub::Behaviour::new(
|
||||
// gossipsub::MessageAuthenticity::Signed(id_keys),
|
||||
// gossipsub_config,
|
||||
// )
|
||||
// .expect("Correct configuration");
|
||||
// // Create a Gossipsub topic
|
||||
// let topic = gossipsub::IdentTopic::new("test-net");
|
||||
// // subscribes to our topic
|
||||
// gossipsub.subscribe(&topic)?;
|
||||
//
|
||||
// let client = MixnetClient::connect_new().await.unwrap();
|
||||
// info!("client address: {}", client.nym_address());
|
||||
//
|
||||
// let local_key = identity::Keypair::generate_ed25519();
|
||||
// let local_peer_id = PeerId::from(local_key.public());
|
||||
// info!("Local peer id: {local_peer_id:?}");
|
||||
//
|
||||
// let transport = NymTransport::new(client, local_key).await?;
|
||||
//
|
||||
// let mut swarm = SwarmBuilder::with_tokio_executor(
|
||||
// transport
|
||||
// .map(|a, _| (a.0, StreamMuxerBox::new(a.1)))
|
||||
// .boxed(),
|
||||
// Behaviour { gossipsub },
|
||||
// local_peer_id,
|
||||
// )
|
||||
// .build();
|
||||
//
|
||||
// if let Some(addr) = std::env::args().nth(1) {
|
||||
// let remote: Multiaddr = addr.parse()?;
|
||||
// swarm.dial(remote)?;
|
||||
// info!("Dialed {addr}")
|
||||
// }
|
||||
//
|
||||
// // Read full lines from stdin
|
||||
// let mut stdin = codec::FramedRead::new(io::stdin(), codec::LinesCodec::new()).fuse();
|
||||
//
|
||||
// info!("Enter messages via STDIN and they will be sent to connected peers using Gossipsub");
|
||||
//
|
||||
// // Kick it off
|
||||
// loop {
|
||||
// select! {
|
||||
// line = stdin.select_next_some() => {
|
||||
// if let Err(e) = swarm
|
||||
// .behaviour_mut().gossipsub
|
||||
// .publish(topic.clone(), line.expect("Stdin not to close").as_bytes()) {
|
||||
// error!("Publish error: {e:?}");
|
||||
// }
|
||||
// },
|
||||
// event = swarm.select_next_some() => {
|
||||
// match event {
|
||||
// SwarmEvent::Behaviour(BehaviourEvent::Gossipsub(gossipsub::Event::Message {
|
||||
// propagation_source: peer_id,
|
||||
// message_id: id,
|
||||
// message,
|
||||
// })) => info!(
|
||||
// "Got message: '{}' with id: {id} from peer: {peer_id}",
|
||||
// String::from_utf8_lossy(&message.data),
|
||||
// ),
|
||||
// SwarmEvent::NewListenAddr { address, .. } => {
|
||||
// info!("Local node is listening on {address}");
|
||||
// }
|
||||
// other => {info!("other event: {:?}", other)}
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -40,102 +40,104 @@
|
||||
//! The two nodes establish a connection, negotiate the ping protocol
|
||||
//! and begin pinging each other.
|
||||
|
||||
use libp2p::futures::StreamExt;
|
||||
use libp2p::ping::Success;
|
||||
use libp2p::swarm::{keep_alive, NetworkBehaviour, SwarmEvent};
|
||||
use libp2p::{identity, ping, Multiaddr, PeerId};
|
||||
use log::{debug, info, LevelFilter};
|
||||
// use libp2p::futures::StreamExt;
|
||||
// use libp2p::ping::Success;
|
||||
// use libp2p::swarm::{keep_alive, NetworkBehaviour, SwarmEvent};
|
||||
// use libp2p::{identity, ping, Multiaddr, PeerId};
|
||||
// use log::{debug, info, LevelFilter};
|
||||
use std::error::Error;
|
||||
use std::time::Duration;
|
||||
|
||||
#[path = "../libp2p_shared/lib.rs"]
|
||||
mod rust_libp2p_nym;
|
||||
// use std::time::Duration;
|
||||
//
|
||||
// #[path = "../libp2p_shared/lib.rs"]
|
||||
// mod rust_libp2p_nym;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
pretty_env_logger::formatted_timed_builder()
|
||||
.filter_level(LevelFilter::Warn)
|
||||
.filter(Some("libp2p_ping"), LevelFilter::Debug)
|
||||
.init();
|
||||
|
||||
let local_key = identity::Keypair::generate_ed25519();
|
||||
let local_peer_id = PeerId::from(local_key.public());
|
||||
info!("Local peer id: {local_peer_id:?}");
|
||||
|
||||
#[cfg(not(feature = "libp2p-vanilla"))]
|
||||
let mut swarm = {
|
||||
debug!("Running `ping` example using NymTransport");
|
||||
use libp2p::core::{muxing::StreamMuxerBox, transport::Transport};
|
||||
use libp2p::swarm::SwarmBuilder;
|
||||
use rust_libp2p_nym::transport::NymTransport;
|
||||
|
||||
let client = nym_sdk::mixnet::MixnetClient::connect_new().await.unwrap();
|
||||
|
||||
let transport = NymTransport::new(client, local_key.clone()).await?;
|
||||
SwarmBuilder::with_tokio_executor(
|
||||
transport
|
||||
.map(|a, _| (a.0, StreamMuxerBox::new(a.1)))
|
||||
.boxed(),
|
||||
Behaviour::default(),
|
||||
local_peer_id,
|
||||
)
|
||||
.build()
|
||||
};
|
||||
|
||||
#[cfg(feature = "libp2p-vanilla")]
|
||||
let mut swarm = {
|
||||
debug!("Running `ping` example using the vanilla libp2p tokio_development_transport");
|
||||
let transport = libp2p::tokio_development_transport(local_key)?;
|
||||
let mut swarm =
|
||||
libp2p::Swarm::with_tokio_executor(transport, Behaviour::default(), local_peer_id);
|
||||
swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
|
||||
swarm
|
||||
};
|
||||
|
||||
// Dial the peer identified by the multi-address given as the second
|
||||
// command-line argument, if any.
|
||||
if let Some(addr) = std::env::args().nth(1) {
|
||||
let remote: Multiaddr = addr.parse()?;
|
||||
swarm.dial(remote)?;
|
||||
info!("Dialed {addr}")
|
||||
}
|
||||
|
||||
let mut total_ping_rtt: Duration = Duration::from_micros(0);
|
||||
let mut counter: u128 = 0;
|
||||
loop {
|
||||
match swarm.select_next_some().await {
|
||||
SwarmEvent::NewListenAddr { address, .. } => info!("Listening on {address:?}"),
|
||||
SwarmEvent::Behaviour(event) => {
|
||||
// Get the round-trip duration for the pings.
|
||||
// This value is already captured in the BehaviourEvent::Ping's `Success::Ping`
|
||||
// field.
|
||||
debug!("{event:?}");
|
||||
if let BehaviourEvent::Ping(ping_event) = event {
|
||||
let result: Success = ping_event.result?;
|
||||
match result {
|
||||
Success::Ping { rtt } => {
|
||||
counter += 1;
|
||||
total_ping_rtt += rtt;
|
||||
let average_ping_rtt = Duration::from_micros(
|
||||
(total_ping_rtt.as_micros() / counter).try_into().unwrap(),
|
||||
);
|
||||
info!("Ping RTT: {rtt:?} AVERAGE RTT: ({counter} pings): {average_ping_rtt:?}");
|
||||
}
|
||||
Success::Pong => info!("Pong Event"),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Our network behaviour.
|
||||
///
|
||||
/// For illustrative purposes, this includes the [`KeepAlive`](behaviour::KeepAlive) behaviour so a continuous sequence of
|
||||
/// pings can be observed.
|
||||
#[derive(NetworkBehaviour, Default)]
|
||||
struct Behaviour {
|
||||
keep_alive: keep_alive::Behaviour,
|
||||
ping: ping::Behaviour,
|
||||
unimplemented!("temporarily disabled")
|
||||
//
|
||||
// pretty_env_logger::formatted_timed_builder()
|
||||
// .filter_level(LevelFilter::Warn)
|
||||
// .filter(Some("libp2p_ping"), LevelFilter::Debug)
|
||||
// .init();
|
||||
//
|
||||
// let local_key = identity::Keypair::generate_ed25519();
|
||||
// let local_peer_id = PeerId::from(local_key.public());
|
||||
// info!("Local peer id: {local_peer_id:?}");
|
||||
//
|
||||
// #[cfg(not(feature = "libp2p-vanilla"))]
|
||||
// let mut swarm = {
|
||||
// debug!("Running `ping` example using NymTransport");
|
||||
// use libp2p::core::{muxing::StreamMuxerBox, transport::Transport};
|
||||
// use libp2p::swarm::SwarmBuilder;
|
||||
// use rust_libp2p_nym::transport::NymTransport;
|
||||
//
|
||||
// let client = nym_sdk::mixnet::MixnetClient::connect_new().await.unwrap();
|
||||
//
|
||||
// let transport = NymTransport::new(client, local_key.clone()).await?;
|
||||
// SwarmBuilder::with_tokio_executor(
|
||||
// transport
|
||||
// .map(|a, _| (a.0, StreamMuxerBox::new(a.1)))
|
||||
// .boxed(),
|
||||
// Behaviour::default(),
|
||||
// local_peer_id,
|
||||
// )
|
||||
// .build()
|
||||
// };
|
||||
//
|
||||
// #[cfg(feature = "libp2p-vanilla")]
|
||||
// let mut swarm = {
|
||||
// debug!("Running `ping` example using the vanilla libp2p tokio_development_transport");
|
||||
// let transport = libp2p::tokio_development_transport(local_key)?;
|
||||
// let mut swarm =
|
||||
// libp2p::Swarm::with_tokio_executor(transport, Behaviour::default(), local_peer_id);
|
||||
// swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?;
|
||||
// swarm
|
||||
// };
|
||||
//
|
||||
// // Dial the peer identified by the multi-address given as the second
|
||||
// // command-line argument, if any.
|
||||
// if let Some(addr) = std::env::args().nth(1) {
|
||||
// let remote: Multiaddr = addr.parse()?;
|
||||
// swarm.dial(remote)?;
|
||||
// info!("Dialed {addr}")
|
||||
// }
|
||||
//
|
||||
// let mut total_ping_rtt: Duration = Duration::from_micros(0);
|
||||
// let mut counter: u128 = 0;
|
||||
// loop {
|
||||
// match swarm.select_next_some().await {
|
||||
// SwarmEvent::NewListenAddr { address, .. } => info!("Listening on {address:?}"),
|
||||
// SwarmEvent::Behaviour(event) => {
|
||||
// // Get the round-trip duration for the pings.
|
||||
// // This value is already captured in the BehaviourEvent::Ping's `Success::Ping`
|
||||
// // field.
|
||||
// debug!("{event:?}");
|
||||
// if let BehaviourEvent::Ping(ping_event) = event {
|
||||
// let result: Success = ping_event.result?;
|
||||
// match result {
|
||||
// Success::Ping { rtt } => {
|
||||
// counter += 1;
|
||||
// total_ping_rtt += rtt;
|
||||
// let average_ping_rtt = Duration::from_micros(
|
||||
// (total_ping_rtt.as_micros() / counter).try_into().unwrap(),
|
||||
// );
|
||||
// info!("Ping RTT: {rtt:?} AVERAGE RTT: ({counter} pings): {average_ping_rtt:?}");
|
||||
// }
|
||||
// Success::Pong => info!("Pong Event"),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// _ => {}
|
||||
// }
|
||||
// }
|
||||
}
|
||||
//
|
||||
// /// Our network behaviour.
|
||||
// ///
|
||||
// /// For illustrative purposes, this includes the [`KeepAlive`](behaviour::KeepAlive) behaviour so a continuous sequence of
|
||||
// /// pings can be observed.
|
||||
// #[derive(NetworkBehaviour, Default)]
|
||||
// struct Behaviour {
|
||||
// keep_alive: keep_alive::Behaviour,
|
||||
// ping: ping::Behaviour,
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user