Skip to content

Commit

Permalink
Merge branch 'main' into feat/cash-valuation
Browse files Browse the repository at this point in the history
  • Loading branch information
mustermeiszer authored Dec 1, 2023
2 parents 474254c + b8cefb4 commit 6054e23
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 121 deletions.
104 changes: 104 additions & 0 deletions runtime/common/src/changes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
use cfg_primitives::SECONDS_PER_WEEK;
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::RuntimeDebug;
use pallet_loans::entities::changes::{Change as LoansChange, InternalMutation, LoanMutation};
use pallet_pool_system::pool_types::changes::{PoolChangeProposal, Requirement};
use scale_info::TypeInfo;
use sp_runtime::DispatchError;
use sp_std::{marker::PhantomData, vec, vec::Vec};

/// Auxiliar type to carry all pallets bounds used by RuntimeChange
pub trait Changeable: pallet_loans::Config {}
impl<T: pallet_loans::Config> Changeable for T {}

/// A change done in the runtime, shared between pallets
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
pub enum RuntimeChange<T: Changeable, Options: Clone = ()> {
Loans(LoansChange<T>),
_Unreachable(PhantomData<Options>),
}

impl<T: Changeable, Options: Clone> RuntimeChange<T, Options> {
fn requirement_list(self) -> Vec<Requirement> {
let epoch = Requirement::NextEpoch;
let week = Requirement::DelayTime(SECONDS_PER_WEEK as u32);
let blocked = Requirement::BlockedByLockedRedemptions;

match self {
RuntimeChange::Loans(change) => match change {
// Requirements gathered from
// <https://docs.google.com/spreadsheets/d/1RJ5RLobAdumXUK7k_ugxy2eDAwI5akvtuqUM2Tyn5ts>
LoansChange::<T>::Loan(_, loan_mutation) => match loan_mutation {
LoanMutation::Maturity(_) => vec![week, blocked],
LoanMutation::MaturityExtension(_) => vec![],
LoanMutation::InterestPayments(_) => vec![week, blocked],
LoanMutation::PayDownSchedule(_) => vec![week, blocked],
LoanMutation::InterestRate(_) => vec![epoch],
LoanMutation::Internal(mutation) => match mutation {
InternalMutation::ValuationMethod(_) => vec![week, blocked],
InternalMutation::ProbabilityOfDefault(_) => vec![epoch],
InternalMutation::LossGivenDefault(_) => vec![epoch],
InternalMutation::DiscountRate(_) => vec![epoch],
},
},
LoansChange::<T>::Policy(_) => vec![week, blocked],
LoansChange::<T>::TransferDebt(_, _, _, _) => vec![],
},
RuntimeChange::_Unreachable(_) => vec![],
}
}
}

impl<T: Changeable> From<RuntimeChange<T>> for PoolChangeProposal {
fn from(runtime_change: RuntimeChange<T>) -> Self {
if cfg!(feature = "runtime-benchmarks") {
PoolChangeProposal::new([])
} else {
PoolChangeProposal::new(runtime_change.requirement_list())
}
}
}

/// Option to pass to RuntimeChange to enable fast delays
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
pub struct FastDelay;

impl<T: Changeable> From<RuntimeChange<T, FastDelay>> for PoolChangeProposal {
fn from(runtime_change: RuntimeChange<T, FastDelay>) -> Self {
let new_requirements = runtime_change
.requirement_list()
.into_iter()
.map(|req| match req {
Requirement::DelayTime(_) => Requirement::DelayTime(60), // 1 min
req => req,
});

PoolChangeProposal::new(new_requirements)
}
}

macro_rules! runtime_change_support {
($change:ident, $variant:ident) => {
/// Used by `ChangeGuard::note()`
impl<T: Changeable, Option: Clone> From<$change<T>> for RuntimeChange<T, Option> {
fn from(change: $change<T>) -> RuntimeChange<T, Option> {
RuntimeChange::$variant(change)
}
}

/// Used `ChangeGuard::released()`
impl<T: Changeable, Option: Clone> TryInto<$change<T>> for RuntimeChange<T, Option> {
type Error = DispatchError;

fn try_into(self) -> Result<$change<T>, DispatchError> {
match self {
RuntimeChange::$variant(change) => Ok(change),
_ => Err(DispatchError::Other("Expected another RuntimeChange")),
}
}
}
};
}

// Add the variants you want to support for RuntimeChange
runtime_change_support!(LoansChange, Loans);
120 changes: 1 addition & 119 deletions runtime/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

pub mod account_conversion;
pub mod apis;
pub mod changes;
pub mod evm;
pub mod fees;
pub mod gateway;
Expand Down Expand Up @@ -163,125 +164,6 @@ pub mod asset_registry {
}
}

pub mod changes {
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::RuntimeDebug;
use pallet_loans::entities::changes::Change as LoansChange;
use pallet_pool_system::pool_types::changes::PoolChangeProposal;
use scale_info::TypeInfo;
use sp_runtime::DispatchError;

#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
pub enum RuntimeChange<T: pallet_loans::Config> {
Loan(LoansChange<T>),
}

#[cfg(not(feature = "runtime-benchmarks"))]
impl<T: pallet_loans::Config> From<RuntimeChange<T>> for PoolChangeProposal {
fn from(RuntimeChange::Loan(loans_change): RuntimeChange<T>) -> Self {
use cfg_primitives::SECONDS_PER_WEEK;
use pallet_loans::entities::changes::{InternalMutation, LoanMutation};
use pallet_pool_system::pool_types::changes::Requirement;
use sp_std::vec;

let epoch = Requirement::NextEpoch;
let week = Requirement::DelayTime(SECONDS_PER_WEEK as u32);
let blocked = Requirement::BlockedByLockedRedemptions;

let requirements = match loans_change {
// Requirements gathered from
// <https://docs.google.com/spreadsheets/d/1RJ5RLobAdumXUK7k_ugxy2eDAwI5akvtuqUM2Tyn5ts>
LoansChange::<T>::Loan(_, loan_mutation) => match loan_mutation {
LoanMutation::Maturity(_) => vec![week, blocked],
LoanMutation::MaturityExtension(_) => vec![],
LoanMutation::InterestPayments(_) => vec![week, blocked],
LoanMutation::PayDownSchedule(_) => vec![week, blocked],
LoanMutation::InterestRate(_) => vec![epoch],
LoanMutation::Internal(mutation) => match mutation {
InternalMutation::ValuationMethod(_) => vec![week, blocked],
InternalMutation::ProbabilityOfDefault(_) => vec![epoch],
InternalMutation::LossGivenDefault(_) => vec![epoch],
InternalMutation::DiscountRate(_) => vec![epoch],
},
},
LoansChange::<T>::Policy(_) => vec![week, blocked],
LoansChange::<T>::TransferDebt(_, _, _, _) => vec![],
};

PoolChangeProposal::new(requirements)
}
}

#[cfg(feature = "runtime-benchmarks")]
impl<T: pallet_loans::Config> From<RuntimeChange<T>> for PoolChangeProposal {
fn from(RuntimeChange::Loan(_): RuntimeChange<T>) -> Self {
// We dont add any requirement in case of benchmarking.
// We assume checking requirements in the pool is something very fast and
// deprecable in relation to reading from any storage.
// If tomorrow any requirement requires a lot of time,
// it should be precomputed in any pool stage, to make the requirement
// validation as fast as possible.
PoolChangeProposal::new([])
}
}

/// Used for building CfgChanges in pallet-loans
impl<T: pallet_loans::Config> From<LoansChange<T>> for RuntimeChange<T> {
fn from(loan_change: LoansChange<T>) -> RuntimeChange<T> {
RuntimeChange::Loan(loan_change)
}
}

/// Used for recovering LoanChange in pallet-loans
impl<T: pallet_loans::Config> TryInto<LoansChange<T>> for RuntimeChange<T> {
type Error = DispatchError;

fn try_into(self) -> Result<LoansChange<T>, DispatchError> {
let RuntimeChange::Loan(loan_change) = self;
Ok(loan_change)
}
}

pub mod fast {
use pallet_pool_system::pool_types::changes::Requirement;

use super::*;
const SECONDS_PER_WEEK: u32 = 60;

#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
pub struct RuntimeChange<T: pallet_loans::Config>(super::RuntimeChange<T>);

impl<T: pallet_loans::Config> From<RuntimeChange<T>> for PoolChangeProposal {
fn from(runtime_change: RuntimeChange<T>) -> Self {
PoolChangeProposal::new(
PoolChangeProposal::from(runtime_change.0)
.requirements()
.map(|req| match req {
Requirement::DelayTime(_) => Requirement::DelayTime(SECONDS_PER_WEEK),
req => req,
}),
)
}
}

/// Used for building CfgChanges in pallet-loans
impl<T: pallet_loans::Config> From<LoansChange<T>> for RuntimeChange<T> {
fn from(loan_change: LoansChange<T>) -> RuntimeChange<T> {
Self(loan_change.into())
}
}

/// Used for recovering LoanChange in pallet-loans
impl<T: pallet_loans::Config> TryInto<LoansChange<T>> for RuntimeChange<T> {
type Error = DispatchError;

fn try_into(self) -> Result<LoansChange<T>, DispatchError> {
self.0.try_into()
}
}
}
}

/// Module for investment portfolio common to all runtimes
pub mod investment_portfolios {
use cfg_primitives::{Balance, PoolId, TrancheId};
Expand Down
5 changes: 3 additions & 2 deletions runtime/development/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate};
use runtime_common::{
account_conversion::AccountConverter,
asset_registry,
changes::FastDelay,
fees::{DealWithFees, WeightToFee},
production_or_benchmark,
xcm::AccountIdToMultiLocation,
Expand Down Expand Up @@ -1071,7 +1072,7 @@ impl pallet_pool_system::Config for Runtime {
type PoolDeposit = PoolDeposit;
type PoolId = PoolId;
type Rate = Rate;
type RuntimeChange = runtime_common::changes::fast::RuntimeChange<Runtime>;
type RuntimeChange = runtime_common::changes::RuntimeChange<Runtime, FastDelay>;
type RuntimeEvent = RuntimeEvent;
type Time = Timestamp;
type Tokens = Tokens;
Expand Down Expand Up @@ -1385,7 +1386,7 @@ impl pallet_loans::Config for Runtime {
type PriceRegistry = PriceCollector;
type Quantity = Quantity;
type Rate = Rate;
type RuntimeChange = runtime_common::changes::fast::RuntimeChange<Runtime>;
type RuntimeChange = runtime_common::changes::RuntimeChange<Runtime, FastDelay>;
type RuntimeEvent = RuntimeEvent;
type Time = Timestamp;
type WeightInfo = weights::pallet_loans::WeightInfo<Self>;
Expand Down

0 comments on commit 6054e23

Please sign in to comment.