Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate lease deposits from reserves to named holds #1794

Closed
wants to merge 14 commits into from
12 changes: 6 additions & 6 deletions polkadot/runtime/common/src/assigned_slots/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,27 @@
use super::*;

use frame_benchmarking::v2::*;
use frame_support::assert_ok;
use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin};
use primitives::Id as ParaId;
use sp_runtime::traits::Bounded;

type CurrencyOf<T> = <<T as Config>::Leaser as Leaser<BlockNumberFor<T>>>::Currency;
type BalanceOf<T> = <<<T as Config>::Leaser as Leaser<BlockNumberFor<T>>>::Currency as Currency<
<T as frame_system::Config>::AccountId,
>>::Balance;
type BalanceOf<T> =
<<<T as Config>::Leaser as Leaser<BlockNumberFor<T>>>::Currency as FunInspect<
<T as frame_system::Config>::AccountId,
>>::Balance;
#[benchmarks(where T: Config)]
mod benchmarks {
use super::*;

use crate::assigned_slots::Pallet as AssignedSlots;
use frame_support::{assert_ok, traits::fungible::Mutate};

fn register_parachain<T: Config>(para_id: ParaId) {
let who: T::AccountId = whitelisted_caller();
let worst_validation_code = T::Registrar::worst_validation_code();
let worst_head_data = T::Registrar::worst_head_data();

CurrencyOf::<T>::make_free_balance_be(&who, BalanceOf::<T>::max_value());
CurrencyOf::<T>::set_balance(&who, BalanceOf::<T>::max_value());

assert_ok!(T::Registrar::register(
who,
Expand Down
15 changes: 9 additions & 6 deletions polkadot/runtime/common/src/assigned_slots/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::{
slots::{self, Pallet as Slots, WeightInfo as SlotsWeightInfo},
traits::{LeaseError, Leaser, Registrar},
};
use frame_support::{pallet_prelude::*, traits::Currency};
use frame_support::{pallet_prelude::*, traits::fungible::Inspect as FunInspect};
use frame_system::pallet_prelude::*;
pub use pallet::*;
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
Expand Down Expand Up @@ -98,9 +98,11 @@ impl WeightInfo for TestWeightInfo {
}
}

type BalanceOf<T> = <<<T as Config>::Leaser as Leaser<BlockNumberFor<T>>>::Currency as Currency<
<T as frame_system::Config>::AccountId,
>>::Balance;
type BalanceOf<T> =
<<<T as Config>::Leaser as Leaser<BlockNumberFor<T>>>::Currency as FunInspect<
<T as frame_system::Config>::AccountId,
>>::Balance;

type LeasePeriodOf<T> = <<T as Config>::Leaser as Leaser<BlockNumberFor<T>>>::LeasePeriod;

#[frame_support::pallet]
Expand Down Expand Up @@ -663,7 +665,7 @@ mod tests {
Configuration: parachains_configuration::{Pallet, Call, Storage, Config<T>},
ParasShared: parachains_shared::{Pallet, Call, Storage},
Parachains: parachains_paras::{Pallet, Call, Storage, Config<T>, Event},
Slots: slots::{Pallet, Call, Storage, Event<T>},
Slots: slots::{Pallet, Call, Storage, Event<T>, HoldReason},
AssignedSlots: assigned_slots::{Pallet, Call, Storage, Event<T>},
}
);
Expand Down Expand Up @@ -753,6 +755,7 @@ mod tests {
impl slots::Config for Test {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type RuntimeHoldReason = RuntimeHoldReason;
type Registrar = TestRegistrar<Test>;
type LeasePeriod = LeasePeriod;
type LeaseOffset = LeaseOffset;
Expand Down Expand Up @@ -781,7 +784,7 @@ mod tests {
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::<Test>::default().build_storage().unwrap();
pallet_balances::GenesisConfig::<Test> {
balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)],
balances: vec![(0, 5), (1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)],
}
.assimilate_storage(&mut t)
.unwrap();
Expand Down
19 changes: 13 additions & 6 deletions polkadot/runtime/common/src/auctions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::{
use frame_support::{
dispatch::DispatchResult,
ensure,
traits::{Currency, Get, Randomness, ReservableCurrency},
traits::{fungible::Inspect as FunInspect, Currency, Get, Randomness, ReservableCurrency},
weights::Weight,
};
use frame_system::pallet_prelude::BlockNumberFor;
Expand All @@ -35,10 +35,9 @@ use primitives::Id as ParaId;
use sp_runtime::traits::{CheckedSub, One, Saturating, Zero};
use sp_std::{mem::swap, prelude::*};

type CurrencyOf<T> = <<T as Config>::Leaser as Leaser<BlockNumberFor<T>>>::Currency;
type BalanceOf<T> = <<<T as Config>::Leaser as Leaser<BlockNumberFor<T>>>::Currency as Currency<
<T as frame_system::Config>::AccountId,
>>::Balance;
type CurrencyOf<T> = <T as Config>::Currency;
type BalanceOf<T> =
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;

pub trait WeightInfo {
fn new_auction() -> Weight;
Expand Down Expand Up @@ -98,6 +97,13 @@ pub mod pallet {
LeasePeriod = BlockNumberFor<Self>,
>;

type Currency: ReservableCurrency<
Self::AccountId,
Balance = <<Self::Leaser as Leaser<BlockNumberFor<Self>>>::Currency as FunInspect<
Self::AccountId,
>>::Balance,
>;

/// The parachain registrar type.
type Registrar: Registrar<AccountId = Self::AccountId>;

Expand Down Expand Up @@ -678,7 +684,7 @@ mod tests {
use ::test_helpers::{dummy_hash, dummy_head_data, dummy_validation_code};
use frame_support::{
assert_noop, assert_ok, assert_storage_noop, ord_parameter_types, parameter_types,
traits::{ConstU32, EitherOfDiverse, OnFinalize, OnInitialize},
traits::{ConstU32, Currency, EitherOfDiverse, OnFinalize, OnInitialize},
};
use frame_system::{EnsureRoot, EnsureSignedBy};
use pallet_balances;
Expand Down Expand Up @@ -873,6 +879,7 @@ mod tests {
impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type Leaser = TestLeaser;
type Currency = Balances;
type Registrar = TestRegistrar<Self>;
type EndingPeriod = EndingPeriod;
type SampleLength = SampleLength;
Expand Down
6 changes: 4 additions & 2 deletions polkadot/runtime/common/src/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ frame_support::construct_runtime!(
Registrar: paras_registrar::{Pallet, Call, Storage, Event<T>},
Auctions: auctions::{Pallet, Call, Storage, Event<T>},
Crowdloan: crowdloan::{Pallet, Call, Storage, Event<T>},
Slots: slots::{Pallet, Call, Storage, Event<T>},
Slots: slots::{Pallet, Call, Storage, Event<T>, HoldReason},
}
);

Expand Down Expand Up @@ -182,7 +182,7 @@ impl pallet_balances::Config for Test {
type ReserveIdentifier = [u8; 8];
type RuntimeHoldReason = RuntimeHoldReason;
type FreezeIdentifier = ();
type MaxHolds = ConstU32<0>;
type MaxHolds = ConstU32<1>;
type MaxFreezes = ConstU32<0>;
}

Expand Down Expand Up @@ -230,6 +230,7 @@ parameter_types! {
impl auctions::Config for Test {
type RuntimeEvent = RuntimeEvent;
type Leaser = Slots;
type Currency = Balances;
type Registrar = Registrar;
type EndingPeriod = EndingPeriod;
type SampleLength = SampleLength;
Expand All @@ -246,6 +247,7 @@ parameter_types! {
impl slots::Config for Test {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type RuntimeHoldReason = RuntimeHoldReason;
type Registrar = Registrar;
type LeasePeriod = LeasePeriod;
type LeaseOffset = LeaseOffset;
Expand Down
124 changes: 124 additions & 0 deletions polkadot/runtime/common/src/slots/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,132 @@

use super::*;
use crate::crowdloan;
use frame_support::traits::OnRuntimeUpgrade;
use sp_runtime::traits::AccountIdConversion;

#[cfg(feature = "try-runtime")]
use sp_runtime::TryRuntimeError;

/// The current storage version.
pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);

pub mod versioned {
use super::*;

/// Wrapper over `MigrateToV1` with convenience version checks.
///
/// This migration would move lease reserves into named holds.
pub type ToV1<T, OldCurrency> = frame_support::migrations::VersionedMigration<
0,
1,
v1::MigrateToV1<T, OldCurrency>,
Pallet<T>,
<T as frame_system::Config>::DbWeight,
>;
}

mod v1 {
use super::*;
use frame_support::traits::ReservableCurrency;
use sp_std::collections::btree_map::BTreeMap;

#[cfg(feature = "try-runtime")]
use frame_support::traits::fungible::InspectHold;

/// Balance type of OldCurrency.
pub type OldBalanceOf<T, OldCurrency> = <OldCurrency as frame_support::traits::Currency<
<T as frame_system::Config>::AccountId,
>>::Balance;

/// Alias to leases storage map with old currency.
#[frame_support::storage_alias]
pub type OldLeases<T: Config, OldCurrency> = StorageMap<
Pallet<T>,
Twox64Concat,
ParaId,
Vec<Option<(<T as frame_system::Config>::AccountId, OldBalanceOf<T, OldCurrency>)>>,
ValueQuery,
>;

/// This migration would move funds for lease from reserved to hold.
pub struct MigrateToV1<T, OldCurrency>(sp_std::marker::PhantomData<(T, OldCurrency)>);

impl<T, OldCurrency> OnRuntimeUpgrade for MigrateToV1<T, OldCurrency>
where
T: Config,
OldCurrency: ReservableCurrency<<T as frame_system::Config>::AccountId>,
BalanceOf<T>: From<OldCurrency::Balance>,
{
fn on_runtime_upgrade() -> Weight {
// useful for calculating weights later
let mut migrated = 0u64;
let mut leases_count = 0u64;

for (_, lease_periods) in OldLeases::<T, OldCurrency>::iter() {
leases_count += 1;
let mut deposit_held: BTreeMap<T::AccountId, OldBalanceOf<T, OldCurrency>> =
BTreeMap::new();

// go through each lease and find the lease deposit required for each leaser.
lease_periods.iter().for_each(|lease| {
if let Some((who, amount)) = lease {
deposit_held
.entry(who.clone())
.and_modify(|deposit| *deposit = *amount.max(deposit))
.or_insert(*amount);
}
});

deposit_held.iter().for_each(|(leaser, deposit)| {
OldCurrency::unreserve(leaser, *deposit);
let hold_result = Pallet::<T>::hold(leaser, BalanceOf::<T>::from(*deposit));
defensive_assert!(
hold_result.is_ok(),
"hold should not fail, since we just unreserved the same amount"
);
migrated += 1;
})
}

T::DbWeight::get().reads_writes(
// reads: leases_count
leases_count,
// writes = migrated * (unreserve + hold)
migrated.saturating_mul(2),
)
}

#[cfg(feature = "try-runtime")]
fn post_upgrade(_data: Vec<u8>) -> Result<(), TryRuntimeError> {
// Build a set of pairs of (para, who) that have a lease.
let mut para_leasers =
sp_std::collections::btree_set::BTreeSet::<(ParaId, T::AccountId)>::new();
for (para, lease_periods) in Leases::<T>::iter() {
lease_periods.into_iter().for_each(|maybe_lease| {
if let Some((who, _)) = maybe_lease {
para_leasers.insert((para, who));
}
});
}

// for each pair assert hold amount is what we expect
para_leasers.iter().try_for_each(|(para, who)| -> Result<(), TryRuntimeError> {
// fixme(ank4n) there is a case where an account has a hold for multiple para-ids..
let actual_hold =
T::Currency::balance_on_hold(&HoldReason::LeaseDeposit.into(), who);
let expected_hold = Pallet::<T>::deposit_held(*para, who);

ensure!(
actual_hold == expected_hold,
"ReservedAmount value not same as actual reserved balance"
);

Ok(())
})
}
}
}

/// Migrations for using fund index to create fund accounts instead of para ID.
pub mod slots_crowdloan_index_migration {
use super::*;
Expand Down
Loading
Loading