From bb5fd3781c9e8dcfbcab5903e4d18adc88fca55e Mon Sep 17 00:00:00 2001 From: akildemir Date: Thu, 1 Aug 2024 12:53:56 +0300 Subject: [PATCH] Finish up fixing pr comments --- substrate/abi/src/lib.rs | 1 - substrate/client/tests/emissions.rs | 23 ++++++------ substrate/emissions/pallet/Cargo.toml | 1 + substrate/emissions/pallet/src/lib.rs | 50 +++++++++++++-------------- substrate/primitives/src/constants.rs | 3 ++ substrate/runtime/Cargo.toml | 5 ++- substrate/runtime/src/abi.rs | 1 - 7 files changed, 45 insertions(+), 39 deletions(-) diff --git a/substrate/abi/src/lib.rs b/substrate/abi/src/lib.rs index 22247e10a..ae25c89ee 100644 --- a/substrate/abi/src/lib.rs +++ b/substrate/abi/src/lib.rs @@ -35,7 +35,6 @@ pub enum Call { Dex(dex::Call), ValidatorSets(validator_sets::Call), GenesisLiquidity(genesis_liquidity::Call), - Emissions, InInstructions(in_instructions::Call), Signals(signals::Call), Babe(babe::Call), diff --git a/substrate/client/tests/emissions.rs b/substrate/client/tests/emissions.rs index 5484dc99d..62ff043ea 100644 --- a/substrate/client/tests/emissions.rs +++ b/substrate/client/tests/emissions.rs @@ -6,7 +6,10 @@ use serai_client::TemporalSerai; use serai_abi::{ emissions::primitives::{INITIAL_REWARD_PER_BLOCK, SECURE_BY}, in_instructions::primitives::Batch, - primitives::{NETWORKS, Coin, BlockHash, COINS, FAST_EPOCH_DURATION, TARGET_BLOCK_TIME}, + primitives::{ + BlockHash, Coin, COINS, FAST_EPOCH_DURATION, FAST_EPOCH_INITIAL_PERIOD, NETWORKS, + TARGET_BLOCK_TIME, + }, validator_sets::primitives::Session, }; @@ -62,6 +65,7 @@ async fn test_emissions(serai: Serai) { { tokio::time::sleep(Duration::from_secs(1)).await; } + let genesis_complete_block = serai.latest_finalized_block().await.unwrap().number(); for _ in 0 .. 3 { // get current stakes @@ -94,15 +98,14 @@ async fn test_emissions(serai: Serai) { let block_count = get_session_blocks(&serai_latest, current_session - 1).await; // calculate how much reward in this session - // TODO: genesis is complete at block 24 in current tests. Initial period is just double that. - // See the emissions pallet to further read on this. We also assume we are in pre-ec era. - let reward_this_epoch = if change_block_number < 24 * 3 { - block_count * INITIAL_REWARD_PER_BLOCK - } else { - let blocks_until = SECURE_BY - change_block_number; - let block_reward = total_distance / blocks_until; - block_count * block_reward - }; + let reward_this_epoch = + if change_block_number < (genesis_complete_block + FAST_EPOCH_INITIAL_PERIOD) { + block_count * INITIAL_REWARD_PER_BLOCK + } else { + let blocks_until = SECURE_BY - change_block_number; + let block_reward = total_distance / blocks_until; + block_count * block_reward + }; let reward_per_network = distances .into_iter() diff --git a/substrate/emissions/pallet/Cargo.toml b/substrate/emissions/pallet/Cargo.toml index 7b3986585..878175730 100644 --- a/substrate/emissions/pallet/Cargo.toml +++ b/substrate/emissions/pallet/Cargo.toml @@ -56,5 +56,6 @@ std = [ "serai-primitives/std", "emissions-primitives/std", ] +fast-epoch = [] try-runtime = [] # TODO default = ["std"] diff --git a/substrate/emissions/pallet/src/lib.rs b/substrate/emissions/pallet/src/lib.rs index 3034931da..9569e85ca 100644 --- a/substrate/emissions/pallet/src/lib.rs +++ b/substrate/emissions/pallet/src/lib.rs @@ -51,6 +51,7 @@ pub mod pallet { pub enum Error { NetworkHasEconomicSecurity, NoValueForCoin, + InsufficientAllocation, } #[pallet::event] @@ -116,6 +117,7 @@ pub mod pallet { // if the genesis complete we shouldn't be economically secure because the funds are not // enough) is because ValidatorSets pallet runs before the genesis pallet in runtime. // So ValidatorSets pallet sees the old state until next block. + // TODO: revisit this when mainnet genesis validator stake code is done. let gcb = GenesisCompleteBlock::::get(); let genesis_ended = gcb.is_some() && (n.saturated_into::() > gcb.unwrap()); @@ -313,6 +315,9 @@ pub mod pallet { } } + // TODO: we have the past session participants here in the emissions pallet so that we can + // distribute rewards to them in the next session. Ideally we should be able to fetch this + // information from valiadtor sets pallet. Self::update_participants(); Weight::zero() // TODO } @@ -325,15 +330,15 @@ pub mod pallet { } fn initial_period(n: BlockNumberFor) -> bool { - // TODO: we should wait for exactly 2 months according to paper. This waits double the time - // it took until genesis complete since we assume it will be done in a month. We know genesis - // period blocks is a month but there will be delay until oracilization is done and genesis - // completed and emissions start happening. If we wait exactly 2 months and the delay is big - // enough we might not be able to distribute all funds we want to in this period. - // In the current case we will distribute more than we want to. What to do? + #[cfg(feature = "fast-epoch")] + let initial_period_duration = FAST_EPOCH_INITIAL_PERIOD; + + #[cfg(not(feature = "fast-epoch"))] + let initial_period_duration = 2 * MONTHS; + let genesis_complete_block = GenesisCompleteBlock::::get(); genesis_complete_block.is_some() && - (n.saturated_into::() < (3 * genesis_complete_block.unwrap())) + (n.saturated_into::() < (genesis_complete_block.unwrap() + initial_period_duration)) } /// Returns true if any of the external networks haven't reached economic security yet. @@ -371,11 +376,7 @@ pub mod pallet { ) .unwrap(); - if Coins::::mint(p, Balance { coin: Coin::Serai, amount: Amount(p_reward) }).is_err() { - // TODO: log the failure - continue; - } - + Coins::::mint(p, Balance { coin: Coin::Serai, amount: Amount(p_reward) }).unwrap(); if ValidatorSets::::deposit_stake(n, p, Amount(p_reward)).is_err() { // TODO: log the failure continue; @@ -427,30 +428,27 @@ pub mod pallet { // doing an unwrap so that it can be properly dealt with. let sri_amount = balance.amount.mul(value); - // Mint & stake the SRI for the network. + // Mint Coins::::mint(to, Balance { coin: Coin::Serai, amount: sri_amount })?; - // TODO: deposit_stake lets staking less than per key share. Should we allow that here? - ValidatorSets::::deposit_stake(network, to, sri_amount)?; + // Stake the SRI for the network. + let allocation_per_key_share = + ValidatorSets::::allocation_per_key_share(network).unwrap().0; + let allocation = ValidatorSets::::allocation((network, to)).unwrap_or(Amount(0)).0; + if allocation.saturating_add(sri_amount.0) < allocation_per_key_share { + Err(Error::::InsufficientAllocation)?; + } + + ValidatorSets::::deposit_stake(network, to, sri_amount)?; Ok(()) } fn update_participants() { for n in NETWORKS { - // TODO: `participants_for_latest_decided_set` returns keys with key shares but we - // store keys with actual stake amounts. Pr https://github.com/serai-dex/serai/pull/518 - // supposed to change that and so this pr relies and that pr. let participants = ValidatorSets::::participants_for_latest_decided_set(n) .unwrap() .into_iter() - .map(|(key, shares)| { - let amount = match n { - NetworkId::Serai => shares * 50_000 * 10_u64.pow(8), - NetworkId::Bitcoin | NetworkId::Ethereum => shares * 1_000_000 * 10_u64.pow(8), - NetworkId::Monero => shares * 100_000 * 10_u64.pow(8), - }; - (key, amount) - }) + .map(|(key, _)| (key, ValidatorSets::::allocation((n, key)).unwrap_or(Amount(0)).0)) .collect::>(); Participants::::set(n, Some(participants.try_into().unwrap())); diff --git a/substrate/primitives/src/constants.rs b/substrate/primitives/src/constants.rs index 851763f8a..7874a2087 100644 --- a/substrate/primitives/src/constants.rs +++ b/substrate/primitives/src/constants.rs @@ -30,3 +30,6 @@ pub const MEDIAN_PRICE_WINDOW_LENGTH: u16 = (2 * ARBITRAGE_TIME) + 1; /// Amount of blocks per epoch in the fast-epoch feature that is used in tests. pub const FAST_EPOCH_DURATION: u64 = 2 * MINUTES; + +/// Amount of blocks for the initial period era for the emissions for fast epoc feature. +pub const FAST_EPOCH_INITIAL_PERIOD: u64 = FAST_EPOCH_DURATION * 2; diff --git a/substrate/runtime/Cargo.toml b/substrate/runtime/Cargo.toml index c2eee13d1..8419d9bfb 100644 --- a/substrate/runtime/Cargo.toml +++ b/substrate/runtime/Cargo.toml @@ -131,7 +131,10 @@ std = [ "pallet-transaction-payment-rpc-runtime-api/std", ] -fast-epoch = ["genesis-liquidity-pallet/fast-epoch"] +fast-epoch = [ + "genesis-liquidity-pallet/fast-epoch", + "emissions-pallet/fast-epoch", +] runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", diff --git a/substrate/runtime/src/abi.rs b/substrate/runtime/src/abi.rs index 6f393eaa1..48b4a6c74 100644 --- a/substrate/runtime/src/abi.rs +++ b/substrate/runtime/src/abi.rs @@ -138,7 +138,6 @@ impl From for RuntimeCall { }) } }, - Call::Emissions => todo!(), // TODO Call::InInstructions(ii) => match ii { serai_abi::in_instructions::Call::execute_batch { batch } => { RuntimeCall::InInstructions(in_instructions::Call::execute_batch { batch })