// Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use super::NodeStatusCache; use crate::node_status_api::helpers::{ _compute_mixnode_reward_estimation, _get_mixnode_avg_uptime, _get_mixnode_inclusion_probability, _get_mixnode_reward_estimation, _get_mixnode_stake_saturation, _get_mixnode_status, _mixnode_core_status_count, _mixnode_report, _mixnode_uptime_history, }; use crate::node_status_api::models::ErrorResponse; use crate::storage::ValidatorApiStorage; use crate::ValidatorCache; use mixnet_contract_common::MixId; use rocket::http::Status; use rocket::serde::json::Json; use rocket::State; use rocket_okapi::openapi; use validator_api_requests::models::{ AllInclusionProbabilitiesResponse, ComputeRewardEstParam, GatewayCoreStatusResponse, GatewayStatusReportResponse, GatewayUptimeHistoryResponse, InclusionProbabilityResponse, MixnodeCoreStatusResponse, MixnodeStatusReportResponse, MixnodeStatusResponse, MixnodeUptimeHistoryResponse, RewardEstimationResponse, StakeSaturationResponse, UptimeResponse, }; #[openapi(tag = "status")] #[get("/gateway//report")] pub(crate) async fn gateway_report( storage: &State, identity: &str, ) -> Result, ErrorResponse> { storage .construct_gateway_report(identity) .await .map(GatewayStatusReportResponse::from) .map(Json) .map_err(|err| ErrorResponse::new(err.to_string(), Status::NotFound)) } #[openapi(tag = "status")] #[get("/gateway//history")] pub(crate) async fn gateway_uptime_history( storage: &State, identity: &str, ) -> Result, ErrorResponse> { storage .get_gateway_uptime_history(identity) .await .map(GatewayUptimeHistoryResponse::from) .map(Json) .map_err(|err| ErrorResponse::new(err.to_string(), Status::NotFound)) } #[openapi(tag = "status")] #[get("/gateway//core-status-count?")] pub(crate) async fn gateway_core_status_count( storage: &State, identity: &str, since: Option, ) -> Json { let count = storage .get_core_gateway_status_count(identity, since) .await .unwrap_or_default(); Json(GatewayCoreStatusResponse { identity: identity.to_string(), count, }) } #[openapi(tag = "status")] #[get("/mixnode//report")] pub(crate) async fn mixnode_report( storage: &State, mix_id: MixId, ) -> Result, ErrorResponse> { Ok(Json(_mixnode_report(storage, mix_id).await?)) } #[openapi(tag = "status")] #[get("/mixnode//history")] pub(crate) async fn mixnode_uptime_history( storage: &State, mix_id: MixId, ) -> Result, ErrorResponse> { Ok(Json(_mixnode_uptime_history(storage, mix_id).await?)) } #[openapi(tag = "status")] #[get("/mixnode//core-status-count?")] pub(crate) async fn mixnode_core_status_count( storage: &State, mix_id: MixId, since: Option, ) -> Result, ErrorResponse> { Ok(Json( _mixnode_core_status_count(storage, mix_id, since).await?, )) } #[openapi(tag = "status")] #[get("/mixnode//status")] pub(crate) async fn get_mixnode_status( cache: &State, mix_id: MixId, ) -> Json { Json(_get_mixnode_status(cache, mix_id).await) } #[openapi(tag = "status")] #[get("/mixnode//reward-estimation")] pub(crate) async fn get_mixnode_reward_estimation( cache: &State, mix_id: MixId, ) -> Result, ErrorResponse> { Ok(Json(_get_mixnode_reward_estimation(cache, mix_id).await?)) } #[openapi(tag = "status")] #[post( "/mixnode//compute-reward-estimation", data = "" )] pub(crate) async fn compute_mixnode_reward_estimation( user_reward_param: Json, cache: &State, mix_id: MixId, ) -> Result, ErrorResponse> { Ok(Json( _compute_mixnode_reward_estimation(user_reward_param.into_inner(), cache, mix_id).await?, )) } #[openapi(tag = "status")] #[get("/mixnode//stake-saturation")] pub(crate) async fn get_mixnode_stake_saturation( cache: &State, mix_id: MixId, ) -> Result, ErrorResponse> { Ok(Json(_get_mixnode_stake_saturation(cache, mix_id).await?)) } #[openapi(tag = "status")] #[get("/mixnode//inclusion-probability")] pub(crate) async fn get_mixnode_inclusion_probability( cache: &State, mix_id: MixId, ) -> Result, ErrorResponse> { Ok(Json( _get_mixnode_inclusion_probability(cache, mix_id).await?, )) } #[openapi(tag = "status")] #[get("/mixnode//avg_uptime")] pub(crate) async fn get_mixnode_avg_uptime( cache: &State, storage: &State, mix_id: MixId, ) -> Result, ErrorResponse> { Ok(Json(_get_mixnode_avg_uptime(cache, storage, mix_id).await?)) } #[openapi(tag = "status")] #[get("/mixnodes/inclusion_probability")] pub(crate) async fn get_mixnode_inclusion_probabilities( cache: &State, ) -> Result, ErrorResponse> { if let Some(prob) = cache.inclusion_probabilities().await { let as_at = prob.timestamp(); let prob = prob.into_inner(); Ok(Json(AllInclusionProbabilitiesResponse { inclusion_probabilities: prob.inclusion_probabilities, samples: prob.samples, elapsed: prob.elapsed, delta_max: prob.delta_max, delta_l2: prob.delta_l2, as_at, })) } else { Err(ErrorResponse::new( "No data available".to_string(), Status::ServiceUnavailable, )) } }