Skip to content

Commit

Permalink
add migration
Browse files Browse the repository at this point in the history
  • Loading branch information
lemunozm committed Feb 26, 2024
1 parent e52e958 commit 0dd088d
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 1 deletion.
59 changes: 59 additions & 0 deletions pallets/loans/src/entities/loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,3 +574,62 @@ impl<T: Config> TryFrom<(T::PoolId, ActiveLoan<T>)> for ActiveLoanInfo<T> {
})
}
}

/// Migration module that contains old loans types.
/// Can be removed once chains contains pallet-loans version v3
pub(crate) mod v2 {
use cfg_traits::Seconds;
use parity_scale_codec::Decode;

use crate::{
entities::pricing::{external::v2::ExternalActivePricing, internal::InternalActivePricing},
types::{LoanRestrictions, RepaidAmount, RepaymentSchedule},
AssetOf, Config,
};

#[derive(Decode)]
pub enum ActivePricing<T: Config> {
Internal(InternalActivePricing<T>),
External(ExternalActivePricing<T>),
}

#[derive(Decode)]
pub struct ActiveLoan<T: Config> {
pub schedule: RepaymentSchedule,
pub collateral: AssetOf<T>,
pub restrictions: LoanRestrictions,
pub borrower: T::AccountId,
pub write_off_percentage: T::Rate,
pub origination_date: Seconds,
pub pricing: ActivePricing<T>,
pub total_borrowed: T::Balance,
pub total_repaid: RepaidAmount<T::Balance>,
pub repayments_on_schedule_until: Seconds,
}

impl<T: Config> ActiveLoan<T> {
pub fn migrate(self) -> crate::entities::loans::ActiveLoan<T> {
crate::entities::loans::ActiveLoan {
schedule: self.schedule,
collateral: self.collateral,
restrictions: self.restrictions,
borrower: self.borrower,
write_off_percentage: self.write_off_percentage,
origination_date: self.origination_date,
pricing: match self.pricing {
ActivePricing::Internal(inner) => {
crate::entities::pricing::ActivePricing::Internal(inner)
}
ActivePricing::External(inner) => {
crate::entities::pricing::ActivePricing::External(
inner.migrate(self.origination_date),
)
}
},
total_borrowed: self.total_borrowed,
total_repaid: self.total_repaid,
repayments_on_schedule_until: self.repayments_on_schedule_until,
}
}
}
}
35 changes: 35 additions & 0 deletions pallets/loans/src/entities/pricing/external.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,3 +289,38 @@ impl<T: Config> ExternalActivePricing<T> {
Ok(())
}
}

/// Migration module that contains old loans types.
/// Can be removed once chains contains pallet-loans version v3
pub(crate) mod v2 {
use cfg_traits::Seconds;
use parity_scale_codec::Decode;

use crate::{
entities::{interest::ActiveInterestRate, pricing::external::ExternalPricing},
Config,
};

#[derive(Decode)]
pub struct ExternalActivePricing<T: Config> {
pub info: ExternalPricing<T>,
pub outstanding_quantity: T::Quantity,
pub interest: ActiveInterestRate<T>,
pub latest_settlement_price: T::Balance,
}

impl<T: Config> ExternalActivePricing<T> {
pub fn migrate(
self,
settlement_price_updated: Seconds,
) -> crate::entities::pricing::external::ExternalActivePricing<T> {
crate::entities::pricing::external::ExternalActivePricing {
info: self.info,
outstanding_quantity: self.outstanding_quantity,
interest: self.interest,
latest_settlement_price: self.latest_settlement_price,
settlement_price_updated,
}
}
}
}
11 changes: 10 additions & 1 deletion pallets/loans/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ mod tests;
#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;

mod migrations;

pub use pallet::*;
pub use weights::WeightInfo;

Expand Down Expand Up @@ -115,7 +117,7 @@ pub mod pallet {
pub type AssetOf<T> = (<T as Config>::CollectionId, <T as Config>::ItemId);
pub type PriceOf<T> = (<T as Config>::Balance, <T as Config>::Moment);

const STORAGE_VERSION: StorageVersion = StorageVersion::new(2);
const STORAGE_VERSION: StorageVersion = StorageVersion::new(3);

#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
Expand Down Expand Up @@ -433,6 +435,13 @@ pub mod pallet {
}
}

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_runtime_upgrade() -> frame_support::weights::Weight {
migrations::migrate_from_v2_to_v3::<T>()
}
}

#[pallet::call]
impl<T: Config> Pallet<T> {
/// Creates a new loan against the collateral provided
Expand Down
65 changes: 65 additions & 0 deletions pallets/loans/src/migrations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright 2024 Centrifuge Foundation (centrifuge.io).
//
// This file is part of the Centrifuge chain project.
// Centrifuge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version (see http://www.gnu.org/licenses).
// Centrifuge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

use frame_support::{
dispatch::GetStorageVersion, inherent::Vec, log, pallet_prelude::StorageVersion, traits::Get,
weights::Weight,
};

use crate::{ActiveLoans, Config, Pallet};

mod v2 {
use frame_support::{pallet_prelude::*, storage_alias};

use crate::{entities::loans::v2, Config, Pallet};

pub type ActiveLoansVec<T> = BoundedVec<
(<T as Config>::LoanId, v2::ActiveLoan<T>),
<T as Config>::MaxActiveLoansPerPool,
>;

#[storage_alias]
pub type ActiveLoans<T: Config> = StorageMap<
Pallet<T>,
Blake2_128Concat,
<T as Config>::PoolId,
ActiveLoansVec<T>,
ValueQuery,
>;
}

pub fn migrate_from_v2_to_v3<T: Config>() -> Weight {
if Pallet::<T>::on_chain_storage_version() == StorageVersion::new(2) {
log::info!("Loans: Starting migration v2 -> v3");

ActiveLoans::<T>::translate::<v2::ActiveLoansVec<T>, _>(|_, active_loans| {
Some(
active_loans
.into_iter()
.map(|(loan_id, active_loan)| (loan_id, active_loan.migrate()))
.collect::<Vec<_>>()
.try_into()
.expect("size doest not change, qed"),
)
});

Pallet::<T>::current_storage_version().put::<Pallet<T>>();

let count = ActiveLoans::<T>::iter().count() as u64;
log::info!("Loans: Migrated {} pools", count);
T::DbWeight::get().reads_writes(count + 1, count + 1)
} else {
// wrong storage version
log::info!("Loans: Migration did not execute. This probably should be removed");
T::DbWeight::get().reads_writes(1, 0)
}
}

0 comments on commit 0dd088d

Please sign in to comment.