Skip to content

Commit

Permalink
fixup! Continue debugging
Browse files Browse the repository at this point in the history
  • Loading branch information
mariari committed Jul 5, 2023
1 parent d92eb8f commit 42998e2
Show file tree
Hide file tree
Showing 10 changed files with 315 additions and 134 deletions.
20 changes: 11 additions & 9 deletions apps/src/lib/config/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use namada::types::key::dkg_session_keys::DkgPublicKey;
use namada::types::key::*;
use namada::types::time::{DateTimeUtc, DurationSecs};
use namada::types::token::Denomination;
use namada::types::uint::I256;
use namada::types::{storage, token};

/// Genesis configuration file format
Expand All @@ -38,6 +39,7 @@ pub mod genesis_config {
use namada::types::key::*;
use namada::types::time::Rfc3339String;
use namada::types::token::Denomination;
use namada::types::uint::I256;
use namada::types::{storage, token};
use serde::{Deserialize, Serialize};
use thiserror::Error;
Expand Down Expand Up @@ -395,8 +397,8 @@ pub mod genesis_config {
let token_vp_config = wasm.get(token_vp_name).unwrap();

TokenAccount {
last_locked_ratio: Decimal::ZERO,
last_inflation: 0,
last_locked_ratio: Dec::zero(),
last_inflation: I256::zero(),
parameters: config.parameters.as_ref().unwrap().to_owned(),
address: Address::decode(config.address.as_ref().unwrap()).unwrap(),
denom: config.denom,
Expand Down Expand Up @@ -816,9 +818,9 @@ pub struct TokenAccount {
/// Token parameters
pub parameters: token::parameters::Parameters,
/// Token inflation from the last epoch (read + write for every epoch)
pub last_inflation: u64,
pub last_inflation: I256,
/// Token shielded ratio from the last epoch (read + write for every epoch)
pub last_locked_ratio: Decimal,
pub last_locked_ratio: Dec,
}

#[derive(
Expand Down Expand Up @@ -1038,17 +1040,17 @@ pub fn genesis(num_validators: u64) -> Genesis {
balances.insert((&validator.account_key).into(), default_key_tokens);
}

let token_accounts = address::masp_rewards()
.into_keys()
.map(|address| TokenAccount {
let token_accounts = address::tokens()
.into_iter()
.map(|(address, (_, denom))| TokenAccount {
address,
denom,
vp_code_path: vp_token_path.into(),
vp_sha256: Default::default(),
balances: balances.clone(),
parameters: token::parameters::Parameters::default(),
last_inflation: 0,
last_locked_ratio: Decimal::ZERO,
last_inflation: I256::zero(),
last_locked_ratio: Dec::zero(),
})
.collect();
Genesis {
Expand Down
13 changes: 6 additions & 7 deletions core/src/ledger/inflation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
//! proof-of-stake, providing liquity to shielded asset pools, and public goods
//! funding.

use namada_core::types::dec::Dec;

use crate::ledger::storage_api::{self, StorageRead, StorageWrite};
use crate::types::address::Address;
use crate::types::dec::Dec;
use crate::types::token;

/// The domains of inflation
Expand Down Expand Up @@ -54,12 +53,12 @@ impl RewardsController {
pub fn new(
locked_tokens: token::Amount,
total_tokens: token::Amount,
locked_ratio_target: Decimal,
locked_ratio_last: Decimal,
max_reward_rate: Decimal,
locked_ratio_target: Dec,
locked_ratio_last: Dec,
max_reward_rate: Dec,
last_inflation_amount: token::Amount,
p_gain_nom: Decimal,
d_gain_nom: Decimal,
p_gain_nom: Dec,
d_gain_nom: Dec,
epochs_per_year: u64,
) -> Self {
Self {
Expand Down
127 changes: 69 additions & 58 deletions core/src/ledger/storage/masp_conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ use crate::ledger::inflation::{mint_tokens, RewardsController, ValsToUpdate};
use crate::ledger::parameters;
use crate::ledger::storage_api::{ResultExt, StorageRead, StorageWrite};
use crate::types::address::Address;
use crate::types::{address, token};
use crate::types::dec::Dec;
use crate::types::storage::{Epoch, Key};
use crate::types::token::MaspDenom;
use crate::types::uint::I256;
use crate::types::{address, token};

/// A representation of the conversion state
#[derive(Debug, Default, BorshSerialize, BorshDeserialize)]
pub struct ConversionState {
/// The last amount of the native token distributed
pub normed_inflation: Option<u64>,
pub normed_inflation: Option<I256>,
/// The tree currently containing all the conversions
pub tree: FrozenCommitmentTree<Node>,
/// Map assets to their latest conversion and position in Merkle tree
Expand All @@ -39,13 +41,11 @@ pub struct ConversionState {
fn calculate_masp_rewards<D, H>(
wl_storage: &mut super::WlStorage<D, H>,
addr: &Address,
) -> crate::ledger::storage_api::Result<(u64, u64)>
) -> crate::ledger::storage_api::Result<(I256, I256)>
where
D: 'static + super::DB + for<'iter> super::DBIter<'iter>,
H: 'static + super::StorageHasher,
{
use rust_decimal::Decimal;

let masp_addr = address::masp();
// Query the storage for information

Expand All @@ -62,35 +62,35 @@ where
let epochs_per_year: u64 = wl_storage
.read(&parameters::storage::get_epochs_per_year_key())?
.expect("");

//// Values from the last epoch
let last_inflation: u64 = wl_storage
let last_inflation: I256 = wl_storage
.read(&token::last_inflation(addr))
.expect("failure to read last inflation")
.expect("");

let last_locked_ratio: Decimal = wl_storage
let last_locked_ratio: Dec = wl_storage
.read(&token::last_locked_ratio(addr))
.expect("failure to read last inflation")
.expect("");

//// Parameters for each token
let max_reward_rate: Decimal = wl_storage
let max_reward_rate: Dec = wl_storage
.read(&token::parameters::max_reward_rate(addr))
.expect("max reward should properly decode")
.expect("");

let kp_gain_nom: Decimal = wl_storage
let kp_gain_nom: Dec = wl_storage
.read(&token::parameters::kp_sp_gain(addr))
.expect("kp_gain_nom reward should properly decode")
.expect("");

let kd_gain_nom: Decimal = wl_storage
let kd_gain_nom: Dec = wl_storage
.read(&token::parameters::kd_sp_gain(addr))
.expect("kd_gain_nom reward should properly decode")
.expect("");

let locked_target_ratio: Decimal = wl_storage
let locked_target_ratio: Dec = wl_storage
.read(&token::parameters::locked_token_ratio(addr))?
.expect("");

Expand All @@ -116,12 +116,11 @@ where
// ∴ n = (inflation * 100) / locked tokens
// Since we must put the notes in a compatible format with the
// note format, we must make the inflation amount discrete.
let total_in = total_token_in_masp.change() as u64;
let noterized_inflation = if 0u64 == total_in {
0u64
let total_in = total_token_in_masp.change();
let noterized_inflation = if total_in.is_zero() {
I256::zero()
} else {
((100 * inflation as u128) / (total_token_in_masp.change() as u128))
as u64
I256::from(100 * inflation) / (total_token_in_masp.change())
};

tracing::debug!(
Expand Down Expand Up @@ -152,8 +151,8 @@ where
wl_storage
.write(
&token::last_inflation(addr),
(noterized_inflation / 100u64)
* total_token_in_masp.change() as u64,
(noterized_inflation / I256::from(100))
* total_token_in_masp.change() as I256,
)
.expect("unable to encode new inflation rate (Decimal)");

Expand All @@ -166,7 +165,7 @@ where
// function This may be unneeded, as we could describe it as a
// ratio of x/1

Ok((noterized_inflation, 100))
Ok((noterized_inflation, I256::from(100)))
}

// This is only enabled when "wasm-runtime" is on, because we're using rayon
Expand Down Expand Up @@ -194,14 +193,15 @@ where
let masp_addr = address::masp();
let key_prefix: storage::Key = masp_addr.to_db_key().into();

let native_token = wl_storage.get_native_token().unwrap();
let masp_rewards = address::masp_rewards();
let mut masp_reward_keys: Vec<_> = masp_rewards.keys().collect();
// Put the native rewards first because other inflation computations depend
// on it
masp_reward_keys.sort_unstable_by(|x, y| {
if (**x == address::nam()) == (**y == address::nam()) {
masp_reward_keys.sort_unstable_by(|(x, _key), (y, _)| {
if (*x == native_token) == (*y == native_token) {
Ordering::Equal
} else if **x == address::nam() {
} else if *x == native_token {
Ordering::Less
} else {
Ordering::Greater
Expand All @@ -215,25 +215,25 @@ where
// have to use. This trick works under the assumption that reward tokens
// from different epochs are exactly equivalent.
let reward_asset =
encode_asset_type(address::nam(), &None, MaspDenom::Zero, Epoch(0));
encode_asset_type(native_token, &None, MaspDenom::Zero, Epoch(0));
// Conversions from the previous to current asset for each address
let mut current_convs =
BTreeMap::<(Address, Option<Key>, MaspDenom), AllowedConversion>::new();
// Reward all tokens according to above reward rates
for ((addr, sub_prefix), reward) in &masp_rewards {
for ((addr, sub_prefix), _reward) in &masp_rewards {
// TODO please intergate this into the logic
let reward = calculate_masp_rewards(wl_storage, addr)?;

// TODO Fix for multiple inflation
// Native token inflation values are always with respect to this
let ref_inflation = masp_rewards[&address::nam()].1;
let ref_inflation = I256::from(1);
// Get the last rewarded amount of the native token
let normed_inflation = wl_storage
let normed_inflation = *wl_storage
.storage
.conversion_state
.normed_inflation
.get_or_insert(ref_inflation);




// Dispense a transparent reward in parallel to the shielded rewards
let addr_bal: token::Amount = match sub_prefix {
None => wl_storage
Expand All @@ -250,7 +250,7 @@ where
// reward.0 units of the reward token
// Since floor(a) + floor(b) <= floor(a+b), there will always be
// enough rewards to reimburse users
total_reward += (addr_bal * *reward).0;
total_reward += (addr_bal * reward).0;

for denom in token::MaspDenom::iter() {
// Provide an allowed conversion from previous timestamp. The
Expand All @@ -268,48 +268,59 @@ where
denom,
wl_storage.storage.block.epoch,
);
// TODO properly fix
// TODO properly fix
if *addr == address::nam() {
// The amount that will be given of the new native token for every
// amount of the native token given in the previous epoch
// The amount that will be given of the new native token for
// every amount of the native token given in the
// previous epoch
let new_normed_inflation =
*normed_inflation + (*normed_inflation * reward.0) / reward.1;
// The conversion is computed such that if consecutive conversions
// are added together, the intermediate native tokens cancel/
normed_inflation + (normed_inflation * reward.0) / reward.1;
// The conversion is computed such that if consecutive
// conversions are added together, the
// intermediate native tokens cancel/
// telescope out
current_convs.insert(
addr.clone(),
(MaspAmount::from_pair(old_asset, -(*normed_inflation as i64))
.unwrap()
+ MaspAmount::from_pair(new_asset, new_normed_inflation)
.unwrap())
.into(),
(addr.clone(), sub_prefix.clone(), denom),
(MaspAmount::from_pair(old_asset, -(normed_inflation))
.unwrap()
+ MaspAmount::from_pair(
new_asset,
new_normed_inflation,
)
.unwrap())
.into(),
);
// The reward for each reward.1 units of the current asset is
// reward.0 units of the reward token
total_reward +=
(addr_bal * (new_normed_inflation, *normed_inflation)).0
- addr_bal;
(addr_bal * (new_normed_inflation, normed_inflation)).0
- addr_bal;
// Save the new normed inflation
*normed_inflation = new_normed_inflation;
_ = wl_storage
.storage
.conversion_state
.normed_inflation
.insert(new_normed_inflation);
} else {
// Express the inflation reward in real terms, that is, with respect
// to the native asset in the zeroth epoch
let real_reward = (reward.0 * ref_inflation) / *normed_inflation;
// The conversion is computed such that if consecutive conversions
// are added together, the intermediate tokens cancel/ telescope out
// Express the inflation reward in real terms, that is, with
// respect to the native asset in the zeroth
// epoch
let real_reward = (reward.0 * ref_inflation) / normed_inflation;
// The conversion is computed such that if consecutive
// conversions are added together, the
// intermediate tokens cancel/ telescope out
current_convs.insert(
addr.clone(),
(MaspAmount::from_pair(old_asset, -(reward.1 as i64)).unwrap()
+ MaspAmount::from_pair(new_asset, reward.1).unwrap()
+ MaspAmount::from_pair(reward_asset, real_reward)
.unwrap())
.into(),
(addr.clone(), sub_prefix.clone(), denom),
(MaspAmount::from_pair(old_asset, -(reward.1)).unwrap()
+ MaspAmount::from_pair(new_asset, reward.1).unwrap()
+ MaspAmount::from_pair(reward_asset, real_reward)
.unwrap())
.into(),
);
// The reward for each reward.1 units of the current asset is
// reward.0 units of the reward token
total_reward += ((addr_bal * (real_reward, reward.1)).0
* (*normed_inflation, ref_inflation))
* (normed_inflation, ref_inflation))
.0;
}
// Add a conversion from the previous asset type
Expand Down
11 changes: 6 additions & 5 deletions core/src/ledger/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -990,15 +990,16 @@ impl From<MerkleTreeError> for Error {
/// Helpers for testing components that depend on storage
#[cfg(any(test, feature = "testing"))]
pub mod testing {
use std::str::FromStr;

use borsh::BorshSerialize;
use rust_decimal::Decimal;
use rust_decimal_macros::dec;

use super::mockdb::MockDB;
use super::*;
use crate::ledger::storage::traits::Sha256Hasher;
use crate::ledger::storage_api::StorageWrite;
use crate::types::address;
use crate::types::dec::Dec;
use crate::types::token::parameters;

/// `WlStorage` with a mock DB for testing
Expand Down Expand Up @@ -1064,14 +1065,14 @@ pub mod testing {
) {
let masp_rewards = address::masp_rewards();
let masp_addr = address::masp();
for addr in masp_rewards.keys() {
for (addr, _key) in masp_rewards.keys() {
parameters::Parameters::init_storage(
&parameters::Parameters::default(),
addr,
self,
);
let initial_inflation: u64 = 1;
let initial_locked_ratio: Decimal = dec!(0.1);
let initial_inflation: u128 = 1;
let initial_locked_ratio: Dec = Dec::from_str("0.1").unwrap();

self.write(&token::last_inflation(addr), initial_inflation)
.expect("Should not fail to put a test inflation source");
Expand Down
Loading

0 comments on commit 42998e2

Please sign in to comment.