Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jedrzej/bugfix/historical uptimes recording #1721

Merged
merged 5 commits into from
Oct 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
### Fixed

- validator-api, mixnode, gateway should now prefer values in config.toml over mainnet defaults ([#1645])
- validator-api should now correctly update historical uptimes for all mixnodes and gateways every 24h ([#1721])
- socks5-client: fix bug where in some cases packet reordering could trigger a connection being closed too early ([#1702],[#1724])

### Changed
Expand All @@ -47,6 +48,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
[#1687]: https://github.com/nymtech/nym/pull/1687
[#1702]: https://github.com/nymtech/nym/pull/1702
[#1703]: https://github.com/nymtech/nym/pull/1703
[#1721]: https://github.com/nymtech/nym/pull/1721
[#1724]: https://github.com/nymtech/nym/pull/1724
[#1725]: https://github.com/nymtech/nym/pull/1725

Expand Down
8 changes: 3 additions & 5 deletions validator-api/src/epoch_operations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub(crate) mod error;
mod helpers;

use crate::epoch_operations::helpers::stake_to_f64;
use crate::node_status_api::ONE_DAY;
use error::RewardingError;
use mixnet_contract_common::mixnode::MixNodeDetails;
use task::ShutdownListener;
Expand All @@ -50,9 +51,6 @@ impl From<MixnodeToReward> for ExecuteMsg {
}
}

// // Epoch has all the same semantics as interval, but has a lower set duration
// type Epoch = Interval;

pub struct RewardedSetUpdater {
nymd_client: Client<SigningNymdClient>,
validator_cache: ValidatorCache,
Expand Down Expand Up @@ -268,8 +266,8 @@ impl RewardedSetUpdater {
log::info!("Advanced the epoch and updated the rewarded set... SUCCESS");
}

log::info!("Puring all node statuses from the storage...");
let cutoff = (epoch_end - Duration::from_secs(86400)).unix_timestamp();
log::info!("Purging old node statuses from the storage...");
let cutoff = (epoch_end - 2 * ONE_DAY).unix_timestamp();
self.storage.purge_old_statuses(cutoff).await?;

Ok(())
Expand Down
62 changes: 43 additions & 19 deletions validator-api/src/node_status_api/uptime_updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ use crate::node_status_api::models::{
use crate::node_status_api::ONE_DAY;
use crate::storage::ValidatorApiStorage;
use log::error;
use std::time::Duration;
use task::ShutdownListener;
use time::OffsetDateTime;
use tokio::time::sleep;
use time::{OffsetDateTime, PrimitiveDateTime, Time};
use tokio::time::{interval, sleep};

pub(crate) struct HistoricalUptimeUpdater {
storage: ValidatorApiStorage,
Expand Down Expand Up @@ -69,28 +70,51 @@ impl HistoricalUptimeUpdater {
}

pub(crate) async fn run(&self, mut shutdown: ShutdownListener) {
// update uptimes at 23:00 UTC each day so that we'd have data from the actual [almost] whole day
// and so that we would avoid the edge case of starting validator API at 23:59 and having some
// nodes update for different days

// the unwrap is fine as 23:00:00 is a valid time
let update_time = Time::from_hms(23, 0, 0).unwrap();
let now = OffsetDateTime::now_utc();
// is the current time within 0:00 - 22:59:59 or 23:00 - 23:59:59 ?
let update_date = if now.hour() < 23 {
now.date()
} else {
// the unwrap is fine as (**PRESUMABLY**) we're not running this code in the year 9999
now.date().next_day().unwrap()
};
let update_datetime = PrimitiveDateTime::new(update_date, update_time).assume_utc();
// the unwrap here is fine as we're certain `update_datetime` is in the future and thus the
// resultant Duration is positive
let time_left: Duration = (update_datetime - now).try_into().unwrap();

log::info!(
"waiting until {update_datetime} to update the historical uptimes for the first time ({} seconds left)", time_left.as_secs()
);

tokio::select! {
biased;
_ = shutdown.recv() => {
trace!("UpdateHandler: Received shutdown");
}
_ = sleep(time_left) => {}
}

let mut interval = interval(ONE_DAY);
while !shutdown.is_shutdown() {
tokio::select! {
_ = sleep(ONE_DAY) => {
tokio::select! {
biased;
_ = shutdown.recv() => {
trace!("UpdateHandler: Received shutdown");
}
Err(err) = self.update_uptimes() => {
// normally that would have been a warning rather than an error,
// however, in this case it implies some underlying issues with our database
// that might affect the entire program
error!(
"We failed to update daily uptimes of active nodes - {}",
err
);
}
}
}
biased;
_ = shutdown.recv() => {
trace!("UpdateHandler: Received shutdown");
}
_ = interval.tick() => {
// we don't want to have another select here; uptime update is relatively speedy
// and we don't want to exit while we're in the middle of database update
if let Err(err) = self.update_uptimes().await {
error!("We failed to update daily uptimes of active nodes - {err}");
}
}
}
}
}
Expand Down