020cad897d
* Calculating gas fees * Ability to set custom fees * Added extra test * Removed commented code * Moved all msg types to common contract crate * Temporarily disabling get_tx method * Finishing up nymd client API * Comment fix * Remaining fee values * Some cleanup * Removed needless borrow * Fixed imports in contract tests * Moved error types around * New ValidatorClient * Experiment with new type of defaults * Removed dead module * Dealt with unwrap * Migrated mixnode to use new validator client * Migrated gateway to use new validator client * Mixnode and gateway adjustments * More exported defaults * Clients using new validator client * Fixed mixnode upgrade * Moved default values to a new crate * Changed behaviour of validator client features * Migrated basic functions of validator api * Updated config + fixed startup * Fixed wasm client build * Integration with the explorer api * Removed tokio dev dependency * Needless borrow * Fixex wasm client build * Fixed tauri client build * Needless borrows * New tables for rewarding * Updated cosmos-sdk version * Removed reward-specific node status routes * New rewarding-specific config entries * Additional network defaults * Initial periodic rewards from validator api * Replaced print with log * Filtering nodes with uptime > 0 * Additional failure logging statements * Fixed operation ordering * Adjusted next rewarding epoch determination * Modified rewarding behaviour to keep track of rewarding in progress * Improved error message on config load failure * Additional log statement * Adjusted rewarding gas limit calculation * Made naming slightly more consistent * Fixed incorrect parentheses placement * Fixed fee calculation * Cargo fmt * Removed failed merge artifacts * Introduced comment for any future reward modification * typos * Helper functions for the future * Making @mfahampshire 's life easier * Redesigned epoch + rewarding skipped epochs (if possible) * Removed old merge artifacts * Naming consistency * Constraining arguments * Removed unnecessary if branch * Ignore monitor check for current epoch * Additional checks for current epoch data * Monitor threshold check * cargo fmt * Fixed post-merge issues in transactions.rs
164 lines
4.5 KiB
Rust
164 lines
4.5 KiB
Rust
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
use crate::nymd_client::Client;
|
|
use anyhow::Result;
|
|
use config::defaults::VALIDATOR_API_VERSION;
|
|
use mixnet_contract::{GatewayBond, MixNodeBond};
|
|
use rocket::fairing::AdHoc;
|
|
use serde::Serialize;
|
|
use std::sync::atomic::{AtomicBool, Ordering};
|
|
use std::sync::Arc;
|
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
|
use tokio::sync::RwLock;
|
|
use tokio::time;
|
|
use validator_client::nymd::CosmWasmClient;
|
|
|
|
pub(crate) mod routes;
|
|
|
|
pub struct ValidatorCacheRefresher<C> {
|
|
nymd_client: Client<C>,
|
|
cache: ValidatorCache,
|
|
caching_interval: Duration,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct ValidatorCache {
|
|
inner: Arc<ValidatorCacheInner>,
|
|
}
|
|
|
|
struct ValidatorCacheInner {
|
|
initialised: AtomicBool,
|
|
mixnodes: RwLock<Cache<Vec<MixNodeBond>>>,
|
|
gateways: RwLock<Cache<Vec<GatewayBond>>>,
|
|
}
|
|
|
|
#[derive(Default, Serialize, Clone)]
|
|
pub struct Cache<T> {
|
|
value: T,
|
|
as_at: u64,
|
|
}
|
|
|
|
impl<T: Clone> Cache<T> {
|
|
fn set(&mut self, value: T) {
|
|
self.value = value;
|
|
self.as_at = SystemTime::now()
|
|
.duration_since(UNIX_EPOCH)
|
|
.unwrap()
|
|
.as_secs()
|
|
}
|
|
|
|
pub fn into_inner(self) -> T {
|
|
self.value
|
|
}
|
|
}
|
|
|
|
impl<C> ValidatorCacheRefresher<C> {
|
|
pub(crate) fn new(
|
|
nymd_client: Client<C>,
|
|
caching_interval: Duration,
|
|
cache: ValidatorCache,
|
|
) -> Self {
|
|
ValidatorCacheRefresher {
|
|
nymd_client,
|
|
cache,
|
|
caching_interval,
|
|
}
|
|
}
|
|
|
|
async fn refresh_cache(&self) -> Result<()>
|
|
where
|
|
C: CosmWasmClient + Sync,
|
|
{
|
|
let (mixnodes, gateways) = tokio::try_join!(
|
|
self.nymd_client.get_mixnodes(),
|
|
self.nymd_client.get_gateways()
|
|
)?;
|
|
|
|
info!(
|
|
"Updating validator cache. There are {} mixnodes and {} gateways",
|
|
mixnodes.len(),
|
|
gateways.len()
|
|
);
|
|
|
|
self.cache.update_cache(mixnodes, gateways).await;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) async fn run(&self)
|
|
where
|
|
C: CosmWasmClient + Sync,
|
|
{
|
|
let mut interval = time::interval(self.caching_interval);
|
|
loop {
|
|
interval.tick().await;
|
|
if let Err(err) = self.refresh_cache().await {
|
|
error!("Failed to refresh validator cache - {}", err);
|
|
} else {
|
|
// relaxed memory ordering is fine here. worst case scenario network monitor
|
|
// will just have to wait for an additional backoff to see the change.
|
|
// And so this will not really incur any performance penalties by setting it every loop iteration
|
|
self.cache.inner.initialised.store(true, Ordering::Relaxed)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ValidatorCache {
|
|
fn new() -> Self {
|
|
ValidatorCache {
|
|
inner: Arc::new(ValidatorCacheInner::new()),
|
|
}
|
|
}
|
|
|
|
pub fn stage() -> AdHoc {
|
|
AdHoc::on_ignite("Validator Cache Stage", |rocket| async {
|
|
rocket.manage(Self::new()).mount(
|
|
// this format! is so ugly...
|
|
format!("/{}", VALIDATOR_API_VERSION),
|
|
routes![routes::get_mixnodes, routes::get_gateways],
|
|
)
|
|
})
|
|
}
|
|
|
|
async fn update_cache(&self, mixnodes: Vec<MixNodeBond>, gateways: Vec<GatewayBond>) {
|
|
self.inner.mixnodes.write().await.set(mixnodes);
|
|
self.inner.gateways.write().await.set(gateways);
|
|
}
|
|
|
|
pub async fn mixnodes(&self) -> Cache<Vec<MixNodeBond>> {
|
|
self.inner.mixnodes.read().await.clone()
|
|
}
|
|
|
|
pub async fn gateways(&self) -> Cache<Vec<GatewayBond>> {
|
|
self.inner.gateways.read().await.clone()
|
|
}
|
|
|
|
pub fn initialised(&self) -> bool {
|
|
self.inner.initialised.load(Ordering::Relaxed)
|
|
}
|
|
|
|
pub(crate) async fn wait_for_initial_values(&self) {
|
|
let initialisation_backoff = Duration::from_secs(5);
|
|
loop {
|
|
if self.initialised() {
|
|
break;
|
|
} else {
|
|
debug!("Validator cache hasn't been initialised yet - waiting for {:?} before trying again", initialisation_backoff);
|
|
tokio::time::sleep(initialisation_backoff).await;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ValidatorCacheInner {
|
|
fn new() -> Self {
|
|
ValidatorCacheInner {
|
|
initialised: AtomicBool::new(false),
|
|
mixnodes: RwLock::new(Cache::default()),
|
|
gateways: RwLock::new(Cache::default()),
|
|
}
|
|
}
|
|
}
|