e52fe65985
* Add identicons package * Tidy up styling and move methods into component directories with better naming * Add mixnode status colours to theme * Mixnode status and icon components * Add status to mixnode types * Add API method to get mixnode details * Add mixnode details to state * Add status and name+description section to mixnode detail page * Wrap with div instead of p * Limit width of description and link to new tab * Limit length of link button and truncate with elipsis * Replace `filter` with `find` * Move mix node detail components to a location that is better named * Refactor mixnode detail state and separate into an independent context from main state. This prevents the mixnode detail page from showing stale data when switching between mix nodes. * Tidy up mixnode detail page adding new state provider and a guard component to handle loading, error and not found states * Layout changes to mixnode description header section * Add methods to Explorer API client to get a mixnode by id, active set by status and overview summary * Add color prop to StatsCard and make count optional * Add optional start and end children to TableToolbar * Tidy up naming * Add summary overview and getting mixnodes by active set status to main state * Add mix node status overview cards * Add mix node status to routes * Mixnode list has a dropdown component to select the active set status * Clean up caching code * Add resource to get a single mixnode by id * Add API resources to get `active`, `inactive` and `standby` mixnodes * Add mixnode summary to API * Add overview summary endpoint to API * Fix OpenAPI/swagger base url * Make clippy happy * Add method to get validators * Add methods to get active and rewarded mixnodes * Fix naming * Move client creation to crate root * Move cache to module * Delete unused files * Add validators API resource * Add gateways API resource * Move tasks to crate root * Add new HTTP resources for validators and gateways to routes * Tidy up naming and locations for mixnodes * Add validator and gateways to state, and tidy up naming * Add gateways and validator modules to main * Overview shows validator and gateway summaries from state * Bundle variable weight Open Sans fonts * Fix up font weights and sizes * Fix up typing * Fix up social icons * Fix navbar colour * Fix paper colour in dark mode and border radius * Fix up stats card * Tidy up Nym icons * Fix up overview * Fix up spacing and padding for overview * Add light mode shades that are darker for mixnode status values * Review feedback
106 lines
3.1 KiB
Rust
106 lines
3.1 KiB
Rust
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
use crate::cache::Cache;
|
|
use crate::mix_nodes::location::Location;
|
|
use mixnet_contract_common::{Addr, Coin, Layer, MixNode};
|
|
use serde::Deserialize;
|
|
use serde::Serialize;
|
|
use std::sync::Arc;
|
|
use std::time::SystemTime;
|
|
use tokio::sync::RwLock;
|
|
|
|
#[derive(Clone, Debug, Serialize, JsonSchema, PartialEq)]
|
|
#[serde(rename_all = "snake_case")]
|
|
pub(crate) 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
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, JsonSchema)]
|
|
pub(crate) struct PrettyDetailedMixNodeBond {
|
|
pub location: Option<Location>,
|
|
pub status: MixnodeStatus,
|
|
pub pledge_amount: Coin,
|
|
pub total_delegation: Coin,
|
|
pub owner: Addr,
|
|
pub layer: Layer,
|
|
pub mix_node: MixNode,
|
|
}
|
|
|
|
pub(crate) struct MixNodeCache {
|
|
pub(crate) descriptions: Cache<NodeDescription>,
|
|
pub(crate) node_stats: Cache<NodeStats>,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub(crate) struct ThreadsafeMixNodeCache {
|
|
inner: Arc<RwLock<MixNodeCache>>,
|
|
}
|
|
|
|
impl ThreadsafeMixNodeCache {
|
|
pub(crate) fn new() -> Self {
|
|
ThreadsafeMixNodeCache {
|
|
inner: Arc::new(RwLock::new(MixNodeCache {
|
|
descriptions: Cache::new(),
|
|
node_stats: Cache::new(),
|
|
})),
|
|
}
|
|
}
|
|
|
|
pub(crate) async fn get_description(&self, identity_key: &str) -> Option<NodeDescription> {
|
|
self.inner.read().await.descriptions.get(identity_key)
|
|
}
|
|
|
|
pub(crate) async fn get_node_stats(&self, identity_key: &str) -> Option<NodeStats> {
|
|
self.inner.read().await.node_stats.get(identity_key)
|
|
}
|
|
|
|
pub(crate) async fn set_description(&self, identity_key: &str, description: NodeDescription) {
|
|
self.inner
|
|
.write()
|
|
.await
|
|
.descriptions
|
|
.set(identity_key, description);
|
|
}
|
|
|
|
pub(crate) async fn set_node_stats(&self, identity_key: &str, node_stats: NodeStats) {
|
|
self.inner
|
|
.write()
|
|
.await
|
|
.node_stats
|
|
.set(identity_key, node_stats);
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
|
pub(crate) struct NodeDescription {
|
|
pub(crate) name: String,
|
|
pub(crate) description: String,
|
|
pub(crate) link: String,
|
|
pub(crate) location: String,
|
|
}
|
|
|
|
#[derive(Serialize, Clone, Deserialize, JsonSchema)]
|
|
pub(crate) struct NodeStats {
|
|
#[serde(
|
|
serialize_with = "humantime_serde::serialize",
|
|
deserialize_with = "humantime_serde::deserialize"
|
|
)]
|
|
update_time: SystemTime,
|
|
|
|
#[serde(
|
|
serialize_with = "humantime_serde::serialize",
|
|
deserialize_with = "humantime_serde::deserialize"
|
|
)]
|
|
previous_update_time: SystemTime,
|
|
|
|
packets_received_since_startup: u64,
|
|
packets_sent_since_startup: u64,
|
|
packets_explicitly_dropped_since_startup: u64,
|
|
packets_received_since_last_update: u64,
|
|
packets_sent_since_last_update: u64,
|
|
packets_explicitly_dropped_since_last_update: u64,
|
|
}
|