Feature/node state endpoint (#1013)
* Introduced route to check mixnode's status (active/standby/inactive/not_found) * Restored default validator API caching interval to a more sane value * Changed status route
This commit is contained in:
committed by
GitHub
parent
30e93c33bb
commit
62fa2ae5e4
Vendored
+54
-1
@@ -4,7 +4,9 @@
|
||||
use crate::nymd_client::Client;
|
||||
use anyhow::Result;
|
||||
use config::defaults::VALIDATOR_API_VERSION;
|
||||
use mixnet_contract::{ContractStateParams, GatewayBond, MixNodeBond, RewardingIntervalResponse};
|
||||
use mixnet_contract::{
|
||||
ContractStateParams, GatewayBond, IdentityKey, MixNodeBond, RewardingIntervalResponse,
|
||||
};
|
||||
use rand::prelude::SliceRandom;
|
||||
use rand_chacha::rand_core::SeedableRng;
|
||||
use rand_chacha::ChaCha20Rng;
|
||||
@@ -20,6 +22,15 @@ use validator_client::nymd::CosmWasmClient;
|
||||
|
||||
pub(crate) mod routes;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum MixnodeStatus {
|
||||
Active, // in both the active set and the rewarded set
|
||||
Standby, // only in the rewarded set
|
||||
Inactive, // in neither the rewarded set nor the active set, but is bonded
|
||||
NotFound, // doesn't even exist in the bonded set
|
||||
}
|
||||
|
||||
pub struct ValidatorCacheRefresher<C> {
|
||||
nymd_client: Client<C>,
|
||||
cache: ValidatorCache,
|
||||
@@ -157,6 +168,7 @@ impl ValidatorCache {
|
||||
routes::get_gateways,
|
||||
routes::get_active_mixnodes,
|
||||
routes::get_rewarded_mixnodes,
|
||||
routes::get_mixnode_status,
|
||||
],
|
||||
)
|
||||
})
|
||||
@@ -305,6 +317,47 @@ impl ValidatorCache {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn mixnode_status(&self, identity: IdentityKey) -> MixnodeStatus {
|
||||
// it might not be the most optimal to possibly iterate the entire vector to find (or not)
|
||||
// the relevant value. However, the vectors are relatively small (< 10_000 elements) and
|
||||
// the implementation for active/rewarded sets might change soon so there's no point in premature optimisation
|
||||
// with HashSets
|
||||
let rewarded_mixnodes = &self.inner.rewarded_mixnodes.read().await.value;
|
||||
let active_set_size = self
|
||||
.inner
|
||||
.current_mixnode_active_set_size
|
||||
.load(Ordering::SeqCst) as usize;
|
||||
|
||||
// see if node is in the top active_set_size of rewarded nodes, i.e. it's active
|
||||
if rewarded_mixnodes
|
||||
.iter()
|
||||
.take(active_set_size)
|
||||
.any(|mix| mix.mix_node.identity_key == identity)
|
||||
{
|
||||
MixnodeStatus::Active
|
||||
// see if it's in the bottom part of the rewarded set, i.e. it's in standby
|
||||
} else if rewarded_mixnodes
|
||||
.iter()
|
||||
.skip(active_set_size)
|
||||
.any(|mix| mix.mix_node.identity_key == identity)
|
||||
{
|
||||
MixnodeStatus::Standby
|
||||
// if it's not in the rewarded set see if its bonded at all
|
||||
} else if self
|
||||
.inner
|
||||
.mixnodes
|
||||
.read()
|
||||
.await
|
||||
.value
|
||||
.iter()
|
||||
.any(|mix| mix.mix_node.identity_key == identity)
|
||||
{
|
||||
MixnodeStatus::Inactive
|
||||
} else {
|
||||
MixnodeStatus::NotFound
|
||||
}
|
||||
}
|
||||
|
||||
pub fn initialised(&self) -> bool {
|
||||
self.inner.initialised.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
Vendored
+17
-1
@@ -1,10 +1,11 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::cache::ValidatorCache;
|
||||
use crate::cache::{MixnodeStatus, ValidatorCache};
|
||||
use mixnet_contract::{GatewayBond, MixNodeBond};
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::State;
|
||||
use serde::Serialize;
|
||||
|
||||
#[get("/mixnodes")]
|
||||
pub(crate) async fn get_mixnodes(cache: &State<ValidatorCache>) -> Json<Vec<MixNodeBond>> {
|
||||
@@ -25,3 +26,18 @@ pub(crate) async fn get_rewarded_mixnodes(cache: &State<ValidatorCache>) -> Json
|
||||
pub(crate) async fn get_active_mixnodes(cache: &State<ValidatorCache>) -> Json<Vec<MixNodeBond>> {
|
||||
Json(cache.active_mixnodes().await.value)
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub(crate) struct MixnodeStatusResponse {
|
||||
status: MixnodeStatus,
|
||||
}
|
||||
|
||||
#[get("/mixnode/<identity>/status")]
|
||||
pub(crate) async fn get_mixnode_status(
|
||||
cache: &State<ValidatorCache>,
|
||||
identity: String,
|
||||
) -> Json<MixnodeStatusResponse> {
|
||||
Json(MixnodeStatusResponse {
|
||||
status: cache.mixnode_status(identity).await,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ const DEFAULT_MINIMUM_TEST_ROUTES: usize = 1;
|
||||
const DEFAULT_ROUTE_TEST_PACKETS: usize = 1000;
|
||||
const DEFAULT_PER_NODE_TEST_PACKETS: usize = 3;
|
||||
|
||||
const DEFAULT_CACHE_INTERVAL: Duration = Duration::from_secs(5);
|
||||
const DEFAULT_CACHE_INTERVAL: Duration = Duration::from_secs(30);
|
||||
const DEFAULT_MONITOR_THRESHOLD: u8 = 60;
|
||||
|
||||
#[derive(Debug, Default, Deserialize, PartialEq, Serialize)]
|
||||
|
||||
Reference in New Issue
Block a user