Update tokenomics
This commit is contained in:
@@ -182,25 +182,18 @@ impl<C> Client<C> {
|
||||
Ok(self.nymd.get_state_params().await?)
|
||||
}
|
||||
|
||||
pub async fn get_total_mix_stake(&self) -> Result<u128, ValidatorClientError>
|
||||
pub async fn get_reward_pool(&self) -> Result<u128, ValidatorClientError>
|
||||
where
|
||||
C: CosmWasmClient + Sync,
|
||||
{
|
||||
Ok(self.nymd.get_total_mix_stake().await?.u128())
|
||||
Ok(self.nymd.get_reward_pool().await?.u128())
|
||||
}
|
||||
|
||||
pub async fn get_total_gateway_stake(&self) -> Result<u128, ValidatorClientError>
|
||||
pub async fn get_circulating_supply(&self) -> Result<u128, ValidatorClientError>
|
||||
where
|
||||
C: CosmWasmClient + Sync,
|
||||
{
|
||||
Ok(self.nymd.get_total_gateway_stake().await?.u128())
|
||||
}
|
||||
|
||||
pub async fn get_inflation_pool(&self) -> Result<u128, ValidatorClientError>
|
||||
where
|
||||
C: CosmWasmClient + Sync,
|
||||
{
|
||||
Ok(self.nymd.get_inflation_pool().await?.u128())
|
||||
Ok(self.nymd.get_circulating_supply().await?.u128())
|
||||
}
|
||||
|
||||
// basically handles paging for us
|
||||
|
||||
@@ -212,31 +212,21 @@ impl<C> NymdClient<C> {
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_total_mix_stake(&self) -> Result<Uint128, NymdError>
|
||||
pub async fn get_reward_pool(&self) -> Result<Uint128, NymdError>
|
||||
where
|
||||
C: CosmWasmClient + Sync,
|
||||
{
|
||||
let request = QueryMsg::GetTotalMixStake {};
|
||||
let request = QueryMsg::GetRewardPool {};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_total_gateway_stake(&self) -> Result<Uint128, NymdError>
|
||||
pub async fn get_circulating_supply(&self) -> Result<Uint128, NymdError>
|
||||
where
|
||||
C: CosmWasmClient + Sync,
|
||||
{
|
||||
let request = QueryMsg::GetTotalGatewayStake {};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_inflation_pool(&self) -> Result<Uint128, NymdError>
|
||||
where
|
||||
C: CosmWasmClient + Sync,
|
||||
{
|
||||
let request = QueryMsg::GetInflationPool {};
|
||||
let request = QueryMsg::GetCirculatingSupply {};
|
||||
self.client
|
||||
.query_contract_smart(self.contract_address()?, &request)
|
||||
.await
|
||||
|
||||
@@ -55,31 +55,31 @@ pub enum Layer {
|
||||
|
||||
#[derive(Debug, Clone, JsonSchema, PartialEq, Serialize, Deserialize, Copy)]
|
||||
pub struct NodeRewardParams {
|
||||
income_global_mix: u128,
|
||||
period_reward_pool: u128,
|
||||
k: u128,
|
||||
one_over_k: Decimal,
|
||||
total_epoch_uptime: u128,
|
||||
reward_blockstamp: Option<u64>,
|
||||
total_mix_stake: u128,
|
||||
circulating_supply: u128,
|
||||
uptime: u128,
|
||||
}
|
||||
|
||||
impl NodeRewardParams {
|
||||
pub fn new(
|
||||
income_global_mix: u128,
|
||||
period_reward_pool: u128,
|
||||
k: u128,
|
||||
total_epoch_uptime: u128,
|
||||
reward_blockstamp: Option<u64>,
|
||||
total_mix_stake: u128,
|
||||
circulating_supply: u128,
|
||||
uptime: u128,
|
||||
) -> NodeRewardParams {
|
||||
NodeRewardParams {
|
||||
income_global_mix,
|
||||
period_reward_pool,
|
||||
k,
|
||||
one_over_k: ratio_to_decimal(Ratio::new(1, k)),
|
||||
total_epoch_uptime,
|
||||
reward_blockstamp,
|
||||
total_mix_stake,
|
||||
circulating_supply,
|
||||
uptime,
|
||||
}
|
||||
}
|
||||
@@ -96,16 +96,16 @@ impl NodeRewardParams {
|
||||
self.reward_blockstamp = Some(blockstamp);
|
||||
}
|
||||
|
||||
pub fn income_global_mix(&self) -> u128 {
|
||||
self.income_global_mix
|
||||
pub fn period_reward_pool(&self) -> u128 {
|
||||
self.period_reward_pool
|
||||
}
|
||||
|
||||
pub fn k(&self) -> u128 {
|
||||
self.k
|
||||
}
|
||||
|
||||
pub fn total_mix_stake(&self) -> u128 {
|
||||
self.total_mix_stake
|
||||
pub fn circulating_supply(&self) -> u128 {
|
||||
self.circulating_supply
|
||||
}
|
||||
|
||||
pub fn reward_blockstamp(&self) -> Result<u64, MixnetContractError> {
|
||||
@@ -207,27 +207,28 @@ impl MixNodeBond {
|
||||
self.total_delegation.clone()
|
||||
}
|
||||
|
||||
pub fn bond_to_total_stake(&self, total_stake: u128) -> Ratio<u128> {
|
||||
Ratio::new(self.bond_amount().amount.u128(), total_stake)
|
||||
pub fn bond_to_circulating_supply(&self, circulating_supply: u128) -> Ratio<u128> {
|
||||
Ratio::new(self.bond_amount().amount.u128(), circulating_supply)
|
||||
}
|
||||
|
||||
pub fn stake_to_total_stake(&self, total_stake: u128) -> Ratio<u128> {
|
||||
pub fn delegations_to_circulating_supply(&self, delegations_to_circulating_supply: u128) -> Ratio<u128> {
|
||||
Ratio::new(
|
||||
self.bond_amount().amount.u128() + self.total_delegation().amount.u128(),
|
||||
total_stake,
|
||||
self.total_delegation().amount.u128(),
|
||||
delegations_to_circulating_supply,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn lambda(&self, params: &NodeRewardParams) -> Ratio<u128> {
|
||||
// Ratio of a bond to the total stake available in the mixnet
|
||||
let bond_to_total_stake_ratio = self.bond_to_total_stake(params.total_mix_stake);
|
||||
bond_to_total_stake_ratio.min(params.one_over_k())
|
||||
let bond_to_circulating_supply_ratio = self.bond_to_circulating_supply(params.circulating_supply());
|
||||
bond_to_circulating_supply_ratio.min(params.one_over_k())
|
||||
}
|
||||
|
||||
pub fn sigma(&self, params: &NodeRewardParams) -> Ratio<u128> {
|
||||
// Ratio of a bond + delegation to the total stake available in the mixnet
|
||||
let stake_to_total_stake_ratio = self.stake_to_total_stake(params.total_mix_stake);
|
||||
stake_to_total_stake_ratio.min(params.one_over_k())
|
||||
let delegations_to_circulating_supply_ratio =
|
||||
self.delegations_to_circulating_supply(params.circulating_supply());
|
||||
delegations_to_circulating_supply_ratio.min(params.one_over_k())
|
||||
}
|
||||
|
||||
pub fn reward(&self, params: &NodeRewardParams) -> NodeRewardResult {
|
||||
@@ -237,7 +238,7 @@ impl MixNodeBond {
|
||||
let sigma = self.sigma(params);
|
||||
|
||||
let reward = (params.performance()
|
||||
* params.income_global_mix()
|
||||
* params.period_reward_pool()
|
||||
* (sigma * omega_k + params.alpha() * lambda * (sigma * params.k)))
|
||||
/ (Ratio::new(1u128, 1u128) + params.alpha());
|
||||
|
||||
@@ -271,8 +272,8 @@ impl MixNodeBond {
|
||||
}
|
||||
|
||||
pub fn sigma_ratio(&self, params: &NodeRewardParams) -> Ratio<u128> {
|
||||
if self.stake_to_total_stake(params.total_mix_stake) < params.one_over_k() {
|
||||
self.stake_to_total_stake(params.total_mix_stake)
|
||||
if self.delegations_to_circulating_supply(params.circulating_supply()) < params.one_over_k() {
|
||||
self.delegations_to_circulating_supply(params.circulating_supply())
|
||||
} else {
|
||||
params.one_over_k()
|
||||
}
|
||||
@@ -283,7 +284,8 @@ impl MixNodeBond {
|
||||
delegation_amount: Uint128,
|
||||
params: &NodeRewardParams,
|
||||
) -> Result<u128, MixnetContractError> {
|
||||
let scaled_delegation_amount = Ratio::new(delegation_amount.u128(), params.total_mix_stake);
|
||||
let scaled_delegation_amount =
|
||||
Ratio::new(delegation_amount.u128(), params.circulating_supply());
|
||||
|
||||
let delegator_reward = (Ratio::new(1, 1) - self.profit_margin_ratio())
|
||||
* (scaled_delegation_amount / self.sigma(params))
|
||||
|
||||
@@ -114,9 +114,8 @@ pub enum QueryMsg {
|
||||
address: Addr,
|
||||
},
|
||||
LayerDistribution {},
|
||||
GetTotalMixStake {},
|
||||
GetTotalGatewayStake {},
|
||||
GetInflationPool {},
|
||||
GetRewardPool {},
|
||||
GetCirculatingSupply {}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
|
||||
@@ -93,6 +93,8 @@ pub const VALIDATOR_API_VERSION: &str = "v1";
|
||||
|
||||
// REWARDING
|
||||
pub const DEFAULT_FIRST_EPOCH_START: OffsetDateTime = time::macros::datetime!(2021-08-23 12:00 UTC);
|
||||
pub const DEFAULT_EPOCH_LENGTH: Duration = Duration::from_secs(24 * 60 * 60); // 24h
|
||||
pub const DEFAULT_EPOCH_LENGTH: Duration = Duration::from_secs(24 * 60 * 60 * 30); // 30 days
|
||||
/// We'll be assuming a few more things, profit margin and cost function. Since we don't have relialable package measurement, we'll be using uptime. We'll also set the value of 1 Nym to 1 $, to be able to translate epoch costs to Nyms. We'll also assume a cost of 40$ per epoch(month), converting that to Nym at our 1$ rate translates to 40_000_000 uNyms
|
||||
pub const DEFAULT_OPERATOR_EPOCH_COST: u64 = 1333333; // 40$ a month at 1 Nym == 1$
|
||||
pub const DEFAULT_OPERATOR_EPOCH_COST: u64 = 40_000_000; // 40$/(30 days) at 1 Nym == 1$
|
||||
// TODO: is there a way to get this from the chain
|
||||
pub const TOTAL_SUPPLY: u128 = 1_000_000_000_000_000;
|
||||
|
||||
@@ -31,8 +31,9 @@ pub const INITIAL_GATEWAY_DELEGATION_REWARD_RATE: u64 = 110;
|
||||
pub const INITIAL_MIXNODE_ACTIVE_SET_SIZE: u32 = 100;
|
||||
pub const INITIAL_GATEWAY_ACTIVE_SET_SIZE: u32 = 20;
|
||||
|
||||
// Based on the PyEcon scripts and scaled down to three nodes on the QA net.
|
||||
pub const INITIAL_INFLATION_POOL: u128 = 10500_00000000;
|
||||
pub const REWARD_POOL: u128 = 250_000_000_000_000;
|
||||
pub const EPOCH_REWARD_PERCENT: u8 = 2; // Used to calculate epoch reward pool
|
||||
|
||||
// We'll be assuming a few more things, profit margin and cost function. Since we don't have relialable package measurement, we'll be using uptime. We'll also set the value of 1 Nym to 1 $, to be able to translate epoch costs to Nyms. We'll also assume a cost of 40$ per epoch(month), converting that to Nym at our 1$ rate translates to 40_000_000 uNyms
|
||||
pub const DEFAULT_COST_PER_EPOCH: u32 = 40_000_000;
|
||||
|
||||
@@ -41,6 +42,7 @@ fn default_initial_state(owner: Addr) -> State {
|
||||
let gateway_bond_reward_rate = Decimal::percent(INITIAL_GATEWAY_BOND_REWARD_RATE);
|
||||
let mixnode_delegation_reward_rate = Decimal::percent(INITIAL_MIXNODE_DELEGATION_REWARD_RATE);
|
||||
let gateway_delegation_reward_rate = Decimal::percent(INITIAL_GATEWAY_DELEGATION_REWARD_RATE);
|
||||
let epoch_reward_percent = EPOCH_REWARD_PERCENT;
|
||||
|
||||
State {
|
||||
owner,
|
||||
@@ -217,23 +219,23 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result<QueryResponse, Cont
|
||||
gateway_identity,
|
||||
address,
|
||||
)?),
|
||||
QueryMsg::GetTotalMixStake {} => to_binary(&queries::query_total_mix_stake(deps)),
|
||||
QueryMsg::GetTotalGatewayStake {} => to_binary(&queries::query_total_gt_stake(deps)),
|
||||
QueryMsg::GetInflationPool {} => to_binary(&queries::query_inflation_pool(deps)),
|
||||
QueryMsg::GetRewardPool {} => to_binary(&queries::query_reward_pool(deps)),
|
||||
QueryMsg::GetCirculatingSupply {} => to_binary(&queries::query_circulating_supply(deps))
|
||||
};
|
||||
|
||||
Ok(query_res?)
|
||||
}
|
||||
#[entry_point]
|
||||
pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
|
||||
use crate::storage::{
|
||||
gateways_read, incr_total_gateway_stake, incr_total_mix_stake, mixnodes, PREFIX_MIXNODES,
|
||||
};
|
||||
use cosmwasm_std::{Coin, Order, StdResult};
|
||||
use crate::storage::{mixnodes, PREFIX_MIXNODES};
|
||||
use cosmwasm_std::{Coin, Order};
|
||||
use cosmwasm_storage::bucket_read;
|
||||
use mixnet_contract::{GatewayBond, Layer, MixNodeBond};
|
||||
use mixnet_contract::{Layer, MixNodeBond};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
// We've done the migraiton on QAnet already
|
||||
return Ok(Default::default());
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct OldMixNodeBond {
|
||||
pub bond_amount: Coin,
|
||||
@@ -266,21 +268,9 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result<Response, C
|
||||
.collect::<Vec<(Vec<u8>, MixNodeBond)>>();
|
||||
|
||||
for (key, bond) in mixnode_bonds {
|
||||
incr_total_mix_stake(bond.bond_amount().amount, deps.storage)?;
|
||||
incr_total_mix_stake(bond.total_delegation().amount, deps.storage)?;
|
||||
mixnodes(deps.storage).save(&key, &bond)?;
|
||||
}
|
||||
|
||||
let gateway_bonds = gateways_read(deps.storage)
|
||||
.range(None, None, Order::Ascending)
|
||||
.map(|res| res.map(|item| item.1))
|
||||
.collect::<StdResult<Vec<GatewayBond>>>()?;
|
||||
|
||||
for bond in gateway_bonds {
|
||||
incr_total_gateway_stake(bond.bond_amount().amount, deps.storage)?;
|
||||
incr_total_gateway_stake(bond.total_delegation().amount, deps.storage)?;
|
||||
}
|
||||
|
||||
Ok(Default::default())
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,7 @@
|
||||
|
||||
use crate::error::ContractError;
|
||||
use crate::helpers::get_all_delegations_paged;
|
||||
use crate::storage::{
|
||||
all_gateway_delegations_read, all_mix_delegations_read, gateway_delegations_read,
|
||||
gateways_owners_read, gateways_read, inflation_pool_value, mix_delegations_read,
|
||||
mixnodes_owners_read, mixnodes_read, read_layer_distribution, read_state_params,
|
||||
reverse_gateway_delegations_read, reverse_mix_delegations_read, total_gateway_stake_value,
|
||||
total_mix_stake_value,
|
||||
};
|
||||
use crate::storage::{all_gateway_delegations_read, all_mix_delegations_read, circulating_supply, gateway_delegations_read, gateways_owners_read, gateways_read, mix_delegations_read, mixnodes_owners_read, mixnodes_read, read_layer_distribution, read_state_params, reverse_gateway_delegations_read, reverse_mix_delegations_read, reward_pool_value};
|
||||
use config::defaults::DENOM;
|
||||
use cosmwasm_std::{coin, Addr, Deps, Order, StdResult, Uint128};
|
||||
use mixnet_contract::{
|
||||
@@ -94,16 +88,12 @@ pub(crate) fn query_layer_distribution(deps: Deps) -> LayerDistribution {
|
||||
read_layer_distribution(deps.storage)
|
||||
}
|
||||
|
||||
pub(crate) fn query_inflation_pool(deps: Deps) -> Uint128 {
|
||||
inflation_pool_value(deps.storage)
|
||||
pub(crate) fn query_reward_pool(deps: Deps) -> Uint128 {
|
||||
reward_pool_value(deps.storage)
|
||||
}
|
||||
|
||||
pub(crate) fn query_total_mix_stake(deps: Deps) -> Uint128 {
|
||||
total_mix_stake_value(deps.storage)
|
||||
}
|
||||
|
||||
pub(crate) fn query_total_gt_stake(deps: Deps) -> Uint128 {
|
||||
total_gateway_stake_value(deps.storage)
|
||||
pub(crate) fn query_circulating_supply(deps: Deps) -> u128 {
|
||||
circulating_supply(deps.storage)
|
||||
}
|
||||
|
||||
/// Adds a 0 byte to terminate the `start_after` value given. This allows CosmWasm
|
||||
@@ -691,6 +681,7 @@ pub(crate) mod tests {
|
||||
gateway_delegation_reward_rate: "0.12".parse().unwrap(),
|
||||
mixnode_active_set_size: 1000,
|
||||
gateway_active_set_size: 20,
|
||||
epoch_reward_percent: 2
|
||||
},
|
||||
mixnode_epoch_bond_reward: "1.23".parse().unwrap(),
|
||||
gateway_epoch_bond_reward: "4.56".parse().unwrap(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
use crate::contract::INITIAL_INFLATION_POOL;
|
||||
use crate::contract::REWARD_POOL;
|
||||
use crate::state::State;
|
||||
use crate::transactions::MINIMUM_BLOCK_AGE_FOR_REWARDING;
|
||||
use crate::{error::ContractError, queries};
|
||||
@@ -16,6 +16,7 @@ use mixnet_contract::{
|
||||
};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
use config::defaults::TOTAL_SUPPLY;
|
||||
|
||||
// storage prefixes
|
||||
// all of them must be unique and presumably not be a prefix of a different one
|
||||
@@ -25,10 +26,7 @@ use serde::Serialize;
|
||||
// singletons
|
||||
const CONFIG_KEY: &[u8] = b"config";
|
||||
const LAYER_DISTRIBUTION_KEY: &[u8] = b"layers";
|
||||
// Keeps total amount of stake towards mixnodes and gateways. Removing a bond removes all its delegations from the total, the reverse is true for adding a bond.
|
||||
const TOTAL_MIX_STAKE_KEY: &[u8] = b"total_mn";
|
||||
const TOTAL_GATEWAY_STAKE_KEY: &[u8] = b"total_gt";
|
||||
const INFLATION_POOL_PREFIX: &[u8] = b"pool";
|
||||
const REWARD_POOL_PREFIX: &[u8] = b"pool";
|
||||
|
||||
// buckets
|
||||
pub const PREFIX_MIXNODES: &[u8] = b"mn";
|
||||
@@ -53,107 +51,46 @@ pub fn config_read(storage: &dyn Storage) -> ReadonlySingleton<State> {
|
||||
singleton_read(storage, CONFIG_KEY)
|
||||
}
|
||||
|
||||
fn total_mix_stake(storage: &dyn Storage) -> ReadonlySingleton<Uint128> {
|
||||
singleton_read(storage, TOTAL_MIX_STAKE_KEY)
|
||||
fn reward_pool(storage: &dyn Storage) -> ReadonlySingleton<Uint128> {
|
||||
singleton_read(storage, REWARD_POOL_PREFIX)
|
||||
}
|
||||
|
||||
pub fn mut_total_mix_stake(storage: &mut dyn Storage) -> Singleton<Uint128> {
|
||||
singleton(storage, TOTAL_MIX_STAKE_KEY)
|
||||
pub fn mut_reward_pool(storage: &mut dyn Storage) -> Singleton<Uint128> {
|
||||
singleton(storage, REWARD_POOL_PREFIX)
|
||||
}
|
||||
|
||||
fn inflation_pool(storage: &dyn Storage) -> ReadonlySingleton<Uint128> {
|
||||
singleton_read(storage, INFLATION_POOL_PREFIX)
|
||||
}
|
||||
|
||||
pub fn mut_inflation_pool(storage: &mut dyn Storage) -> Singleton<Uint128> {
|
||||
singleton(storage, INFLATION_POOL_PREFIX)
|
||||
}
|
||||
|
||||
fn total_gateway_stake(storage: &dyn Storage) -> ReadonlySingleton<Uint128> {
|
||||
singleton_read(storage, TOTAL_GATEWAY_STAKE_KEY)
|
||||
}
|
||||
|
||||
pub fn mut_total_gateway_stake(storage: &mut dyn Storage) -> Singleton<Uint128> {
|
||||
singleton(storage, TOTAL_GATEWAY_STAKE_KEY)
|
||||
}
|
||||
|
||||
pub fn total_mix_stake_value(storage: &dyn Storage) -> Uint128 {
|
||||
match total_mix_stake(storage).load() {
|
||||
pub fn reward_pool_value(storage: &dyn Storage) -> Uint128 {
|
||||
match reward_pool(storage).load() {
|
||||
Ok(value) => value,
|
||||
Err(_e) => Uint128(0),
|
||||
Err(_e) => Uint128(REWARD_POOL),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn total_gateway_stake_value(storage: &dyn Storage) -> Uint128 {
|
||||
match total_gateway_stake(storage).load() {
|
||||
Ok(value) => value,
|
||||
Err(_e) => Uint128(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inflation_pool_value(storage: &dyn Storage) -> Uint128 {
|
||||
match inflation_pool(storage).load() {
|
||||
Ok(value) => value,
|
||||
Err(_e) => Uint128(INITIAL_INFLATION_POOL),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn incr_total_mix_stake(
|
||||
amount: Uint128,
|
||||
storage: &mut dyn Storage,
|
||||
) -> Result<Uint128, ContractError> {
|
||||
let stake = total_mix_stake_value(storage).checked_add(amount)?;
|
||||
mut_total_mix_stake(storage).save(&stake)?;
|
||||
Ok(stake)
|
||||
}
|
||||
|
||||
pub fn decr_total_mix_stake(
|
||||
amount: Uint128,
|
||||
storage: &mut dyn Storage,
|
||||
) -> Result<Uint128, ContractError> {
|
||||
let stake = total_mix_stake_value(storage).checked_sub(amount)?;
|
||||
mut_total_mix_stake(storage).save(&stake)?;
|
||||
Ok(stake)
|
||||
}
|
||||
|
||||
pub fn incr_total_gateway_stake(
|
||||
amount: Uint128,
|
||||
storage: &mut dyn Storage,
|
||||
) -> Result<Uint128, ContractError> {
|
||||
let stake = total_gateway_stake_value(storage).checked_add(amount)?;
|
||||
mut_total_gateway_stake(storage).save(&stake)?;
|
||||
Ok(stake)
|
||||
}
|
||||
|
||||
pub fn decr_total_gateway_stake(
|
||||
amount: Uint128,
|
||||
storage: &mut dyn Storage,
|
||||
) -> Result<Uint128, ContractError> {
|
||||
let stake = total_gateway_stake_value(storage).checked_sub(amount)?;
|
||||
mut_total_gateway_stake(storage).save(&stake)?;
|
||||
Ok(stake)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn incr_inflation_pool(
|
||||
pub fn incr_reward_pool(
|
||||
amount: Uint128,
|
||||
storage: &mut dyn Storage,
|
||||
) -> Result<Uint128, ContractError> {
|
||||
let stake = inflation_pool_value(storage).saturating_add(amount);
|
||||
mut_inflation_pool(storage).save(&stake)?;
|
||||
let stake = reward_pool_value(storage).saturating_add(amount);
|
||||
mut_reward_pool(storage).save(&stake)?;
|
||||
Ok(stake)
|
||||
}
|
||||
|
||||
pub fn decr_inflation_pool(
|
||||
pub fn decr_reward_pool(
|
||||
amount: Uint128,
|
||||
storage: &mut dyn Storage,
|
||||
) -> Result<Uint128, ContractError> {
|
||||
// TODO: This could got to < 0
|
||||
let stake = inflation_pool_value(storage).checked_sub(amount)?;
|
||||
mut_inflation_pool(storage).save(&stake)?;
|
||||
let stake = reward_pool_value(storage).checked_sub(amount)?;
|
||||
mut_reward_pool(storage).save(&stake)?;
|
||||
Ok(stake)
|
||||
}
|
||||
|
||||
pub fn circulating_supply(storage: &dyn Storage) -> u128 {
|
||||
let reward_pool = reward_pool_value(storage).u128();
|
||||
TOTAL_SUPPLY - reward_pool
|
||||
}
|
||||
|
||||
pub(crate) fn read_state_params(storage: &dyn Storage) -> StateParams {
|
||||
// note: In any other case, I wouldn't have attempted to unwrap this result, but in here
|
||||
// if we fail to load the stored state we would already be in the undefined behaviour land,
|
||||
|
||||
@@ -112,8 +112,6 @@ pub(crate) fn try_add_mixnode(
|
||||
mixnodes(deps.storage).save(identity.as_bytes(), &bond)?;
|
||||
mixnodes_owners(deps.storage).save(sender_bytes, identity)?;
|
||||
increment_layer_count(deps.storage, bond.layer)?;
|
||||
incr_total_mix_stake(bond.bond_amount().amount, deps.storage)?;
|
||||
incr_total_mix_stake(bond.total_delegation().amount, deps.storage)?;
|
||||
|
||||
let attributes = vec![attr("overwritten", was_present)];
|
||||
Ok(Response {
|
||||
@@ -153,9 +151,6 @@ pub(crate) fn try_remove_mixnode(
|
||||
// decrement layer count
|
||||
decrement_layer_count(deps.storage, mixnode_bond.layer)?;
|
||||
|
||||
decr_total_mix_stake(mixnode_bond.bond_amount().amount, deps.storage)?;
|
||||
decr_total_mix_stake(mixnode_bond.total_delegation().amount, deps.storage)?;
|
||||
|
||||
// log our actions
|
||||
let attributes = vec![attr("action", "unbond"), attr("mixnode_bond", mixnode_bond)];
|
||||
|
||||
@@ -249,9 +244,6 @@ pub(crate) fn try_add_gateway(
|
||||
gateways_owners(deps.storage).save(sender_bytes, identity)?;
|
||||
increment_layer_count(deps.storage, Layer::Gateway)?;
|
||||
|
||||
incr_total_gateway_stake(bond.bond_amount().amount, deps.storage)?;
|
||||
incr_total_gateway_stake(bond.total_delegation().amount, deps.storage)?;
|
||||
|
||||
let attributes = vec![attr("overwritten", was_present)];
|
||||
Ok(Response {
|
||||
submessages: Vec::new(),
|
||||
@@ -290,9 +282,6 @@ pub(crate) fn try_remove_gateway(
|
||||
// decrement layer count
|
||||
decrement_layer_count(deps.storage, Layer::Gateway)?;
|
||||
|
||||
decr_total_gateway_stake(gateway_bond.bond_amount().amount, deps.storage)?;
|
||||
decr_total_gateway_stake(gateway_bond.total_delegation().amount, deps.storage)?;
|
||||
|
||||
// log our actions
|
||||
let attributes = vec![
|
||||
attr("action", "unbond"),
|
||||
@@ -501,10 +490,8 @@ pub(crate) fn try_reward_mixnode_v2(
|
||||
current_bond.bond_amount.amount += operator_reward;
|
||||
current_bond.total_delegation.amount += total_delegation_reward;
|
||||
mixnodes(deps.storage).save(mix_identity.as_bytes(), ¤t_bond)?;
|
||||
decr_inflation_pool(operator_reward, deps.storage)?;
|
||||
decr_inflation_pool(total_delegation_reward, deps.storage)?;
|
||||
incr_total_mix_stake(operator_reward, deps.storage)?;
|
||||
incr_total_mix_stake(total_delegation_reward, deps.storage)?;
|
||||
decr_reward_pool(operator_reward, deps.storage)?;
|
||||
decr_reward_pool(total_delegation_reward, deps.storage)?;
|
||||
}
|
||||
|
||||
Ok(Response {
|
||||
@@ -656,8 +643,6 @@ pub(crate) fn try_delegate_to_mixnode(
|
||||
|
||||
reverse_mix_delegations(deps.storage, &info.sender).save(mix_identity.as_bytes(), &())?;
|
||||
|
||||
incr_total_mix_stake(amount, deps.storage)?;
|
||||
|
||||
Ok(Response::default())
|
||||
}
|
||||
|
||||
@@ -693,8 +678,6 @@ pub(crate) fn try_remove_delegation_from_mixnode(
|
||||
.checked_sub(delegation.amount)
|
||||
.unwrap();
|
||||
mixnodes_bucket.save(mix_identity.as_bytes(), &existing_bond)?;
|
||||
// We should only decr total if a node is bonded, node unbonding remove all delegations from the total
|
||||
decr_total_mix_stake(delegation.amount, deps.storage)?;
|
||||
}
|
||||
|
||||
Ok(Response {
|
||||
@@ -750,8 +733,6 @@ pub(crate) fn try_delegate_to_gateway(
|
||||
reverse_gateway_delegations(deps.storage, &info.sender)
|
||||
.save(gateway_identity.as_bytes(), &())?;
|
||||
|
||||
incr_total_gateway_stake(info.funds[0].amount, deps.storage)?;
|
||||
|
||||
Ok(Response::default())
|
||||
}
|
||||
|
||||
@@ -790,8 +771,6 @@ pub(crate) fn try_remove_delegation_from_gateway(
|
||||
.checked_sub(delegation.amount)
|
||||
.unwrap();
|
||||
gateways_bucket.save(gateway_identity.as_bytes(), &existing_bond)?;
|
||||
|
||||
decr_total_gateway_stake(delegation.amount, deps.storage)?;
|
||||
}
|
||||
|
||||
Ok(Response {
|
||||
@@ -1691,6 +1670,7 @@ pub mod tests {
|
||||
),
|
||||
mixnode_active_set_size: 42, // change something
|
||||
gateway_active_set_size: 5,
|
||||
epoch_reward_percent: 2,
|
||||
};
|
||||
|
||||
// cannot be updated from non-owner account
|
||||
@@ -4090,126 +4070,9 @@ pub mod tests {
|
||||
assert_eq!(bob_node.layer, Layer::Two);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mix_stake_accounting() {
|
||||
let mut deps = helpers::init_contract();
|
||||
let mut test_bond = INITIAL_MIXNODE_BOND;
|
||||
try_add_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("alice", &good_mixnode_bond()),
|
||||
MixNode {
|
||||
identity_key: "alice".to_string(),
|
||||
..helpers::mix_node_fixture()
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(total_mix_stake_value(&deps.storage), test_bond);
|
||||
|
||||
let delegation = coin(100, DENOM);
|
||||
try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("bob", &vec![delegation.clone()]),
|
||||
"alice".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
test_bond += Uint128(100);
|
||||
assert_eq!(total_mix_stake_value(&deps.storage), test_bond);
|
||||
|
||||
try_remove_mixnode(deps.as_mut(), mock_info("alice", &[])).unwrap();
|
||||
|
||||
test_bond = Uint128(0);
|
||||
assert_eq!(total_mix_stake_value(&deps.storage), test_bond);
|
||||
|
||||
try_add_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("alice", &good_mixnode_bond()),
|
||||
MixNode {
|
||||
identity_key: "alice".to_string(),
|
||||
..helpers::mix_node_fixture()
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
test_bond = Uint128(100) + INITIAL_MIXNODE_BOND;
|
||||
assert_eq!(total_mix_stake_value(&deps.storage), test_bond);
|
||||
|
||||
try_remove_delegation_from_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_info("bob", &[]),
|
||||
"alice".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
test_bond = test_bond.checked_sub(Uint128(100)).unwrap();
|
||||
assert_eq!(total_mix_stake_value(&deps.storage), test_bond);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gateway_stake_accounting() {
|
||||
let mut deps = helpers::init_contract();
|
||||
let mut test_bond = INITIAL_GATEWAY_BOND;
|
||||
try_add_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("alice", &good_gateway_bond()),
|
||||
Gateway {
|
||||
identity_key: "alice".to_string(),
|
||||
..helpers::gateway_fixture()
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(total_gateway_stake_value(&deps.storage), test_bond);
|
||||
|
||||
let delegation = coin(100, DENOM);
|
||||
try_delegate_to_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("bob", &vec![delegation.clone()]),
|
||||
"alice".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
test_bond += Uint128(100);
|
||||
assert_eq!(total_gateway_stake_value(&deps.storage), test_bond);
|
||||
|
||||
try_remove_gateway(deps.as_mut(), mock_info("alice", &[])).unwrap();
|
||||
|
||||
test_bond = Uint128(0);
|
||||
assert_eq!(total_gateway_stake_value(&deps.storage), test_bond);
|
||||
|
||||
try_add_gateway(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("alice", &good_gateway_bond()),
|
||||
Gateway {
|
||||
identity_key: "alice".to_string(),
|
||||
..helpers::gateway_fixture()
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
test_bond = Uint128(100) + INITIAL_GATEWAY_BOND;
|
||||
assert_eq!(total_gateway_stake_value(&deps.storage), test_bond);
|
||||
|
||||
try_remove_delegation_from_gateway(
|
||||
deps.as_mut(),
|
||||
mock_info("bob", &[]),
|
||||
"alice".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
test_bond = test_bond.checked_sub(Uint128(100)).unwrap();
|
||||
assert_eq!(total_gateway_stake_value(&deps.storage), test_bond);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tokenomics_rewarding() {
|
||||
use crate::contract::{EPOCH_REWARD_PERCENT, REWARD_POOL};
|
||||
use num::rational::Ratio;
|
||||
use std::str::FromStr;
|
||||
|
||||
@@ -4217,11 +4080,14 @@ pub mod tests {
|
||||
let mut env = mock_env();
|
||||
let current_state = config(deps.as_mut().storage).load().unwrap();
|
||||
let network_monitor_address = current_state.network_monitor_address;
|
||||
let income_global_mix = 17500_000000;
|
||||
let k = 5;
|
||||
mut_inflation_pool(deps.as_mut().storage)
|
||||
.save(&Uint128(income_global_mix))
|
||||
.unwrap();
|
||||
let period_reward_pool = (REWARD_POOL / 100) * EPOCH_REWARD_PERCENT as u128;
|
||||
assert_eq!(period_reward_pool, 5_000_000_000_000);
|
||||
let k = 200; // Imagining our active set size is 200
|
||||
let circulating_supply = circulating_supply(&deps.storage);
|
||||
assert_eq!(circulating_supply, 750_000_000_000_000u128);
|
||||
// mut_reward_pool(deps.as_mut().storage)
|
||||
// .save(&Uint128(period_reward_pool))
|
||||
// .unwrap();
|
||||
|
||||
try_add_mixnode(
|
||||
deps.as_mut(),
|
||||
@@ -4234,170 +4100,99 @@ pub mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
try_add_mixnode(
|
||||
try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("mix_1", &good_mixnode_bond()),
|
||||
MixNode {
|
||||
identity_key: "mix_1".to_string(),
|
||||
..helpers::mix_node_fixture()
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
try_add_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("mix_2", &good_mixnode_bond()),
|
||||
MixNode {
|
||||
identity_key: "mix_2".to_string(),
|
||||
..helpers::mix_node_fixture()
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
try_add_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("mix_3", &good_mixnode_bond()),
|
||||
MixNode {
|
||||
identity_key: "mix_3".to_string(),
|
||||
..helpers::mix_node_fixture()
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
try_add_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("mix_4", &good_mixnode_bond()),
|
||||
MixNode {
|
||||
identity_key: "mix_4".to_string(),
|
||||
..helpers::mix_node_fixture()
|
||||
},
|
||||
mock_info("d1", &vec![coin(10_000000, DENOM)]),
|
||||
"alice".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("d1.mix_1", &vec![coin(10_000000, DENOM)]),
|
||||
"mix_1".to_string(),
|
||||
mock_info("d2", &vec![coin(20_000000, DENOM)]),
|
||||
"alice".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("d2.mix_1", &vec![coin(20_000000, DENOM)]),
|
||||
"mix_1".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("d1.mix_2", &vec![coin(10_000000, DENOM)]),
|
||||
"mix_2".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
try_delegate_to_mixnode(
|
||||
deps.as_mut(),
|
||||
mock_env(),
|
||||
mock_info("d2.mix_2", &vec![coin(10_000000, DENOM)]),
|
||||
"mix_2".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(total_mix_stake_value(&deps.storage).u128(), 550_000000);
|
||||
|
||||
let total_mix_stake = total_mix_stake_value(&deps.storage);
|
||||
|
||||
let total_uptime = 380;
|
||||
let total_uptime = 200_000;
|
||||
|
||||
let info = mock_info(network_monitor_address.as_ref(), &[]);
|
||||
|
||||
env.block.height += 2 * MINIMUM_BLOCK_AGE_FOR_REWARDING;
|
||||
|
||||
let mix_1 = mixnodes_read(&deps.storage).load(b"mix_1").unwrap();
|
||||
let mix_1 = mixnodes_read(&deps.storage).load(b"alice").unwrap();
|
||||
let mix_1_uptime = 100;
|
||||
let _mix_1_performance = Decimal::from_ratio(mix_1_uptime, total_uptime);
|
||||
|
||||
let mut params = NodeRewardParams::new(
|
||||
income_global_mix,
|
||||
period_reward_pool,
|
||||
k,
|
||||
total_uptime,
|
||||
None,
|
||||
total_mix_stake.u128(),
|
||||
circulating_supply,
|
||||
mix_1_uptime,
|
||||
);
|
||||
|
||||
params.set_reward_blockstamp(env.block.height);
|
||||
|
||||
assert_eq!(params.performance(), Ratio::new(5, 19));
|
||||
assert_eq!(params.performance(), Ratio::new(1, 2000));
|
||||
|
||||
let mix_1_reward_result = mix_1.reward(¶ms);
|
||||
|
||||
assert_eq!(
|
||||
mix_1_reward_result.sigma(),
|
||||
Decimal::from_str("0.2").unwrap()
|
||||
Decimal::from_str("0.000000040000000000").unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
mix_1_reward_result.lambda(),
|
||||
Decimal::from_str("0.181818181818181818").unwrap()
|
||||
Decimal::from_str("0.000000133333333333").unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
mix_1_reward_result.reward(),
|
||||
Decimal::from_str("901729849.098270150901729849").unwrap()
|
||||
Decimal::from_str("76.923692307692307692").unwrap()
|
||||
);
|
||||
|
||||
let mix1_operator_profit = mix_1.operator_reward(¶ms).unwrap();
|
||||
|
||||
let mix1_delegator1_reward = mix_1
|
||||
.reward_delegation(Uint128(10_000000), ¶ms)
|
||||
.reward_delegation(Uint128(10_000_000), ¶ms)
|
||||
.unwrap();
|
||||
|
||||
let mix1_delegator2_reward = mix_1
|
||||
.reward_delegation(Uint128(20_000000), ¶ms)
|
||||
.reward_delegation(Uint128(20_000_000), ¶ms)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(mix1_operator_profit, 827951952);
|
||||
assert_eq!(mix1_delegator1_reward, 73777896);
|
||||
assert_eq!(mix1_delegator2_reward, 147555793);
|
||||
// These might be generalizable over percentages, instead of exact values
|
||||
assert_eq!(mix1_operator_profit, 238);
|
||||
assert_eq!(mix1_delegator1_reward, 23);
|
||||
assert_eq!(mix1_delegator2_reward, 46);
|
||||
|
||||
let pre_reward_bond = read_mixnode_bond(&deps.storage, b"mix_1").unwrap().u128();
|
||||
assert_eq!(pre_reward_bond, 100_000000);
|
||||
let pre_reward_bond = read_mixnode_bond(&deps.storage, b"alice").unwrap().u128();
|
||||
assert_eq!(pre_reward_bond, 100_000_000);
|
||||
|
||||
let pre_reward_delegation = read_mixnode_delegation(&deps.storage, b"mix_1")
|
||||
let pre_reward_delegation = read_mixnode_delegation(&deps.storage, b"alice")
|
||||
.unwrap()
|
||||
.u128();
|
||||
assert_eq!(pre_reward_delegation, 30_000000);
|
||||
assert_eq!(pre_reward_delegation, 30_000_000);
|
||||
|
||||
try_reward_mixnode_v2(deps.as_mut(), env, info, "mix_1".to_string(), params).unwrap();
|
||||
try_reward_mixnode_v2(deps.as_mut(), env, info, "alice".to_string(), params).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
read_mixnode_bond(&deps.storage, b"mix_1").unwrap().u128(),
|
||||
read_mixnode_bond(&deps.storage, b"alice").unwrap().u128(),
|
||||
pre_reward_bond + mix1_operator_profit + params.operator_cost().to_u128().unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
read_mixnode_delegation(&deps.storage, b"mix_1")
|
||||
read_mixnode_delegation(&deps.storage, b"alice")
|
||||
.unwrap()
|
||||
.u128(),
|
||||
251333689
|
||||
);
|
||||
assert_eq!(
|
||||
total_mix_stake_value(&deps.storage).u128(),
|
||||
total_mix_stake.u128()
|
||||
+ mix1_operator_profit as u128
|
||||
+ params.operator_cost().to_u128().unwrap()
|
||||
+ mix1_delegator1_reward
|
||||
+ mix1_delegator2_reward
|
||||
pre_reward_delegation + mix1_delegator1_reward + mix1_delegator2_reward
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
inflation_pool_value(&deps.storage).u128(),
|
||||
income_global_mix
|
||||
reward_pool_value(&deps.storage).u128(),
|
||||
REWARD_POOL
|
||||
- (mix1_operator_profit as u128
|
||||
+ params.operator_cost().to_u128().unwrap()
|
||||
+ mix1_delegator1_reward
|
||||
|
||||
Vendored
+3
-29
@@ -37,9 +37,6 @@ struct ValidatorCacheInner {
|
||||
|
||||
current_mixnode_active_set_size: AtomicUsize,
|
||||
current_gateway_active_set_size: AtomicUsize,
|
||||
|
||||
total_mix_stake: RwLock<Cache<u128>>,
|
||||
total_gateway_stake: RwLock<Cache<u128>>,
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize, Clone)]
|
||||
@@ -79,30 +76,21 @@ impl<C> ValidatorCacheRefresher<C> {
|
||||
where
|
||||
C: CosmWasmClient + Sync,
|
||||
{
|
||||
let (mixnodes, gateways, total_mix_stake, total_gt_state) = tokio::try_join!(
|
||||
let (mixnodes, gateways) = tokio::try_join!(
|
||||
self.nymd_client.get_mixnodes(),
|
||||
self.nymd_client.get_gateways(),
|
||||
self.nymd_client.get_total_mix_stake(),
|
||||
self.nymd_client.get_total_gateway_stake()
|
||||
)?;
|
||||
|
||||
let state_params = self.nymd_client.get_state_params().await?;
|
||||
|
||||
info!(
|
||||
"Updating validator cache. There are {} mixnodes and {} gateways, total_mix_stake is {}",
|
||||
"Updating validator cache. There are {} mixnodes and {} gateways",
|
||||
mixnodes.len(),
|
||||
gateways.len(),
|
||||
total_mix_stake
|
||||
);
|
||||
|
||||
self.cache
|
||||
.update_cache(
|
||||
mixnodes,
|
||||
gateways,
|
||||
total_mix_stake,
|
||||
total_gt_state,
|
||||
state_params,
|
||||
)
|
||||
.update_cache(mixnodes, gateways, state_params)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
@@ -189,8 +177,6 @@ impl ValidatorCache {
|
||||
&self,
|
||||
mut mixnodes: Vec<MixNodeBond>,
|
||||
mut gateways: Vec<GatewayBond>,
|
||||
total_mix_stake: u128,
|
||||
total_gt_stake: u128,
|
||||
state: StateParams,
|
||||
) {
|
||||
// if our data is valid, it means the active sets are available,
|
||||
@@ -232,16 +218,6 @@ impl ValidatorCache {
|
||||
|
||||
self.inner.mixnodes.write().await.set(mixnodes);
|
||||
self.inner.gateways.write().await.set(gateways);
|
||||
self.inner
|
||||
.total_mix_stake
|
||||
.write()
|
||||
.await
|
||||
.set(total_mix_stake);
|
||||
self.inner
|
||||
.total_gateway_stake
|
||||
.write()
|
||||
.await
|
||||
.set(total_gt_stake);
|
||||
}
|
||||
|
||||
pub async fn mixnodes(&self) -> Cache<Vec<MixNodeBond>> {
|
||||
@@ -327,8 +303,6 @@ impl ValidatorCacheInner {
|
||||
active_gateways_available: AtomicBool::new(false),
|
||||
current_mixnode_active_set_size: Default::default(),
|
||||
current_gateway_active_set_size: Default::default(),
|
||||
total_mix_stake: Default::default(),
|
||||
total_gateway_stake: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,25 +94,18 @@ impl<C> Client<C> {
|
||||
Ok(time)
|
||||
}
|
||||
|
||||
pub(crate) async fn get_total_mix_stake(&self) -> Result<u128, ValidatorClientError>
|
||||
pub(crate) async fn get_reward_pool(&self) -> Result<u128, ValidatorClientError>
|
||||
where
|
||||
C: CosmWasmClient + Sync,
|
||||
{
|
||||
Ok(self.0.read().await.get_total_mix_stake().await?)
|
||||
Ok(self.0.read().await.get_reward_pool().await?)
|
||||
}
|
||||
|
||||
pub(crate) async fn get_total_gateway_stake(&self) -> Result<u128, ValidatorClientError>
|
||||
pub(crate) async fn get_circulating_supply(&self) -> Result<u128, ValidatorClientError>
|
||||
where
|
||||
C: CosmWasmClient + Sync,
|
||||
{
|
||||
Ok(self.0.read().await.get_total_gateway_stake().await?)
|
||||
}
|
||||
|
||||
pub(crate) async fn get_inflation_pool(&self) -> Result<u128, ValidatorClientError>
|
||||
where
|
||||
C: CosmWasmClient + Sync,
|
||||
{
|
||||
Ok(self.0.read().await.get_inflation_pool().await?)
|
||||
Ok(self.0.read().await.get_circulating_supply().await?)
|
||||
}
|
||||
|
||||
pub(crate) async fn get_mixnodes(&self) -> Result<Vec<MixNodeBond>, ValidatorClientError>
|
||||
|
||||
@@ -291,13 +291,13 @@ impl Rewarder {
|
||||
// by people hesitating to delegate to nodes without them and thus those nodes disappearing
|
||||
// from the active set (once introduced)
|
||||
let mixnode_delegators = self.produce_active_mixnode_delegators_map().await?;
|
||||
let total_mix_stake = self.nymd_client.get_total_mix_stake().await?;
|
||||
let inflation_pool = self.nymd_client.get_inflation_pool().await?;
|
||||
let k = self
|
||||
.nymd_client
|
||||
.get_state_params()
|
||||
.await?
|
||||
.mixnode_active_set_size;
|
||||
// TODO: get node saturation
|
||||
let reward_pool = self.nymd_client.get_reward_pool().await?;
|
||||
let circulating_supply = self.nymd_client.get_circulating_supply().await?;
|
||||
let state = self.nymd_client.get_state_params().await?;
|
||||
let k = state.mixnode_active_set_size;
|
||||
let period_reward_pool = (reward_pool / 100) * 2_u128;
|
||||
|
||||
// 1. go through all active mixnodes
|
||||
// 2. filter out nodes that are currently not in the active set (as `mixnode_delegators` was obtained by
|
||||
// querying the validator)
|
||||
@@ -325,11 +325,11 @@ impl Rewarder {
|
||||
if cfg!(feature = "tokenomics") {
|
||||
for mix in eligible_nodes.iter_mut() {
|
||||
mix.params = Some(NodeRewardParams::new(
|
||||
inflation_pool,
|
||||
period_reward_pool,
|
||||
k.into(),
|
||||
total_epoch_uptime,
|
||||
None,
|
||||
total_mix_stake,
|
||||
circulating_supply,
|
||||
mix.uptime.u8().into(),
|
||||
))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user