Skip to content

Commit

Permalink
Increased the precision of MASP rewards.
Browse files Browse the repository at this point in the history
  • Loading branch information
murisi committed Oct 17, 2023
1 parent b452c43 commit a625126
Show file tree
Hide file tree
Showing 33 changed files with 99 additions and 184 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ libc = "0.2.97"
libloading = "0.7.2"
libsecp256k1 = {git = "https://github.com/heliaxdev/libsecp256k1", rev = "bbb3bd44a49db361f21d9db80f9a087c194c0ae9", default-features = false, features = ["std", "static-context"]}
# branch = "murisi/namada-integration"
masp_primitives = { git = "https://github.com/anoma/masp", rev = "50acc5028fbcd52a05970fe7991c7850ab04358e" }
masp_proofs = { git = "https://github.com/anoma/masp", rev = "50acc5028fbcd52a05970fe7991c7850ab04358e", default-features = false, features = ["local-prover"] }
masp_primitives = { git = "https://github.com/anoma/masp", rev = "1345b463e8fa3b3a6fa13e4a43fb1c410690ad62" }
masp_proofs = { git = "https://github.com/anoma/masp", rev = "1345b463e8fa3b3a6fa13e4a43fb1c410690ad62", default-features = false, features = ["local-prover"] }
num256 = "0.3.5"
num_cpus = "1.13.0"
num-derive = "0.3.3"
Expand Down
4 changes: 2 additions & 2 deletions apps/src/lib/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2126,7 +2126,7 @@ pub async fn query_conversions<
// Track whether any non-sentinel conversions are found
let mut conversions_found = false;
for ((addr, _), epoch, conv, _) in conv_state.assets.values() {
let amt: masp_primitives::transaction::components::I32Sum =
let amt: masp_primitives::transaction::components::I128Sum =
conv.clone().into();
// If the user has specified any targets, then meet them
// If we have a sentinel conversion, then skip printing
Expand Down Expand Up @@ -2181,7 +2181,7 @@ pub async fn query_conversion<C: namada::ledger::queries::Client + Sync>(
Address,
MaspDenom,
Epoch,
masp_primitives::transaction::components::I32Sum,
masp_primitives::transaction::components::I128Sum,
MerklePath<Node>,
)> {
namada::sdk::rpc::query_conversion(client, asset_type).await
Expand Down
4 changes: 2 additions & 2 deletions apps/src/lib/config/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1012,8 +1012,8 @@ pub fn genesis(num_validators: u64) -> Genesis {
implicit_vp_code_path: vp_implicit_path.into(),
implicit_vp_sha256: Default::default(),
max_signatures_per_transaction: 15,
epochs_per_year: 525_600, /* seconds in yr (60*60*24*365) div seconds
* per epoch (60 = min_duration) */
epochs_per_year: 365, /* seconds in yr (60*60*24*365) div seconds
* per epoch (60 = min_duration) */
pos_gain_p: Dec::new(1, 1).expect("This can't fail"),
pos_gain_d: Dec::new(1, 1).expect("This can't fail"),
staked_ratio: Dec::zero(),
Expand Down
4 changes: 2 additions & 2 deletions core/src/ledger/inflation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ mod test {
4_000,
NATIVE_MAX_DECIMAL_PLACES,
)
.unwrap(),
.unwrap(),
total_native_tokens: token::Amount::from_uint(
4_000,
NATIVE_MAX_DECIMAL_PLACES,
Expand Down Expand Up @@ -209,7 +209,7 @@ mod test {
1_000,
NATIVE_MAX_DECIMAL_PLACES,
)
.unwrap(),
.unwrap(),
total_native_tokens: token::Amount::from_uint(
1_000,
NATIVE_MAX_DECIMAL_PLACES,
Expand Down
57 changes: 29 additions & 28 deletions core/src/ledger/storage/masp_conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,19 @@ use masp_primitives::sapling::Node;

use crate::ledger::inflation::{RewardsController, ValsToUpdate};
use crate::ledger::parameters;
use crate::ledger::storage_api::token::read_denom;
use crate::ledger::storage_api::{StorageRead, StorageWrite};
use crate::types::address::Address;
use crate::types::dec::Dec;
use crate::types::storage::Epoch;
use crate::types::token::MaspDenom;
use crate::types::{address, token};

/// Inflation is implicitly denominated by this value. The lower this figure,
/// the less precise inflation computations are. The higher this figure, the
/// larger the fixed-width types that are required to carry out inflation
/// computations. This value should be fixed constant for each asset type - here
/// we have simplified it and made it constant across asset types.
const PRECISION: u64 = 100;

/// 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<u32>,
pub normed_inflation: Option<u128>,
/// The tree currently containing all the conversions
pub tree: FrozenCommitmentTree<Node>,
/// Map assets to their latest conversion and position in Merkle tree
Expand All @@ -44,17 +38,26 @@ pub struct ConversionState {
pub fn calculate_masp_rewards<D, H>(
wl_storage: &mut super::WlStorage<D, H>,
addr: &Address,
) -> crate::ledger::storage_api::Result<(u32, u32)>
) -> crate::ledger::storage_api::Result<(u128, u128)>
where
D: 'static + super::DB + for<'iter> super::DBIter<'iter>,
H: 'static + super::StorageHasher,
{
let denomination = read_denom(wl_storage, addr).unwrap().unwrap();
// Inflation is implicitly denominated by this value. The lower this
// figure, the less precise inflation computations are. This is especially
// problematic when inflation is coming from a token with much higher
// denomination than the native token. The higher this figure, the higher
// the threshold of holdings required in order to receive non-zero rewards.
// This value should be fixed constant for each asset type.
let precision = 10u128.pow(std::cmp::max(u32::from(denomination.0), 3) - 3);

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

//// information about the amount of tokens on the chain
let total_tokens: token::Amount = wl_storage
.read(&token::minted_balance_key(&addr))?
.read(&token::minted_balance_key(addr))?
.expect("the total supply key should be here");

//// information about the amount of native tokens on the chain
Expand Down Expand Up @@ -126,10 +129,11 @@ where
// Since we must put the notes in a compatible format with the
// note format, we must make the inflation amount discrete.
let noterized_inflation = if total_token_in_masp.is_zero() {
0u32
0u128
} else {
crate::types::uint::Uint::try_into(
(inflation.raw_amount() * PRECISION)
(inflation.raw_amount()
* crate::types::uint::Uint::from(precision))
/ total_token_in_masp.raw_amount(),
)
.unwrap()
Expand Down Expand Up @@ -164,23 +168,20 @@ where
wl_storage
.write(
&token::masp_last_inflation(addr),
(total_token_in_masp / PRECISION) * u64::from(noterized_inflation),
token::Amount::from_uint(
(total_token_in_masp.raw_amount() / precision)
* crate::types::uint::Uint::from(noterized_inflation),
0,
)
.unwrap(),
)
.expect("unable to encode new inflation rate (Decimal)");

wl_storage
.write(&token::masp_last_locked_ratio(addr), locked_ratio)
.expect("unable to encode new locked ratio (Decimal)");

// to make it conform with the expected output, we need to
// move it to a ratio of x/100 to match the masp_rewards
// function This may be unneeded, as we could describe it as a
// ratio of x/1

Ok((
noterized_inflation,
PRECISION.try_into().expect("inflation precision too large"),
))
Ok((noterized_inflation, precision))
}

// This is only enabled when "wasm-runtime" is on, because we're using rayon
Expand All @@ -196,7 +197,7 @@ where
use std::cmp::Ordering;

use masp_primitives::ff::PrimeField;
use masp_primitives::transaction::components::I32Sum as MaspAmount;
use masp_primitives::transaction::components::I128Sum as MaspAmount;
use rayon::iter::{
IndexedParallelIterator, IntoParallelIterator, ParallelIterator,
};
Expand Down Expand Up @@ -288,12 +289,12 @@ where
(addr.clone(), denom),
(MaspAmount::from_pair(
old_asset,
-(*normed_inflation as i32),
-(*normed_inflation as i128),
)
.unwrap()
+ MaspAmount::from_pair(
new_asset,
new_normed_inflation as i32,
new_normed_inflation as i128,
)
.unwrap())
.into(),
Expand All @@ -320,13 +321,13 @@ where
// intermediate tokens cancel/ telescope out
current_convs.insert(
(addr.clone(), denom),
(MaspAmount::from_pair(old_asset, -(reward.1 as i32))
(MaspAmount::from_pair(old_asset, -(reward.1 as i128))
.unwrap()
+ MaspAmount::from_pair(new_asset, reward.1 as i32)
+ MaspAmount::from_pair(new_asset, reward.1 as i128)
.unwrap()
+ MaspAmount::from_pair(
reward_assets[denom as usize],
real_reward as i32,
real_reward as i128,
)
.unwrap())
.into(),
Expand Down
17 changes: 0 additions & 17 deletions core/src/types/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -681,23 +681,6 @@ pub fn tokens() -> HashMap<Address, (&'static str, Denomination)> {
.collect()
}

/// Temporary helper for testing, a hash map of tokens addresses with their
/// MASP XAN incentive schedules. If the reward is (a, b) then a rewarded tokens
/// are dispensed for every b possessed tokens.
pub fn masp_rewards() -> HashMap<Address, (u32, u32)> {
vec![
(nam(), (0, 100)),
(btc(), (1, 100)),
(eth(), (2, 100)),
(dot(), (3, 100)),
(schnitzel(), (4, 100)),
(apfel(), (5, 100)),
(kartoffel(), (6, 100)),
]
.into_iter()
.collect()
}

#[cfg(test)]
pub mod tests {
use proptest::prelude::*;
Expand Down
20 changes: 17 additions & 3 deletions core/src/types/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,20 @@ impl Mul<Amount> for Amount {
}
}

/// A combination of Euclidean division and fractions:
/// x*(a,b) = (a*(x//b), x%b).
impl Mul<(u128, u128)> for Amount {
type Output = (Amount, Amount);

fn mul(mut self, rhs: (u128, u128)) -> Self::Output {
let amt = Amount {
raw: (self.raw / rhs.1) * Uint::from(rhs.0),
};
self.raw %= rhs.1;
(amt, self)
}
}

/// A combination of Euclidean division and fractions:
/// x*(a,b) = (a*(x//b), x%b).
impl Mul<(u64, u64)> for Amount {
Expand Down Expand Up @@ -1336,10 +1350,10 @@ pub mod testing {
H: 'static + ledger_storage::StorageHasher,
{
use crate::ledger::parameters::storage::get_epochs_per_year_key;
use crate::types::address::masp_rewards;
use crate::types::address::tokens;

let masp_rewards = masp_rewards();
let masp_reward_keys: Vec<_> = masp_rewards.keys().collect();
let tokens = tokens();
let masp_reward_keys: Vec<_> = tokens.keys().collect();

wl_storage
.write(&get_epochs_per_year_key(), epochs_per_year)
Expand Down
4 changes: 2 additions & 2 deletions shared/src/ledger/queries/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Conversion = (
Address,
MaspDenom,
Epoch,
masp_primitives::transaction::components::I32Sum,
masp_primitives::transaction::components::I128Sum,
MerklePath<Node>,
);

Expand Down Expand Up @@ -254,7 +254,7 @@ where
addr.clone(),
*denom,
*epoch,
Into::<masp_primitives::transaction::components::I32Sum>::into(
Into::<masp_primitives::transaction::components::I128Sum>::into(
conv.clone(),
),
ctx.wl_storage.storage.conversion_state.tree.path(*pos),
Expand Down
6 changes: 3 additions & 3 deletions shared/src/sdk/masp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ use masp_primitives::transaction::builder::{self, *};
use masp_primitives::transaction::components::sapling::builder::SaplingMetadata;
use masp_primitives::transaction::components::transparent::builder::TransparentBuilder;
use masp_primitives::transaction::components::{
ConvertDescription, I128Sum, I32Sum, OutputDescription, SpendDescription,
TxOut, U64Sum,
ConvertDescription, I128Sum, OutputDescription, SpendDescription, TxOut,
U64Sum,
};
use masp_primitives::transaction::fees::fixed::FeeRule;
use masp_primitives::transaction::sighash::{signature_hash, SignableInput};
Expand Down Expand Up @@ -989,7 +989,7 @@ impl<U: ShieldedUtils> ShieldedContext<U> {
Address,
MaspDenom,
_,
I32Sum,
I128Sum,
MerklePath<Node>,
) = rpc::query_conversion(client, asset_type).await?;
self.asset_types
Expand Down
2 changes: 1 addition & 1 deletion shared/src/sdk/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ pub async fn query_conversion<C: crate::ledger::queries::Client + Sync>(
Address,
MaspDenom,
Epoch,
masp_primitives::transaction::components::I32Sum,
masp_primitives::transaction::components::I128Sum,
MerklePath<Node>,
)> {
Some(unwrap_client_response::<C, _>(
Expand Down
4 changes: 2 additions & 2 deletions shared/src/sdk/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use masp_primitives::transaction::components::sapling::fees::{
use masp_primitives::transaction::components::transparent::fees::{
InputView as TransparentInputView, OutputView as TransparentOutputView,
};
use masp_primitives::transaction::components::I32Sum;
use masp_primitives::transaction::components::I128Sum;
use namada_core::ledger::governance::cli::onchain::{
DefaultProposal, OnChainProposal, PgfFundingProposal, PgfStewardProposal,
ProposalVote,
Expand Down Expand Up @@ -1643,7 +1643,7 @@ async fn used_asset_types<
// Collect all the asset types used in the Sapling converts
for output in builder.sapling_converts() {
for (asset_type, _) in
I32Sum::from(output.conversion().clone()).components()
I128Sum::from(output.conversion().clone()).components()
{
add_asset_type(&mut asset_types, shielded, client, *asset_type)
.await;
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit a625126

Please sign in to comment.