Skip to content

Commit

Permalink
Merge branch 'mariari/inflation-rewards' into draft
Browse files Browse the repository at this point in the history
* mariari/inflation-rewards:
  masp: implement remaining inflation logic
  Fixup clippy issues
  Update the test with the correct inflation values
  Corrected the compounding of the MASP transparent balance.
  Now handle native inflation rewards for native tokens.
  Make the formula for the conversion rates reliable, also dump logs for e2e
  Update e2e tests
  Change the last inflation amount to reflect the actual amount minted
  Fix dev.toml having inconsistent token values and inconsistent dot
  Convert test storage to use the WlStorage and added token initalizer
  Add the total token balance to the address of each token account
  Add default values for each token parameter
  Add Parameter data structure for holding an initalizing token params
  Update the update_allowed_conversions to use the pd controller
  Reaplace by hand reward depositing, with a call to mint
  Add Token Parameters module, and keys like inflation and lock ratio
  Move inflation to core from shared
  app/node: tidy up some commented out code and logging
  core/storage: refactor epoch update tracker
  apps/finalize_block: log error when last proposer is missing
  app/finalize_block: refactor log_block_rewards/apply_inflation
  clean redundant code and old comments
  fix `value` types in functions that update parameters storage
  fix block proposer look-up and unit tests
  pos/docs: fix docstring typo
  app/ledger/finalize_block: write inflation + locked ratio via write-log
  app/ledger: tidy up some logging
  app/ledger/finalize_block: fix and refactor block proposer look-up
  test/finalize_block: extend no-DB commit test to ensure we hit inflation
  apps/ledger: only specify num of validators in "dev" build
  changelog: add #714
  [ci] wasm checksums update
  redo block proposer storage in abciplus mode
  clean up documentation and print-outs
  fix e2e::ledger_tests::double_signing_gets_slashed
  fix e2e::ledger_tests::pos_init_validator error
  fix e2e::ledger_tests::proposal_submission
  upgrade total token supply tracking and balance tracking at genesis
  fix e2e test ibc
  WIP - current changes, debug printouts, etc stuff
  update comments and documentation
  Cargo lock and tomls
  tests for inflation
  configure genesis to set up any number of validators
  trigger 2-block countdown to new epoch for Tendermint
  log block rewards with accumulator LazyMaps and apply inflation with rewards products
  storage types and keys for inflation
  inflation and rewards modules
  • Loading branch information
juped committed Jul 18, 2023
2 parents 9448c85 + 9cab267 commit f9997c5
Show file tree
Hide file tree
Showing 18 changed files with 1,510 additions and 539 deletions.
6 changes: 6 additions & 0 deletions .changelog/unreleased/features/714-pos-inflation-rewards.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- Introduce infrastructure for PoS inflation and rewards. Includes inflation
using the PD controller mechanism and rewards based on validator block voting
behavior. Rewards are tracked and effectively distributed using the F1 fee
mechanism. In this PR, rewards are calculated and stored, but they are not
yet applied to voting powers or considered when unbonding and withdrawing.
([#714](https://github.com/anoma/namada/pull/714))
40 changes: 20 additions & 20 deletions apps/src/lib/config/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,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::Uint;
use namada::types::uint::{Uint, I256};
use namada::types::{storage, token};

/// Genesis configuration file format
Expand All @@ -46,7 +46,7 @@ pub mod genesis_config {
use namada::types::key::*;
use namada::types::time::Rfc3339String;
use namada::types::token::Denomination;
use namada::types::uint::Uint;
use namada::types::uint::{Uint, I256};
use namada::types::{storage, token};
use serde::{Deserialize, Serialize};
use thiserror::Error;
Expand Down Expand Up @@ -217,6 +217,9 @@ pub mod genesis_config {
pub vp: Option<String>,
// Initial balances held by accounts defined elsewhere.
pub balances: Option<HashMap<String, token::Amount>>,
// Token parameters
// XXX: u64 doesn't work with toml-rs!
pub parameters: Option<token::parameters::Parameters>,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
Expand Down Expand Up @@ -404,6 +407,9 @@ pub mod genesis_config {
let token_vp_config = wasm.get(token_vp_name).unwrap();

TokenAccount {
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,
vp_code_path: token_vp_config.filename.to_owned(),
Expand Down Expand Up @@ -823,6 +829,13 @@ pub struct TokenAccount {
/// Accounts' balances of this token
#[derivative(PartialOrd = "ignore", Ord = "ignore")]
pub balances: HashMap<Address, token::Amount>,
// please put the last inflation amount here.
/// Token parameters
pub parameters: token::parameters::Parameters,
/// Token inflation from the last epoch (read + write for every epoch)
pub last_inflation: I256,
/// Token shielded ratio from the last epoch (read + write for every epoch)
pub last_locked_ratio: Dec,
}

#[derive(
Expand Down Expand Up @@ -898,9 +911,7 @@ pub fn genesis(
}
#[cfg(any(test, feature = "dev"))]
pub fn genesis(num_validators: u64) -> Genesis {
use namada::types::address::{
self, apfel, btc, dot, eth, kartoffel, nam, schnitzel,
};
use namada::types::address::{self};

use crate::wallet;

Expand Down Expand Up @@ -1064,28 +1075,17 @@ pub fn genesis(num_validators: u64) -> Genesis {
balances.insert((&validator.account_key).into(), default_key_tokens);
}

/// Deprecated function, soon to be deleted. Generates default tokens
fn tokens() -> HashMap<Address, (&'static str, Denomination)> {
vec![
(nam(), ("NAM", 6.into())),
(btc(), ("BTC", 8.into())),
(eth(), ("ETH", 18.into())),
(dot(), ("DOT", 10.into())),
(schnitzel(), ("Schnitzel", 6.into())),
(apfel(), ("Apfel", 6.into())),
(kartoffel(), ("Kartoffel", 6.into())),
]
.into_iter()
.collect()
}
let token_accounts = tokens()
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: I256::zero(),
last_locked_ratio: Dec::zero(),
})
.collect();
Genesis {
Expand Down
21 changes: 21 additions & 0 deletions apps/src/lib/node/ledger/shell/init_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,20 @@ where
vp_code_path,
vp_sha256,
balances,
parameters,
last_inflation,
last_locked_ratio,
} in accounts
{
// Init token parameters and last inflation and caching rates
parameters.init_storage(&address, &mut self.wl_storage);
self.wl_storage
.write(&token::last_inflation(&address), last_inflation)
.unwrap();
self.wl_storage
.write(&token::last_locked_ratio(&address), last_locked_ratio)
.unwrap();

// associate a token with its denomination.
write_denom(
&mut self.wl_storage,
Expand Down Expand Up @@ -387,10 +399,19 @@ where
.write_bytes(&Key::validity_predicate(&address), vp_code_hash)
.unwrap();

let mut total_balance_for_token = token::Amount::default();
for (owner, amount) in balances {
total_balance_for_token += amount;
credit_tokens(&mut self.wl_storage, &address, &owner, amount)
.unwrap();
}
// Write the total amount of tokens for the ratio
self.wl_storage
.write(
&token::total_supply_key(&address),
total_balance_for_token,
)
.unwrap();
}
}

Expand Down
2 changes: 2 additions & 0 deletions apps/src/lib/node/ledger/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,7 @@ mod test_utils {
use namada::ledger::storage_api::StorageWrite;
use namada::proto::{Code, Data};
use namada::types::address;
use namada::types::address::init_token_storage;
use namada::types::chain::ChainId;
use namada::types::ethereum_events::Uint;
use namada::types::hash::Hash;
Expand Down Expand Up @@ -1917,6 +1918,7 @@ mod test_utils {
.storage
.begin_block(BlockHash::default(), BlockHeight(1))
.expect("begin_block failed");
init_token_storage(&mut shell.wl_storage, 60);
let keypair = gen_keypair();
// enqueue a wrapper tx
let mut wrapper = Tx::new(TxType::Wrapper(Box::new(WrapperTx::new(
Expand Down
2 changes: 2 additions & 0 deletions apps/src/lib/node/ledger/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ mod tests {
types, update_allowed_conversions, WlStorage,
};
use namada::ledger::storage_api::{self, StorageWrite};
use namada::types::address::init_token_storage;
use namada::types::chain::ChainId;
use namada::types::hash::Hash;
use namada::types::storage::{BlockHash, BlockHeight, Key};
Expand Down Expand Up @@ -144,6 +145,7 @@ mod tests {
storage.block.pred_epochs.new_epoch(BlockHeight(100), 1000);
// make wl_storage to update conversion for a new epoch
let mut wl_storage = WlStorage::new(WriteLog::default(), storage);
init_token_storage(&mut wl_storage, 60);
update_allowed_conversions(&mut wl_storage)
.expect("update conversions failed");
wl_storage.commit_block().expect("commit failed");
Expand Down
59 changes: 57 additions & 2 deletions shared/src/ledger/inflation.rs → core/src/ledger/inflation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +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 @@ -47,6 +48,32 @@ pub struct RewardsController {
}

impl RewardsController {
/// Initialize a new PD controller
#[allow(clippy::too_many_arguments)]
pub fn new(
locked_tokens: token::Amount,
total_tokens: token::Amount,
locked_ratio_target: Dec,
locked_ratio_last: Dec,
max_reward_rate: Dec,
last_inflation_amount: token::Amount,
p_gain_nom: Dec,
d_gain_nom: Dec,
epochs_per_year: u64,
) -> Self {
Self {
locked_tokens,
total_tokens,
locked_ratio_target,
locked_ratio_last,
max_reward_rate,
last_inflation_amount,
p_gain_nom,
d_gain_nom,
epochs_per_year,
}
}

/// Calculate a new rewards rate
pub fn run(self) -> ValsToUpdate {
let Self {
Expand Down Expand Up @@ -95,3 +122,31 @@ impl RewardsController {
}
}
}

/// Function that allows the protocol to mint some number of tokens of a desired
/// type to a destination address TODO: think of error cases that must be
/// handled.
pub fn mint_tokens<S>(
storage: &mut S,
target: &Address,
token: &Address,
amount: token::Amount,
) -> storage_api::Result<()>
where
S: StorageWrite + StorageRead,
{
let dest_key = token::balance_key(token, target);
let mut dest_bal: token::Amount =
storage.read(&dest_key)?.unwrap_or_default();
dest_bal.receive(&amount);
storage.write(&dest_key, dest_bal)?;

// Update the total supply of the tokens in storage
let mut total_tokens: token::Amount = storage
.read(&token::total_supply_key(token))?
.unwrap_or_default();
total_tokens.receive(&amount);
storage.write(&token::total_supply_key(token), total_tokens)?;

Ok(())
}
1 change: 1 addition & 0 deletions core/src/ledger/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod gas;
pub mod governance;
#[cfg(any(feature = "abciplus", feature = "abcipp"))]
pub mod ibc;
pub mod inflation;
pub mod parameters;
pub mod replay_protection;
pub mod slash_fund;
Expand Down
Loading

0 comments on commit f9997c5

Please sign in to comment.