[mixnode] replace rocket with axum (#4071)
* axum-equivalent mixnode http api routes * replaced all rocket routes with axum equivalents * removed '_axum' suffix from the routes
This commit is contained in:
committed by
GitHub
parent
a209b87a41
commit
da9d743f39
@@ -1,9 +1,14 @@
|
||||
use crate::node::node_description::NodeDescription;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::State;
|
||||
use axum::extract::Query;
|
||||
use nym_node::http::api::{FormattedResponse, OutputParams};
|
||||
|
||||
/// Returns a description of the node and why someone might want to delegate stake to it.
|
||||
#[get("/description")]
|
||||
pub(crate) fn description(description: &State<NodeDescription>) -> Json<NodeDescription> {
|
||||
Json(description.inner().clone())
|
||||
pub(crate) async fn description(
|
||||
description: NodeDescription,
|
||||
Query(output): Query<OutputParams>,
|
||||
) -> MixnodeDescriptionResponse {
|
||||
let output = output.output.unwrap_or_default();
|
||||
output.to_response(description)
|
||||
}
|
||||
|
||||
pub type MixnodeDescriptionResponse = FormattedResponse<NodeDescription>;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use axum::extract::Query;
|
||||
use cupid::TopologyType;
|
||||
use rocket::serde::{json::Json, Serialize};
|
||||
use nym_node::http::api::{FormattedResponse, OutputParams};
|
||||
use serde::Serialize;
|
||||
use sysinfo::{System, SystemExt};
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub(crate) struct Hardware {
|
||||
pub struct Hardware {
|
||||
ram: String,
|
||||
num_cores: usize,
|
||||
crypto_hardware: Option<CryptoHardware>,
|
||||
@@ -12,7 +13,6 @@ pub(crate) struct Hardware {
|
||||
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
#[derive(Serialize, Debug)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub(crate) struct CryptoHardware {
|
||||
aesni: bool,
|
||||
avx2: bool,
|
||||
@@ -24,11 +24,13 @@ pub(crate) struct CryptoHardware {
|
||||
}
|
||||
|
||||
/// Provides hardware information which Nym can use to optimize mixnet speed over time (memory, crypto hardware, CPU, cores, etc).
|
||||
#[get("/hardware")]
|
||||
pub(crate) fn hardware() -> Json<Option<Hardware>> {
|
||||
Json(hardware_info())
|
||||
pub(crate) async fn hardware(Query(output): Query<OutputParams>) -> MixnodeHardwareResponse {
|
||||
let output = output.output.unwrap_or_default();
|
||||
output.to_response(hardware_info())
|
||||
}
|
||||
|
||||
pub type MixnodeHardwareResponse = FormattedResponse<Option<Hardware>>;
|
||||
|
||||
/// Gives back a summary report of whatever system hardware info we can get for this platform.
|
||||
fn hardware_info() -> Option<Hardware> {
|
||||
let crypto_hardware = hardware_info_from_cupid();
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
pub(crate) mod description;
|
||||
pub(crate) mod hardware;
|
||||
pub(crate) mod state;
|
||||
pub(crate) mod stats;
|
||||
pub(crate) mod verloc;
|
||||
|
||||
use rocket::Request;
|
||||
use axum::http::{StatusCode, Uri};
|
||||
use axum::response::IntoResponse;
|
||||
|
||||
#[catch(404)]
|
||||
pub(crate) fn not_found(req: &Request<'_>) -> String {
|
||||
format!("I couldn't find '{}'. Try something else?", req.uri())
|
||||
pub(crate) async fn not_found(uri: Uri) -> impl IntoResponse {
|
||||
(
|
||||
StatusCode::NOT_FOUND,
|
||||
format!("I couldn't find '{uri}'. Try something else?"),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::node::http::verloc::VerlocState;
|
||||
use crate::node::node_statistics::SharedNodeStats;
|
||||
use axum::extract::FromRef;
|
||||
|
||||
// this is a temporary thing for the transition period
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct MixnodeAppState {
|
||||
pub(crate) verloc: VerlocState,
|
||||
pub(crate) stats: SharedNodeStats,
|
||||
}
|
||||
|
||||
impl FromRef<MixnodeAppState> for VerlocState {
|
||||
fn from_ref(app_state: &MixnodeAppState) -> Self {
|
||||
app_state.verloc.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRef<MixnodeAppState> for SharedNodeStats {
|
||||
fn from_ref(app_state: &MixnodeAppState) -> Self {
|
||||
app_state.stats.clone()
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,38 @@
|
||||
use crate::node::node_statistics::{NodeStats, NodeStatsSimple, SharedNodeStats};
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::State;
|
||||
use serde::Serialize;
|
||||
use axum::extract::{Query, State};
|
||||
use nym_node::http::api::{FormattedResponse, Output};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub(crate) enum NodeStatsResponse {
|
||||
pub enum NodeStatsResponse {
|
||||
Full(NodeStats),
|
||||
Simple(NodeStatsSimple),
|
||||
}
|
||||
|
||||
/// Returns a running stats of the node.
|
||||
#[get("/stats?<debug>")]
|
||||
pub(crate) async fn stats(
|
||||
stats: &State<SharedNodeStats>,
|
||||
debug: Option<bool>,
|
||||
) -> Json<NodeStatsResponse> {
|
||||
Query(params): Query<StatsQueryParams>,
|
||||
State(stats): State<SharedNodeStats>,
|
||||
) -> MixnodeStatsResponse {
|
||||
let output = params.output.unwrap_or_default();
|
||||
|
||||
let snapshot_data = stats.clone_data().await;
|
||||
|
||||
// there's no point in returning the entire hashmap of sending destinations in regular mode
|
||||
if let Some(debug) = debug {
|
||||
if debug {
|
||||
return Json(NodeStatsResponse::Full(snapshot_data));
|
||||
}
|
||||
}
|
||||
|
||||
Json(NodeStatsResponse::Simple(snapshot_data.simplify()))
|
||||
let response = if params.debug {
|
||||
NodeStatsResponse::Full(snapshot_data)
|
||||
} else {
|
||||
NodeStatsResponse::Simple(snapshot_data.simplify())
|
||||
};
|
||||
output.to_response(response)
|
||||
}
|
||||
|
||||
pub type MixnodeStatsResponse = FormattedResponse<NodeStatsResponse>;
|
||||
|
||||
#[derive(Default, Debug, Serialize, Deserialize, Copy, Clone)]
|
||||
// #[derive(Default, Debug, Serialize, Deserialize, Copy, Clone, IntoParams, ToSchema)]
|
||||
#[serde(default)]
|
||||
pub(crate) struct StatsQueryParams {
|
||||
debug: bool,
|
||||
pub output: Option<Output>,
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use axum::extract::{Query, State};
|
||||
use nym_mixnode_common::verloc::{AtomicVerlocResult, VerlocResult};
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::State;
|
||||
use nym_node::http::api::{FormattedResponse, OutputParams};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct VerlocState {
|
||||
shared: AtomicVerlocResult,
|
||||
}
|
||||
@@ -16,8 +17,12 @@ impl VerlocState {
|
||||
|
||||
/// Provides verifiable location (verloc) measurements for this mixnode - a list of the
|
||||
/// round-trip times, in milliseconds, for all other mixnodes that this node knows about.
|
||||
#[get("/verloc")]
|
||||
pub(crate) async fn verloc(state: &State<VerlocState>) -> Json<VerlocResult> {
|
||||
// since it's impossible to get a mutable reference to the state, we can't cache any results outside the lock : (
|
||||
Json(state.shared.clone_data().await)
|
||||
pub(crate) async fn verloc(
|
||||
State(verloc): State<VerlocState>,
|
||||
Query(output): Query<OutputParams>,
|
||||
) -> MixnodeVerlocResponse {
|
||||
let output = output.output.unwrap_or_default();
|
||||
output.to_response(verloc.shared.clone_data().await)
|
||||
}
|
||||
|
||||
pub type MixnodeVerlocResponse = FormattedResponse<VerlocResult>;
|
||||
|
||||
@@ -7,6 +7,8 @@ use crate::node::listener::connection_handler::packet_processing::{
|
||||
use crate::node::packet_delayforwarder::PacketDelayForwardSender;
|
||||
use crate::node::TaskClient;
|
||||
use futures::StreamExt;
|
||||
use log::debug;
|
||||
use log::{error, info, warn};
|
||||
use nym_mixnode_common::measure;
|
||||
use nym_sphinx::forwarding::packet::MixPacket;
|
||||
use nym_sphinx::framing::codec::NymCodec;
|
||||
@@ -16,8 +18,9 @@ use std::net::SocketAddr;
|
||||
use tokio::net::TcpStream;
|
||||
use tokio::time::Instant;
|
||||
use tokio_util::codec::Framed;
|
||||
|
||||
#[cfg(feature = "cpucycles")]
|
||||
use tracing::{error, info, instrument};
|
||||
use tracing::instrument;
|
||||
|
||||
pub(crate) mod packet_processing;
|
||||
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::node::listener::connection_handler::ConnectionHandler;
|
||||
use log::{error, info, warn};
|
||||
use std::net::SocketAddr;
|
||||
use std::process;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio::task::JoinHandle;
|
||||
#[cfg(feature = "cpucycles")]
|
||||
use tracing::error;
|
||||
|
||||
use super::TaskClient;
|
||||
|
||||
|
||||
+34
-27
@@ -2,23 +2,26 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::node::http::{
|
||||
description::description,
|
||||
hardware::hardware,
|
||||
not_found,
|
||||
stats::stats,
|
||||
verloc::{verloc as verloc_route, VerlocState},
|
||||
};
|
||||
use crate::node::http::description::description;
|
||||
use crate::node::http::hardware::hardware;
|
||||
use crate::node::http::not_found;
|
||||
use crate::node::http::state::MixnodeAppState;
|
||||
use crate::node::http::stats::stats;
|
||||
use crate::node::http::verloc::{verloc, VerlocState};
|
||||
use crate::node::listener::connection_handler::packet_processing::PacketProcessor;
|
||||
use crate::node::listener::connection_handler::ConnectionHandler;
|
||||
use crate::node::listener::Listener;
|
||||
use crate::node::node_description::NodeDescription;
|
||||
use crate::node::node_statistics::SharedNodeStats;
|
||||
use crate::node::packet_delayforwarder::{DelayForwarder, PacketDelayForwardSender};
|
||||
use axum::routing::get;
|
||||
use axum::Router;
|
||||
use log::{error, info, warn};
|
||||
use nym_bin_common::output_format::OutputFormat;
|
||||
use nym_bin_common::version_checker::parse_version;
|
||||
use nym_crypto::asymmetric::{encryption, identity};
|
||||
use nym_mixnode_common::verloc::{self, AtomicVerlocResult, VerlocMeasurer};
|
||||
use nym_node::http::middleware::logging;
|
||||
use nym_task::{TaskClient, TaskManager};
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::thread_rng;
|
||||
@@ -26,9 +29,6 @@ use std::net::SocketAddr;
|
||||
use std::process;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[cfg(feature = "cpucycles")]
|
||||
use tracing::{error, info, warn};
|
||||
|
||||
mod http;
|
||||
mod listener;
|
||||
pub(crate) mod node_description;
|
||||
@@ -99,29 +99,36 @@ impl MixNode {
|
||||
atomic_verloc_result: AtomicVerlocResult,
|
||||
node_stats_pointer: SharedNodeStats,
|
||||
) {
|
||||
info!(
|
||||
"Starting HTTP API on http://{}:{}",
|
||||
self.config.mixnode.listening_address, self.config.mixnode.http_api_port
|
||||
let bind_address = SocketAddr::new(
|
||||
self.config.mixnode.listening_address,
|
||||
self.config.mixnode.http_api_port,
|
||||
);
|
||||
|
||||
let mut config = rocket::config::Config::release_default();
|
||||
info!("Starting HTTP API on http://{bind_address}",);
|
||||
|
||||
// bind to the same address as we are using for mixnodes
|
||||
config.address = self.config.mixnode.listening_address;
|
||||
config.port = self.config.mixnode.http_api_port;
|
||||
let state = MixnodeAppState {
|
||||
verloc: VerlocState::new(atomic_verloc_result),
|
||||
stats: node_stats_pointer,
|
||||
};
|
||||
|
||||
let verloc_state = VerlocState::new(atomic_verloc_result);
|
||||
let descriptor = self.descriptor.clone();
|
||||
let router = Router::new()
|
||||
.route("/verloc", get(verloc))
|
||||
.route(
|
||||
"/description",
|
||||
get({
|
||||
let descriptor = self.descriptor.clone();
|
||||
move |query| description(descriptor, query)
|
||||
}),
|
||||
)
|
||||
.route("/stats", get(stats))
|
||||
.route("/hardware", get(hardware))
|
||||
.fallback(not_found)
|
||||
.layer(axum::middleware::from_fn(logging::logger))
|
||||
.with_state(state);
|
||||
|
||||
tokio::spawn(async move {
|
||||
rocket::build()
|
||||
.configure(config)
|
||||
.mount("/", routes![verloc_route, description, stats, hardware])
|
||||
.register("/", catchers![not_found])
|
||||
.manage(verloc_state)
|
||||
.manage(descriptor)
|
||||
.manage(node_stats_pointer)
|
||||
.launch()
|
||||
axum::Server::bind(&bind_address)
|
||||
.serve(router.into_make_service_with_connect_info::<SocketAddr>())
|
||||
.await
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use super::TaskClient;
|
||||
use futures::channel::mpsc;
|
||||
use futures::lock::Mutex;
|
||||
use futures::StreamExt;
|
||||
use log::{debug, info, trace};
|
||||
use serde::Serialize;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::DerefMut;
|
||||
@@ -9,8 +11,6 @@ use std::sync::Arc;
|
||||
use std::time::{Duration, SystemTime};
|
||||
use tokio::sync::{RwLock, RwLockReadGuard};
|
||||
|
||||
use super::TaskClient;
|
||||
|
||||
// convenience aliases
|
||||
type PacketsMap = HashMap<String, u64>;
|
||||
type PacketDataReceiver = mpsc::UnboundedReceiver<PacketEvent>;
|
||||
@@ -80,7 +80,7 @@ impl SharedNodeStats {
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone)]
|
||||
pub(crate) struct NodeStats {
|
||||
pub struct NodeStats {
|
||||
#[serde(serialize_with = "humantime_serde::serialize")]
|
||||
update_time: SystemTime,
|
||||
|
||||
@@ -126,7 +126,7 @@ impl NodeStats {
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone)]
|
||||
pub(crate) struct NodeStatsSimple {
|
||||
pub struct NodeStatsSimple {
|
||||
#[serde(serialize_with = "humantime_serde::serialize")]
|
||||
update_time: SystemTime,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user