diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/interval.rs index 019b7a7062..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, @@ -67,11 +66,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/nym-wallet/src-tauri/src/main.rs b/nym-wallet/src-tauri/src/main.rs index bb5320e403..61d78ed3de 100644 --- a/nym-wallet/src-tauri/src/main.rs +++ b/nym-wallet/src-tauri/src/main.rs @@ -56,6 +56,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 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..749ee16d41 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::{ @@ -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, @@ -357,28 +356,6 @@ impl Client { Ok(()) } - pub(crate) async fn reward_mixnodes( - &self, - nodes: &[MixnodeToReward], - interval_id: u32, - ) -> Result)>, RewardingError> - where - C: SigningCosmWasmClient + Sync, - { - let msgs: Vec<(ExecuteMsg, _)> = nodes - .iter() - .map(|node| node.to_reward_execute_msg(interval_id)) - .zip(std::iter::repeat(Vec::new())) - .collect(); - - // 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( &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> {