Feature/validator api panics (#1520)
* Coconut unwraps * Fail softly on epoch queries * Update changelog * Retry a few times before failing as before
This commit is contained in:
committed by
GitHub
parent
a7afd2a1c7
commit
41ac866729
@@ -53,6 +53,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
||||
- All binaries and cosmwasm blobs are configured at runtime now; binaries are configured using environment variables or .env files and contracts keep the configuration parameters in storage ([#1463])
|
||||
- gateway, network-statistics: include gateway id in the sent statistical data ([#1478])
|
||||
- network explorer: tweak how active set probability is shown ([#1503])
|
||||
- validator-api: rewarder set update fails without panicking on possible nymd queries ([#1520])
|
||||
|
||||
|
||||
[#1249]: https://github.com/nymtech/nym/pull/1249
|
||||
@@ -81,6 +82,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
||||
[#1487]: https://github.com/nymtech/nym/pull/1487
|
||||
[#1496]: https://github.com/nymtech/nym/pull/1496
|
||||
[#1503]: https://github.com/nymtech/nym/pull/1503
|
||||
[#1520]: https://github.com/nymtech/nym/pull/1520
|
||||
|
||||
## [nym-connect-v1.0.1](https://github.com/nymtech/nym/tree/nym-connect-v1.0.1) (2022-07-22)
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ gateway-client = { path="../common/client-libs/gateway-client" }
|
||||
mixnet-contract-common = { path= "../common/cosmwasm-smart-contracts/mixnet-contract" }
|
||||
multisig-contract-common = { path = "../common/cosmwasm-smart-contracts/multisig-contract" }
|
||||
nymsphinx = { path="../common/nymsphinx" }
|
||||
nymcoconut = { path = "../common/nymcoconut", optional = true }
|
||||
task = { path = "../common/task" }
|
||||
topology = { path="../common/topology" }
|
||||
validator-api-requests = { path = "validator-api-requests" }
|
||||
@@ -71,7 +72,7 @@ console-subscriber = { version = "0.1.1", optional = true}
|
||||
cfg-if = "1.0"
|
||||
|
||||
[features]
|
||||
coconut = ["coconut-interface", "credentials", "gateway-client/coconut", "credentials/coconut", "validator-api-requests/coconut"]
|
||||
coconut = ["coconut-interface", "credentials", "gateway-client/coconut", "credentials/coconut", "validator-api-requests/coconut", "nymcoconut"]
|
||||
no-reward = []
|
||||
generate-ts = []
|
||||
|
||||
@@ -82,6 +83,5 @@ vergen = { version = "5", default-features = false, features = ["build", "git",
|
||||
|
||||
[dev-dependencies]
|
||||
attohttpc = {version = "0.18.0", features = ["json"]}
|
||||
nymcoconut = { path = "../common/nymcoconut" }
|
||||
cw3 = "0.13.2"
|
||||
cw-utils = "0.13.2"
|
||||
|
||||
@@ -31,6 +31,9 @@ pub enum CoconutError {
|
||||
#[error("Nymd error - {0}")]
|
||||
NymdError(#[from] NymdError),
|
||||
|
||||
#[error("Coconut internal error - {0}")]
|
||||
CoconutInternalError(#[from] nymcoconut::CoconutError),
|
||||
|
||||
#[error("Could not find a deposit event in the transaction provided")]
|
||||
DepositEventNotFound,
|
||||
|
||||
|
||||
@@ -192,15 +192,14 @@ impl InternalSignRequest {
|
||||
}
|
||||
}
|
||||
|
||||
fn blind_sign(request: InternalSignRequest, key_pair: &KeyPair) -> BlindedSignature {
|
||||
let params = Parameters::new(request.total_params()).unwrap();
|
||||
coconut_interface::blind_sign(
|
||||
fn blind_sign(request: InternalSignRequest, key_pair: &KeyPair) -> Result<BlindedSignature> {
|
||||
let params = Parameters::new(request.total_params())?;
|
||||
Ok(coconut_interface::blind_sign(
|
||||
¶ms,
|
||||
&key_pair.secret_key(),
|
||||
request.blind_sign_request(),
|
||||
request.public_attributes(),
|
||||
)
|
||||
.unwrap()
|
||||
)?)
|
||||
}
|
||||
|
||||
#[post("/blind-sign", data = "<blind_sign_request_body>")]
|
||||
@@ -226,7 +225,7 @@ pub async fn post_blind_sign(
|
||||
blind_sign_request_body.public_attributes(),
|
||||
blind_sign_request_body.blind_sign_request().clone(),
|
||||
);
|
||||
let blinded_signature = blind_sign(internal_request, &state.key_pair);
|
||||
let blinded_signature = blind_sign(internal_request, &state.key_pair)?;
|
||||
|
||||
let response = state
|
||||
.encrypt_and_store(
|
||||
|
||||
@@ -22,6 +22,7 @@ use mixnet_contract_common::{IdentityKey, Interval, MixNodeBond};
|
||||
use rand::prelude::SliceRandom;
|
||||
use rand::rngs::OsRng;
|
||||
use std::collections::HashSet;
|
||||
use std::ops::Deref;
|
||||
use std::time::Duration;
|
||||
use time::OffsetDateTime;
|
||||
use tokio::time::sleep;
|
||||
@@ -58,7 +59,44 @@ impl MixnodeToReward {
|
||||
}
|
||||
|
||||
// Epoch has all the same semantics as interval, but has a lower set duration
|
||||
type Epoch = Interval;
|
||||
pub struct Epoch(Interval);
|
||||
|
||||
impl Epoch {
|
||||
pub(crate) async fn update_to_latest(
|
||||
&mut self,
|
||||
rewarded_set_updater: &RewardedSetUpdater,
|
||||
) -> Result<(), RewardingError> {
|
||||
let mut wait_time = 2;
|
||||
let mut ret = Ok(());
|
||||
for _ in 0..3 {
|
||||
match rewarded_set_updater.nymd_client.get_current_epoch().await {
|
||||
Ok(epoch) => {
|
||||
*self = Epoch(epoch);
|
||||
return Ok(());
|
||||
}
|
||||
Err(e) => {
|
||||
warn!(
|
||||
"Could not update epoch: {:?}. Retrying again in {} seconds",
|
||||
e, wait_time
|
||||
);
|
||||
ret = Err(e);
|
||||
}
|
||||
};
|
||||
sleep(Duration::from_secs(wait_time)).await;
|
||||
wait_time *= wait_time;
|
||||
}
|
||||
error!("Failed to update epoch. Exiting now");
|
||||
Ok(ret?)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Epoch {
|
||||
type Target = Interval;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RewardedSetUpdater {
|
||||
nymd_client: Client<SigningNymdClient>,
|
||||
@@ -68,7 +106,7 @@ pub struct RewardedSetUpdater {
|
||||
|
||||
impl RewardedSetUpdater {
|
||||
pub(crate) async fn epoch(&self) -> Result<Epoch, RewardingError> {
|
||||
Ok(self.nymd_client.get_current_epoch().await?)
|
||||
Ok(Epoch(self.nymd_client.get_current_epoch().await?))
|
||||
}
|
||||
|
||||
pub(crate) async fn new(
|
||||
@@ -120,9 +158,10 @@ impl RewardedSetUpdater {
|
||||
|
||||
async fn reward_current_rewarded_set(
|
||||
&self,
|
||||
epoch: &mut Epoch,
|
||||
) -> Result<Vec<(ExecuteMsg, Vec<Coin>)>, RewardingError> {
|
||||
let to_reward = self.nodes_to_reward().await?;
|
||||
let epoch = self.epoch().await?;
|
||||
let to_reward = self.nodes_to_reward(epoch).await?;
|
||||
epoch.update_to_latest(self).await?;
|
||||
|
||||
// self.storage.insert_started_epoch_rewarding(epoch).await?;
|
||||
|
||||
@@ -157,8 +196,11 @@ impl RewardedSetUpdater {
|
||||
}
|
||||
}
|
||||
|
||||
async fn nodes_to_reward(&self) -> Result<Vec<MixnodeToReward>, RewardingError> {
|
||||
let epoch = self.epoch().await?;
|
||||
async fn nodes_to_reward(
|
||||
&self,
|
||||
epoch: &mut Epoch,
|
||||
) -> Result<Vec<MixnodeToReward>, RewardingError> {
|
||||
epoch.update_to_latest(self).await?;
|
||||
let active_set = self
|
||||
.validator_cache
|
||||
.active_set_detailed()
|
||||
@@ -200,8 +242,8 @@ impl RewardedSetUpdater {
|
||||
}
|
||||
|
||||
// This is where the epoch gets advanced, and all epoch related transactions originate
|
||||
async fn update(&self) -> Result<(), RewardingError> {
|
||||
let epoch = self.epoch().await?;
|
||||
async fn update(&self, epoch: &mut Epoch) -> Result<(), RewardingError> {
|
||||
epoch.update_to_latest(self).await?;
|
||||
log::info!("Starting rewarded set update");
|
||||
// we know the entries are not stale, as a matter of fact they were JUST updated, since we got notified
|
||||
let all_nodes = self.validator_cache.mixnodes().await;
|
||||
@@ -218,7 +260,7 @@ impl RewardedSetUpdater {
|
||||
// log::info!("Rewarded current rewarded set... SUCCESS");
|
||||
// }
|
||||
|
||||
let reward_msgs = self.reward_current_rewarded_set().await?;
|
||||
let reward_msgs = self.reward_current_rewarded_set(epoch).await?;
|
||||
|
||||
let rewarded_set_size = epoch_reward_params.rewarded_set_size() as u32;
|
||||
let active_set_size = epoch_reward_params.active_set_size() as u32;
|
||||
@@ -288,11 +330,12 @@ impl RewardedSetUpdater {
|
||||
|
||||
pub(crate) async fn run(&mut self) -> Result<(), RewardingError> {
|
||||
self.validator_cache.wait_for_initial_values().await;
|
||||
let mut epoch = self.epoch().await?;
|
||||
|
||||
loop {
|
||||
// wait until the cache refresher determined its time to update the rewarded/active sets
|
||||
let time = OffsetDateTime::now_utc().unix_timestamp();
|
||||
let epoch = self.epoch().await?;
|
||||
epoch.update_to_latest(self).await?;
|
||||
let time_to_epoch_change = epoch.end_unix_timestamp() - time;
|
||||
if time_to_epoch_change <= 0 {
|
||||
self.update_blacklist(&epoch).await?;
|
||||
@@ -300,7 +343,7 @@ impl RewardedSetUpdater {
|
||||
"Time to epoch change is {}, updating rewarded set",
|
||||
time_to_epoch_change
|
||||
);
|
||||
self.update().await?;
|
||||
self.update(&mut epoch).await?;
|
||||
} else {
|
||||
log::info!(
|
||||
"Waiting for epoch change, time to epoch change is {}",
|
||||
|
||||
Reference in New Issue
Block a user