diff --git a/.changelog/unreleased/improvements/1985-compounding-rewards.md b/.changelog/unreleased/improvements/1985-compounding-rewards.md new file mode 100644 index 0000000000..1b41c6ca20 --- /dev/null +++ b/.changelog/unreleased/improvements/1985-compounding-rewards.md @@ -0,0 +1,2 @@ +- MASP rewards are now distributed in the manner dictated by the PD-controller + ([\#1985](https://github.com/anoma/namada/pull/1985)) \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 84cbd6f48e..1c0d1cb6d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3748,7 +3748,7 @@ dependencies = [ [[package]] name = "masp_note_encryption" version = "0.2.0" -source = "git+https://github.com/anoma/masp?rev=50acc5028fbcd52a05970fe7991c7850ab04358e#50acc5028fbcd52a05970fe7991c7850ab04358e" +source = "git+https://github.com/anoma/masp?rev=1345b463e8fa3b3a6fa13e4a43fb1c410690ad62#1345b463e8fa3b3a6fa13e4a43fb1c410690ad62" dependencies = [ "borsh 0.9.4", "chacha20 0.9.1", @@ -3761,7 +3761,7 @@ dependencies = [ [[package]] name = "masp_primitives" version = "0.9.0" -source = "git+https://github.com/anoma/masp?rev=50acc5028fbcd52a05970fe7991c7850ab04358e#50acc5028fbcd52a05970fe7991c7850ab04358e" +source = "git+https://github.com/anoma/masp?rev=1345b463e8fa3b3a6fa13e4a43fb1c410690ad62#1345b463e8fa3b3a6fa13e4a43fb1c410690ad62" dependencies = [ "aes 0.7.5", "bip0039", @@ -3792,7 +3792,7 @@ dependencies = [ [[package]] name = "masp_proofs" version = "0.9.0" -source = "git+https://github.com/anoma/masp?rev=50acc5028fbcd52a05970fe7991c7850ab04358e#50acc5028fbcd52a05970fe7991c7850ab04358e" +source = "git+https://github.com/anoma/masp?rev=1345b463e8fa3b3a6fa13e4a43fb1c410690ad62#1345b463e8fa3b3a6fa13e4a43fb1c410690ad62" dependencies = [ "bellman", "blake2b_simd", diff --git a/Cargo.toml b/Cargo.toml index 9c731f0fdf..db71e92989 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/apps/src/lib/client/rpc.rs b/apps/src/lib/client/rpc.rs index d750ccc759..1645009011 100644 --- a/apps/src/lib/client/rpc.rs +++ b/apps/src/lib/client/rpc.rs @@ -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 @@ -2181,7 +2181,7 @@ pub async fn query_conversion( Address, MaspDenom, Epoch, - masp_primitives::transaction::components::I32Sum, + masp_primitives::transaction::components::I128Sum, MerklePath, )> { namada::sdk::rpc::query_conversion(client, asset_type).await diff --git a/apps/src/lib/config/genesis.rs b/apps/src/lib/config/genesis.rs index b7281fd4ce..3331a30c03 100644 --- a/apps/src/lib/config/genesis.rs +++ b/apps/src/lib/config/genesis.rs @@ -213,6 +213,8 @@ pub mod genesis_config { pub vp: Option, // Initial balances held by accounts defined elsewhere. pub balances: Option>, + // Token parameters + pub parameters: Option, } #[derive(Clone, Debug, Deserialize, Serialize)] @@ -404,6 +406,9 @@ pub mod genesis_config { implicit_accounts: &HashMap, ) -> TokenAccount { TokenAccount { + last_locked_ratio: Dec::zero(), + last_inflation: token::Amount::zero(), + parameters: config.parameters.as_ref().unwrap().to_owned(), address: Address::decode(config.address.as_ref().unwrap()).unwrap(), denom: config.denom, balances: config @@ -818,6 +823,12 @@ pub struct TokenAccount { /// Accounts' balances of this token #[derivative(PartialOrd = "ignore", Ord = "ignore")] pub balances: HashMap, + /// Token parameters + pub parameters: token::Parameters, + /// Token inflation from the last epoch (read + write for every epoch) + pub last_inflation: token::Amount, + /// Token shielded ratio from the last epoch (read + write for every epoch) + pub last_locked_ratio: Dec, } #[derive( @@ -1001,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(), @@ -1100,6 +1111,9 @@ pub fn genesis(num_validators: u64) -> Genesis { .into_iter() .map(|(k, v)| (k, token::Amount::from_uint(v, denom).unwrap())) .collect(), + parameters: token::Parameters::default(), + last_inflation: token::Amount::zero(), + last_locked_ratio: Dec::zero(), }) .collect(); Genesis { diff --git a/apps/src/lib/node/ledger/shell/finalize_block.rs b/apps/src/lib/node/ledger/shell/finalize_block.rs index 53252065f1..f36cd4b7e7 100644 --- a/apps/src/lib/node/ledger/shell/finalize_block.rs +++ b/apps/src/lib/node/ledger/shell/finalize_block.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use data_encoding::HEXUPPER; +use namada::core::ledger::inflation; use namada::core::ledger::pgf::ADDRESS as pgf_address; use namada::ledger::events::EventType; use namada::ledger::gas::{GasMetering, TxGasMeter}; @@ -11,7 +12,7 @@ use namada::ledger::pos::{namada_proof_of_stake, staking_token_address}; use namada::ledger::storage::EPOCH_SWITCH_BLOCKS_DELAY; use namada::ledger::storage_api::token::credit_tokens; use namada::ledger::storage_api::{pgf, StorageRead, StorageWrite}; -use namada::ledger::{inflation, protocol, replay_protection}; +use namada::ledger::{protocol, replay_protection}; use namada::proof_of_stake::{ delegator_rewards_products_handle, find_validator_by_raw_hash, read_last_block_proposer_address, read_pos_params, read_total_stake, @@ -617,10 +618,8 @@ where /// with respect to the previous epoch. fn apply_inflation(&mut self, current_epoch: Epoch) -> Result<()> { let last_epoch = current_epoch.prev(); - // Get input values needed for the PD controller for PoS and MASP. + // Get input values needed for the PD controller for PoS. // Run the PD controllers to calculate new rates. - // - // MASP is included below just for some completeness. let params = read_pos_params(&self.wl_storage)?; @@ -642,7 +641,7 @@ where .read_storage_key(¶ms_storage::get_pos_inflation_amount_key()) .expect("PoS inflation amount should exist in storage"); // Read from PoS storage - let total_tokens = self + let total_tokens: token::Amount = self .read_storage_key(&token::minted_balance_key( &staking_token_address(&self.wl_storage), )) @@ -652,47 +651,25 @@ where let pos_locked_ratio_target = params.target_staked_ratio; let pos_max_inflation_rate = params.max_inflation_rate; - // TODO: properly fetch these values (arbitrary for now) - let masp_locked_supply: Amount = Amount::default(); - let masp_locked_ratio_target = Dec::new(5, 1).expect("Cannot fail"); - let masp_locked_ratio_last = Dec::new(5, 1).expect("Cannot fail"); - let masp_max_inflation_rate = Dec::new(2, 1).expect("Cannot fail"); - let masp_last_inflation_rate = Dec::new(12, 2).expect("Cannot fail"); - let masp_p_gain = Dec::new(1, 1).expect("Cannot fail"); - let masp_d_gain = Dec::new(1, 1).expect("Cannot fail"); - // Run rewards PD controller let pos_controller = inflation::RewardsController { - locked_tokens: pos_locked_supply, - total_tokens, + locked_tokens: pos_locked_supply.raw_amount(), + total_tokens: total_tokens.raw_amount(), + total_native_tokens: total_tokens.raw_amount(), locked_ratio_target: pos_locked_ratio_target, locked_ratio_last: pos_last_staked_ratio, max_reward_rate: pos_max_inflation_rate, - last_inflation_amount: pos_last_inflation_amount, + last_inflation_amount: pos_last_inflation_amount.raw_amount(), p_gain_nom: pos_p_gain_nom, d_gain_nom: pos_d_gain_nom, epochs_per_year, }; - let _masp_controller = inflation::RewardsController { - locked_tokens: masp_locked_supply, - total_tokens, - locked_ratio_target: masp_locked_ratio_target, - locked_ratio_last: masp_locked_ratio_last, - max_reward_rate: masp_max_inflation_rate, - last_inflation_amount: token::Amount::from( - masp_last_inflation_rate, - ), - p_gain_nom: masp_p_gain, - d_gain_nom: masp_d_gain, - epochs_per_year, - }; // Run the rewards controllers let inflation::ValsToUpdate { locked_ratio, inflation, } = pos_controller.run(); - // let new_masp_vals = _masp_controller.run(); // Get the number of blocks in the last epoch let first_block_of_last_epoch = self @@ -712,6 +689,9 @@ where // for the previous epoch // // TODO: think about changing the reward to Decimal + let inflation = token::Amount::from_uint(inflation, 0) + .expect("Should not fail Uint -> Amount conversion"); + let mut reward_tokens_remaining = inflation; let mut new_rewards_products: HashMap = HashMap::new(); diff --git a/apps/src/lib/node/ledger/shell/init_chain.rs b/apps/src/lib/node/ledger/shell/init_chain.rs index d6b2efe4dd..abe231e9af 100644 --- a/apps/src/lib/node/ledger/shell/init_chain.rs +++ b/apps/src/lib/node/ledger/shell/init_chain.rs @@ -330,14 +330,41 @@ where address, denom, 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::masp_last_inflation_key(&address), + last_inflation, + ) + .unwrap(); + self.wl_storage + .write( + &token::masp_last_locked_ratio_key(&address), + last_locked_ratio, + ) + .unwrap(); // associate a token with its denomination. write_denom(&mut self.wl_storage, &address, denom).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::minted_balance_key(&address), + total_balance_for_token, + ) + .unwrap(); } } diff --git a/apps/src/lib/node/ledger/shell/mod.rs b/apps/src/lib/node/ledger/shell/mod.rs index a1c17fe450..8230ce2a76 100644 --- a/apps/src/lib/node/ledger/shell/mod.rs +++ b/apps/src/lib/node/ledger/shell/mod.rs @@ -1980,6 +1980,7 @@ mod test_utils { /// We test that on shell shutdown, the tx queue gets persisted in a DB, and /// on startup it is read successfully + #[cfg(feature = "testing")] #[test] fn test_tx_queue_persistence() { let base_dir = tempdir().unwrap().as_ref().canonicalize().unwrap(); @@ -2017,6 +2018,7 @@ mod test_utils { .storage .begin_block(BlockHash::default(), BlockHeight(1)) .expect("begin_block failed"); + token::testing::init_token_storage(&mut shell.wl_storage, 60); let keypair = gen_keypair(); // enqueue a wrapper tx let mut wrapper = diff --git a/apps/src/lib/node/ledger/storage/mod.rs b/apps/src/lib/node/ledger/storage/mod.rs index 659f561cce..43617879c8 100644 --- a/apps/src/lib/node/ledger/storage/mod.rs +++ b/apps/src/lib/node/ledger/storage/mod.rs @@ -118,6 +118,7 @@ mod tests { assert_eq!(result, None); } + #[cfg(feature = "testing")] #[test] fn test_commit_block() { let db_path = @@ -144,6 +145,7 @@ mod tests { storage.block.pred_epochs.new_epoch(BlockHeight(100)); // make wl_storage to update conversion for a new epoch let mut wl_storage = WlStorage::new(WriteLog::default(), storage); + namada::types::token::testing::init_token_storage(&mut wl_storage, 60); update_allowed_conversions(&mut wl_storage) .expect("update conversions failed"); wl_storage.commit_block().expect("commit failed"); diff --git a/shared/src/ledger/inflation.rs b/core/src/ledger/inflation.rs similarity index 70% rename from shared/src/ledger/inflation.rs rename to core/src/ledger/inflation.rs index da2d5ed1e1..3e1902a445 100644 --- a/shared/src/ledger/inflation.rs +++ b/core/src/ledger/inflation.rs @@ -2,9 +2,8 @@ //! proof-of-stake, providing liquity to shielded asset pools, and public goods //! funding. -use namada_core::types::dec::Dec; - -use crate::types::token; +use crate::types::dec::Dec; +use crate::types::uint::Uint; /// The domains of inflation pub enum RewardsType { @@ -20,16 +19,18 @@ pub enum RewardsType { #[allow(missing_docs)] pub struct ValsToUpdate { pub locked_ratio: Dec, - pub inflation: token::Amount, + pub inflation: Uint, } /// PD controller used to dynamically adjust the rewards rates #[derive(Debug, Clone)] pub struct RewardsController { /// Locked token amount in the relevant system - pub locked_tokens: token::Amount, + pub locked_tokens: Uint, /// Total token supply - pub total_tokens: token::Amount, + pub total_tokens: Uint, + /// Total native token supply + pub total_native_tokens: Uint, /// PD target locked ratio pub locked_ratio_target: Dec, /// PD last locked ratio @@ -37,7 +38,7 @@ pub struct RewardsController { /// Maximum reward rate pub max_reward_rate: Dec, /// Last inflation amount - pub last_inflation_amount: token::Amount, + pub last_inflation_amount: Uint, /// Nominal proportional gain pub p_gain_nom: Dec, /// Nominal derivative gain @@ -52,6 +53,7 @@ impl RewardsController { let Self { locked_tokens, total_tokens, + total_native_tokens, locked_ratio_target, locked_ratio_last, max_reward_rate, @@ -63,14 +65,16 @@ impl RewardsController { // Token amounts must be expressed in terms of the raw amount (namnam) // to properly run the PD controller - let locked = Dec::try_from(locked_tokens.raw_amount()) - .expect("Should not fail to convert token Amount to Dec"); - let total = Dec::try_from(total_tokens.raw_amount()) - .expect("Should not fail to convert token Amount to Dec"); + let locked = Dec::try_from(locked_tokens) + .expect("Should not fail to convert Uint to Dec"); + let total = Dec::try_from(total_tokens) + .expect("Should not fail to convert Uint to Dec"); + let total_native = Dec::try_from(total_native_tokens) + .expect("Should not fail to convert Uint to Dec"); let epochs_py: Dec = epochs_per_year.into(); let locked_ratio = locked / total; - let max_inflation = total * max_reward_rate / epochs_py; + let max_inflation = total_native * max_reward_rate / epochs_py; let p_gain = p_gain_nom * max_inflation; let d_gain = d_gain_nom * max_inflation; @@ -78,29 +82,20 @@ impl RewardsController { let delta_error = locked_ratio_last - locked_ratio; let control_val = p_gain * error - d_gain * delta_error; - let last_inflation_amount = - Dec::try_from(last_inflation_amount.raw_amount()) - .expect("Should not fail to convert token Amount to Dec"); + let last_inflation_amount = Dec::try_from(last_inflation_amount) + .expect("Should not fail to convert Uint to Dec"); let new_inflation_amount_raw = last_inflation_amount + control_val; let new_inflation_amount = if new_inflation_amount_raw.is_negative() { - token::Amount::zero() + Uint::zero() } else { - token::Amount::from_uint( - new_inflation_amount_raw - .to_uint() - .expect("Should not fail to convert Dec to Uint"), - 0, - ) - .expect("Should not fail to convert Uint to Amount") + new_inflation_amount_raw + .to_uint() + .expect("Should not fail to convert Dec to Uint") }; - let max_inflation = token::Amount::from_uint( - max_inflation - .to_uint() - .expect("Should not fail to convert Dec to Uint"), - 0, - ) - .expect("Should not fail to convert Uint to Amount"); + let max_inflation = max_inflation + .to_uint() + .expect("Should not fail to convert Dec to Uint"); let inflation = std::cmp::min(new_inflation_amount, max_inflation); ValsToUpdate { @@ -114,27 +109,18 @@ impl RewardsController { mod test { use std::str::FromStr; - use namada_core::types::token::NATIVE_MAX_DECIMAL_PLACES; - use super::*; #[test] fn test_inflation_calc_up() { let mut controller = RewardsController { - locked_tokens: token::Amount::from_uint( - 2_000, - NATIVE_MAX_DECIMAL_PLACES, - ) - .unwrap(), - total_tokens: token::Amount::from_uint( - 4_000, - NATIVE_MAX_DECIMAL_PLACES, - ) - .unwrap(), + locked_tokens: Uint::from(2_000_000_000), + total_tokens: Uint::from(4_000_000_000_u64), + total_native_tokens: Uint::from(4_000_000_000_u64), locked_ratio_target: Dec::from_str("0.66666666").unwrap(), locked_ratio_last: Dec::from_str("0.5").unwrap(), max_reward_rate: Dec::from_str("0.1").unwrap(), - last_inflation_amount: token::Amount::zero(), + last_inflation_amount: Uint::zero(), p_gain_nom: Dec::from_str("0.1").unwrap(), d_gain_nom: Dec::from_str("0.1").unwrap(), epochs_per_year: 365, @@ -146,11 +132,10 @@ mod test { inflation: inflation_0, } = controller.clone().run(); println!( - "Round 0: Locked ratio: {locked_ratio_0}, inflation: {}", - inflation_0.to_string_native() + "Round 0: Locked ratio: {locked_ratio_0}, inflation: {inflation_0}" ); assert_eq!(locked_ratio_0, Dec::from_str("0.5").unwrap()); - assert_eq!(inflation_0, token::Amount::from_uint(18_264, 0).unwrap()); + assert_eq!(inflation_0, Uint::from(18_264)); controller.locked_ratio_last = locked_ratio_0; controller.last_inflation_amount = inflation_0; @@ -162,13 +147,12 @@ mod test { inflation: inflation_1, } = controller.clone().run(); println!( - "Round 1: Locked ratio: {locked_ratio_1}, inflation: {}", - inflation_1.to_string_native() + "Round 1: Locked ratio: {locked_ratio_1}, inflation: {inflation_1}" ); assert!(locked_ratio_1 > locked_ratio_0); assert!(locked_ratio_1 > Dec::from_str("0.5").unwrap()); assert!(locked_ratio_1 < Dec::from_str("0.51").unwrap()); - assert_eq!(inflation_1, token::Amount::from_uint(36_528, 0).unwrap()); + assert_eq!(inflation_1, Uint::from(36_528)); controller.locked_ratio_last = locked_ratio_1; controller.last_inflation_amount = inflation_1; @@ -180,32 +164,24 @@ mod test { inflation: inflation_2, } = controller.run(); println!( - "Round 2: Locked ratio: {locked_ratio_2}, inflation: {}", - inflation_2.to_string_native() + "Round 2: Locked ratio: {locked_ratio_2}, inflation: {inflation_2}", ); assert!(locked_ratio_2 > locked_ratio_1); assert!(locked_ratio_2 > Dec::from_str("0.5").unwrap()); assert!(locked_ratio_2 < Dec::from_str("0.51").unwrap()); - assert_eq!(inflation_2, token::Amount::from_uint(54_792, 0).unwrap()); + assert_eq!(inflation_2, Uint::from(54_792)); } #[test] fn test_inflation_calc_down() { let mut controller = RewardsController { - locked_tokens: token::Amount::from_uint( - 900, - NATIVE_MAX_DECIMAL_PLACES, - ) - .unwrap(), - total_tokens: token::Amount::from_uint( - 1_000, - NATIVE_MAX_DECIMAL_PLACES, - ) - .unwrap(), + locked_tokens: Uint::from(900_000_000), + total_tokens: Uint::from(1_000_000_000), + total_native_tokens: Uint::from(1_000_000_000), locked_ratio_target: Dec::from_str("0.66666666").unwrap(), locked_ratio_last: Dec::from_str("0.9").unwrap(), max_reward_rate: Dec::from_str("0.1").unwrap(), - last_inflation_amount: token::Amount::from_uint(10_000, 0).unwrap(), + last_inflation_amount: Uint::from(10_000), p_gain_nom: Dec::from_str("0.1").unwrap(), d_gain_nom: Dec::from_str("0.1").unwrap(), epochs_per_year: 365, @@ -217,11 +193,10 @@ mod test { inflation: inflation_0, } = controller.clone().run(); println!( - "Round 0: Locked ratio: {locked_ratio_0}, inflation: {}", - inflation_0.to_string_native() + "Round 0: Locked ratio: {locked_ratio_0}, inflation: {inflation_0}", ); assert_eq!(locked_ratio_0, Dec::from_str("0.9").unwrap()); - assert_eq!(inflation_0, token::Amount::from_uint(3_607, 0).unwrap()); + assert_eq!(inflation_0, Uint::from(3_607)); controller.locked_ratio_last = locked_ratio_0; controller.last_inflation_amount = inflation_0; @@ -233,13 +208,12 @@ mod test { inflation: inflation_1, } = controller.clone().run(); println!( - "Round 1: Locked ratio: {locked_ratio_1}, inflation: {}", - inflation_1.to_string_native() + "Round 1: Locked ratio: {locked_ratio_1}, inflation: {inflation_1}", ); assert!(locked_ratio_1 > locked_ratio_0); assert!(locked_ratio_1 > Dec::from_str("0.9").unwrap()); assert!(locked_ratio_1 < Dec::from_str("0.91").unwrap()); - assert_eq!(inflation_1, token::Amount::zero()); + assert_eq!(inflation_1, Uint::zero()); controller.locked_ratio_last = locked_ratio_1; controller.last_inflation_amount = inflation_1; @@ -251,10 +225,9 @@ mod test { inflation: inflation_2, } = controller.run(); println!( - "Round 2: Locked ratio: {locked_ratio_2}, inflation: {}", - inflation_2.to_string_native() + "Round 2: Locked ratio: {locked_ratio_2}, inflation: {inflation_2}", ); assert_eq!(locked_ratio_2, locked_ratio_1); - assert_eq!(inflation_2, token::Amount::zero()); + assert_eq!(inflation_2, Uint::zero()); } } diff --git a/core/src/ledger/mod.rs b/core/src/ledger/mod.rs index 890d58044d..301cf78e08 100644 --- a/core/src/ledger/mod.rs +++ b/core/src/ledger/mod.rs @@ -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 pgf; pub mod replay_protection; diff --git a/core/src/ledger/storage/masp_conversions.rs b/core/src/ledger/storage/masp_conversions.rs index 624fe2aa1f..69c1461e71 100644 --- a/core/src/ledger/storage/masp_conversions.rs +++ b/core/src/ledger/storage/masp_conversions.rs @@ -8,15 +8,22 @@ use masp_primitives::convert::AllowedConversion; use masp_primitives::merkle_tree::FrozenCommitmentTree; 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::uint::Uint; +use crate::types::{address, token}; /// A representation of the conversion state #[derive(Debug, Default, BorshSerialize, BorshDeserialize)] pub struct ConversionState { - /// The merkle root from the previous epoch - pub prev_root: Node, + /// The last amount of the native token distributed + pub normed_inflation: Option, /// The tree currently containing all the conversions pub tree: FrozenCommitmentTree, /// Map assets to their latest conversion and position in Merkle tree @@ -27,6 +34,159 @@ pub struct ConversionState { >, } +/// Compute the MASP rewards by applying the PD-controller to the genesis +/// parameters and the last inflation and last locked rewards ratio values. +pub fn calculate_masp_rewards( + wl_storage: &mut super::WlStorage, + addr: &Address, +) -> 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)? + .expect("failed to read token denomination"); + // 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. Here we choose + // a thousandth of the given asset. + 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))? + .expect("the total supply key should be here"); + + //// information about the amount of native tokens on the chain + let total_native_tokens: token::Amount = wl_storage + .read(&token::minted_balance_key(&wl_storage.storage.native_token))? + .expect("the total supply key should be here"); + + // total staked amount in the Shielded pool + let total_token_in_masp: token::Amount = wl_storage + .read(&token::balance_key(addr, &masp_addr))? + .unwrap_or_default(); + + let epochs_per_year: u64 = wl_storage + .read(¶meters::storage::get_epochs_per_year_key())? + .expect("epochs per year should properly decode"); + + //// Values from the last epoch + let last_inflation: token::Amount = wl_storage + .read(&token::masp_last_inflation_key(addr))? + .expect("failure to read last inflation"); + + let last_locked_ratio: Dec = wl_storage + .read(&token::masp_last_locked_ratio_key(addr))? + .expect("failure to read last inflation"); + + //// Parameters for each token + let max_reward_rate: Dec = wl_storage + .read(&token::masp_max_reward_rate_key(addr))? + .expect("max reward should properly decode"); + + let kp_gain_nom: Dec = wl_storage + .read(&token::masp_kp_gain_key(addr))? + .expect("kp_gain_nom reward should properly decode"); + + let kd_gain_nom: Dec = wl_storage + .read(&token::masp_kd_gain_key(addr))? + .expect("kd_gain_nom reward should properly decode"); + + let locked_target_ratio: Dec = wl_storage + .read(&token::masp_locked_ratio_target_key(addr))? + .expect("locked ratio target should properly decode"); + + // Creating the PD controller for handing out tokens + let controller = RewardsController { + locked_tokens: total_token_in_masp.raw_amount(), + total_tokens: total_tokens.raw_amount(), + total_native_tokens: total_native_tokens.raw_amount(), + locked_ratio_target: locked_target_ratio, + locked_ratio_last: last_locked_ratio, + max_reward_rate, + last_inflation_amount: last_inflation.raw_amount(), + p_gain_nom: kp_gain_nom, + d_gain_nom: kd_gain_nom, + epochs_per_year, + }; + + let ValsToUpdate { + locked_ratio, + inflation, + } = RewardsController::run(controller); + + // inflation-per-token = inflation / locked tokens = n/PRECISION + // ∴ n = (inflation * PRECISION) / locked tokens + // 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() { + 0u128 + } else { + inflation + .checked_mul_div( + Uint::from(precision), + total_token_in_masp.raw_amount(), + ) + .and_then(|x| x.0.try_into().ok()) + .unwrap_or_else(|| { + tracing::warn!( + "MASP inflation for {} assumed to be 0 because the \ + computed value is too large. Please check the inflation \ + parameters.", + *addr + ); + 0u128 + }) + }; + + tracing::debug!( + "Controller, call: total_in_masp {:?}, total_tokens {:?}, \ + total_native_tokens {:?}, locked_target_ratio {:?}, \ + last_locked_ratio {:?}, max_reward_rate {:?}, last_inflation {:?}, \ + kp_gain_nom {:?}, kd_gain_nom {:?}, epochs_per_year {:?}", + total_token_in_masp, + total_tokens, + total_native_tokens, + locked_target_ratio, + last_locked_ratio, + max_reward_rate, + last_inflation, + kp_gain_nom, + kd_gain_nom, + epochs_per_year, + ); + tracing::debug!("Please give me: {:?}", addr); + tracing::debug!("Ratio {:?}", locked_ratio); + tracing::debug!("inflation from the pd controller {:?}", inflation); + tracing::debug!("total in the masp {:?}", total_token_in_masp); + tracing::debug!("Please give me inflation: {:?}", noterized_inflation); + + // Is it fine to write the inflation rate, this is accurate, + // but we should make sure the return value's ratio matches + // this new inflation rate in 'update_allowed_conversions', + // otherwise we will have an inaccurate view of inflation + wl_storage.write( + &token::masp_last_inflation_key(addr), + token::Amount::from_uint( + (total_token_in_masp.raw_amount() / precision) + * Uint::from(noterized_inflation), + 0, + ) + .unwrap(), + )?; + + wl_storage.write(&token::masp_last_locked_ratio_key(addr), locked_ratio)?; + + Ok((noterized_inflation, precision)) +} + // This is only enabled when "wasm-runtime" is on, because we're using rayon #[cfg(feature = "wasm-runtime")] /// Update the MASP's allowed conversions @@ -37,45 +197,66 @@ where D: 'static + super::DB + for<'iter> super::DBIter<'iter>, H: 'static + super::StorageHasher, { + 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, }; use rayon::prelude::ParallelSlice; - use crate::ledger::storage_api::{ResultExt, StorageRead, StorageWrite}; + use crate::ledger::storage_api::ResultExt; use crate::types::storage::{self, KeySeg}; - use crate::types::{address, token}; // The derived conversions will be placed in MASP address space let masp_addr = address::masp(); let key_prefix: storage::Key = masp_addr.to_db_key().into(); - let masp_rewards = address::masp_rewards(); + let tokens = address::tokens(); + let mut masp_reward_keys: Vec<_> = tokens.into_keys().collect(); + // Put the native rewards first because other inflation computations depend + // on it + let native_token = wl_storage.storage.native_token.clone(); + masp_reward_keys.sort_unstable_by(|x, y| { + if (*x == native_token) == (*y == native_token) { + Ordering::Equal + } else if *x == native_token { + Ordering::Less + } else { + Ordering::Greater + } + }); // The total transparent value of the rewards being distributed let mut total_reward = token::Amount::native_whole(0); - // Construct MASP asset type for rewards. Always timestamp reward tokens - // with the zeroth epoch to minimize the number of convert notes clients - // 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(), MaspDenom::Zero, Epoch(0)); + // Construct MASP asset type for rewards. Always deflate and timestamp + // reward tokens with the zeroth epoch to minimize the number of convert + // notes clients have to use. This trick works under the assumption that + // reward tokens will then be reinflated back to the current epoch. + let reward_assets = [ + encode_asset_type(native_token.clone(), MaspDenom::Zero, Epoch(0)), + encode_asset_type(native_token.clone(), MaspDenom::One, Epoch(0)), + encode_asset_type(native_token.clone(), MaspDenom::Two, Epoch(0)), + encode_asset_type(native_token.clone(), MaspDenom::Three, Epoch(0)), + ]; // Conversions from the previous to current asset for each address let mut current_convs = BTreeMap::<(Address, MaspDenom), AllowedConversion>::new(); + // Native token inflation values are always with respect to this + let mut ref_inflation = 0; // Reward all tokens according to above reward rates - for (addr, reward) in &masp_rewards { + for addr in &masp_reward_keys { + let reward = calculate_masp_rewards(wl_storage, addr)?; + if *addr == native_token { + // The reference inflation is the denominator of the native token + // inflation, which is always a constant + ref_inflation = reward.1; + } // Dispense a transparent reward in parallel to the shielded rewards let addr_bal: token::Amount = wl_storage .read(&token::balance_key(addr, &masp_addr))? .unwrap_or_default(); - // The reward for each reward.1 units of the current asset is - // 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; for denom in token::MaspDenom::iter() { // Provide an allowed conversion from previous timestamp. The // negative sign allows each instance of the old asset to be @@ -90,15 +271,102 @@ where denom, wl_storage.storage.block.epoch, ); - current_convs.insert( - (addr.clone(), denom), - (MaspAmount::from_pair(old_asset, -(reward.1 as i32)).unwrap() - + MaspAmount::from_pair(new_asset, reward.1 as i32) + // Get the last rewarded amount of the native token + let normed_inflation = wl_storage + .storage + .conversion_state + .normed_inflation + .get_or_insert(ref_inflation); + if *addr == native_token { + // 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 = Uint::from(*normed_inflation) + .checked_add( + (Uint::from(*normed_inflation) * Uint::from(reward.0)) + / reward.1, + ) + .and_then(|x| x.try_into().ok()) + .unwrap_or_else(|| { + tracing::warn!( + "MASP reward for {} assumed to be 0 because the \ + computed value is too large. Please check the \ + inflation parameters.", + *addr + ); + *normed_inflation + }); + // The conversion is computed such that if consecutive + // conversions are added together, the + // intermediate native tokens cancel/ + // telescope out + current_convs.insert( + (addr.clone(), denom), + (MaspAmount::from_pair( + old_asset, + -(*normed_inflation as i128), + ) + .unwrap() + + MaspAmount::from_pair( + new_asset, + new_normed_inflation as i128, + ) + .unwrap()) + .into(), + ); + // Operations that happen exactly once for each token + if denom == MaspDenom::Three { + // 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; + // Save the new normed inflation + *normed_inflation = 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 = ((Uint::from(reward.0) + * Uint::from(ref_inflation)) + / *normed_inflation) + .try_into() + .unwrap_or_else(|_| { + tracing::warn!( + "MASP reward for {} assumed to be 0 because the \ + computed value is too large. Please check the \ + inflation parameters.", + *addr + ); + 0u128 + }); + // The conversion is computed such that if consecutive + // conversions are added together, the + // intermediate tokens cancel/ telescope out + current_convs.insert( + (addr.clone(), denom), + (MaspAmount::from_pair(old_asset, -(reward.1 as i128)) .unwrap() - + MaspAmount::from_pair(reward_asset, reward.0 as i32) + + MaspAmount::from_pair(new_asset, reward.1 as i128) + .unwrap() + + MaspAmount::from_pair( + reward_assets[denom as usize], + real_reward as i128, + ) .unwrap()) - .into(), - ); + .into(), + ); + // Operations that happen exactly once for each token + if denom == MaspDenom::Three { + // 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)) + .0; + } + } // Add a conversion from the previous asset type wl_storage.storage.conversion_state.assets.insert( old_asset, @@ -145,7 +413,7 @@ where // Update the MASP's transparent reward token balance to ensure that it // is sufficiently backed to redeem rewards - let reward_key = token::balance_key(&address::nam(), &masp_addr); + let reward_key = token::balance_key(&native_token, &masp_addr); let addr_bal: token::Amount = wl_storage.read(&reward_key)?.unwrap_or_default(); let new_bal = addr_bal + total_reward; @@ -163,11 +431,6 @@ where .map(FrozenCommitmentTree::new) .collect(); - // Keep the merkle root from the old tree for transactions constructed - // close to the epoch boundary - wl_storage.storage.conversion_state.prev_root = - wl_storage.storage.conversion_state.tree.root(); - // Convert conversion vector into tree so that Merkle paths can be // obtained wl_storage.storage.conversion_state.tree = @@ -175,7 +438,7 @@ where // Add purely decoding entries to the assets map. These will be // overwritten before the creation of the next commitment tree - for addr in masp_rewards.keys() { + for addr in masp_reward_keys { for denom in token::MaspDenom::iter() { // Add the decoding entry for the new asset type. An uncommited // node position is used since this is not a conversion. diff --git a/core/src/ledger/storage/mod.rs b/core/src/ledger/storage/mod.rs index 81be7e48a6..868e49fbdd 100644 --- a/core/src/ledger/storage/mod.rs +++ b/core/src/ledger/storage/mod.rs @@ -26,7 +26,9 @@ pub use wl_storage::{ #[cfg(feature = "wasm-runtime")] pub use self::masp_conversions::update_allowed_conversions; -pub use self::masp_conversions::{encode_asset_type, ConversionState}; +pub use self::masp_conversions::{ + calculate_masp_rewards, encode_asset_type, ConversionState, +}; use super::replay_protection::is_replay_protection_key; use crate::ledger::eth_bridge::storage::bridge_pool::is_pending_transfer_key; use crate::ledger::gas::{ diff --git a/core/src/types/address.rs b/core/src/types/address.rs index 416b3f059e..b0b709d69f 100644 --- a/core/src/types/address.rs +++ b/core/src/types/address.rs @@ -681,23 +681,6 @@ pub fn tokens() -> HashMap { .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 { - 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::*; diff --git a/core/src/types/token.rs b/core/src/types/token.rs index 0ee60b4326..ffc21f817d 100644 --- a/core/src/types/token.rs +++ b/core/src/types/token.rs @@ -13,8 +13,9 @@ use thiserror::Error; use super::dec::POS_DECIMAL_PRECISION; use crate::ibc::applications::transfer::Amount as IbcAmount; +use crate::ledger::storage as ledger_storage; use crate::ledger::storage_api::token::read_denom; -use crate::ledger::storage_api::{self, StorageRead}; +use crate::ledger::storage_api::{self, StorageRead, StorageWrite}; use crate::types::address::{ masp, Address, DecodeError as AddressError, InternalAddress, }; @@ -595,6 +596,20 @@ impl Mul 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 { @@ -814,6 +829,31 @@ pub const TX_KEY_PREFIX: &str = "tx-"; pub const CONVERSION_KEY_PREFIX: &str = "conv"; /// Key segment prefix for pinned shielded transactions pub const PIN_KEY_PREFIX: &str = "pin-"; +/// Last calculated inflation value handed out +pub const MASP_LAST_INFLATION_KEY: &str = "last_inflation"; +/// The last locked ratio +pub const MASP_LAST_LOCKED_RATIO_KEY: &str = "last_locked_ratio"; +/// The key for the nominal proportional gain of a shielded pool for a given +/// asset +pub const MASP_KP_GAIN_KEY: &str = "proportional_gain"; +/// The key for the nominal derivative gain of a shielded pool for a given asset +pub const MASP_KD_GAIN_KEY: &str = "derivative_gain"; +/// The key for the locked ratio target for a given asset +pub const MASP_LOCKED_RATIO_TARGET_KEY: &str = "locked_ratio_target"; +/// The key for the max reward rate for a given asset +pub const MASP_MAX_REWARD_RATE_KEY: &str = "max_reward_rate"; + +/// Gets the key for the given token address, error with the given +/// message to expect if the key is not in the address +pub fn key_of_token( + token_addr: &Address, + specific_key: &str, + expect_message: &str, +) -> Key { + Key::from(token_addr.to_db_key()) + .push(&specific_key.to_owned()) + .expect(expect_message) +} /// Obtain a storage key for user's balance. pub fn balance_key(token_addr: &Address, owner: &Address) -> Key { @@ -847,6 +887,98 @@ pub fn minted_balance_key(token_addr: &Address) -> Key { .expect("Cannot obtain a storage key") } +/// Obtain the nominal proportional key for the given token +pub fn masp_kp_gain_key(token_addr: &Address) -> Key { + key_of_token(token_addr, MASP_KP_GAIN_KEY, "nominal proproitonal gains") +} + +/// Obtain the nominal derivative key for the given token +pub fn masp_kd_gain_key(token_addr: &Address) -> Key { + key_of_token(token_addr, MASP_KD_GAIN_KEY, "nominal proproitonal gains") +} + +/// The max reward rate key for the given token +pub fn masp_max_reward_rate_key(token_addr: &Address) -> Key { + key_of_token(token_addr, MASP_MAX_REWARD_RATE_KEY, "max reward rate") +} + +/// Obtain the locked target ratio key for the given token +pub fn masp_locked_ratio_target_key(token_addr: &Address) -> Key { + key_of_token( + token_addr, + MASP_LOCKED_RATIO_TARGET_KEY, + "nominal proproitonal gains", + ) +} + +/// Token parameters for each kind of asset held on chain +#[derive( + Clone, + Debug, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + BorshSerialize, + BorshDeserialize, + BorshSchema, + Deserialize, + Serialize, +)] +pub struct Parameters { + /// Maximum reward rate + pub max_reward_rate: Dec, + /// Shielded Pool nominal derivative gain + pub kd_gain_nom: Dec, + /// Shielded Pool nominal proportional gain for the given token + pub kp_gain_nom: Dec, + /// Locked ratio for the given token + pub locked_ratio_target: Dec, +} + +impl Parameters { + /// Initialize parameters for the token in storage during the genesis block. + pub fn init_storage( + &self, + address: &Address, + wl_storage: &mut ledger_storage::WlStorage, + ) where + DB: ledger_storage::DB + for<'iter> ledger_storage::DBIter<'iter>, + H: ledger_storage::StorageHasher, + { + let Self { + max_reward_rate: max_rate, + kd_gain_nom, + kp_gain_nom, + locked_ratio_target: locked_target, + } = self; + wl_storage + .write(&masp_max_reward_rate_key(address), max_rate) + .expect("max reward rate for the given asset must be initialized"); + wl_storage + .write(&masp_locked_ratio_target_key(address), locked_target) + .expect("locked ratio must be initialized"); + wl_storage + .write(&masp_kp_gain_key(address), kp_gain_nom) + .expect("The nominal proportional gain must be initialized"); + wl_storage + .write(&masp_kd_gain_key(address), kd_gain_nom) + .expect("The nominal derivative gain must be initialized"); + } +} + +impl Default for Parameters { + fn default() -> Self { + Self { + max_reward_rate: Dec::from_str("0.1").unwrap(), + kp_gain_nom: Dec::from_str("0.1").unwrap(), + kd_gain_nom: Dec::from_str("0.1").unwrap(), + locked_ratio_target: Dec::from_str("0.1").unwrap(), + } + } +} + /// Check if the given storage key is balance key for the given token. If it is, /// returns the owner. For minted balances, use [`is_any_minted_balance_key()`]. pub fn is_balance_key<'a>( @@ -914,6 +1046,24 @@ pub fn is_masp_key(key: &Key) -> bool { || key.starts_with(PIN_KEY_PREFIX))) } +/// Obtain the storage key for the last locked ratio of a token +pub fn masp_last_locked_ratio_key(token_address: &Address) -> Key { + key_of_token( + token_address, + MASP_LAST_LOCKED_RATIO_KEY, + "cannot obtain storage key for the last locked ratio", + ) +} + +/// Obtain the storage key for the last inflation of a token +pub fn masp_last_inflation_key(token_address: &Address) -> Key { + key_of_token( + token_address, + MASP_LAST_INFLATION_KEY, + "cannot obtain storage key for the last inflation rate", + ) +} + /// Check if the given storage key is for a minter of a unspecified token. /// If it is, returns the token. pub fn is_any_minter_key(key: &Key) -> Option<&Address> { @@ -1185,4 +1335,50 @@ pub mod testing { ) -> impl Strategy { (1..=max).prop_map(|val| Amount::from_uint(val, 0).unwrap()) } + + /// init_token_storage is useful when the initialization of the network is + /// not properly made. This properly sets up the storage such that + /// inflation calculations can be ran on the token addresses. We assume + /// a total supply that may not be real + pub fn init_token_storage( + wl_storage: &mut ledger_storage::WlStorage, + epochs_per_year: u64, + ) where + D: 'static + + ledger_storage::DB + + for<'iter> ledger_storage::DBIter<'iter>, + H: 'static + ledger_storage::StorageHasher, + { + use crate::ledger::parameters::storage::get_epochs_per_year_key; + use crate::types::address::tokens; + + let tokens = tokens(); + let masp_reward_keys: Vec<_> = tokens.keys().collect(); + + wl_storage + .write(&get_epochs_per_year_key(), epochs_per_year) + .unwrap(); + let params = Parameters { + max_reward_rate: Dec::from_str("0.1").unwrap(), + kd_gain_nom: Dec::from_str("0.1").unwrap(), + kp_gain_nom: Dec::from_str("0.1").unwrap(), + locked_ratio_target: Dec::zero(), + }; + + for address in masp_reward_keys { + params.init_storage(address, wl_storage); + wl_storage + .write( + &minted_balance_key(address), + Amount::native_whole(5), // arbitrary amount + ) + .unwrap(); + wl_storage + .write(&masp_last_inflation_key(address), Amount::zero()) + .expect("inflation ought to be written"); + wl_storage + .write(&masp_last_locked_ratio_key(address), Dec::zero()) + .expect("last locked set default"); + } + } } diff --git a/core/src/types/uint.rs b/core/src/types/uint.rs index ee14e67ad1..fbf1045ca9 100644 --- a/core/src/types/uint.rs +++ b/core/src/types/uint.rs @@ -21,10 +21,276 @@ pub const ZERO: Uint = Uint::from_u64(0); pub const ONE: Uint = Uint::from_u64(1); impl Uint { + const N_WORDS: usize = 4; + /// Convert a [`u64`] to a [`Uint`]. pub const fn from_u64(x: u64) -> Uint { Uint([x.to_le(), 0, 0, 0]) } + + /// Return the least number of bits needed to represent the number + #[inline] + pub fn bits_512(arr: &[u64; 2 * Self::N_WORDS]) -> usize { + for i in 1..arr.len() { + if arr[arr.len() - i] > 0 { + return (0x40 * (arr.len() - i + 1)) + - arr[arr.len() - i].leading_zeros() as usize; + } + } + 0x40 - arr[0].leading_zeros() as usize + } + + fn div_mod_small_512( + mut slf: [u64; 2 * Self::N_WORDS], + other: u64, + ) -> ([u64; 2 * Self::N_WORDS], Self) { + let mut rem = 0u64; + slf.iter_mut().rev().for_each(|d| { + let (q, r) = Self::div_mod_word(rem, *d, other); + *d = q; + rem = r; + }); + (slf, rem.into()) + } + + fn shr_512( + original: [u64; 2 * Self::N_WORDS], + shift: u32, + ) -> [u64; 2 * Self::N_WORDS] { + let shift = shift as usize; + let mut ret = [0u64; 2 * Self::N_WORDS]; + let word_shift = shift / 64; + let bit_shift = shift % 64; + + // shift + for i in word_shift..original.len() { + ret[i - word_shift] = original[i] >> bit_shift; + } + + // Carry + if bit_shift > 0 { + for i in word_shift + 1..original.len() { + ret[i - word_shift - 1] += original[i] << (64 - bit_shift); + } + } + + ret + } + + fn full_shl_512( + slf: [u64; 2 * Self::N_WORDS], + shift: u32, + ) -> [u64; 2 * Self::N_WORDS + 1] { + debug_assert!(shift < Self::WORD_BITS as u32); + let mut u = [0u64; 2 * Self::N_WORDS + 1]; + let u_lo = slf[0] << shift; + let u_hi = Self::shr_512(slf, Self::WORD_BITS as u32 - shift); + u[0] = u_lo; + u[1..].copy_from_slice(&u_hi[..]); + u + } + + fn full_shr_512( + u: [u64; 2 * Self::N_WORDS + 1], + shift: u32, + ) -> [u64; 2 * Self::N_WORDS] { + debug_assert!(shift < Self::WORD_BITS as u32); + let mut res = [0; 2 * Self::N_WORDS]; + for i in 0..res.len() { + res[i] = u[i] >> shift; + } + // carry + if shift > 0 { + for i in 1..=res.len() { + res[i - 1] |= u[i] << (Self::WORD_BITS as u32 - shift); + } + } + res + } + + // See Knuth, TAOCP, Volume 2, section 4.3.1, Algorithm D. + fn div_mod_knuth_512( + slf: [u64; 2 * Self::N_WORDS], + mut v: Self, + n: usize, + m: usize, + ) -> ([u64; 2 * Self::N_WORDS], Self) { + debug_assert!(Self::bits_512(&slf) >= v.bits() && !v.fits_word()); + debug_assert!(n + m <= slf.len()); + // D1. + // Make sure 64th bit in v's highest word is set. + // If we shift both self and v, it won't affect the quotient + // and the remainder will only need to be shifted back. + let shift = v.0[n - 1].leading_zeros(); + v <<= shift; + // u will store the remainder (shifted) + let mut u = Self::full_shl_512(slf, shift); + + // quotient + let mut q = [0; 2 * Self::N_WORDS]; + let v_n_1 = v.0[n - 1]; + let v_n_2 = v.0[n - 2]; + + // D2. D7. + // iterate from m downto 0 + for j in (0..=m).rev() { + let u_jn = u[j + n]; + + // D3. + // q_hat is our guess for the j-th quotient digit + // q_hat = min(b - 1, (u_{j+n} * b + u_{j+n-1}) / v_{n-1}) + // b = 1 << WORD_BITS + // Theorem B: q_hat >= q_j >= q_hat - 2 + let mut q_hat = if u_jn < v_n_1 { + let (mut q_hat, mut r_hat) = + Self::div_mod_word(u_jn, u[j + n - 1], v_n_1); + // this loop takes at most 2 iterations + loop { + // check if q_hat * v_{n-2} > b * r_hat + u_{j+n-2} + let (hi, lo) = + Self::split_u128(u128::from(q_hat) * u128::from(v_n_2)); + if (hi, lo) <= (r_hat, u[j + n - 2]) { + break; + } + // then iterate till it doesn't hold + q_hat -= 1; + let (new_r_hat, overflow) = r_hat.overflowing_add(v_n_1); + r_hat = new_r_hat; + // if r_hat overflowed, we're done + if overflow { + break; + } + } + q_hat + } else { + // here q_hat >= q_j >= q_hat - 1 + u64::max_value() + }; + + // ex. 20: + // since q_hat * v_{n-2} <= b * r_hat + u_{j+n-2}, + // either q_hat == q_j, or q_hat == q_j + 1 + + // D4. + // let's assume optimistically q_hat == q_j + // subtract (q_hat * v) from u[j..] + let q_hat_v = v.full_mul_u64(q_hat); + // u[j..] -= q_hat_v; + let c = Self::sub_slice(&mut u[j..], &q_hat_v[..n + 1]); + + // D6. + // actually, q_hat == q_j + 1 and u[j..] has overflowed + // highly unlikely ~ (1 / 2^63) + if c { + q_hat -= 1; + // add v to u[j..] + let c = Self::add_slice(&mut u[j..], &v.0[..n]); + u[j + n] = u[j + n].wrapping_add(u64::from(c)); + } + + // D5. + q[j] = q_hat; + } + + // D8. + let remainder = Self::full_shr_512(u, shift); + // The remainder should never exceed the capacity of Self + debug_assert!( + Self::bits_512(&remainder) <= Self::N_WORDS * Self::WORD_BITS + ); + (q, Self(remainder[..Self::N_WORDS].try_into().unwrap())) + } + + /// Returns a pair `(self / other, self % other)`. + /// + /// # Panics + /// + /// Panics if `other` is zero. + pub fn div_mod_512( + slf: [u64; 2 * Self::N_WORDS], + other: Self, + ) -> ([u64; 2 * Self::N_WORDS], Self) { + let my_bits = Self::bits_512(&slf); + let your_bits = other.bits(); + + assert!(your_bits != 0, "division by zero"); + + // Early return in case we are dividing by a larger number than us + if my_bits < your_bits { + return ( + [0; 2 * Self::N_WORDS], + Self(slf[..Self::N_WORDS].try_into().unwrap()), + ); + } + + if your_bits <= Self::WORD_BITS { + return Self::div_mod_small_512(slf, other.low_u64()); + } + + let (n, m) = { + let my_words = Self::words(my_bits); + let your_words = Self::words(your_bits); + (your_words, my_words - your_words) + }; + + Self::div_mod_knuth_512(slf, other, n, m) + } + + /// Returns a pair `(Some((self * num) / denom), (self * num) % denom)` if + /// the quotient fits into Self. Otherwise `(None, (self * num) % denom)` is + /// returned. + /// + /// # Panics + /// + /// Panics if `denom` is zero. + pub fn checked_mul_div( + &self, + num: Self, + denom: Self, + ) -> Option<(Self, Self)> { + if denom.is_zero() { + None + } else { + let prod = uint::uint_full_mul_reg!(Uint, 4, self, num); + let (quotient, remainder) = Self::div_mod_512(prod, denom); + // The compiler WILL NOT inline this if you remove this annotation. + #[inline(always)] + fn any_nonzero(arr: &[u64]) -> bool { + use uint::unroll; + unroll! { + for i in 0..4 { + if arr[i] != 0 { + return true; + } + } + } + + false + } + if any_nonzero("ient[Self::N_WORDS..]) { + None + } else { + Some(( + Self(quotient[0..Self::N_WORDS].try_into().unwrap()), + remainder, + )) + } + } + } + + /// Returns a pair `((self * num) / denom, (self * num) % denom)`. + /// + /// # Panics + /// + /// Panics if `denom` is zero. + pub fn mul_div(&self, num: Self, denom: Self) -> (Self, Self) { + let prod = uint::uint_full_mul_reg!(Uint, 4, self, num); + let (quotient, remainder) = Self::div_mod_512(prod, denom); + ( + Self(quotient[0..Self::N_WORDS].try_into().unwrap()), + remainder, + ) + } } construct_uint! { @@ -171,10 +437,10 @@ impl Uint { /// * `self` * 10^(`denom`) overflows 256 bits /// * `other` is zero (`checked_div` will return `None`). pub fn fixed_precision_div(&self, rhs: &Self, denom: u8) -> Option { - let lhs = Uint::from(10) + Uint::from(10) .checked_pow(Uint::from(denom)) - .and_then(|res| res.checked_mul(*self))?; - lhs.checked_div(*rhs) + .and_then(|res| res.checked_mul_div(*self, *rhs)) + .map(|x| x.0) } /// Compute the two's complement of a number. @@ -554,6 +820,8 @@ impl TryFrom for i128 { #[cfg(test)] mod test_uint { + use std::str::FromStr; + use super::*; /// Test that dividing two [`Uint`]s with the specified precision @@ -581,8 +849,14 @@ mod test_uint { two.fixed_precision_div(&three, 3).expect("Satan lives"), Uint::from(666) ); - assert!(two.fixed_precision_div(&three, 77).is_none()); - assert!(Uint::from(20).fixed_precision_div(&three, 76).is_none()); + assert_eq!( + two.fixed_precision_div(&three, 77).expect("Test failed"), + Uint::from_str("9363ff047551e60c314a09cf62a269d471bafcf44a8c6aaaaaaaaaaaaaaaaaaa").unwrap() + ); + assert_eq!( + Uint::from(20).fixed_precision_div(&three, 76).expect("Test failed"), + Uint::from_str("9363ff047551e60c314a09cf62a269d471bafcf44a8c6aaaaaaaaaaaaaaaaaaa").unwrap() + ); } /// Test that adding one to the max signed @@ -710,4 +984,39 @@ mod test_uint { let amount: Result = serde_json::from_str(r#""1000000000.2""#); assert!(amount.is_err()); } + + #[test] + fn test_mul_div() { + use std::str::FromStr; + let a: Uint = Uint::from_str( + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + ).unwrap(); + let b: Uint = Uint::from_str( + "0x8000000000000000000000000000000000000000000000000000000000000000", + ).unwrap(); + let c: Uint = Uint::from_str( + "0x4000000000000000000000000000000000000000000000000000000000000000", + ).unwrap(); + let d: Uint = Uint::from_str( + "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + ).unwrap(); + let e: Uint = Uint::from_str( + "0x0000000000000000000000000000000000000000000000000000000000000001", + ).unwrap(); + let f: Uint = Uint::from_str( + "0x0000000000000000000000000000000000000000000000000000000000000000", + ).unwrap(); + assert_eq!(a.mul_div(a, a), (a, Uint::zero())); + assert_eq!(b.mul_div(c, b), (c, Uint::zero())); + assert_eq!(a.mul_div(c, b), (d, c)); + assert_eq!(a.mul_div(e, e), (a, Uint::zero())); + assert_eq!(e.mul_div(c, b), (Uint::zero(), c)); + assert_eq!(f.mul_div(a, e), (Uint::zero(), Uint::zero())); + assert_eq!(a.checked_mul_div(a, a), Some((a, Uint::zero()))); + assert_eq!(b.checked_mul_div(c, b), Some((c, Uint::zero()))); + assert_eq!(a.checked_mul_div(c, b), Some((d, c))); + assert_eq!(a.checked_mul_div(e, e), Some((a, Uint::zero()))); + assert_eq!(e.checked_mul_div(c, b), Some((Uint::zero(), c))); + assert_eq!(d.checked_mul_div(a, e), None); + } } diff --git a/genesis/e2e-tests-single-node.toml b/genesis/e2e-tests-single-node.toml index 4a3c02b805..1096be0d28 100644 --- a/genesis/e2e-tests-single-node.toml +++ b/genesis/e2e-tests-single-node.toml @@ -36,6 +36,11 @@ Christel = "1000000" Daewon = "1000000" Ester = "1000000" "validator-0.public_key" = "100" +[token.NAM.parameters] +max_reward_rate = "0.1" +kd_gain_nom = "0.1" +kp_gain_nom = "0.1" +locked_ratio_target = "0.6667" [token.BTC] address = "atest1v4ehgw36xdzryve5gsc52veeg5cnsv2yx5eygvp38qcrvd29xy6rys6p8yc5xvp4xfpy2v694wgwcp" @@ -46,6 +51,11 @@ Bertha = "1000000" Christel = "1000000" Daewon = "1000000" Ester = "1000000" +[token.BTC.parameters] +max_reward_rate = "0.1" +kd_gain_nom = "0.1" +kp_gain_nom = "0.1" +locked_ratio_target = "0.6667" [token.ETH] address = "atest1v4ehgw36xqmr2d3nx3ryvd2xxgmrq33j8qcns33sxezrgv6zxdzrydjrxveygd2yxumrsdpsf9jc2p" @@ -56,6 +66,11 @@ Bertha = "1000000" Christel = "1000000" Daewon = "1000000" Ester = "1000000" +[token.ETH.parameters] +max_reward_rate = "0.1" +kd_gain_nom = "0.1" +kp_gain_nom = "0.1" +locked_ratio_target = "0.6667" [token.DOT] address = "atest1v4ehgw36gg6nvs2zgfpyxsfjgc65yv6pxy6nwwfsxgungdzrggeyzv35gveyxsjyxymyz335hur2jn" @@ -66,6 +81,11 @@ Bertha = "1000000" Christel = "1000000" Daewon = "1000000" Ester = "1000000" +[token.DOT.parameters] +max_reward_rate = "0.1" +kd_gain_nom = "0.1" +kp_gain_nom = "0.1" +locked_ratio_target = "0.6667" [token.Schnitzel] address = "atest1v4ehgw36xue5xvf5xvuyzvpjx5un2v3k8qeyvd3cxdqns32p89rrxd6xx9zngvpegccnzs699rdnnt" @@ -76,6 +96,11 @@ Bertha = "1000000" Christel = "1000000" Daewon = "1000000" Ester = "1000000" +[token.Schnitzel.parameters] +max_reward_rate = "0.1" +kd_gain_nom = "0.1" +kp_gain_nom = "0.1" +locked_ratio_target = "0.6667" [token.Apfel] address = "atest1v4ehgw36gfryydj9g3p5zv3kg9znyd358ycnzsfcggc5gvecgc6ygs2rxv6ry3zpg4zrwdfeumqcz9" @@ -86,6 +111,11 @@ Bertha = "1000000" Christel = "1000000" Daewon = "1000000" Ester = "1000000" +[token.Apfel.parameters] +max_reward_rate = "0.1" +kd_gain_nom = "0.1" +kp_gain_nom = "0.1" +locked_ratio_target = "0.6667" [token.Kartoffel] address = "atest1v4ehgw36gep5ysecxq6nyv3jg3zygv3e89qn2vp48pryxsf4xpznvve5gvmy23fs89pryvf5a6ht90" @@ -97,6 +127,11 @@ Bertha = "1000000" Christel = "1000000" Daewon = "1000000" Ester = "1000000" +[token.Kartoffel.parameters] +max_reward_rate = "0.1" +kd_gain_nom = "0.1" +kp_gain_nom = "0.1" +locked_ratio_target = "0.6667" [established.Albert] vp = "vp_user" diff --git a/scripts/generator.sh b/scripts/generator.sh index 3fe1792a49..c9635d498d 100755 --- a/scripts/generator.sh +++ b/scripts/generator.sh @@ -9,8 +9,10 @@ # vectors. NAMADA_DIR="$(pwd)" +NAMADA_BASE_DIR_FILE="$(pwd)/namada_base_dir" export NAMADA_LEDGER_LOG_PATH="$(pwd)/vectors.json" export NAMADA_TX_LOG_PATH="$(pwd)/debugs.txt" +export NAMADA_DEV=false if [ "$#" -ne 1 ]; then echo "Illegal number of parameters" @@ -19,11 +21,14 @@ elif [ "$1" = "server" ]; then sed -i 's/^epochs_per_year = 31_536_000$/epochs_per_year = 262_800/' genesis/test-vectors-single-node.toml - NAMADA_GENESIS_FILE=$(cargo run --bin namadac -- utils init-network --genesis-path genesis/test-vectors-single-node.toml --wasm-checksums-path wasm/checksums.json --chain-prefix e2e-test --unsafe-dont-encrypt --localhost --allow-duplicate-ip | grep 'Genesis file generated at ' | sed 's/^Genesis file generated at //') + NAMADA_GENESIS_FILE=$(cargo run --bin namadac --package namada_apps --manifest-path Cargo.toml -- utils init-network --genesis-path genesis/test-vectors-single-node.toml --wasm-checksums-path wasm/checksums.json --chain-prefix e2e-test --unsafe-dont-encrypt --localhost --dont-archive --allow-duplicate-ip | grep 'Genesis file generated at ' | sed 's/^Genesis file generated at //') rm genesis/test-vectors-single-node.toml NAMADA_BASE_DIR=${NAMADA_GENESIS_FILE%.toml} + echo $NAMADA_BASE_DIR > $NAMADA_BASE_DIR_FILE + + sed -i 's/^mode = "RemoteEndpoint"$/mode = "Off"/' $NAMADA_BASE_DIR/config.toml cp wasm/*.wasm $NAMADA_BASE_DIR/wasm/ @@ -31,8 +36,14 @@ elif [ "$1" = "server" ]; then cp $NAMADA_BASE_DIR/setup/other/wallet.toml $NAMADA_BASE_DIR/wallet.toml - cargo run --bin namadan -- --base-dir $NAMADA_BASE_DIR/setup/validator-0/.namada/ ledger + sed -i 's/^mode = "RemoteEndpoint"$/mode = "Off"/' $NAMADA_BASE_DIR/setup/validator-0/.namada/$(basename $NAMADA_BASE_DIR)/config.toml + + cargo run --bin namadan --package namada_apps --manifest-path Cargo.toml -- --base-dir $NAMADA_BASE_DIR/setup/validator-0/.namada/ ledger elif [ "$1" = "client" ]; then + if test -f "$NAMADA_BASE_DIR_FILE"; then + NAMADA_BASE_DIR="$(cat $NAMADA_BASE_DIR_FILE)" + fi + echo > $NAMADA_TX_LOG_PATH echo $'[' > $NAMADA_LEDGER_LOG_PATH @@ -40,120 +51,49 @@ elif [ "$1" = "client" ]; then ALBERT_ADDRESS=$(cargo run --bin namadaw -- address find --alias albert | sed 's/^Found address Established: //') echo '{ - "author":"'$ALBERT_ADDRESS'", - "content":{ - "abstract":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros. Nullam sed ex justo. Ut at placerat ipsum, sit amet rhoncus libero. Sed blandit non purus non suscipit. Phasellus sed quam nec augue bibendum bibendum ut vitae urna. Sed odio diam, ornare nec sapien eget, congue viverra enim.", - "authors":"test@test.com", - "created":"2022-03-10T08:54:37Z", - "details":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros.", - "discussions-to":"www.github.com/anoma/aip/1", - "license":"MIT", - "motivation":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices.", - "requires":"2", - "title":"TheTitle" - }, - "grace_epoch":30, - "type":{ - "Default":"'$NAMADA_DIR'/wasm_for_tests/tx_proposal_code.wasm" - }, - "voting_end_epoch":24, - "voting_start_epoch":12 -} -' > proposal_submission_valid_proposal.json - + "proposal": { + "author":"'$ALBERT_ADDRESS'", + "content":{ + "abstract":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros. Nullam sed ex justo. Ut at placerat ipsum, sit amet rhoncus libero. Sed blandit non purus non suscipit. Phasellus sed quam nec augue bibendum bibendum ut vitae urna. Sed odio diam, ornare nec sapien eget, congue viverra enim.", + "authors":"test@test.com", + "created":"2022-03-10T08:54:37Z", + "details":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros.", + "discussions-to":"www.github.com/anoma/aip/1", + "license":"MIT", + "motivation":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices.", + "requires":"2", + "title":"TheTitle" + }, + "grace_epoch":30, + "voting_end_epoch":24, + "voting_start_epoch":12 + } + }' > proposal_default.json + echo '{ - "content": { - "abstract": "Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros. Nullam sed ex justo. Ut at placerat ipsum, sit amet rhoncus libero. Sed blandit non purus non suscipit. Phasellus sed quam nec augue bibendum bibendum ut vitae urna. Sed odio diam, ornare nec sapien eget, congue viverra enim.", - "authors": "test@test.com", - "created": "2022-03-10T08:54:37Z", - "details": "Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros.", - "discussions-to": "www.github.com/anoma/aip/1", - "license": "MIT", - "motivation": "Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices.", - "requires": "2", - "title": "TheTitle" - }, - "author": "'$ALBERT_ADDRESS'", - "tally_epoch": 18, - "signature": { - "Ed25519": { - "R_bytes": [ - 113, - 196, - 231, - 134, - 101, - 191, - 75, - 17, - 245, - 19, - 50, - 231, - 183, - 80, - 162, - 38, - 108, - 72, - 72, - 2, - 116, - 112, - 121, - 33, - 197, - 67, - 64, - 116, - 21, - 250, - 196, - 121 - ], - "s_bytes": [ - 87, - 163, - 134, - 87, - 42, - 156, - 121, - 211, - 189, - 19, - 255, - 5, - 23, - 178, - 143, - 39, - 118, - 249, - 37, - 53, - 121, - 136, - 59, - 103, - 190, - 91, - 121, - 95, - 46, - 54, - 168, - 9 - ] + "data":['$(od -An -tu1 -v wasm_for_tests/tx_proposal_code.wasm | tr '\n' ' ' | sed 's/\b\s\+\b/,/g')'], + "proposal": { + "author":"'$ALBERT_ADDRESS'", + "content":{ + "abstract":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros. Nullam sed ex justo. Ut at placerat ipsum, sit amet rhoncus libero. Sed blandit non purus non suscipit. Phasellus sed quam nec augue bibendum bibendum ut vitae urna. Sed odio diam, ornare nec sapien eget, congue viverra enim.", + "authors":"test@test.com", + "created":"2022-03-10T08:54:37Z", + "details":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros.", + "discussions-to":"www.github.com/anoma/aip/1", + "license":"MIT", + "motivation":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices.", + "requires":"2", + "title":"TheTitle" + }, + "grace_epoch":30, + "voting_end_epoch":24, + "voting_start_epoch":12 } - }, - "address": "'$ALBERT_ADDRESS'" -} -' > proposal_offline_proposal + }' > proposal_default_with_data.json echo '{ - "author":"'$ALBERT_ADDRESS'", - "content":{ + "author":"'$ALBERT_ADDRESS'", + "content":{ "abstract":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros. Nullam sed ex justo. Ut at placerat ipsum, sit amet rhoncus libero. Sed blandit non purus non suscipit. Phasellus sed quam nec augue bibendum bibendum ut vitae urna. Sed odio diam, ornare nec sapien eget, congue viverra enim.", "authors":"test@test.com", "created":"2022-03-10T08:54:37Z", @@ -164,59 +104,41 @@ elif [ "$1" = "client" ]; then "requires":"2", "title":"TheTitle" }, - "grace_epoch":18, - "type":{ - "Default":null - }, - "voting_end_epoch":9, - "voting_start_epoch":3 -}' > proposal_offline_valid_proposal.json + "tally_epoch":1 + }' > proposal_offline.json echo '{ - "author":"'$ALBERT_ADDRESS'", - "content":{ - "abstract":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros. Nullam sed ex justo. Ut at placerat ipsum, sit amet rhoncus libero. Sed blandit non purus non suscipit. Phasellus sed quam nec augue bibendum bibendum ut vitae urna. Sed odio diam, ornare nec sapien eget, congue viverra enim.", - "authors":"test@test.com", - "created":"2022-03-10T08:54:37Z", - "details":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros.", - "discussions-to":"www.github.com/anoma/aip/1", - "license":"MIT", - "motivation":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices.", - "requires":"2", - "title":"TheTitle" + "proposal": { + "author":"'$ALBERT_ADDRESS'", + "content":{ + "abstract":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros. Nullam sed ex justo. Ut at placerat ipsum, sit amet rhoncus libero. Sed blandit non purus non suscipit. Phasellus sed quam nec augue bibendum bibendum ut vitae urna. Sed odio diam, ornare nec sapien eget, congue viverra enim.", + "authors":"test@test.com", + "created":"2022-03-10T08:54:37Z", + "details":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros.", + "discussions-to":"www.github.com/anoma/aip/1", + "license":"MIT", + "motivation":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices.", + "requires":"2", + "title":"TheTitle" + }, + "grace_epoch":30, + "voting_end_epoch":24, + "voting_start_epoch":12 }, - "grace_epoch":30, - "type":"ETHBridge", - "voting_end_epoch":24, - "voting_start_epoch":12 -}' > eth_governance_proposal_valid_proposal.json + "data": {"add":"'$ALBERT_ADDRESS'","remove":[]} + }' > proposal_pgf_steward_add.json - echo '{ - "author":"'$ALBERT_ADDRESS'", - "content":{ - "abstract":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros. Nullam sed ex justo. Ut at placerat ipsum, sit amet rhoncus libero. Sed blandit non purus non suscipit. Phasellus sed quam nec augue bibendum bibendum ut vitae urna. Sed odio diam, ornare nec sapien eget, congue viverra enim.", - "authors":"test@test.com", - "created":"2022-03-10T08:54:37Z", - "details":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros.", - "discussions-to":"www.github.com/anoma/aip/1", - "license":"MIT", - "motivation":"Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices.", - "requires":"2", - "title":"TheTitle" - }, - "grace_epoch":30, - "type":"PGFCouncil", - "voting_end_epoch":24, - "voting_start_epoch":12 -}' > pgf_governance_proposal_valid_proposal.json + # proposal_default - # proposal_submission + cargo run --bin namadac --features std -- bond --validator validator-0 --source Bertha --amount 900 --gas-token NAM --node 127.0.0.1:27657 - cargo run --bin namadac --features std -- bond --validator validator-0 --source Bertha --amount 900 --gas-amount 0 --gas-limit 0 --gas-token NAM --node 127.0.0.1:27657 + cargo run --bin namadac --features std -- unjail-validator --validator Bertha --gas-token NAM --force --node 127.0.0.1:27657 - cargo run --bin namadac --features std -- change-commission-rate --validator Bertha --commission-rate 0.02 --gas-amount 0 --gas-limit 0 --gas-token NAM --force --node 127.0.0.1:27657 + cargo run --bin namadac --features std -- change-commission-rate --validator Bertha --commission-rate 0.02 --gas-token NAM --force --node 127.0.0.1:27657 - PROPOSAL_ID_0=$(cargo run --bin namadac --features std -- init-proposal --force --data-path proposal_submission_valid_proposal.json --node 127.0.0.1:27657 | grep -o -P '(?<=/proposal/).*(?=/author)') + PROPOSAL_ID_0=$(cargo run --bin namadac --features std -- init-proposal --force --data-path proposal_default.json --node 127.0.0.1:27657 | grep -o -P '(?<=/proposal/).*(?=/author)') + + cargo run --bin namadac --features std -- init-proposal --force --data-path proposal_default_with_data.json --node 127.0.0.1:27657 cargo run --bin namadac --features std -- --base-dir $NAMADA_BASE_DIR/setup/validator-0/.namada vote-proposal --force --proposal-id $PROPOSAL_ID_0 --vote yay --address validator-0 --node 127.0.0.1:27657 @@ -226,41 +148,29 @@ elif [ "$1" = "client" ]; then # proposal_offline - cargo run --bin namadac --features std -- bond --validator validator-0 --source Albert --amount 900 --gas-amount 0 --gas-limit 0 --gas-token NAM --node 127.0.0.1:27657 - - cargo run --bin namadac --features std -- change-commission-rate --validator Albert --commission-rate 0.05 --gas-amount 0 --gas-limit 0 --gas-token NAM --force --node 127.0.0.1:27657 - - cargo run --bin namadac --features std -- init-proposal --force --data-path proposal_offline_valid_proposal.json --offline --node 127.0.0.1:27657 + cargo run --bin namadac --features std -- bond --validator validator-0 --source Albert --amount 900 --gas-token NAM --node 127.0.0.1:27657 - cargo run --bin namadac --features std -- vote-proposal --data-path proposal_offline_proposal --vote yay --address Albert --offline --node 127.0.0.1:27657 + cargo run --bin namadac --features std -- change-commission-rate --validator Albert --commission-rate 0.05 --gas-token NAM --force --node 127.0.0.1:27657 - # eth_governance_proposal + PROPOSAL_OFFLINE_SIGNED=$(cargo run --bin namadac --features std -- init-proposal --force --data-path proposal_offline.json --signing-keys albert-key --offline --node 127.0.0.1:27657 | grep -o -P '(?<=Proposal serialized to:\s).*') - cargo run --bin namadac --features std -- bond --validator validator-0 --source Bertha --amount 900 --gas-amount 0 --gas-limit 0 --gas-token NAM --ledger-address 127.0.0.1:27657 - - cargo run --bin namadac --features std -- change-commission-rate --validator Bertha --commission-rate 0.07 --gas-amount 0 --gas-limit 0 --gas-token NAM --force --node 127.0.0.1:27657 - - PROPOSAL_ID_0=$(cargo run --bin namadac --features std -- init-proposal --force --data-path eth_governance_proposal_valid_proposal.json --ledger-address 127.0.0.1:27657 | grep -o -P '(?<=/proposal/).*(?=/author)') - - cargo run --bin namadac --features std -- vote-proposal --force --proposal-id 0 --vote yay --eth '011586062748ba53bc53155e817ec1ea708de75878dcb9a5713bf6986d87fe14e7 fd34672ab5' --address Bertha --ledger-address 127.0.0.1:27657 - - cargo run --bin namadac --features std -- --base-dir $NAMADA_BASE_DIR/setup/validator-0/.namada vote-proposal --force --proposal-id $PROPOSAL_ID_0 --vote yay --eth '011586062748ba53bc53155e817ec1ea708de75878dcb9a5713bf6986d87fe14e7 fd34672ab5' --address validator-0 --ledger-address 127.0.0.1:27657 + cargo run --bin namadac --features std -- vote-proposal --data-path $PROPOSAL_OFFLINE_SIGNED --vote yay --address Albert --offline --node 127.0.0.1:27657 # pgf_governance_proposal - cargo run --bin namadac --features std -- bond --validator validator-0 --source Bertha --amount 900 --gas-amount 0 --gas-limit 0 --gas-token NAM --ledger-address 127.0.0.1:27657 + cargo run --bin namadac --features std -- bond --validator validator-0 --source Bertha --amount 900 --gas-token NAM --ledger-address 127.0.0.1:27657 - cargo run --bin namadac --features std -- change-commission-rate --validator Bertha --commission-rate 0.09 --gas-amount 0 --gas-limit 0 --gas-token NAM --force --node 127.0.0.1:27657 + cargo run --bin namadac --features std -- change-commission-rate --validator Bertha --commission-rate 0.09 --gas-token NAM --force --node 127.0.0.1:27657 - PROPOSAL_ID_0=$(cargo run --bin namadac --features std -- init-proposal --force --data-path pgf_governance_proposal_valid_proposal.json --ledger-address 127.0.0.1:27657 | grep -o -P '(?<=/proposal/).*(?=/author)') + PROPOSAL_ID_0=$(cargo run --bin namadac --features std -- init-proposal --pgf-stewards --force --data-path proposal_pgf_steward_add.json --ledger-address 127.0.0.1:27657 | grep -o -P '(?<=/proposal/).*(?=/author)') - PROPOSAL_ID_1=$(cargo run --bin namadac --features std -- init-proposal --force --data-path pgf_governance_proposal_valid_proposal.json --ledger-address 127.0.0.1:27657 | grep -o -P '(?<=/proposal/).*(?=/author)') + PROPOSAL_ID_1=$(cargo run --bin namadac --features std -- init-proposal --pgf-stewards --force --data-path proposal_pgf_steward_add.json --ledger-address 127.0.0.1:27657 | grep -o -P '(?<=/proposal/).*(?=/author)') - cargo run --bin namadac --features std -- --base-dir $NAMADA_BASE_DIR/setup/validator-0/.namada vote-proposal --force --proposal-id $PROPOSAL_ID_0 --vote yay --pgf "$ALBERT_ADDRESS 1000" --address validator-0 --ledger-address 127.0.0.1:27657 + cargo run --bin namadac --features std -- --base-dir $NAMADA_BASE_DIR/setup/validator-0/.namada vote-proposal --force --proposal-id $PROPOSAL_ID_0 --vote yay --address validator-0 --ledger-address 127.0.0.1:27657 - cargo run --bin namadac --features std -- vote-proposal --force --proposal-id $PROPOSAL_ID_0 --vote yay --pgf "$ALBERT_ADDRESS 900" --address Bertha --ledger-address 127.0.0.1:27657 + cargo run --bin namadac --features std -- vote-proposal --force --proposal-id $PROPOSAL_ID_0 --vote yay --address Bertha --signing-keys bertha-key --ledger-address 127.0.0.1:27657 - cargo run --bin namadac --features std -- vote-proposal --force --proposal-id $PROPOSAL_ID_1 --vote yay --pgf "$ALBERT_ADDRESS 900" --address Bertha --ledger-address 127.0.0.1:27657 + cargo run --bin namadac --features std -- vote-proposal --force --proposal-id $PROPOSAL_ID_1 --vote yay --address Bertha --signing-keys bertha-key --ledger-address 127.0.0.1:27657 # non-proposal tests @@ -268,24 +178,38 @@ elif [ "$1" = "client" ]; then cargo run --bin namadac --features std -- bond --validator bertha --amount 25 --signing-keys bertha-key --force --ledger-address 127.0.0.1:27657 - cargo run --bin namadac --features std -- change-commission-rate --validator Bertha --commission-rate 0.11 --gas-amount 0 --gas-limit 0 --gas-token NAM --force --node 127.0.0.1:27657 + cargo run --bin namadac --features std -- change-commission-rate --validator Bertha --commission-rate 0.11 --gas-token NAM --force --node 127.0.0.1:27657 cargo run --bin namadac --features std -- reveal-pk --public-key albert-key --gas-payer albert-key --force --ledger-address 127.0.0.1:27657 cargo run --bin namadac --features std -- update-account --code-path vp_user.wasm --address bertha --signing-keys bertha-key --force --ledger-address 127.0.0.1:27657 - cargo run --bin namadac --features std -- init-validator --alias bertha-validator --account-keys bertha --commission-rate 0.05 --max-commission-rate-change 0.01 --signing-keys bertha-key --unsafe-dont-encrypt --force --ledger-address 127.0.0.1:27657 + cargo run --bin namadac --features std -- update-account --code-path vp_user.wasm --address bertha --public-keys albert-key,bertha-key --force --ledger-address 127.0.0.1:27657 + + cargo run --bin namadac --features std -- update-account --code-path vp_user.wasm --address bertha --public-keys albert-key,bertha-key,christel-key --threshold 2 --force --ledger-address 127.0.0.1:27657 + + cargo run --bin namadac --features std -- init-validator --alias bertha-validator --account-keys bertha-key --commission-rate 0.05 --max-commission-rate-change 0.01 --signing-keys bertha-key --unsafe-dont-encrypt --force --ledger-address 127.0.0.1:27657 + + cargo run --bin namadac --features std -- init-validator --alias validator-mult --account-keys albert-key,bertha-key --commission-rate 0.05 --max-commission-rate-change 0.01 --signing-keys albert-key,bertha-key --threshold 2 --unsafe-dont-encrypt --force --ledger-address 127.0.0.1:27657 + # TODO works but panics cargo run --bin namadac --features std -- unbond --validator christel --amount 5 --signing-keys christel-key --force --ledger-address 127.0.0.1:27657 cargo run --bin namadac --features std -- withdraw --validator albert --signing-keys albert-key --force --ledger-address 127.0.0.1:27657 cargo run --bin namadac --features std -- init-account --alias albert-account --public-keys albert-key --signing-keys albert-key --force --ledger-address 127.0.0.1:27657 - cargo run --bin namadac --features std -- tx --code-path $NAMADA_DIR/wasm_for_tests/tx_no_op.wasm --data-path README.md --signing-keys albert-key --owner albert --force --ledger-address 127.0.0.1:27657 + cargo run --bin namadac --features std -- init-account --alias account-mul --public-keys albert-key,bertha-key,christel-key --signing-keys albert-key,bertha-key,christel-key --threshold 2 --force --ledger-address 127.0.0.1:27657 + + # TODO panics, no vector produced + # cargo run --bin namadac --features std -- tx --code-path $NAMADA_DIR/wasm_for_tests/tx_no_op.wasm --data-path README.md --signing-keys albert-key --owner albert --force --ledger-address 127.0.0.1:27657 cargo run --bin namadac --features std -- ibc-transfer --source bertha --receiver christel --token btc --amount 24 --channel-id channel-141 --signing-keys bertha-key --force --ledger-address 127.0.0.1:27657 + cargo run --bin namadac --features std -- ibc-transfer --source albert --receiver bertha --token nam --amount 100000 --channel-id channel-0 --port-id transfer --signing-keys albert-key --force --ledger-address 127.0.0.1:27657 + + cargo run --bin namadac --features std -- ibc-transfer --source albert --receiver bertha --token nam --amount 100000 --channel-id channel-0 --port-id transfer --signing-keys albert-key --timeout-sec-offset 5 --force --ledger-address 127.0.0.1:27657 + cargo run --bin namadaw -- masp add --alias a_spending_key --value xsktest1qqqqqqqqqqqqqq9v0sls5r5de7njx8ehu49pqgmqr9ygelg87l5x8y4s9r0pjlvu69au6gn3su5ewneas486hdccyayx32hxvt64p3d0hfuprpgcgv2q9gdx3jvxrn02f0nnp3jtdd6f5vwscfuyum083cvfv4jun75ak5sdgrm2pthzj3sflxc0jx0edrakx3vdcngrfjmru8ywkguru8mxss2uuqxdlglaz6undx5h8w7g70t2es850g48xzdkqay5qs0yw06rtxcvedhsv --unsafe-dont-encrypt cargo run --bin namadaw -- masp add --alias b_spending_key --value xsktest1qqqqqqqqqqqqqqpagte43rsza46v55dlz8cffahv0fnr6eqacvnrkyuf9lmndgal7c2k4r7f7zu2yr5rjwr374unjjeuzrh6mquzy6grfdcnnu5clzaq2llqhr70a8yyx0p62aajqvrqjxrht3myuyypsvm725uyt5vm0fqzrzuuedtf6fala4r4nnazm9y9hq5yu6pq24arjskmpv4mdgfn3spffxxv8ugvym36kmnj45jcvvmm227vqjm5fq8882yhjsq97p7xrwqqd82s0 --unsafe-dont-encrypt @@ -296,27 +220,31 @@ elif [ "$1" = "client" ]; then cargo run --bin namadaw -- masp add --alias bb_payment_address --value patest1vqe0vyxh6wmhahwa52gthgd6edgqxfmgyv8e94jtwn55mdvpvylcyqnp59595272qrz3zxn0ysg + # TODO vector produced only when epoch boundaries not straddled cargo run --bin namadac --features std -- transfer --source albert --target aa_payment_address --token btc --amount 20 --force --ledger-address 127.0.0.1:27657 - cargo run --bin namadac --features std -- transfer --source a_spending_key --target ab_payment_address --token btc --amount 7 --force --ledger-address 127.0.0.1:27657 + # TODO vector produced only when epoch boundaries not straddled + cargo run --bin namadac --features std -- transfer --gas-payer albert-key --source a_spending_key --target ab_payment_address --token btc --amount 7 --force --ledger-address 127.0.0.1:27657 - until cargo run --bin namadac -- epoch --ledger-address 127.0.0.1:27657 | grep -m1 "Last committed epoch: 2" ; do sleep 10 ; done; + # TODO fragile + until cargo run --bin namadac -- epoch --ledger-address 127.0.0.1:27657 | grep -m1 "Last committed epoch: 2" ; do sleep 10 ; done; - cargo run --bin namadac --features std -- transfer --source a_spending_key --target bb_payment_address --token btc --amount 7 --force --ledger-address 127.0.0.1:27657 + # TODO vector produced only when epoch boundaries not straddled + cargo run --bin namadac --features std -- transfer --gas-payer albert-key --source a_spending_key --target bb_payment_address --token btc --amount 7 --force --ledger-address 127.0.0.1:27657 - cargo run --bin namadac --features std -- transfer --source a_spending_key --target bb_payment_address --token btc --amount 6 --force --ledger-address 127.0.0.1:27657 + # TODO vector produced only when epoch boundaries not straddled + cargo run --bin namadac --features std -- transfer --gas-payer albert-key --source a_spending_key --target bb_payment_address --token btc --amount 6 --force --ledger-address 127.0.0.1:27657 - cargo run --bin namadac --features std -- transfer --source b_spending_key --target bb_payment_address --token btc --amount 6 --force --ledger-address 127.0.0.1:27657 + # TODO vector produced only when epoch boundaries not straddled + cargo run --bin namadac --features std -- transfer --gas-payer albert-key --source b_spending_key --target bb_payment_address --token btc --amount 6 --force --ledger-address 127.0.0.1:27657 - rm proposal_submission_valid_proposal.json - - rm proposal_offline_proposal - - rm proposal_offline_valid_proposal.json + rm -f proposal_default.json + + rm -f proposal_default_with_data.json - rm eth_governance_proposal_valid_proposal.json + rm -f proposal_offline.json - rm pgf_governance_proposal_valid_proposal.json + rm -f proposal_pgf_steward_add.json perl -0777 -i.original -pe 's/,\s*$//igs' $NAMADA_LEDGER_LOG_PATH diff --git a/shared/src/ledger/mod.rs b/shared/src/ledger/mod.rs index 04b5809bc2..a1a6e93c40 100644 --- a/shared/src/ledger/mod.rs +++ b/shared/src/ledger/mod.rs @@ -4,7 +4,6 @@ pub mod eth_bridge; pub mod events; pub mod governance; pub mod ibc; -pub mod inflation; pub mod native_vp; pub mod pgf; pub mod pos; diff --git a/shared/src/ledger/queries/shell.rs b/shared/src/ledger/queries/shell.rs index a766846916..520c702608 100644 --- a/shared/src/ledger/queries/shell.rs +++ b/shared/src/ledger/queries/shell.rs @@ -30,7 +30,7 @@ type Conversion = ( Address, MaspDenom, Epoch, - masp_primitives::transaction::components::I32Sum, + masp_primitives::transaction::components::I128Sum, MerklePath, ); @@ -254,7 +254,7 @@ where addr.clone(), *denom, *epoch, - Into::::into( + Into::::into( conv.clone(), ), ctx.wl_storage.storage.conversion_state.tree.path(*pos), diff --git a/shared/src/sdk/masp.rs b/shared/src/sdk/masp.rs index 739f941b9a..f9459f6cab 100644 --- a/shared/src/sdk/masp.rs +++ b/shared/src/sdk/masp.rs @@ -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}; @@ -989,7 +989,7 @@ impl ShieldedContext { Address, MaspDenom, _, - I32Sum, + I128Sum, MerklePath, ) = rpc::query_conversion(client, asset_type).await?; self.asset_types diff --git a/shared/src/sdk/rpc.rs b/shared/src/sdk/rpc.rs index 58609bed42..cb881e88a2 100644 --- a/shared/src/sdk/rpc.rs +++ b/shared/src/sdk/rpc.rs @@ -228,7 +228,7 @@ pub async fn query_conversion( Address, MaspDenom, Epoch, - masp_primitives::transaction::components::I32Sum, + masp_primitives::transaction::components::I128Sum, MerklePath, )> { Some(unwrap_client_response::( diff --git a/shared/src/sdk/tx.rs b/shared/src/sdk/tx.rs index 9d7fe0cfe4..0381e6f6aa 100644 --- a/shared/src/sdk/tx.rs +++ b/shared/src/sdk/tx.rs @@ -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, @@ -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; diff --git a/test_fixtures/masp_proofs/0B436B9FB574776E45EDA537DCF334701D250179C310C7076DAEE5367CB3D74A.bin b/test_fixtures/masp_proofs/0B436B9FB574776E45EDA537DCF334701D250179C310C7076DAEE5367CB3D74A.bin deleted file mode 100644 index 283608af3c..0000000000 Binary files a/test_fixtures/masp_proofs/0B436B9FB574776E45EDA537DCF334701D250179C310C7076DAEE5367CB3D74A.bin and /dev/null differ diff --git a/test_fixtures/masp_proofs/1362F1CF9B836CF8B05D8189EA9CB1712CCA85B0E96A3330A63BE7CD9E5ECD22.bin b/test_fixtures/masp_proofs/1362F1CF9B836CF8B05D8189EA9CB1712CCA85B0E96A3330A63BE7CD9E5ECD22.bin index 13110a81e5..741f4d5106 100644 Binary files a/test_fixtures/masp_proofs/1362F1CF9B836CF8B05D8189EA9CB1712CCA85B0E96A3330A63BE7CD9E5ECD22.bin and b/test_fixtures/masp_proofs/1362F1CF9B836CF8B05D8189EA9CB1712CCA85B0E96A3330A63BE7CD9E5ECD22.bin differ diff --git a/test_fixtures/masp_proofs/574D00A0B71BE528A2923F6B68934EAA4FA91FFF4AFDF3B08047E7DC6BFCED36.bin b/test_fixtures/masp_proofs/29AC8DE3B07495BEABEAF50FE8FF8BF07596031CD460FEBFAEA4F75AF65D5402.bin similarity index 58% rename from test_fixtures/masp_proofs/574D00A0B71BE528A2923F6B68934EAA4FA91FFF4AFDF3B08047E7DC6BFCED36.bin rename to test_fixtures/masp_proofs/29AC8DE3B07495BEABEAF50FE8FF8BF07596031CD460FEBFAEA4F75AF65D5402.bin index 83e5789827..b748454de8 100644 Binary files a/test_fixtures/masp_proofs/574D00A0B71BE528A2923F6B68934EAA4FA91FFF4AFDF3B08047E7DC6BFCED36.bin and b/test_fixtures/masp_proofs/29AC8DE3B07495BEABEAF50FE8FF8BF07596031CD460FEBFAEA4F75AF65D5402.bin differ diff --git a/test_fixtures/masp_proofs/37332141CB34FC30FF51F4BEE8D76149D3088F539CF8372D404609B89B095EF7.bin b/test_fixtures/masp_proofs/37332141CB34FC30FF51F4BEE8D76149D3088F539CF8372D404609B89B095EF7.bin index 0e74c8f67b..18f83d0543 100644 Binary files a/test_fixtures/masp_proofs/37332141CB34FC30FF51F4BEE8D76149D3088F539CF8372D404609B89B095EF7.bin and b/test_fixtures/masp_proofs/37332141CB34FC30FF51F4BEE8D76149D3088F539CF8372D404609B89B095EF7.bin differ diff --git a/test_fixtures/masp_proofs/DDD66A8E673E8E8A1401967F6FCDD5724C594E275B353F45FF749CB76D3CFF52.bin b/test_fixtures/masp_proofs/52984E26D4A044A259B441C1DAEB66F886B3A3B6C71D33F456B859D01DA47ADD.bin similarity index 52% rename from test_fixtures/masp_proofs/DDD66A8E673E8E8A1401967F6FCDD5724C594E275B353F45FF749CB76D3CFF52.bin rename to test_fixtures/masp_proofs/52984E26D4A044A259B441C1DAEB66F886B3A3B6C71D33F456B859D01DA47ADD.bin index 0a8cd50818..c51b5ed0d9 100644 Binary files a/test_fixtures/masp_proofs/DDD66A8E673E8E8A1401967F6FCDD5724C594E275B353F45FF749CB76D3CFF52.bin and b/test_fixtures/masp_proofs/52984E26D4A044A259B441C1DAEB66F886B3A3B6C71D33F456B859D01DA47ADD.bin differ diff --git a/test_fixtures/masp_proofs/8B29BC2E1A96DF331C7C3A2B227C98D1E5AAAA9988F26B1A47090ACCE693572F.bin b/test_fixtures/masp_proofs/8B29BC2E1A96DF331C7C3A2B227C98D1E5AAAA9988F26B1A47090ACCE693572F.bin index 76b40e6552..afcad7c654 100644 Binary files a/test_fixtures/masp_proofs/8B29BC2E1A96DF331C7C3A2B227C98D1E5AAAA9988F26B1A47090ACCE693572F.bin and b/test_fixtures/masp_proofs/8B29BC2E1A96DF331C7C3A2B227C98D1E5AAAA9988F26B1A47090ACCE693572F.bin differ diff --git a/test_fixtures/masp_proofs/9883C2EF7971504BB1CF651BAFFC3DA2C57E4FD8FF0811D9CB129887F0F9F706.bin b/test_fixtures/masp_proofs/9883C2EF7971504BB1CF651BAFFC3DA2C57E4FD8FF0811D9CB129887F0F9F706.bin new file mode 100644 index 0000000000..094103100a Binary files /dev/null and b/test_fixtures/masp_proofs/9883C2EF7971504BB1CF651BAFFC3DA2C57E4FD8FF0811D9CB129887F0F9F706.bin differ diff --git a/test_fixtures/masp_proofs/B9D0EC03A64BC8F9536A05F587B35316EE670A242606A81AF0139B3F21CDEDD8.bin b/test_fixtures/masp_proofs/99393E3AC8046F86ABA05519568B6780B6F18A312AE3909BEA19D16FCFE837DC.bin similarity index 61% rename from test_fixtures/masp_proofs/B9D0EC03A64BC8F9536A05F587B35316EE670A242606A81AF0139B3F21CDEDD8.bin rename to test_fixtures/masp_proofs/99393E3AC8046F86ABA05519568B6780B6F18A312AE3909BEA19D16FCFE837DC.bin index 6519f4fbc3..f456d94d7d 100644 Binary files a/test_fixtures/masp_proofs/B9D0EC03A64BC8F9536A05F587B35316EE670A242606A81AF0139B3F21CDEDD8.bin and b/test_fixtures/masp_proofs/99393E3AC8046F86ABA05519568B6780B6F18A312AE3909BEA19D16FCFE837DC.bin differ diff --git a/test_fixtures/masp_proofs/B94B8EDBFA5038FFB9D439D316EBD09A62AAF19015EF8149D6502B6C0FA871C4.bin b/test_fixtures/masp_proofs/B94B8EDBFA5038FFB9D439D316EBD09A62AAF19015EF8149D6502B6C0FA871C4.bin deleted file mode 100644 index 0cabab2505..0000000000 Binary files a/test_fixtures/masp_proofs/B94B8EDBFA5038FFB9D439D316EBD09A62AAF19015EF8149D6502B6C0FA871C4.bin and /dev/null differ diff --git a/test_fixtures/masp_proofs/C82CD3AD0DACE8091365CB0D91AE73F7B5BC1D64F787FA8A7985D301776103DD.bin b/test_fixtures/masp_proofs/BA4FED83467B6FEE522748C6F7E72A01F0B169F946835583DC2C71B550315603.bin similarity index 55% rename from test_fixtures/masp_proofs/C82CD3AD0DACE8091365CB0D91AE73F7B5BC1D64F787FA8A7985D301776103DD.bin rename to test_fixtures/masp_proofs/BA4FED83467B6FEE522748C6F7E72A01F0B169F946835583DC2C71B550315603.bin index 863fb078ac..565d189c0c 100644 Binary files a/test_fixtures/masp_proofs/C82CD3AD0DACE8091365CB0D91AE73F7B5BC1D64F787FA8A7985D301776103DD.bin and b/test_fixtures/masp_proofs/BA4FED83467B6FEE522748C6F7E72A01F0B169F946835583DC2C71B550315603.bin differ diff --git a/test_fixtures/masp_proofs/C7ECE8C02C2E764EFD5B6A0756CFE8EEC08E2D8512695A667D294AE1A4A8D4E6.bin b/test_fixtures/masp_proofs/C7ECE8C02C2E764EFD5B6A0756CFE8EEC08E2D8512695A667D294AE1A4A8D4E6.bin new file mode 100644 index 0000000000..d7fe00a74f Binary files /dev/null and b/test_fixtures/masp_proofs/C7ECE8C02C2E764EFD5B6A0756CFE8EEC08E2D8512695A667D294AE1A4A8D4E6.bin differ diff --git a/test_fixtures/masp_proofs/EE7C912B7E21F07494D58AA6668DC6BBB31619C7E93A1A5A2E64B694DBE1BD6E.bin b/test_fixtures/masp_proofs/EE7C912B7E21F07494D58AA6668DC6BBB31619C7E93A1A5A2E64B694DBE1BD6E.bin index c0a788ee99..fee4361a2b 100644 Binary files a/test_fixtures/masp_proofs/EE7C912B7E21F07494D58AA6668DC6BBB31619C7E93A1A5A2E64B694DBE1BD6E.bin and b/test_fixtures/masp_proofs/EE7C912B7E21F07494D58AA6668DC6BBB31619C7E93A1A5A2E64B694DBE1BD6E.bin differ diff --git a/test_fixtures/masp_proofs/72CAB503E1E0568CC0CAFA892125DB879A97D990F8395D0D8C34BC7EDD203DA9.bin b/test_fixtures/masp_proofs/EEB91EB873807EC77BBCA95D4CFA3F379DB351AB4AE081207ABFDFC429C9FA48.bin similarity index 59% rename from test_fixtures/masp_proofs/72CAB503E1E0568CC0CAFA892125DB879A97D990F8395D0D8C34BC7EDD203DA9.bin rename to test_fixtures/masp_proofs/EEB91EB873807EC77BBCA95D4CFA3F379DB351AB4AE081207ABFDFC429C9FA48.bin index fda6b2648e..5064fd5593 100644 Binary files a/test_fixtures/masp_proofs/72CAB503E1E0568CC0CAFA892125DB879A97D990F8395D0D8C34BC7EDD203DA9.bin and b/test_fixtures/masp_proofs/EEB91EB873807EC77BBCA95D4CFA3F379DB351AB4AE081207ABFDFC429C9FA48.bin differ diff --git a/test_fixtures/masp_proofs/F068FDF05B8F25DD923E667215344FFFAA6CA273027CD480AEA68DDED57D88CA.bin b/test_fixtures/masp_proofs/F068FDF05B8F25DD923E667215344FFFAA6CA273027CD480AEA68DDED57D88CA.bin index 1b18c1a6b3..3b05c546b0 100644 Binary files a/test_fixtures/masp_proofs/F068FDF05B8F25DD923E667215344FFFAA6CA273027CD480AEA68DDED57D88CA.bin and b/test_fixtures/masp_proofs/F068FDF05B8F25DD923E667215344FFFAA6CA273027CD480AEA68DDED57D88CA.bin differ diff --git a/test_fixtures/masp_proofs/434F17129C496E5DE034C4F2553E767C0E74D457A68F8606AFBF41E6F2F56D6E.bin b/test_fixtures/masp_proofs/F36A8353F15FD6D8158DBC67DDB827EEEDA858AB983D16024AAA415579A68953.bin similarity index 55% rename from test_fixtures/masp_proofs/434F17129C496E5DE034C4F2553E767C0E74D457A68F8606AFBF41E6F2F56D6E.bin rename to test_fixtures/masp_proofs/F36A8353F15FD6D8158DBC67DDB827EEEDA858AB983D16024AAA415579A68953.bin index e86721b9f7..755c32011e 100644 Binary files a/test_fixtures/masp_proofs/434F17129C496E5DE034C4F2553E767C0E74D457A68F8606AFBF41E6F2F56D6E.bin and b/test_fixtures/masp_proofs/F36A8353F15FD6D8158DBC67DDB827EEEDA858AB983D16024AAA415579A68953.bin differ diff --git a/tests/src/integration/masp.rs b/tests/src/integration/masp.rs index ecd1b34465..592130e574 100644 --- a/tests/src/integration/masp.rs +++ b/tests/src/integration/masp.rs @@ -6,9 +6,6 @@ use namada::types::io::DefaultIo; use namada_apps::client::tx::CLIShieldedUtils; use namada_apps::node::ledger::shell::testing::client::run; use namada_apps::node::ledger::shell::testing::utils::{Bin, CapturedOutput}; -use namada_core::types::address::{btc, eth, masp_rewards}; -use namada_core::types::token; -use namada_core::types::token::{DenominatedAmount, NATIVE_MAX_DECIMAL_PLACES}; use test_log::test; use super::setup; @@ -22,10 +19,6 @@ use crate::e2e::setup::constants::{ /// for leaving their assets in the pool for varying periods of time. #[test] fn masp_incentives() -> Result<()> { - // The number of decimal places used by BTC amounts. - const BTC_DENOMINATION: u8 = 8; - // The number of decimal places used by ETH amounts. - const ETH_DENOMINATION: u8 = 18; // This address doesn't matter for tests. But an argument is required. let validator_one_rpc = "127.0.0.1:26567"; // Download the shielded pool parameters before starting node @@ -35,7 +28,7 @@ fn masp_incentives() -> Result<()> { // not invalidated. let mut node = setup::setup()?; // Wait till epoch boundary - let ep0 = node.next_epoch(); + node.next_epoch(); // Send 20 BTC from Albert to PA run( &node, @@ -94,10 +87,8 @@ fn masp_incentives() -> Result<()> { assert!(captured.result.is_ok()); assert!(captured.contains("No shielded nam balance found")); - let masp_rewards = masp_rewards(); - // Wait till epoch boundary - let ep1 = node.next_epoch(); + node.next_epoch(); // Assert BTC balance at VK(A) is 20 let captured = CapturedOutput::of(|| { @@ -118,9 +109,6 @@ fn masp_incentives() -> Result<()> { assert!(captured.result.is_ok()); assert!(captured.contains("btc: 20")); - let amt20 = token::Amount::from_uint(20, BTC_DENOMINATION).unwrap(); - let amt10 = token::Amount::from_uint(10, ETH_DENOMINATION).unwrap(); - // Assert NAM balance at VK(A) is 20*BTC_reward*(epoch_1-epoch_0) let captured = CapturedOutput::of(|| { run( @@ -138,13 +126,8 @@ fn masp_incentives() -> Result<()> { ) }); - let amt = (amt20 * masp_rewards[&btc()]).0 * (ep1.0 - ep0.0); - let denominated = DenominatedAmount { - amount: amt, - denom: NATIVE_MAX_DECIMAL_PLACES.into(), - }; assert!(captured.result.is_ok()); - assert!(captured.contains(&format!("nam: {}", denominated))); + assert!(captured.contains("nam: 22.74")); // Assert NAM balance at MASP pool is 20*BTC_reward*(epoch_1-epoch_0) let captured = CapturedOutput::of(|| { @@ -162,16 +145,11 @@ fn masp_incentives() -> Result<()> { ], ) }); - let amt = (amt20 * masp_rewards[&btc()]).0 * (ep1.0 - ep0.0); - let denominated = DenominatedAmount { - amount: amt, - denom: NATIVE_MAX_DECIMAL_PLACES.into(), - }; assert!(captured.result.is_ok()); - assert!(captured.contains(&format!("nam: {}", denominated))); + assert!(captured.contains("nam: 22.74")); // Wait till epoch boundary - let ep2 = node.next_epoch(); + node.next_epoch(); // Assert BTC balance at VK(A) is 20 let captured = CapturedOutput::of(|| { @@ -208,13 +186,8 @@ fn masp_incentives() -> Result<()> { ], ) }); - let amt = (amt20 * masp_rewards[&btc()]).0 * (ep2.0 - ep0.0); - let denominated = DenominatedAmount { - amount: amt, - denom: NATIVE_MAX_DECIMAL_PLACES.into(), - }; assert!(captured.result.is_ok()); - assert!(captured.contains(&format!("nam: {}", denominated))); + assert!(captured.contains("nam: 90.96")); // Assert NAM balance at MASP pool is 20*BTC_reward*(epoch_2-epoch_0) let captured = CapturedOutput::of(|| { @@ -232,16 +205,11 @@ fn masp_incentives() -> Result<()> { ], ) }); - let amt = (amt20 * masp_rewards[&btc()]).0 * (ep2.0 - ep0.0); - let denominated = DenominatedAmount { - amount: amt, - denom: NATIVE_MAX_DECIMAL_PLACES.into(), - }; assert!(captured.result.is_ok()); - assert!(captured.contains(&format!("nam: {}", denominated))); + assert!(captured.contains("nam: 90.96")); // Wait till epoch boundary - let ep3 = node.next_epoch(); + node.next_epoch(); // Send 10 ETH from Albert to PA(B) run( @@ -302,7 +270,7 @@ fn masp_incentives() -> Result<()> { assert!(captured.contains("No shielded nam balance found")); // Wait till epoch boundary - let ep4 = node.next_epoch(); + node.next_epoch(); // Assert ETH balance at VK(B) is 10 let captured = CapturedOutput::of(|| { @@ -339,13 +307,8 @@ fn masp_incentives() -> Result<()> { ], ) }); - let amt = (amt10 * masp_rewards[ð()]).0 * (ep4.0 - ep3.0); - let denominated = DenominatedAmount { - amount: amt, - denom: NATIVE_MAX_DECIMAL_PLACES.into(), - }; assert!(captured.result.is_ok()); - assert!(captured.contains(&format!("nam: {}", denominated))); + assert!(captured.contains("nam: 22.71432")); // Assert NAM balance at MASP pool is // 20*BTC_reward*(epoch_4-epoch_0)+10*ETH_reward*(epoch_4-epoch_3) @@ -364,17 +327,11 @@ fn masp_incentives() -> Result<()> { ], ) }); - let amt = ((amt20 * masp_rewards[&btc()]).0 * (ep4.0 - ep0.0)) - + ((amt10 * masp_rewards[ð()]).0 * (ep4.0 - ep3.0)); - let denominated = DenominatedAmount { - amount: amt, - denom: NATIVE_MAX_DECIMAL_PLACES.into(), - }; assert!(captured.result.is_ok()); - assert!(captured.contains(&format!("nam: {}", denominated))); + assert!(captured.contains("nam: 386.46336")); // Wait till epoch boundary - let ep5 = node.next_epoch(); + node.next_epoch(); // Send 10 ETH from SK(B) to Christel run( @@ -417,7 +374,7 @@ fn masp_incentives() -> Result<()> { assert!(captured.result.is_ok()); assert!(captured.contains("No shielded eth balance found")); - let _ep = node.next_epoch(); + node.next_epoch(); // Assert NAM balance at VK(B) is 10*ETH_reward*(ep-epoch_3) let captured = CapturedOutput::of(|| { @@ -435,15 +392,10 @@ fn masp_incentives() -> Result<()> { ], ) }); - let amt = (amt10 * masp_rewards[ð()]).0 * (ep5.0 - ep3.0); - let denominated = DenominatedAmount { - amount: amt, - denom: NATIVE_MAX_DECIMAL_PLACES.into(), - }; assert!(captured.result.is_ok()); - assert!(captured.contains(&format!("nam: {}", denominated))); + assert!(captured.contains("nam: 86.60024")); - let ep = node.next_epoch(); + node.next_epoch(); // Assert NAM balance at MASP pool is // 20*BTC_reward*(epoch_5-epoch_0)+10*ETH_reward*(epoch_5-epoch_3) let captured = CapturedOutput::of(|| { @@ -461,17 +413,11 @@ fn masp_incentives() -> Result<()> { ], ) }); - let amt = ((amt20 * masp_rewards[&btc()]).0 * (ep.0 - ep0.0)) - + ((amt10 * masp_rewards[ð()]).0 * (ep5.0 - ep3.0)); - let denominated = DenominatedAmount { - amount: amt, - denom: NATIVE_MAX_DECIMAL_PLACES.into(), - }; assert!(captured.result.is_ok()); - assert!(captured.contains(&format!("nam: {}", denominated))); + assert!(captured.contains("nam: 1180.41525")); // Wait till epoch boundary - let ep6 = node.next_epoch(); + node.next_epoch(); // Send 20 BTC from SK(A) to Christel run( @@ -530,13 +476,8 @@ fn masp_incentives() -> Result<()> { ], ) }); - let amt = (amt20 * masp_rewards[&btc()]).0 * (ep6.0 - ep0.0); - let denominated = DenominatedAmount { - amount: amt, - denom: NATIVE_MAX_DECIMAL_PLACES.into(), - }; assert!(captured.result.is_ok()); - assert!(captured.contains(&format!("nam: {}", denominated,))); + assert!(captured.contains("nam: 1407.16324")); // Assert NAM balance at MASP pool is // 20*BTC_reward*(epoch_6-epoch_0)+20*ETH_reward*(epoch_5-epoch_3) @@ -555,17 +496,11 @@ fn masp_incentives() -> Result<()> { ], ) }); - let amt = ((amt20 * masp_rewards[&btc()]).0 * (ep6.0 - ep0.0)) - + ((amt10 * masp_rewards[ð()]).0 * (ep5.0 - ep3.0)); - let denominated = DenominatedAmount { - amount: amt, - denom: NATIVE_MAX_DECIMAL_PLACES.into(), - }; assert!(captured.result.is_ok()); - assert!(captured.contains(&format!("nam: {}", denominated,))); + assert!(captured.contains("nam: 1520.37191")); // Wait till epoch boundary - let _ep7 = node.next_epoch(); + node.next_epoch(); // Assert NAM balance at VK(A) is 20*BTC_reward*(epoch_6-epoch_0) let captured = CapturedOutput::of(|| { @@ -583,13 +518,8 @@ fn masp_incentives() -> Result<()> { ], ) }); - let amt = (amt20 * masp_rewards[&btc()]).0 * (ep6.0 - ep0.0); - let denominated = DenominatedAmount { - amount: amt, - denom: NATIVE_MAX_DECIMAL_PLACES.into(), - }; assert!(captured.result.is_ok()); - assert!(captured.contains(&format!("nam: {}", denominated))); + assert!(captured.contains("nam: 1573.18")); // Assert NAM balance at VK(B) is 10*ETH_reward*(epoch_5-epoch_3) let captured = CapturedOutput::of(|| { @@ -607,13 +537,8 @@ fn masp_incentives() -> Result<()> { ], ) }); - let amt = (amt10 * masp_rewards[ð()]).0 * (ep5.0 - ep3.0); - let denominated = DenominatedAmount { - amount: amt, - denom: NATIVE_MAX_DECIMAL_PLACES.into(), - }; assert!(captured.result.is_ok()); - assert!(captured.contains(&format!("nam: {}", denominated,))); + assert!(captured.contains("nam: 126.565")); // Assert NAM balance at MASP pool is // 20*BTC_reward*(epoch_6-epoch_0)+10*ETH_reward*(epoch_5-epoch_3) @@ -632,18 +557,12 @@ fn masp_incentives() -> Result<()> { ], ) }); - let amt = ((amt20 * masp_rewards[&btc()]).0 * (ep6.0 - ep0.0)) - + ((amt10 * masp_rewards[ð()]).0 * (ep5.0 - ep3.0)); - let denominated = DenominatedAmount { - amount: amt, - denom: NATIVE_MAX_DECIMAL_PLACES.into(), - }; assert!(captured.result.is_ok()); - assert!(captured.contains(&format!("nam: {}", denominated,))); + assert!(captured.contains("nam: 1699.745")); // Wait till epoch boundary to prevent conversion expiry during transaction // construction - let _ep8 = node.next_epoch(); + node.next_epoch(); // Send 10*ETH_reward*(epoch_5-epoch_3) NAM from SK(B) to Christel run( @@ -658,8 +577,7 @@ fn masp_incentives() -> Result<()> { "--token", NAM, "--amount", - &((amt10 * masp_rewards[ð()]).0 * (ep5.0 - ep3.0)) - .to_string_native(), + "141.49967", "--signing-keys", BERTHA, "--node", @@ -669,7 +587,7 @@ fn masp_incentives() -> Result<()> { node.assert_success(); // Wait till epoch boundary - let _ep9 = node.next_epoch(); + node.next_epoch(); // Send 20*BTC_reward*(epoch_6-epoch_0) NAM from SK(A) to Bertha run( @@ -684,8 +602,7 @@ fn masp_incentives() -> Result<()> { "--token", NAM, "--amount", - &((amt20 * masp_rewards[&btc()]).0 * (ep6.0 - ep0.0)) - .to_string_native(), + "1980.356", "--signing-keys", ALBERT, "--node", diff --git a/wasm/Cargo.lock b/wasm/Cargo.lock index 5dbe91c1e4..439d62e184 100644 --- a/wasm/Cargo.lock +++ b/wasm/Cargo.lock @@ -3101,7 +3101,7 @@ dependencies = [ [[package]] name = "masp_note_encryption" version = "0.2.0" -source = "git+https://github.com/anoma/masp?rev=50acc5028fbcd52a05970fe7991c7850ab04358e#50acc5028fbcd52a05970fe7991c7850ab04358e" +source = "git+https://github.com/anoma/masp?rev=1345b463e8fa3b3a6fa13e4a43fb1c410690ad62#1345b463e8fa3b3a6fa13e4a43fb1c410690ad62" dependencies = [ "borsh 0.9.4", "chacha20 0.9.1", @@ -3114,7 +3114,7 @@ dependencies = [ [[package]] name = "masp_primitives" version = "0.9.0" -source = "git+https://github.com/anoma/masp?rev=50acc5028fbcd52a05970fe7991c7850ab04358e#50acc5028fbcd52a05970fe7991c7850ab04358e" +source = "git+https://github.com/anoma/masp?rev=1345b463e8fa3b3a6fa13e4a43fb1c410690ad62#1345b463e8fa3b3a6fa13e4a43fb1c410690ad62" dependencies = [ "aes 0.7.5", "bip0039", @@ -3145,7 +3145,7 @@ dependencies = [ [[package]] name = "masp_proofs" version = "0.9.0" -source = "git+https://github.com/anoma/masp?rev=50acc5028fbcd52a05970fe7991c7850ab04358e#50acc5028fbcd52a05970fe7991c7850ab04358e" +source = "git+https://github.com/anoma/masp?rev=1345b463e8fa3b3a6fa13e4a43fb1c410690ad62#1345b463e8fa3b3a6fa13e4a43fb1c410690ad62" dependencies = [ "bellman", "blake2b_simd", diff --git a/wasm/wasm_source/Cargo.toml b/wasm/wasm_source/Cargo.toml index 81f07ba049..2022e64ca0 100644 --- a/wasm/wasm_source/Cargo.toml +++ b/wasm/wasm_source/Cargo.toml @@ -43,7 +43,7 @@ once_cell = {version = "1.8.0", optional = true} wee_alloc = "0.4.5" getrandom = { version = "0.2", features = ["custom"] } # branch = "murisi/namada-integration" -masp_primitives = { git = "https://github.com/anoma/masp", rev = "50acc5028fbcd52a05970fe7991c7850ab04358e", optional = true } +masp_primitives = { git = "https://github.com/anoma/masp", rev = "1345b463e8fa3b3a6fa13e4a43fb1c410690ad62", optional = true } ripemd = "0.1" [dev-dependencies] diff --git a/wasm_for_tests/wasm_source/Cargo.lock b/wasm_for_tests/wasm_source/Cargo.lock index 8e3bc2bb20..c8cafdda1c 100644 --- a/wasm_for_tests/wasm_source/Cargo.lock +++ b/wasm_for_tests/wasm_source/Cargo.lock @@ -3101,7 +3101,7 @@ dependencies = [ [[package]] name = "masp_note_encryption" version = "0.2.0" -source = "git+https://github.com/anoma/masp?rev=50acc5028fbcd52a05970fe7991c7850ab04358e#50acc5028fbcd52a05970fe7991c7850ab04358e" +source = "git+https://github.com/anoma/masp?rev=1345b463e8fa3b3a6fa13e4a43fb1c410690ad62#1345b463e8fa3b3a6fa13e4a43fb1c410690ad62" dependencies = [ "borsh 0.9.4", "chacha20 0.9.1", @@ -3114,7 +3114,7 @@ dependencies = [ [[package]] name = "masp_primitives" version = "0.9.0" -source = "git+https://github.com/anoma/masp?rev=50acc5028fbcd52a05970fe7991c7850ab04358e#50acc5028fbcd52a05970fe7991c7850ab04358e" +source = "git+https://github.com/anoma/masp?rev=1345b463e8fa3b3a6fa13e4a43fb1c410690ad62#1345b463e8fa3b3a6fa13e4a43fb1c410690ad62" dependencies = [ "aes 0.7.5", "bip0039", @@ -3145,7 +3145,7 @@ dependencies = [ [[package]] name = "masp_proofs" version = "0.9.0" -source = "git+https://github.com/anoma/masp?rev=50acc5028fbcd52a05970fe7991c7850ab04358e#50acc5028fbcd52a05970fe7991c7850ab04358e" +source = "git+https://github.com/anoma/masp?rev=1345b463e8fa3b3a6fa13e4a43fb1c410690ad62#1345b463e8fa3b3a6fa13e4a43fb1c410690ad62" dependencies = [ "bellman", "blake2b_simd",