From ec956a1f8b1b73caa69744c2543d1ca944a7ee19 Mon Sep 17 00:00:00 2001 From: kostekIV <27210860+kostekIV@users.noreply.github.com> Date: Fri, 11 Oct 2024 10:20:38 +0100 Subject: [PATCH] L1-297: Add inflation api (#1831) --- aleph-client/src/aleph_zero.rs | 64 ++++++++++++++++++++++++++++ bin/fake-runtime-api/src/lib.rs | 10 ++++- bin/runtime/src/lib.rs | 53 +++++++++++++++-------- pallets/aleph-runtime-api/src/lib.rs | 8 +++- 4 files changed, 115 insertions(+), 20 deletions(-) diff --git a/aleph-client/src/aleph_zero.rs b/aleph-client/src/aleph_zero.rs index 8c75b15c46..3c75ce072c 100644 --- a/aleph-client/src/aleph_zero.rs +++ b/aleph-client/src/aleph_zero.rs @@ -1173,6 +1173,42 @@ pub mod api { ], ) } + #[doc = " Returns inflation from now to now + 1 year. Capped at 100%"] + pub fn yearly_inflation( + &self, + ) -> ::subxt::runtime_api::Payload< + types::YearlyInflation, + runtime_types::sp_arithmetic::per_things::Perbill, + > { + ::subxt::runtime_api::Payload::new_static( + "AlephSessionApi", + "yearly_inflation", + types::YearlyInflation {}, + [ + 139u8, 25u8, 143u8, 190u8, 127u8, 191u8, 235u8, 69u8, 16u8, 116u8, + 112u8, 112u8, 54u8, 191u8, 49u8, 113u8, 139u8, 52u8, 66u8, 37u8, 43u8, + 81u8, 15u8, 144u8, 77u8, 17u8, 224u8, 107u8, 178u8, 227u8, 171u8, 52u8, + ], + ) + } + #[doc = " Returns payout. First tuple item is a validators payout, 2nd is the rest."] + pub fn current_era_payout( + &self, + ) -> ::subxt::runtime_api::Payload< + types::CurrentEraPayout, + (::core::primitive::u128, ::core::primitive::u128), + > { + ::subxt::runtime_api::Payload::new_static( + "AlephSessionApi", + "current_era_payout", + types::CurrentEraPayout {}, + [ + 55u8, 146u8, 5u8, 196u8, 176u8, 34u8, 184u8, 92u8, 198u8, 150u8, 212u8, + 142u8, 203u8, 99u8, 146u8, 45u8, 21u8, 125u8, 209u8, 88u8, 98u8, 5u8, + 10u8, 63u8, 48u8, 176u8, 68u8, 234u8, 115u8, 19u8, 64u8, 10u8, + ], + ) + } } pub mod types { use super::runtime_types; @@ -1334,6 +1370,34 @@ pub mod api { pub struct KeyOwner { pub key: runtime_types::primitives::app::Public, } + #[derive( + :: subxt :: ext :: codec :: Decode, + :: subxt :: ext :: codec :: Encode, + :: subxt :: ext :: scale_decode :: DecodeAsType, + :: subxt :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt :: ext :: scale_encode")] + pub struct YearlyInflation {} + #[derive( + :: subxt :: ext :: codec :: Decode, + :: subxt :: ext :: codec :: Encode, + :: subxt :: ext :: scale_decode :: DecodeAsType, + :: subxt :: ext :: scale_encode :: EncodeAsType, + Clone, + Debug, + Eq, + PartialEq, + )] + # [codec (crate = :: subxt :: ext :: codec)] + #[decode_as_type(crate_path = ":: subxt :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt :: ext :: scale_encode")] + pub struct CurrentEraPayout {} } } pub mod nomination_pools_api { diff --git a/bin/fake-runtime-api/src/lib.rs b/bin/fake-runtime-api/src/lib.rs index ebb903e1f2..20609d2eef 100644 --- a/bin/fake-runtime-api/src/lib.rs +++ b/bin/fake-runtime-api/src/lib.rs @@ -9,7 +9,7 @@ use pallet_transaction_payment::FeeDetails; use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; use primitives::{ AccountId, ApiError as AlephApiError, AuraId, AuthorityId as AlephId, Balance, Block, Nonce, - SessionAuthorityData, SessionCommittee, SessionIndex, SessionValidatorError, + Perbill, SessionAuthorityData, SessionCommittee, SessionIndex, SessionValidatorError, Version as FinalityVersion, }; use sp_consensus_aura::SlotDuration; @@ -187,6 +187,14 @@ pub mod fake_runtime { fn key_owner(_key: AlephId) -> Option { unimplemented!() } + + fn yearly_inflation() -> Perbill { + unimplemented!() + } + + fn current_era_payout() -> (Balance, Balance) { + unimplemented!() + } } /// There’s an important remark on how this fake runtime must be implemented - it does not need to diff --git a/bin/runtime/src/lib.rs b/bin/runtime/src/lib.rs index 382319b896..33b70b5bbe 100644 --- a/bin/runtime/src/lib.rs +++ b/bin/runtime/src/lib.rs @@ -452,6 +452,23 @@ parameter_types! { pub struct ExponentialEraPayout; +impl ExponentialEraPayout { + fn era_payout(total_issuance: Balance, era_duration_millis: u64) -> (Balance, Balance) { + const VALIDATOR_REWARD: Perbill = Perbill::from_percent(90); + + let azero_cap = pallet_aleph::AzeroCap::::get(); + let horizon = pallet_aleph::ExponentialInflationHorizon::::get(); + + let total_payout: Balance = + exp_helper(Perbill::from_rational(era_duration_millis, horizon)) + * (azero_cap.saturating_sub(total_issuance)); + let validators_payout = VALIDATOR_REWARD * total_payout; + let rest = total_payout - validators_payout; + + (validators_payout, rest) + } +} + /// Calculates 1 - exp(-x) for small positive x fn exp_helper(x: Perbill) -> Perbill { let x2 = x * x; @@ -467,18 +484,7 @@ impl pallet_staking::EraPayout for ExponentialEraPayout { total_issuance: Balance, era_duration_millis: u64, ) -> (Balance, Balance) { - const VALIDATOR_REWARD: Perbill = Perbill::from_percent(90); - - let azero_cap = pallet_aleph::AzeroCap::::get(); - let horizon = pallet_aleph::ExponentialInflationHorizon::::get(); - - let total_payout: Balance = - exp_helper(Perbill::from_rational(era_duration_millis, horizon)) - * (azero_cap.saturating_sub(total_issuance)); - let validators_payout = VALIDATOR_REWARD * total_payout; - let rest = total_payout - validators_payout; - - (validators_payout, rest) + ExponentialEraPayout::era_payout(total_issuance, era_duration_millis) } } @@ -1214,6 +1220,24 @@ impl_runtime_apis! { fn key_owner(key: AlephId) -> Option { Session::key_owner(primitives::KEY_TYPE, key.as_ref()) } + + fn yearly_inflation() -> Perbill { + // Milliseconds per year for the Julian year (365.25 days). + const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100; + let total_issuance = pallet_balances::Pallet::::total_issuance(); + + let (validator_payout, rest) + = ExponentialEraPayout::era_payout(total_issuance, MILLISECONDS_PER_YEAR); + + Perbill::from_rational(validator_payout + rest, total_issuance) + } + + fn current_era_payout() -> (Balance, Balance) { + const MILLISECONDS_PER_ERA: u64 = MILLISECS_PER_BLOCK * (DEFAULT_SESSION_PERIOD * DEFAULT_SESSIONS_PER_ERA) as u64; + let total_issuance = pallet_balances::Pallet::::total_issuance(); + + ExponentialEraPayout::era_payout(total_issuance, MILLISECONDS_PER_ERA) + } } impl pallet_nomination_pools_runtime_api::NominationPoolsApi for Runtime { @@ -1371,7 +1395,6 @@ impl_runtime_apis! { #[cfg(test)] mod tests { use frame_support::traits::Get; - use pallet_staking::EraPayout; use primitives::HEAP_PAGES; use smallvec::Array; @@ -1600,8 +1623,6 @@ mod tests { assert!(lhs < rhs); } - /// `EraPayout::era_payout` ignores the first argument, we set it to zero. - const DUMMY_TOTAL_STAKED: Balance = 0; const MILLISECS_PER_DAY: u64 = 24 * 60 * 60 * 1000; struct EraPayoutInputs { @@ -1623,7 +1644,6 @@ mod tests { pallet_aleph::ExponentialInflationHorizon::::put(inputs.horizon); let (validators_payout, rest) = ::EraPayout::era_payout( - DUMMY_TOTAL_STAKED, inputs.total_issuance, inputs.era_duration_millis, ); @@ -1645,7 +1665,6 @@ mod tests { pallet_aleph::ExponentialInflationHorizon::::put(inputs.horizon); let (validators_payout, rest) = ::EraPayout::era_payout( - DUMMY_TOTAL_STAKED, total_issuance, inputs.era_duration_millis, ); diff --git a/pallets/aleph-runtime-api/src/lib.rs b/pallets/aleph-runtime-api/src/lib.rs index 5ba1bbc412..9471664c80 100644 --- a/pallets/aleph-runtime-api/src/lib.rs +++ b/pallets/aleph-runtime-api/src/lib.rs @@ -2,8 +2,8 @@ #![cfg_attr(not(feature = "std"), no_std)] use primitives::{ - AccountId, ApiError, AuthorityId, SessionAuthorityData, SessionCommittee, SessionIndex, - SessionValidatorError, Version, + AccountId, ApiError, AuthorityId, Balance, Perbill, SessionAuthorityData, SessionCommittee, + SessionIndex, SessionValidatorError, Version, }; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_std::vec::Vec; @@ -33,5 +33,9 @@ sp_api::decl_runtime_apis! { /// also as `aleph_key` - consensus engine's part of session keys) in the current session /// of AlephBFT (finalisation committee). fn key_owner(key: AuthorityId) -> Option; + /// Returns inflation from now to now + 1 year. Capped at 100% + fn yearly_inflation() -> Perbill; + /// Returns payout. First tuple item is a validators payout, 2nd is the rest. + fn current_era_payout() -> (Balance, Balance); } }