Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5007d867b8 | |||
| fa0ec3453d | |||
| a2b1917d06 | |||
| 77b4fd2aa5 | |||
| 61e08d6e43 |
Generated
+12
-49
@@ -447,29 +447,6 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-extra"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0be6ea09c9b96cb5076af0de2e383bd2bc0c18f827cf1967bdd353e0b910d733"
|
||||
dependencies = [
|
||||
"axum 0.7.5",
|
||||
"axum-core 0.4.3",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"headers",
|
||||
"http 1.1.0",
|
||||
"http-body 1.0.0",
|
||||
"http-body-util",
|
||||
"mime",
|
||||
"pin-project-lite",
|
||||
"serde",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.71"
|
||||
@@ -2738,30 +2715,6 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "headers"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bytes",
|
||||
"headers-core",
|
||||
"http 1.1.0",
|
||||
"httpdate",
|
||||
"mime",
|
||||
"sha1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "headers-core"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4"
|
||||
dependencies = [
|
||||
"http 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
@@ -3933,6 +3886,7 @@ version = "1.1.38"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"axum 0.7.5",
|
||||
"bip39",
|
||||
"bs58 0.5.1",
|
||||
"cfg-if",
|
||||
@@ -3946,6 +3900,7 @@ dependencies = [
|
||||
"dirs 4.0.0",
|
||||
"futures",
|
||||
"getset",
|
||||
"http 1.1.0",
|
||||
"humantime-serde",
|
||||
"itertools 0.12.1",
|
||||
"k256",
|
||||
@@ -3963,6 +3918,7 @@ dependencies = [
|
||||
"nym-crypto",
|
||||
"nym-dkg",
|
||||
"nym-gateway-client",
|
||||
"nym-http-api-common",
|
||||
"nym-inclusion-probability",
|
||||
"nym-mixnet-contract-common",
|
||||
"nym-multisig-contract-common",
|
||||
@@ -3997,8 +3953,11 @@ dependencies = [
|
||||
"time",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tower-http",
|
||||
"ts-rs",
|
||||
"url",
|
||||
"utoipa",
|
||||
"utoipa-swagger-ui",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
@@ -4732,11 +4691,17 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"axum 0.7.5",
|
||||
"bytes",
|
||||
"colored",
|
||||
"futures",
|
||||
"mime",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"tokio",
|
||||
"tower",
|
||||
"tracing",
|
||||
"utoipa",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5120,11 +5085,9 @@ name = "nym-node-http-api"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"axum 0.7.5",
|
||||
"axum-extra",
|
||||
"colored",
|
||||
"dashmap",
|
||||
"fastrand 2.1.0",
|
||||
"headers",
|
||||
"hmac 0.12.1",
|
||||
"hyper 1.3.1",
|
||||
"ipnetwork 0.16.0",
|
||||
|
||||
@@ -12,9 +12,15 @@ license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
axum.workspace = true
|
||||
bytes = { workspace = true }
|
||||
mime = { workspace = true }
|
||||
bytes.workspace = true
|
||||
colored.workspace = true
|
||||
futures.workspace = true
|
||||
mime.workspace = true
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json.workspace = true
|
||||
serde_yaml = { workspace = true }
|
||||
utoipa = { workspace = true }
|
||||
serde_yaml.workspace = true
|
||||
tokio.workspace = true
|
||||
tower.workspace = true
|
||||
tracing.workspace = true
|
||||
utoipa.workspace = true
|
||||
zeroize.workspace = true
|
||||
|
||||
@@ -8,6 +8,8 @@ use bytes::{BufMut, BytesMut};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
|
||||
pub mod middleware;
|
||||
|
||||
#[derive(Debug, Clone, ToSchema)]
|
||||
pub enum FormattedResponse<T> {
|
||||
Json(Json<T>),
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use axum::http::{header, HeaderValue, StatusCode};
|
||||
use axum::response::IntoResponse;
|
||||
use axum::{extract::Request, response::Response};
|
||||
use futures::future::BoxFuture;
|
||||
use std::sync::Arc;
|
||||
use std::task::{Context, Poll};
|
||||
use tower::{Layer, Service};
|
||||
use tracing::{debug, instrument, trace};
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BearerAuthLayer {
|
||||
bearer_token: Arc<Zeroizing<String>>,
|
||||
allow_empty: bool,
|
||||
}
|
||||
|
||||
impl BearerAuthLayer {
|
||||
pub fn new(bearer_token: Arc<Zeroizing<String>>) -> Self {
|
||||
BearerAuthLayer {
|
||||
bearer_token,
|
||||
allow_empty: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_raw(bearer_token: impl Into<String>) -> Self {
|
||||
BearerAuthLayer::new(Arc::new(Zeroizing::new(bearer_token.into())))
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_allow_empty(mut self, allow_empty: bool) -> Self {
|
||||
self.allow_empty = allow_empty;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Layer<S> for BearerAuthLayer {
|
||||
type Service = RequireBearerAuth<S>;
|
||||
|
||||
fn layer(&self, inner: S) -> Self::Service {
|
||||
RequireBearerAuth::new(inner, self.bearer_token.clone()).with_allow_empty(self.allow_empty)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RequireBearerAuth<S> {
|
||||
inner: S,
|
||||
bearer_token: Arc<Zeroizing<String>>,
|
||||
allow_empty: bool,
|
||||
}
|
||||
|
||||
impl<S> RequireBearerAuth<S> {
|
||||
pub fn new(inner: S, bearer_token: Arc<Zeroizing<String>>) -> Self {
|
||||
RequireBearerAuth {
|
||||
inner,
|
||||
bearer_token,
|
||||
allow_empty: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_allow_empty(mut self, allow_empty: bool) -> Self {
|
||||
self.allow_empty = allow_empty;
|
||||
self
|
||||
}
|
||||
|
||||
fn check_auth_header(&self, header: Option<&HeaderValue>) -> Result<(), &'static str> {
|
||||
let Some(token) = header else {
|
||||
trace!("missing header");
|
||||
return Err("`Authorization` header is missing");
|
||||
};
|
||||
|
||||
let Ok(authorization) = token.to_str() else {
|
||||
trace!("invalid header");
|
||||
return Err("`Authorization` header contains invalid characters");
|
||||
};
|
||||
|
||||
debug!("header value: '{authorization}'");
|
||||
|
||||
let split = authorization.split_once(' ');
|
||||
let bearer_token = match split {
|
||||
// Found proper bearer
|
||||
Some(("Bearer", contents)) => contents,
|
||||
// Found empty bearer;
|
||||
_ if authorization == "Bearer" => "",
|
||||
// Found nothing
|
||||
_ => return Err("`Authorization` header must be a bearer token"),
|
||||
};
|
||||
|
||||
debug!("parsed token: '{bearer_token}'");
|
||||
|
||||
if self.bearer_token.is_empty() && bearer_token.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
if bearer_token.is_empty() {
|
||||
return Err("`Authorization` header must contain non-empty `Bearer` token");
|
||||
}
|
||||
|
||||
if self.bearer_token.as_str() != bearer_token {
|
||||
return Err("`Authorization` header does not contain the correct `Bearer` token");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Service<Request> for RequireBearerAuth<S>
|
||||
where
|
||||
S: Service<Request, Response = Response> + Send + 'static,
|
||||
S: Send + Sync + 'static,
|
||||
S::Future: Send + 'static,
|
||||
{
|
||||
type Response = S::Response;
|
||||
type Error = S::Error;
|
||||
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
|
||||
|
||||
#[inline]
|
||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||
self.inner.poll_ready(cx)
|
||||
}
|
||||
|
||||
#[instrument(skip_all, fields(uri = %req.uri()))]
|
||||
fn call(&mut self, req: Request) -> Self::Future {
|
||||
debug!("checking the auth");
|
||||
|
||||
if self.bearer_token.is_empty() && !self.allow_empty {
|
||||
return Box::pin(async move {
|
||||
Ok((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"no valid access token has been specified on the server",
|
||||
)
|
||||
.into_response())
|
||||
});
|
||||
}
|
||||
|
||||
let auth_header = req.headers().get(header::AUTHORIZATION);
|
||||
|
||||
match self.check_auth_header(auth_header) {
|
||||
Ok(_authorised) => Box::pin(self.inner.call(req)),
|
||||
Err(err) => {
|
||||
Box::pin(async move { Ok((StatusCode::UNAUTHORIZED, err).into_response()) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub mod bearer;
|
||||
+15
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use axum::{
|
||||
@@ -12,6 +12,7 @@ use axum::{
|
||||
};
|
||||
use colored::*;
|
||||
use std::net::SocketAddr;
|
||||
use tokio::time::Instant;
|
||||
use tracing::info;
|
||||
|
||||
/// Simple logger for requests
|
||||
@@ -29,7 +30,9 @@ pub async fn logger(
|
||||
|
||||
let host = header_map(req.headers().get(HOST), "Unknown Host".to_string());
|
||||
|
||||
let start = Instant::now();
|
||||
let res = next.run(req).await;
|
||||
let time_taken = start.elapsed();
|
||||
let status = res.status();
|
||||
let print_status = if status.is_client_error() || status.is_server_error() {
|
||||
status.to_string().red()
|
||||
@@ -39,7 +42,17 @@ pub async fn logger(
|
||||
status.to_string().yellow()
|
||||
};
|
||||
|
||||
info!(target: "incoming request", "[{addr} -> {host}] {method} '{uri}': {print_status} / agent: {agent}");
|
||||
let taken = "time taken".bold();
|
||||
|
||||
let time_taken = match time_taken.as_millis() {
|
||||
ms if ms > 500 => format!("{taken}: {}", format!("{ms}ms").red()),
|
||||
ms if ms > 200 => format!("{taken}: {}", format!("{ms}ms").yellow()),
|
||||
ms if ms > 50 => format!("{taken}: {}", format!("{ms}ms").bright_yellow()),
|
||||
ms => format!("{taken}: {ms}ms"),
|
||||
};
|
||||
|
||||
let agent_str = "agent".bold();
|
||||
info!("[{addr} -> {host}] {method} '{uri}': {print_status} {time_taken} {agent_str}: {agent}");
|
||||
|
||||
res
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub mod auth;
|
||||
pub mod logging;
|
||||
|
||||
pub use auth::bearer::{BearerAuthLayer, RequireBearerAuth};
|
||||
pub use logging::logger;
|
||||
+12
-7
@@ -32,8 +32,6 @@ pin-project = { workspace = true }
|
||||
rand = "0.8.5"
|
||||
rand-07 = { package = "rand", version = "0.7.3" } # required for compatibility
|
||||
reqwest = { workspace = true, features = ["json"] }
|
||||
rocket = { workspace = true, features = ["json"] }
|
||||
rocket_cors = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tap = { workspace = true }
|
||||
@@ -55,11 +53,21 @@ sqlx = { workspace = true, features = [
|
||||
"migrate",
|
||||
] }
|
||||
|
||||
okapi = { workspace = true, features = ["impl_json_schema"] }
|
||||
rocket_okapi = { workspace = true, features = ["swagger"] }
|
||||
schemars = { workspace = true, features = ["preserve_order"] }
|
||||
zeroize = { workspace = true }
|
||||
|
||||
rocket = { workspace = true, features = ["json"] }
|
||||
rocket_cors = { workspace = true }
|
||||
rocket_okapi = { workspace = true, features = ["swagger"] }
|
||||
okapi = { workspace = true, features = ["impl_json_schema"] }
|
||||
|
||||
axum.workspace = true
|
||||
http.workspace = true
|
||||
tower-http = { workspace = true, features = ["cors"] }
|
||||
utoipa = { workspace = true, features = ["axum_extras", "time"] }
|
||||
utoipa-swagger-ui = { workspace = true, features = ["axum"] }
|
||||
nym-http-api-common = { path = "../common/http-api-common" }
|
||||
|
||||
## ephemera-specific
|
||||
#actix-web = "4"
|
||||
#array-bytes = "6.0.0"
|
||||
@@ -68,12 +76,9 @@ zeroize = { workspace = true }
|
||||
#serde_derive = "1.0.149"
|
||||
#uuid = { version = "1.3.0", features = ["serde", "v4"] }
|
||||
|
||||
## internal
|
||||
#ephemera = { path = "../ephemera" }
|
||||
nym-bandwidth-controller = { path = "../common/bandwidth-controller" }
|
||||
nym-coconut-bandwidth-contract-common = { path = "../common/cosmwasm-smart-contracts/coconut-bandwidth-contract" }
|
||||
nym-coconut-dkg-common = { path = "../common/cosmwasm-smart-contracts/coconut-dkg" }
|
||||
#nym-ephemera-common = { path = "../common/cosmwasm-smart-contracts/ephemera" }
|
||||
nym-config = { path = "../common/config" }
|
||||
cosmwasm-std = { workspace = true }
|
||||
nym-credential-storage = { path = "../common/credential-storage" }
|
||||
|
||||
@@ -34,3 +34,141 @@ impl<T> From<T> for Deprecated<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! absolute_route {
|
||||
( $name:ident, $parent:expr, $suffix:expr ) => {
|
||||
pub fn $name() -> String {
|
||||
format!("{}{}", $parent, $suffix)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub mod routes {
|
||||
pub const V1: &str = "/v1";
|
||||
|
||||
pub mod v1 {
|
||||
use super::*;
|
||||
|
||||
pub const CIRCULATING_SUPPLY: &str = "/circulating-supply";
|
||||
pub const MIXNODES: &str = "/mixnodes";
|
||||
pub const GATEWAYS: &str = "/gateways";
|
||||
pub const STATUS: &str = "/status";
|
||||
pub const EPOCH: &str = "/epoch";
|
||||
pub const NETWORK: &str = "/network";
|
||||
pub const API_STATUS: &str = "/api-status";
|
||||
|
||||
pub mod circulating_supply {
|
||||
use super::*;
|
||||
|
||||
pub const TOTAL_SUPPLY_VALUE: &str = "/total-supply-value";
|
||||
pub const CIRCULATING_SUPPLY_VALUE: &str = "/circulating-supply-value";
|
||||
}
|
||||
|
||||
pub mod mixnodes {
|
||||
use super::*;
|
||||
|
||||
pub const DETAILED: &str = "/detailed";
|
||||
pub const ACTIVE: &str = "/active";
|
||||
pub const REWARDED: &str = "/rewarded";
|
||||
pub const BLACKLISTED: &str = "/blacklisted";
|
||||
|
||||
pub mod active {
|
||||
pub const DETAILED: &str = "/detailed";
|
||||
}
|
||||
|
||||
pub mod rewarded {
|
||||
pub const DETAILED: &str = "/detailed";
|
||||
}
|
||||
}
|
||||
|
||||
pub mod gateways {
|
||||
use super::*;
|
||||
|
||||
pub const DETAILED: &str = "/detailed";
|
||||
pub const BLACKLISTED: &str = "/blacklisted";
|
||||
pub const DESCRIBED: &str = "/described";
|
||||
}
|
||||
|
||||
pub mod epoch {
|
||||
use super::*;
|
||||
|
||||
pub const REWARD_PARAMS: &str = "reward_params";
|
||||
pub const CURRENT: &str = "current";
|
||||
}
|
||||
|
||||
pub mod status {
|
||||
use super::*;
|
||||
|
||||
pub const GATEWAY: &str = "/gateway";
|
||||
pub const MIXNODE: &str = "/mixnode";
|
||||
pub const MIXNODES: &str = "/mixnode";
|
||||
pub const GATEWAYS: &str = "/gateways";
|
||||
pub const UNSTABLE: &str = "/unstable";
|
||||
|
||||
pub mod gateway {
|
||||
pub const REPORT: &str = "/report";
|
||||
pub const HISTORY: &str = "/history";
|
||||
pub const CORE_STATUS_COUNT: &str = "/core-status-count";
|
||||
pub const AVG_UPTIME: &str = "/avg_uptime";
|
||||
}
|
||||
|
||||
pub mod mixnode {
|
||||
pub const REPORT: &str = "/report";
|
||||
pub const HISTORY: &str = "/history";
|
||||
pub const CORE_STATUS_COUNT: &str = "/core-status-count";
|
||||
pub const STATUS: &str = "/status";
|
||||
pub const REWARD_ESTIMATION: &str = "/reward-estimation";
|
||||
pub const COMPUTE_REWARD_ESTIMATION: &str = "/compute-reward-estimation";
|
||||
pub const STAKE_SATURATION: &str = "/stake-saturation";
|
||||
|
||||
pub const INCLUSION_PROBABILITY: &str = "/inclusion-probability";
|
||||
pub const AVG_UPTIME: &str = "/avg_uptime";
|
||||
}
|
||||
|
||||
pub mod mixnodes {
|
||||
pub const INCLUSION_PROBABILITY: &str = "/inclusion-probability";
|
||||
|
||||
pub const DETAILED: &str = "/detailed";
|
||||
pub const DETAILED_UNFILTERED: &str = "/detailed-unfiltered";
|
||||
|
||||
pub const ACTIVE: &str = "/active";
|
||||
pub const REWARDED: &str = "/rewarded";
|
||||
pub mod rewarded {
|
||||
pub const DETAILED: &str = "/detailed";
|
||||
}
|
||||
|
||||
pub mod active {
|
||||
pub const DETAILED: &str = "/detailed";
|
||||
}
|
||||
}
|
||||
|
||||
pub mod gateways {
|
||||
pub const DETAILED: &str = "/detailed";
|
||||
pub const DETAILED_UNFILTERED: &str = "/detailed-unfiltered";
|
||||
}
|
||||
|
||||
pub mod unstable {
|
||||
pub mod by_mix_id {
|
||||
pub const TEST_RESULTS: &str = "/test-results";
|
||||
}
|
||||
pub mod by_gateway_identity {
|
||||
pub const TEST_RESULTS: &str = "/test-results";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod network {
|
||||
use super::*;
|
||||
pub const DETAILS: &str = "/details";
|
||||
pub const NYM_CONTRACTS: &str = "/nym-contracts";
|
||||
pub const NYM_CONTRACTS_DETAILED: &str = "/nym-contracts-detailed";
|
||||
}
|
||||
|
||||
pub mod api_status {
|
||||
use super::*;
|
||||
pub const HEALTH: &str = "/health";
|
||||
pub const BUILD_INFORMATION: &str = "/build-information";
|
||||
pub const SIGNER_INFORMATION: &str = "/signer-information";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
use self::data::CirculatingSupplyCacheData;
|
||||
use cosmwasm_std::Addr;
|
||||
use log::error;
|
||||
use nym_api_requests::models::CirculatingSupplyResponse;
|
||||
use nym_validator_client::nyxd::error::NyxdError;
|
||||
use nym_validator_client::nyxd::Coin;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
use super::CirculatingSupplyCache;
|
||||
use crate::circulating_supply_api::cache::CirculatingSupplyCacheError;
|
||||
use crate::support::nyxd::Client;
|
||||
use log::{error, trace};
|
||||
use nym_contracts_common::truncate_decimal;
|
||||
use nym_task::TaskClient;
|
||||
use nym_validator_client::nyxd::Coin;
|
||||
|
||||
@@ -7,7 +7,7 @@ use nym_api_requests::models::CirculatingSupplyResponse;
|
||||
use nym_validator_client::nyxd::Coin;
|
||||
use rocket::http::Status;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::State;
|
||||
use rocket::{get, State};
|
||||
use rocket_okapi::openapi;
|
||||
|
||||
// TODO: this is not the best place to put it, it should be more centralised,
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use std::ops::Deref;
|
||||
|
||||
use k256::ecdsa::signature::Verifier;
|
||||
use rand::rngs::OsRng;
|
||||
use rand::RngCore;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::State as RocketState;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
use log::{debug, error, trace};
|
||||
use nym_api_requests::coconut::models::{
|
||||
CredentialsRequestBody, EpochCredentialsResponse, FreePassNonceResponse, FreePassRequest,
|
||||
IssuedCredentialResponse, IssuedCredentialsResponse,
|
||||
@@ -26,6 +19,12 @@ use nym_credentials::coconut::bandwidth::{
|
||||
bandwidth_credential_params, CredentialType, IssuanceBandwidthCredential,
|
||||
};
|
||||
use nym_validator_client::nyxd::Coin;
|
||||
use rand::rngs::OsRng;
|
||||
use rand::RngCore;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::{get, post, State as RocketState};
|
||||
use std::ops::Deref;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
use crate::coconut::api_routes::helpers::build_credentials_response;
|
||||
use crate::coconut::error::{CoconutError, Result};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::coconut::error::Result;
|
||||
use async_trait::async_trait;
|
||||
use cw3::{ProposalResponse, VoteResponse};
|
||||
use cw4::MemberResponse;
|
||||
use nym_coconut_bandwidth_contract_common::spend_credential::SpendCredentialResponse;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
use crate::coconut::error::Result;
|
||||
use crate::nyxd;
|
||||
use crate::support::nyxd::ClientInner;
|
||||
use async_trait::async_trait;
|
||||
use nym_coconut::VerificationKey;
|
||||
use nym_coconut_dkg_common::types::{Epoch, EpochId};
|
||||
use nym_credentials::coconut::utils::obtain_aggregate_verification_key;
|
||||
|
||||
@@ -5,6 +5,7 @@ use crate::coconut::client::Client;
|
||||
use crate::coconut::keys::KeyPairWithEpoch;
|
||||
use crate::support::{config, nyxd};
|
||||
use anyhow::{anyhow, bail, Context};
|
||||
use log::warn;
|
||||
use nym_coconut_dkg_common::types::{EpochId, EpochState};
|
||||
use nym_dkg::bte::keys::KeyPair as DkgKeyPair;
|
||||
use rand::{CryptoRng, RngCore};
|
||||
|
||||
@@ -8,6 +8,7 @@ use crate::coconut::keys::KeyPair as CoconutKeyPair;
|
||||
use crate::nyxd;
|
||||
use crate::support::config;
|
||||
use anyhow::{bail, Result};
|
||||
use log::{debug, error, info, trace, warn};
|
||||
use nym_coconut_dkg_common::types::{Epoch, EpochId, EpochState};
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_dkg::bte::keys::KeyPair as DkgKeyPair;
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::coconut::dkg::controller::keys::archive_coconut_keypair;
|
||||
use crate::coconut::dkg::controller::DkgController;
|
||||
use crate::coconut::error::CoconutError;
|
||||
use crate::coconut::keys::KeyPairWithEpoch;
|
||||
use log::debug;
|
||||
use log::{debug, error, info, warn};
|
||||
use nym_coconut_dkg_common::dealing::{chunk_dealing, DealingChunkInfo, MAX_DEALING_CHUNK_SIZE};
|
||||
use nym_coconut_dkg_common::types::{DealingIndex, EpochId};
|
||||
use nym_dkg::{Dealing, Scalar};
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::coconut::error::CoconutError;
|
||||
use crate::coconut::keys::KeyPairWithEpoch;
|
||||
use crate::coconut::state::bandwidth_credential_params;
|
||||
use cosmwasm_std::Addr;
|
||||
use log::debug;
|
||||
use log::{debug, error, info, warn};
|
||||
use nym_coconut::KeyPair as CoconutKeyPair;
|
||||
use nym_coconut::{check_vk_pairing, Base58, SecretKey, VerificationKey};
|
||||
use nym_coconut_dkg_common::event_attributes::DKG_PROPOSAL_ID;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
use crate::coconut::dkg::controller::DkgController;
|
||||
use crate::coconut::error::CoconutError;
|
||||
use cw3::Status;
|
||||
use log::{debug, error, info, warn};
|
||||
use nym_coconut_dkg_common::types::EpochId;
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::coconut::error::CoconutError;
|
||||
use crate::coconut::state::bandwidth_credential_params;
|
||||
use cosmwasm_std::Addr;
|
||||
use cw3::Vote;
|
||||
use log::{debug, error, info, warn};
|
||||
use nym_coconut::{check_vk_pairing, Base58, VerificationKey};
|
||||
use nym_coconut_dkg_common::types::EpochId;
|
||||
use nym_coconut_dkg_common::verification_key::ContractVKShare;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
use crate::coconut::dkg::controller::DkgController;
|
||||
use crate::coconut::error::CoconutError;
|
||||
use log::debug;
|
||||
use log::{debug, info};
|
||||
use nym_coconut_dkg_common::types::EpochId;
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::coconut::dkg::state::registration::{
|
||||
use crate::coconut::error::CoconutError;
|
||||
use crate::coconut::keys::{KeyPair as CoconutKeyPair, KeyPairWithEpoch};
|
||||
use cosmwasm_std::Addr;
|
||||
use log::debug;
|
||||
use log::{debug, warn};
|
||||
use nym_coconut_dkg_common::dealer::DealerDetails;
|
||||
use nym_coconut_dkg_common::types::EpochId;
|
||||
use nym_crypto::asymmetric::identity;
|
||||
|
||||
@@ -10,6 +10,7 @@ use nym_config::defaults::NYM_API_VERSION;
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_validator_client::nym_api::routes::{BANDWIDTH, COCONUT_ROUTES};
|
||||
use rocket::fairing::AdHoc;
|
||||
use rocket::routes;
|
||||
|
||||
pub(crate) mod api_routes;
|
||||
pub(crate) mod client;
|
||||
|
||||
@@ -8,6 +8,7 @@ use crate::coconut::error::{CoconutError, Result};
|
||||
use crate::coconut::keys::KeyPair;
|
||||
use crate::coconut::storage::CoconutStorageExt;
|
||||
use crate::support::storage::NymApiStorage;
|
||||
use log::{debug, warn};
|
||||
use nym_api_requests::coconut::helpers::issued_credential_plaintext;
|
||||
use nym_api_requests::coconut::BlindSignRequestBody;
|
||||
use nym_coconut::{BlindedSignature, VerificationKey};
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
use crate::coconut::storage::models::{EpochCredentials, IssuedCredential};
|
||||
use crate::support::storage::manager::StorageManager;
|
||||
use async_trait::async_trait;
|
||||
use nym_coconut_dkg_common::types::EpochId;
|
||||
use thiserror::Error;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ use crate::coconut::storage::manager::CoconutStorageManagerExt;
|
||||
use crate::coconut::storage::models::{join_attributes, EpochCredentials, IssuedCredential};
|
||||
use crate::node_status_api::models::NymApiStorageError;
|
||||
use crate::support::storage::NymApiStorage;
|
||||
use async_trait::async_trait;
|
||||
use nym_api_requests::coconut::models::Pagination;
|
||||
use nym_coconut::{Base58, BlindedSignature};
|
||||
use nym_coconut_dkg_common::types::EpochId;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
use crate::epoch_operations::error::RewardingError;
|
||||
use crate::RewardedSetUpdater;
|
||||
use log::{error, warn};
|
||||
use nym_mixnet_contract_common::EpochState;
|
||||
use std::cmp::max;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ use crate::support::nyxd::Client;
|
||||
use crate::support::storage::NymApiStorage;
|
||||
use error::RewardingError;
|
||||
pub(crate) use helpers::MixnodeWithPerformance;
|
||||
use log::{error, info, trace, warn};
|
||||
use nym_mixnet_contract_common::{CurrentIntervalResponse, Interval};
|
||||
use nym_task::{TaskClient, TaskManager};
|
||||
use std::collections::HashSet;
|
||||
|
||||
@@ -5,6 +5,7 @@ use crate::epoch_operations::error::RewardingError;
|
||||
use crate::epoch_operations::helpers::stake_to_f64;
|
||||
use crate::RewardedSetUpdater;
|
||||
use cosmwasm_std::Decimal;
|
||||
use log::{debug, error, warn};
|
||||
use nym_mixnet_contract_common::families::FamilyHead;
|
||||
use nym_mixnet_contract_common::reward_params::Performance;
|
||||
use nym_mixnet_contract_common::{
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
use crate::epoch_operations::error::RewardingError;
|
||||
use crate::epoch_operations::helpers::MixnodeWithPerformance;
|
||||
use crate::RewardedSetUpdater;
|
||||
use log::{error, warn};
|
||||
use nym_mixnet_contract_common::{EpochState, Interval, MixId};
|
||||
|
||||
impl RewardedSetUpdater {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
use crate::epoch_operations::error::RewardingError;
|
||||
use crate::epoch_operations::RewardedSetUpdater;
|
||||
use log::{error, info};
|
||||
|
||||
impl RewardedSetUpdater {
|
||||
// returns boolean indicating whether we should bother continuing
|
||||
|
||||
+2
-4
@@ -1,9 +1,6 @@
|
||||
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#[macro_use]
|
||||
extern crate rocket;
|
||||
|
||||
use crate::coconut::dkg::controller::keys::{
|
||||
can_validate_coconut_keys, load_bte_keypair, load_coconut_keypair_if_exists,
|
||||
};
|
||||
@@ -20,6 +17,7 @@ use ::nym_config::defaults::setup_env;
|
||||
use circulating_supply_api::cache::CirculatingSupplyCache;
|
||||
use clap::Parser;
|
||||
use coconut::dkg::controller::DkgController;
|
||||
use log::{info, trace};
|
||||
use node_status_api::NodeStatusCache;
|
||||
use nym_bin_common::logging::setup_logging;
|
||||
use nym_config::defaults::NymNetworkDetails;
|
||||
@@ -86,7 +84,7 @@ async fn start_nym_api_tasks(config: Config) -> anyhow::Result<ShutdownHandles>
|
||||
let identity_public_key = *identity_keypair.public_key();
|
||||
|
||||
// let's build our rocket!
|
||||
let rocket = http::setup_rocket(
|
||||
let rocket = http::old_setup_rest_api(
|
||||
&config,
|
||||
network_details,
|
||||
nyxd_client.clone(),
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::network::models::{ContractInformation, NetworkDetails};
|
||||
use crate::nym_contract_cache::cache::NymContractCache;
|
||||
use nym_contracts_common::ContractBuildInformation;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::State;
|
||||
use rocket::{get, State};
|
||||
use rocket_okapi::openapi;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Deref;
|
||||
|
||||
@@ -15,6 +15,7 @@ use crate::nym_contract_cache::cache::NymContractCache;
|
||||
use crate::storage::NymApiStorage;
|
||||
use crate::support::{config, nyxd};
|
||||
use futures::channel::mpsc;
|
||||
use log::info;
|
||||
use nym_bandwidth_controller::BandwidthController;
|
||||
use nym_credential_storage::persistent_storage::PersistentStorage;
|
||||
use nym_crypto::asymmetric::{encryption, identity};
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::network_monitor::test_packet::NodeTestMessage;
|
||||
use crate::network_monitor::test_route::TestRoute;
|
||||
use crate::storage::NymApiStorage;
|
||||
use crate::support::config;
|
||||
use log::{debug, error, info};
|
||||
use log::{debug, error, info, trace};
|
||||
use nym_sphinx::params::PacketType;
|
||||
use nym_sphinx::receiver::MessageReceiver;
|
||||
use nym_task::TaskClient;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
use crate::network_monitor::monitor::sender::GatewayPackets;
|
||||
use crate::network_monitor::test_route::TestRoute;
|
||||
use crate::nym_contract_cache::cache::NymContractCache;
|
||||
use log::info;
|
||||
use log::{error, info, trace};
|
||||
use nym_crypto::asymmetric::{encryption, identity};
|
||||
use nym_mixnet_contract_common::{GatewayBond, Layer, MixNodeBond};
|
||||
use nym_node_tester_utils::node::TestableNode;
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::network_monitor::ROUTE_TESTING_TEST_NONCE;
|
||||
use futures::channel::mpsc;
|
||||
use futures::lock::{Mutex, MutexGuard};
|
||||
use futures::{SinkExt, StreamExt};
|
||||
use log::warn;
|
||||
use log::{debug, error, trace, warn};
|
||||
use nym_crypto::asymmetric::encryption;
|
||||
use nym_node_tester_utils::error::NetworkTestingError;
|
||||
use nym_node_tester_utils::processor::TestPacketProcessor;
|
||||
|
||||
@@ -5,6 +5,7 @@ use crate::network_monitor::gateways_reader::{GatewayMessages, GatewaysReader};
|
||||
use crate::network_monitor::monitor::processor::ReceivedProcessorSender;
|
||||
use futures::channel::mpsc;
|
||||
use futures::StreamExt;
|
||||
use log::trace;
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_gateway_client::{AcknowledgementReceiver, MixnetMessageReceiver};
|
||||
use nym_task::TaskClient;
|
||||
|
||||
@@ -6,7 +6,9 @@ use crate::support::caching::cache::{SharedCache, UninitialisedCache};
|
||||
use crate::support::caching::refresher::{CacheItemProvider, CacheRefresher};
|
||||
use crate::support::config;
|
||||
use crate::support::config::DEFAULT_NODE_DESCRIBE_BATCH_SIZE;
|
||||
use async_trait::async_trait;
|
||||
use futures::{stream, StreamExt};
|
||||
use log::debug;
|
||||
use nym_api_requests::models::{
|
||||
IpPacketRouterDetails, NetworkRequesterDetails, NymNodeDescription,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use log::error;
|
||||
use nym_api_requests::models::InclusionProbability;
|
||||
use nym_contracts_common::truncate_decimal;
|
||||
use nym_mixnet_contract_common::{MixId, MixNodeDetails, RewardingParams};
|
||||
|
||||
+1
@@ -4,6 +4,7 @@
|
||||
use self::data::NodeStatusCacheData;
|
||||
use self::inclusion_probabilities::InclusionProbabilities;
|
||||
use crate::support::caching::Cache;
|
||||
use log::error;
|
||||
use nym_api_requests::models::{GatewayBondAnnotated, MixNodeBondAnnotated, MixnodeStatus};
|
||||
use nym_contracts_common::{IdentityKey, IdentityKeyRef};
|
||||
use nym_mixnet_contract_common::MixId;
|
||||
|
||||
@@ -15,6 +15,7 @@ use crate::{
|
||||
storage::NymApiStorage,
|
||||
support::caching::CacheNotification,
|
||||
};
|
||||
use log::error;
|
||||
use nym_task::TaskClient;
|
||||
use std::time::Duration;
|
||||
use tokio::sync::watch;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use log::warn;
|
||||
use rocket::http::Status;
|
||||
use rocket::request::{FromRequest, Outcome};
|
||||
use rocket::Request;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
use crate::node_status_api::utils::NodeUptimes;
|
||||
use crate::storage::models::NodeStatus;
|
||||
use log::error;
|
||||
use nym_api_requests::models::{
|
||||
GatewayStatusReportResponse, GatewayUptimeHistoryResponse, HistoricalUptimeResponse,
|
||||
MixnodeStatusReportResponse, MixnodeUptimeHistoryResponse, NodePerformance, RequestError,
|
||||
|
||||
@@ -11,7 +11,7 @@ use nym_api_requests::models::{
|
||||
};
|
||||
use nym_mixnet_contract_common::MixId;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::State;
|
||||
use rocket::{get, post, State};
|
||||
use rocket_okapi::openapi;
|
||||
|
||||
use super::helpers::_get_gateways_detailed;
|
||||
@@ -233,6 +233,7 @@ pub mod unstable {
|
||||
use crate::node_status_api::models::ErrorResponse;
|
||||
use crate::support::http::helpers::PaginationRequest;
|
||||
use crate::support::storage::NymApiStorage;
|
||||
use log::{error, trace};
|
||||
use nym_api_requests::models::{
|
||||
GatewayTestResultResponse, MixnodeTestResultResponse, PartialTestResult, TestNode,
|
||||
TestRoute,
|
||||
@@ -241,7 +242,7 @@ pub mod unstable {
|
||||
use nym_mixnet_contract_common::MixId;
|
||||
use rocket::http::Status;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::State;
|
||||
use rocket::{get, State};
|
||||
use rocket_okapi::openapi;
|
||||
use std::cmp::min;
|
||||
use std::collections::HashMap;
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::node_status_api::models::{
|
||||
};
|
||||
use crate::node_status_api::ONE_DAY;
|
||||
use crate::storage::NymApiStorage;
|
||||
use log::error;
|
||||
use log::{error, info, trace, warn};
|
||||
use nym_task::{TaskClient, TaskManager};
|
||||
use std::time::Duration;
|
||||
use time::{OffsetDateTime, PrimitiveDateTime, Time};
|
||||
|
||||
+1
@@ -4,6 +4,7 @@
|
||||
use crate::nym_contract_cache::cache::data::CachedContractsInfo;
|
||||
use crate::support::caching::Cache;
|
||||
use data::ValidatorCacheData;
|
||||
use log::{debug, error};
|
||||
use nym_api_requests::models::MixnodeStatus;
|
||||
use nym_mixnet_contract_common::{
|
||||
families::FamilyHead, GatewayBond, IdentityKey, Interval, MixId, MixNodeBond, MixNodeDetails,
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::nyxd::Client;
|
||||
use crate::support::caching::CacheNotification;
|
||||
use anyhow::Result;
|
||||
use futures::future::join_all;
|
||||
use log::{error, info, trace, warn};
|
||||
use nym_mixnet_contract_common::{MixId, MixNodeDetails, RewardedSetNodeStatus};
|
||||
use nym_task::TaskClient;
|
||||
use nym_validator_client::nyxd::contract_traits::{
|
||||
|
||||
@@ -15,7 +15,7 @@ use nym_mixnet_contract_common::{
|
||||
|
||||
use nym_name_service_common::response::NamesListResponse;
|
||||
use nym_service_provider_directory_common::response::ServicesListResponse;
|
||||
use rocket::{serde::json::Json, State};
|
||||
use rocket::{get, serde::json::Json, State};
|
||||
use rocket_okapi::openapi;
|
||||
use std::collections::HashSet;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::nym_contract_cache::cache::NymContractCache;
|
||||
use crate::support::caching::cache::SharedCache;
|
||||
use nym_api_requests::models::DescribedGateway;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::State;
|
||||
use rocket::{get, State};
|
||||
use rocket_okapi::openapi;
|
||||
use std::ops::Deref;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ use nym_bin_common::build_information::BinaryBuildInformationOwned;
|
||||
use nym_coconut::Base58;
|
||||
use rocket::http::Status;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::State;
|
||||
use rocket::{get, State};
|
||||
use rocket_okapi::openapi;
|
||||
|
||||
#[openapi(tag = "Api Status")]
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::support::caching::cache::SharedCache;
|
||||
use async_trait::async_trait;
|
||||
use log::error;
|
||||
use nym_task::TaskClient;
|
||||
use std::time::Duration;
|
||||
use tokio::time::interval;
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::support::config::persistence::{
|
||||
use crate::support::config::r#override::OverrideConfig;
|
||||
use crate::support::config::template::CONFIG_TEMPLATE;
|
||||
use anyhow::bail;
|
||||
use log::debug;
|
||||
use nym_config::defaults::mainnet::read_parsed_var_if_not_default;
|
||||
use nym_config::defaults::var_names::{CONFIGURED, NYXD};
|
||||
use nym_config::serde_helpers::de_maybe_stringified;
|
||||
@@ -16,6 +17,7 @@ use nym_config::{
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::io;
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::Duration;
|
||||
use url::Url;
|
||||
@@ -225,6 +227,17 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
fn default_http_socket_addr() -> SocketAddr {
|
||||
// replicate rocket behaviour
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(debug_assertions)] {
|
||||
SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 8080)
|
||||
} else {
|
||||
SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 8080)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we only really care about the mnemonic being zeroized
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Zeroize, ZeroizeOnDrop)]
|
||||
pub struct Base {
|
||||
@@ -234,6 +247,12 @@ pub struct Base {
|
||||
#[zeroize(skip)]
|
||||
pub local_validator: Url,
|
||||
|
||||
/// Socket address this api will use for binding its http API.
|
||||
/// default: `0.0.0.0:8080`
|
||||
#[zeroize(skip)]
|
||||
#[serde(default = "default_http_socket_addr")]
|
||||
pub bind_address: SocketAddr,
|
||||
|
||||
/// Mnemonic used for rewarding and/or multisig operations
|
||||
// TODO: similarly to the note in gateway, this should get moved to a separate file
|
||||
#[serde(deserialize_with = "de_maybe_stringified")]
|
||||
@@ -256,6 +275,7 @@ impl Base {
|
||||
storage_paths: NymApiPaths::new_default(&id),
|
||||
id,
|
||||
local_validator: default_validator,
|
||||
bind_address: default_http_socket_addr(),
|
||||
mnemonic: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,10 @@ id = '{{ base.id }}'
|
||||
# Validator server to which the API will be getting information about the network.
|
||||
local_validator = '{{ base.local_validator }}'
|
||||
|
||||
# Socket address this api will use for binding its http API.
|
||||
# default: `0.0.0.0:8080`
|
||||
bind_address = '{{ base.bind_address }}'
|
||||
|
||||
# Mnemonic used for rewarding and validator interaction
|
||||
mnemonic = '{{ base.mnemonic }}'
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use rocket::FromForm;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
@@ -13,21 +13,48 @@ use crate::nym_contract_cache::cache::NymContractCache;
|
||||
use crate::status::{api_status_routes, ApiStatusState, SignerState};
|
||||
use crate::support::caching::cache::SharedCache;
|
||||
use crate::support::config::Config;
|
||||
use crate::support::http::router::NymApiRouter;
|
||||
use crate::support::{nyxd, storage};
|
||||
use crate::{circulating_supply_api, nym_contract_cache, nym_nodes::nym_node_routes};
|
||||
use anyhow::{bail, Result};
|
||||
use anyhow::{bail, Context, Result};
|
||||
use axum::Router;
|
||||
use http::{header, Method, Request, Response};
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_validator_client::nyxd::Coin;
|
||||
use rocket::http::Method;
|
||||
use rocket::{Ignite, Rocket};
|
||||
use rocket_cors::{AllowedHeaders, AllowedOrigins, Cors};
|
||||
use rocket_okapi::mount_endpoints_and_merged_docs;
|
||||
use rocket_okapi::swagger_ui::make_swagger_ui;
|
||||
use std::net::SocketAddr;
|
||||
use tower_http::cors::{Any, CorsLayer};
|
||||
|
||||
pub(crate) mod helpers;
|
||||
pub(crate) mod openapi;
|
||||
pub(crate) mod router;
|
||||
pub(crate) mod state;
|
||||
|
||||
pub(crate) async fn setup_rocket(
|
||||
pub(crate) async fn setup_rest_api(
|
||||
config: &Config,
|
||||
network_details: NetworkDetails,
|
||||
nyxd_client: nyxd::Client,
|
||||
identity_keypair: identity::KeyPair,
|
||||
coconut_keypair: coconut::keys::KeyPair,
|
||||
) -> anyhow::Result<()> {
|
||||
let bind_address = config.base.bind_address;
|
||||
// TODO: we might want to bind on both ipv4 and ipv6:
|
||||
// https://github.com/tokio-rs/axum/blob/main/examples/listen-multiple-addrs/src/main.rs
|
||||
let listener = tokio::net::TcpListener::bind(&bind_address)
|
||||
.await
|
||||
.context(format!("failed to bind http api to {bind_address}"))?;
|
||||
|
||||
let serve_future = axum::serve(
|
||||
listener,
|
||||
NymApiRouter::new().into_make_service_with_connect_info(),
|
||||
);
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub(crate) async fn old_setup_rest_api(
|
||||
config: &Config,
|
||||
network_details: NetworkDetails,
|
||||
nyxd_client: nyxd::Client,
|
||||
@@ -56,7 +83,7 @@ pub(crate) async fn setup_rocket(
|
||||
.manage(network_details)
|
||||
.manage(SharedCache::<DescribedNodes>::new())
|
||||
.mount("/swagger", make_swagger_ui(&openapi::get_docs()))
|
||||
.attach(setup_cors()?)
|
||||
.attach(old_setup_cors()?)
|
||||
.attach(NymContractCache::stage())
|
||||
.attach(NodeStatusCache::stage())
|
||||
.attach(CirculatingSupplyCache::stage(mix_denom.clone()))
|
||||
@@ -121,13 +148,13 @@ pub(crate) async fn setup_rocket(
|
||||
Ok(rocket.manage(status_state).ignite().await?)
|
||||
}
|
||||
|
||||
fn setup_cors() -> Result<Cors> {
|
||||
fn old_setup_cors() -> Result<Cors> {
|
||||
let allowed_origins = AllowedOrigins::all();
|
||||
|
||||
// You can also deserialize this
|
||||
let cors = rocket_cors::CorsOptions {
|
||||
allowed_origins,
|
||||
allowed_methods: vec![Method::Post, Method::Get]
|
||||
allowed_methods: vec![rocket::http::Method::Post, rocket::http::Method::Get]
|
||||
.into_iter()
|
||||
.map(From::from)
|
||||
.collect(),
|
||||
@@ -139,3 +166,11 @@ fn setup_cors() -> Result<Cors> {
|
||||
|
||||
Ok(cors)
|
||||
}
|
||||
|
||||
fn setup_cors() -> CorsLayer {
|
||||
CorsLayer::new()
|
||||
.allow_origin(Any)
|
||||
.allow_methods([Method::GET, Method::POST])
|
||||
.allow_headers(Any)
|
||||
.allow_credentials(true)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use axum::extract::connect_info::IntoMakeServiceWithConnectInfo;
|
||||
use axum::Router;
|
||||
use nym_http_api_common::middleware::logger;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
pub mod v1;
|
||||
|
||||
pub struct NymApiRouter {
|
||||
inner: Router,
|
||||
}
|
||||
|
||||
impl NymApiRouter {
|
||||
pub fn new() -> NymApiRouter {
|
||||
// TODO: perhaps metrics:
|
||||
// https://github.com/tokio-rs/axum/blob/main/examples/prometheus-metrics/src/main.rs
|
||||
NymApiRouter {
|
||||
inner: Router::new().layer(axum::middleware::from_fn(logger)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_make_service_with_connect_info(
|
||||
self,
|
||||
) -> IntoMakeServiceWithConnectInfo<Router, SocketAddr> {
|
||||
self.inner.into_make_service_with_connect_info()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
@@ -0,0 +1,2 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
@@ -0,0 +1,2 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
@@ -0,0 +1,2 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
@@ -0,0 +1,2 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
pub(crate) mod api_status;
|
||||
pub(crate) mod circulating_supply;
|
||||
pub(crate) mod epoch;
|
||||
pub(crate) mod gateways;
|
||||
pub(crate) mod mixnodes;
|
||||
pub(crate) mod network;
|
||||
pub(crate) mod status;
|
||||
@@ -0,0 +1,2 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
@@ -0,0 +1,2 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::circulating_supply_api::cache::CirculatingSupplyCache;
|
||||
use crate::node_describe_cache::DescribedNodes;
|
||||
use crate::node_status_api::NodeStatusCache;
|
||||
use crate::nym_contract_cache::cache::NymContractCache;
|
||||
use crate::support::caching::cache::SharedCache;
|
||||
use crate::support::storage::NymApiStorage;
|
||||
use axum::extract::FromRef;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
pub contract_cache: NymContractCache,
|
||||
pub status_cache: NodeStatusCache,
|
||||
pub circulating_supply_cache: CirculatingSupplyCache,
|
||||
pub storage: NymApiStorage,
|
||||
pub describes_nodes_state: SharedCache<DescribedNodes>,
|
||||
}
|
||||
|
||||
impl FromRef<AppState> for NymContractCache {
|
||||
fn from_ref(app_state: &AppState) -> Self {
|
||||
app_state.contract_cache.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRef<AppState> for NodeStatusCache {
|
||||
fn from_ref(app_state: &AppState) -> Self {
|
||||
app_state.status_cache.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRef<AppState> for CirculatingSupplyCache {
|
||||
fn from_ref(app_state: &AppState) -> Self {
|
||||
app_state.circulating_supply_cache.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRef<AppState> for NymApiStorage {
|
||||
fn from_ref(app_state: &AppState) -> Self {
|
||||
app_state.storage.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromRef<AppState> for SharedCache<DescribedNodes> {
|
||||
fn from_ref(app_state: &AppState) -> Self {
|
||||
app_state.describes_nodes_state.clone()
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ use crate::storage::models::{NodeStatus, TestingRoute};
|
||||
use crate::support::storage::models::{
|
||||
GatewayDetails, MixnodeDetails, TestedGatewayStatus, TestedMixnodeStatus,
|
||||
};
|
||||
use log::{error, info, warn};
|
||||
use nym_mixnet_contract_common::MixId;
|
||||
use rocket::fairing::AdHoc;
|
||||
use sqlx::ConnectOptions;
|
||||
|
||||
@@ -8,8 +8,6 @@ license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
axum.workspace = true
|
||||
axum-extra = { workspace = true, features = ["typed-header"] }
|
||||
headers.workspace = true
|
||||
|
||||
# useful for `#[axum_macros::debug_handler]`
|
||||
#axum-macros = "0.3.8"
|
||||
|
||||
@@ -11,7 +11,6 @@ use std::net::SocketAddr;
|
||||
use tracing::{debug, error};
|
||||
|
||||
pub mod error;
|
||||
pub mod middleware;
|
||||
pub mod router;
|
||||
pub mod state;
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
pub mod logging;
|
||||
@@ -9,7 +9,6 @@ use nym_task::TaskClient;
|
||||
use std::net::SocketAddr;
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
pub mod middleware;
|
||||
pub mod router;
|
||||
pub mod state;
|
||||
|
||||
|
||||
@@ -8,24 +8,30 @@ use crate::state::metrics::MetricsAppState;
|
||||
use axum::extract::FromRef;
|
||||
use axum::routing::get;
|
||||
use axum::Router;
|
||||
use nym_http_api_common::middleware::BearerAuthLayer;
|
||||
use nym_node_requests::routes::api::v1::metrics;
|
||||
|
||||
pub mod mixing;
|
||||
pub mod prometheus;
|
||||
pub mod verloc;
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct Config {
|
||||
//
|
||||
pub prometheus_token: String,
|
||||
}
|
||||
|
||||
pub(super) fn routes<S>(_config: Config) -> Router<S>
|
||||
pub(super) fn routes<S>(config: Config) -> Router<S>
|
||||
where
|
||||
S: Send + Sync + 'static + Clone,
|
||||
MetricsAppState: FromRef<S>,
|
||||
{
|
||||
let auth_middleware = BearerAuthLayer::new_raw(config.prometheus_token);
|
||||
|
||||
Router::new()
|
||||
.route(metrics::MIXING, get(mixing_stats))
|
||||
.route(metrics::VERLOC, get(verloc_stats))
|
||||
.route(metrics::PROMETHEUS, get(prometheus_metrics))
|
||||
.route(
|
||||
metrics::PROMETHEUS,
|
||||
get(prometheus_metrics).layer(auth_middleware),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::state::metrics::MetricsAppState;
|
||||
use axum::extract::State;
|
||||
use axum::http::StatusCode;
|
||||
use axum_extra::TypedHeader;
|
||||
use headers::authorization::Bearer;
|
||||
use headers::Authorization;
|
||||
use nym_metrics::metrics;
|
||||
|
||||
/// Returns `prometheus` compatible metrics
|
||||
@@ -25,21 +19,6 @@ use nym_metrics::metrics;
|
||||
("prometheus_token" = [])
|
||||
)
|
||||
)]
|
||||
pub(crate) async fn prometheus_metrics<'a>(
|
||||
TypedHeader(authorization): TypedHeader<Authorization<Bearer>>,
|
||||
State(state): State<MetricsAppState>,
|
||||
) -> Result<String, StatusCode> {
|
||||
if authorization.token().is_empty() {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
// TODO: is 500 the correct error code here?
|
||||
let Some(metrics_key) = state.prometheus_access_token else {
|
||||
return Err(StatusCode::INTERNAL_SERVER_ERROR);
|
||||
};
|
||||
|
||||
if metrics_key != authorization.token() {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
Ok(metrics!())
|
||||
pub(crate) async fn prometheus_metrics() -> String {
|
||||
metrics!()
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
pub use crate::api::v1::gateway::client_interfaces::wireguard::WireguardAppState;
|
||||
use crate::error::NymNodeHttpError;
|
||||
use crate::middleware::logging;
|
||||
use crate::state::AppState;
|
||||
use crate::NymNodeHTTPServer;
|
||||
use axum::response::Redirect;
|
||||
use axum::routing::get;
|
||||
use axum::Router;
|
||||
use nym_http_api_common::middleware::logger;
|
||||
use nym_node_requests::api::v1::gateway::models::{Gateway, Wireguard};
|
||||
use nym_node_requests::api::v1::ip_packet_router::models::IpPacketRouter;
|
||||
use nym_node_requests::api::v1::mixnode::models::Mixnode;
|
||||
@@ -148,6 +148,12 @@ impl Config {
|
||||
self.api.v1_config.ip_packet_router.details = Some(ip_packet_router);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_metrics_token(mut self, bearer_token: impl Into<Option<String>>) -> Self {
|
||||
self.api.v1_config.metrics.prometheus_token = bearer_token.into().unwrap_or_default();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NymNodeRouter {
|
||||
@@ -193,7 +199,7 @@ impl NymNodeRouter {
|
||||
routes::API,
|
||||
api::routes(config.api, initial_wg_state.unwrap_or_default()),
|
||||
)
|
||||
.layer(axum::middleware::from_fn(logging::logger))
|
||||
.layer(axum::middleware::from_fn(logger))
|
||||
.with_state(state),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,8 +134,6 @@ impl VerlocStatsState {
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct MetricsAppState {
|
||||
pub(crate) prometheus_access_token: Option<String>,
|
||||
|
||||
pub(crate) mixing_stats: SharedMixingStats,
|
||||
|
||||
pub(crate) verloc: SharedVerlocStats,
|
||||
|
||||
@@ -37,10 +37,4 @@ impl AppState {
|
||||
self.metrics.verloc = verloc_stats;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_metrics_key(mut self, bearer_token: impl Into<Option<String>>) -> Self {
|
||||
self.metrics.prometheus_access_token = bearer_token.into();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,6 +369,7 @@ pub struct Http {
|
||||
/// An optional bearer token for accessing certain http endpoints.
|
||||
/// Currently only used for obtaining mixnode's stats.
|
||||
#[serde(default)]
|
||||
#[serde(deserialize_with = "de_maybe_stringified")]
|
||||
pub access_token: Option<String>,
|
||||
|
||||
/// Specify whether basic system information should be exposed.
|
||||
|
||||
@@ -540,7 +540,8 @@ impl NymNode {
|
||||
.with_ip_packet_router_details(ipr_details)
|
||||
.with_used_exit_policy(exit_policy_details)
|
||||
.with_description(self.description.clone())
|
||||
.with_auxiliary_details(auxiliary_details);
|
||||
.with_auxiliary_details(auxiliary_details)
|
||||
.with_metrics_token(self.config.http.access_token.clone());
|
||||
|
||||
if self.config.http.expose_system_info {
|
||||
config = config.with_system_info(get_system_info(
|
||||
@@ -560,8 +561,7 @@ impl NymNode {
|
||||
|
||||
let app_state = AppState::new()
|
||||
.with_mixing_stats(self.mixnode.mixing_stats.clone())
|
||||
.with_verloc_stats(self.verloc_stats.clone())
|
||||
.with_metrics_key(self.config.http.access_token.clone());
|
||||
.with_verloc_stats(self.verloc_stats.clone());
|
||||
|
||||
Ok(NymNodeRouter::new(config, Some(app_state), Some(wg_state))
|
||||
.build_server(&self.config.http.bind_address)
|
||||
|
||||
Reference in New Issue
Block a user