From 66799446894cae24807e2edd241f8c34258552f9 Mon Sep 17 00:00:00 2001 From: Drazen Urch Date: Mon, 21 Mar 2022 17:30:08 +0100 Subject: [PATCH 1/4] Feature flag reward payments (#1154) --- validator-api/Cargo.toml | 1 + validator-api/src/nymd_client.rs | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/validator-api/Cargo.toml b/validator-api/Cargo.toml index ad55ccfc28..0b606cd4aa 100644 --- a/validator-api/Cargo.toml +++ b/validator-api/Cargo.toml @@ -60,6 +60,7 @@ cfg-if = "1.0" [features] coconut = ["coconut-interface", "credentials", "gateway-client/coconut"] +no-reward = [] [build-dependencies] tokio = { version = "1.4", features = ["rt-multi-thread", "macros"] } diff --git a/validator-api/src/nymd_client.rs b/validator-api/src/nymd_client.rs index c88a5035dd..a221f51366 100644 --- a/validator-api/src/nymd_client.rs +++ b/validator-api/src/nymd_client.rs @@ -365,18 +365,24 @@ impl Client { where C: SigningCosmWasmClient + Sync, { - let msgs: Vec<(ExecuteMsg, _)> = nodes + cfg_if::cfg_if! { + if #[cfg(feature = "no-reward")] { + Ok(vec![]) + } else { + let msgs: Vec<(ExecuteMsg, _)> = nodes .iter() .map(|node| node.to_reward_execute_msg(interval_id)) .zip(std::iter::repeat(Vec::new())) .collect(); + Ok(msgs) + } + } + // let memo = format!("rewarding {} mixnodes", msgs.len()); // self.execute_multiple_with_retry(msgs, Default::default(), memo) // .await - - Ok(msgs) } async fn execute_multiple_with_retry( From 071720c1cc828c97ed7740bd5430113852a85ce7 Mon Sep 17 00:00:00 2001 From: Drazen Urch Date: Mon, 21 Mar 2022 18:24:40 +0100 Subject: [PATCH 2/4] Cleanup (#1155) --- .../mixnet-contract/src/interval.rs | 5 ++-- .../mixnet-contract/src/msg.rs | 3 -- contracts/mixnet/src/contract.rs | 10 ++----- validator-api/src/nymd_client.rs | 30 +------------------ validator-api/src/rewarded_set_updater/mod.rs | 28 ++++++++++------- 5 files changed, 24 insertions(+), 52 deletions(-) diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs index 019b7a7062..8b1e8c2476 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs @@ -67,11 +67,12 @@ pub struct Interval { impl Interval { /// Initialize epoch in the contract with default values. - /// FIXME: THIS unwrap! pub fn init_epoch(env: Env) -> Self { Interval { id: 0, - start: OffsetDateTime::from_unix_timestamp(env.block.time.seconds() as i64).unwrap(), + // I really don't see a way for this to fail, unless the blockchain is lying to us + start: OffsetDateTime::from_unix_timestamp(env.block.time.seconds() as i64) + .expect("Invalid timestamp from env.block.time"), length: Duration::from_secs(3600), } } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs index 4a05088e32..7a48f343d1 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs @@ -62,9 +62,6 @@ pub enum ExecuteMsg { identity: IdentityKey, // percentage value in range 0-100 params: NodeRewardParams, - - // id of the current rewarding interval - interval_id: u32, }, // RewardNextMixDelegators { // mix_identity: IdentityKey, diff --git a/contracts/mixnet/src/contract.rs b/contracts/mixnet/src/contract.rs index d82def8b0c..6dce029ae8 100644 --- a/contracts/mixnet/src/contract.rs +++ b/contracts/mixnet/src/contract.rs @@ -146,13 +146,9 @@ pub fn execute( deps, info, params, ) } - #[allow(unused_variables)] - // FIXME: remove interval_id - ExecuteMsg::RewardMixnode { - identity, - params, - interval_id, - } => crate::rewards::transactions::try_reward_mixnode(deps, env, info, identity, params), + ExecuteMsg::RewardMixnode { identity, params } => { + crate::rewards::transactions::try_reward_mixnode(deps, env, info, identity, params) + } ExecuteMsg::DelegateToMixnode { mix_identity } => { crate::delegations::transactions::try_delegate_to_mixnode(deps, env, info, mix_identity) } diff --git a/validator-api/src/nymd_client.rs b/validator-api/src/nymd_client.rs index a221f51366..9cdbcb96dc 100644 --- a/validator-api/src/nymd_client.rs +++ b/validator-api/src/nymd_client.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::config::Config; -use crate::rewarded_set_updater::{error::RewardingError, MixnodeToReward}; +use crate::rewarded_set_updater::error::RewardingError; use config::defaults::{DEFAULT_NETWORK, DEFAULT_VALIDATOR_API_PORT}; use mixnet_contract_common::Interval; use mixnet_contract_common::{ @@ -357,34 +357,6 @@ impl Client { Ok(()) } - pub(crate) async fn reward_mixnodes( - &self, - nodes: &[MixnodeToReward], - interval_id: u32, - ) -> Result)>, RewardingError> - where - C: SigningCosmWasmClient + Sync, - { - cfg_if::cfg_if! { - if #[cfg(feature = "no-reward")] { - Ok(vec![]) - } else { - let msgs: Vec<(ExecuteMsg, _)> = nodes - .iter() - .map(|node| node.to_reward_execute_msg(interval_id)) - .zip(std::iter::repeat(Vec::new())) - .collect(); - - Ok(msgs) - } - } - - // let memo = format!("rewarding {} mixnodes", msgs.len()); - - // self.execute_multiple_with_retry(msgs, Default::default(), memo) - // .await - } - async fn execute_multiple_with_retry( &self, msgs: Vec<(M, Vec)>, diff --git a/validator-api/src/rewarded_set_updater/mod.rs b/validator-api/src/rewarded_set_updater/mod.rs index b5a2ddbf04..cdec073ba4 100644 --- a/validator-api/src/rewarded_set_updater/mod.rs +++ b/validator-api/src/rewarded_set_updater/mod.rs @@ -43,15 +43,16 @@ pub(crate) struct MixnodeToReward { } impl MixnodeToReward { + #[allow(dead_code)] fn params(&self) -> NodeRewardParams { self.params } - pub(crate) fn to_reward_execute_msg(&self, interval_id: u32) -> ExecuteMsg { + #[allow(dead_code)] + pub(crate) fn to_reward_execute_msg(&self) -> ExecuteMsg { ExecuteMsg::RewardMixnode { identity: self.identity.clone(), params: self.params(), - interval_id, } } } @@ -138,20 +139,25 @@ impl RewardedSetUpdater { .insert_rewarding_report(rewarding_report) .await?; - Ok(self.distribute_rewards(&to_reward).await?) + Ok(self.generate_reward_messages(&to_reward).await?) } - async fn distribute_rewards( + #[allow(unused_variables)] + async fn generate_reward_messages( &self, eligible_mixnodes: &[MixnodeToReward], ) -> Result)>, RewardingError> { - let epoch = self.epoch().await?; - - let reward_msgs = self - .nymd_client - .reward_mixnodes(eligible_mixnodes, epoch.id()) - .await?; - Ok(reward_msgs) + cfg_if::cfg_if! { + if #[cfg(feature = "no-reward")] { + Ok(vec![]) + } else { + Ok(eligible_mixnodes + .iter() + .map(|node| node.to_reward_execute_msg()) + .zip(std::iter::repeat(Vec::new())) + .collect()) + } + } } async fn nodes_to_reward(&self) -> Result, RewardingError> { From fb5a9a7a3e9cd5332c2dffb7b2bc2dee5dac9087 Mon Sep 17 00:00:00 2001 From: durch Date: Mon, 21 Mar 2022 20:08:57 +0100 Subject: [PATCH 3/4] Fix opeartion order --- validator-api/src/nymd_client.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/validator-api/src/nymd_client.rs b/validator-api/src/nymd_client.rs index 9cdbcb96dc..749ee16d41 100644 --- a/validator-api/src/nymd_client.rs +++ b/validator-api/src/nymd_client.rs @@ -332,13 +332,12 @@ impl Client { where C: SigningCosmWasmClient + Sync, { - let mut msgs = vec![(ExecuteMsg::AdvanceCurrentEpoch {}, vec![])]; - - msgs.extend(reward_msgs); + let mut msgs = reward_msgs; let epoch_msgs = vec![ (ExecuteMsg::ReconcileDelegations {}, vec![]), (ExecuteMsg::CheckpointMixnodes {}, vec![]), + (ExecuteMsg::AdvanceCurrentEpoch {}, vec![]), ( ExecuteMsg::WriteRewardedSet { rewarded_set, From b710f796f908786735007600636bd2a1decd1e07 Mon Sep 17 00:00:00 2001 From: durch Date: Tue, 22 Mar 2022 11:10:41 +0100 Subject: [PATCH 4/4] get_current_epoch tauri --- .../mixnet-contract/src/interval.rs | 1 - nym-wallet/src-tauri/src/main.rs | 1 + .../src-tauri/src/operations/mixnet/epoch.rs | 36 +++++++++++++++++++ .../src-tauri/src/operations/mixnet/mod.rs | 1 + nym-wallet/src/types/rust/epoch.ts | 2 ++ 5 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 nym-wallet/src-tauri/src/operations/mixnet/epoch.rs create mode 100644 nym-wallet/src/types/rust/epoch.ts diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs index 8b1e8c2476..1062980cdb 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs @@ -56,7 +56,6 @@ pub(crate) mod string_rfc3339_offset_date_time { } } -/// Representation of rewarding interval. #[derive(Clone, Copy, Debug, Deserialize, PartialEq, PartialOrd, Serialize)] pub struct Interval { id: u32, diff --git a/nym-wallet/src-tauri/src/main.rs b/nym-wallet/src-tauri/src/main.rs index 7ade07deaf..07671da836 100644 --- a/nym-wallet/src-tauri/src/main.rs +++ b/nym-wallet/src-tauri/src/main.rs @@ -55,6 +55,7 @@ fn main() { mixnet::delegate::get_reverse_mix_delegations_paged, mixnet::delegate::undelegate_from_mixnode, mixnet::delegate::get_pending_delegation_events, + mixnet::epoch::get_current_epoch, mixnet::send::send, utils::major_to_minor, utils::minor_to_major, diff --git a/nym-wallet/src-tauri/src/operations/mixnet/epoch.rs b/nym-wallet/src-tauri/src/operations/mixnet/epoch.rs new file mode 100644 index 0000000000..085564ca06 --- /dev/null +++ b/nym-wallet/src-tauri/src/operations/mixnet/epoch.rs @@ -0,0 +1,36 @@ +use crate::error::BackendError; +use crate::nymd_client; +use crate::state::State; +use mixnet_contract_common::Interval; +use serde::{Deserialize, Serialize}; +use std::sync::Arc; +use tokio::sync::RwLock; + +#[cfg_attr(test, derive(ts_rs::TS))] +#[cfg_attr(test, ts(export, export_to = "../src/types/rust/epoch.ts"))] +#[derive(Clone, Copy, Debug, Deserialize, PartialEq, PartialOrd, Serialize)] +pub struct Epoch { + id: u32, + start: i64, + end: i64, + duration_seconds: u64, +} + +impl From for Epoch { + fn from(interval: Interval) -> Self { + Self { + id: interval.id(), + start: interval.start_unix_timestamp(), + end: interval.end_unix_timestamp(), + duration_seconds: interval.length().as_secs(), + } + } +} + +#[tauri::command] +pub async fn get_current_epoch( + state: tauri::State<'_, Arc>>, +) -> Result { + let interval = nymd_client!(state).get_current_epoch().await?; + Ok(interval.into()) +} diff --git a/nym-wallet/src-tauri/src/operations/mixnet/mod.rs b/nym-wallet/src-tauri/src/operations/mixnet/mod.rs index 47f4788d6c..e59890f38e 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/mod.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/mod.rs @@ -2,4 +2,5 @@ pub mod account; pub mod admin; pub mod bond; pub mod delegate; +pub mod epoch; pub mod send; diff --git a/nym-wallet/src/types/rust/epoch.ts b/nym-wallet/src/types/rust/epoch.ts new file mode 100644 index 0000000000..eaa95571ff --- /dev/null +++ b/nym-wallet/src/types/rust/epoch.ts @@ -0,0 +1,2 @@ + +export interface Epoch { id: number, start: bigint, end: bigint, duration_seconds: bigint, } \ No newline at end of file