diff --git a/pallets/gear-program/Cargo.toml b/pallets/gear-program/Cargo.toml index c9f62a92c6d..3946f0b00e5 100644 --- a/pallets/gear-program/Cargo.toml +++ b/pallets/gear-program/Cargo.toml @@ -31,7 +31,7 @@ sp-std.workspace = true sp-io.workspace = true sp-runtime.workspace = true -# Temporary dependencies required for migration to v7. To be removed upon migration. +# Temporary dependencies required for migration to v8. To be removed upon migration. pallet-balances.workspace = true pallet-treasury.workspace = true diff --git a/pallets/gear-program/src/migrations/v8.rs b/pallets/gear-program/src/migrations/ed_locks.rs similarity index 80% rename from pallets/gear-program/src/migrations/v8.rs rename to pallets/gear-program/src/migrations/ed_locks.rs index 1b146bb5858..b2281a36830 100644 --- a/pallets/gear-program/src/migrations/v8.rs +++ b/pallets/gear-program/src/migrations/ed_locks.rs @@ -19,7 +19,10 @@ use crate::{Config, Pallet, ProgramStorage}; use common::Origin; use frame_support::{ - traits::{tokens::Pay, Currency, Get, GetStorageVersion, OnRuntimeUpgrade, StorageVersion}, + traits::{ + tokens::Pay, Currency, Get, GetStorageVersion, LockableCurrency, OnRuntimeUpgrade, + StorageVersion, WithdrawReasons, + }, weights::Weight, }; use gear_core::program::Program; @@ -44,22 +47,32 @@ const MIGRATE_FROM_VERSION: u16 = 7; const MIGRATE_TO_VERSION: u16 = 8; const ALLOWED_CURRENT_STORAGE_VERSION: u16 = 9; +// Redefine this constant from the `pallet_gear` crate to avoid a cyclic dependency. +const EXISTENTIAL_DEPOSIT_LOCK_ID: [u8; 8] = *b"glock/ed"; + pub(crate) type AccountIdOf = ::AccountId; pub(crate) type CurrencyOf = ::Currency; pub(crate) type BalanceOf = as Currency>>::Balance; -pub struct MigrateToV8(PhantomData); +pub struct SetLocksOnED(PhantomData); -impl OnRuntimeUpgrade for MigrateToV8 +impl OnRuntimeUpgrade for SetLocksOnED where T: pallet_treasury::Config + pallet_balances::Config, T::AccountId: Origin, T::Paymaster: Pay>, + CurrencyOf: LockableCurrency, { fn on_runtime_upgrade() -> Weight { let onchain = Pallet::::on_chain_storage_version(); let existential_deposit = CurrencyOf::::minimum_balance(); - let transfer_weight = ::WeightInfo::transfer_allow_death(); + // Benchmarked value + let set_lock_weight = Weight::from_parts(12_000_000, 4764) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)); + let single_migration_weight = + ::WeightInfo::transfer_allow_death() + .saturating_add(set_lock_weight); // 1 read for on chain storage version let mut weight = T::DbWeight::get().reads(1); @@ -98,7 +111,16 @@ where ); } }; - weight = weight.saturating_add(transfer_weight); + + // Set the lock for the program's account + CurrencyOf::::set_lock( + EXISTENTIAL_DEPOSIT_LOCK_ID, + &program_id.cast(), + existential_deposit, + WithdrawReasons::all(), + ); + + weight = weight.saturating_add(single_migration_weight); }; }); @@ -121,7 +143,7 @@ where let current = Pallet::::current_storage_version(); let onchain = Pallet::::on_chain_storage_version(); - log::debug!("[MigrateToV8::pre_upgrade] current: {current:?}, onchain: {onchain:?}"); + log::debug!("[SetLocksOnED::pre_upgrade] current: {current:?}, onchain: {onchain:?}"); let res = if onchain == MIGRATE_FROM_VERSION { ensure!( current == ALLOWED_CURRENT_STORAGE_VERSION, @@ -158,11 +180,26 @@ where .map_err(|_| "`pre_upgrade` provided an invalid state")? { log::debug!( - "[MigrateToV8::post_upgrade] old_sum: {old_sum:?}, old_count: {old_count:?}" + "[SetLocksOnED::post_upgrade] old_sum: {old_sum:?}, old_count: {old_count:?}" ); let (new_sum, new_count) = ProgramStorage::::iter() .filter_map(|(program_id, program)| match program { - Program::Active(_p) => Some(Balances::::free_balance(&program_id.cast())), + Program::Active(_p) => { + let locks = Balances::::locks::(program_id.cast()) + .into_iter() + .filter_map(|l| { + if l.id == EXISTENTIAL_DEPOSIT_LOCK_ID { + Some(l) + } else { + None + } + }) + .collect::>(); + assert_eq!(locks.len(), 1); // only one lock should have been set + assert_eq!(locks[0].amount, ed.unique_saturated_into()); + + Some(Balances::::free_balance(&program_id.cast())) + } _ => None, }) .fold((0_u128, 0_u64), |(sum, count), balance| { @@ -172,7 +209,7 @@ where ) }); log::debug!( - "[MigrateToV8::post_upgrade] new_sum: {new_sum:?}, new_count: {new_count:?}" + "[SetLocksOnED::post_upgrade] new_sum: {new_sum:?}, new_count: {new_count:?}" ); ensure!( new_count == old_count, @@ -210,7 +247,7 @@ mod tests { // Mint enough funds to the treasury account let _ = CurrencyOf::::deposit_creating(&treasury_account, 1000 * UNITS); - const NUM_ACTIVE_PROGRAMS: u64 = 690; // Close to actual number of programs in the Runtime + const NUM_ACTIVE_PROGRAMS: u64 = 700; // Close to actual number of programs in the Runtime const NUM_EXITED_PROGRAMS: u64 = 50; const NUM_TERMINATED_PROGRAMS: u64 = 30; @@ -255,11 +292,11 @@ mod tests { let treasury_balance = CurrencyOf::::free_balance(treasury_account); // Run the migration - let state = MigrateToV8::::pre_upgrade().unwrap(); - let weight = MigrateToV8::::on_runtime_upgrade(); + let state = SetLocksOnED::::pre_upgrade().unwrap(); + let weight = SetLocksOnED::::on_runtime_upgrade(); println!("Weight: {:?}", weight); assert!(!weight.is_zero()); - MigrateToV8::::post_upgrade(state).unwrap(); + SetLocksOnED::::post_upgrade(state).unwrap(); // Check that balances of the active programs add up let ed = CurrencyOf::::minimum_balance(); diff --git a/pallets/gear-program/src/migrations/mod.rs b/pallets/gear-program/src/migrations/mod.rs index 4e84b299344..8f4ce9964d1 100644 --- a/pallets/gear-program/src/migrations/mod.rs +++ b/pallets/gear-program/src/migrations/mod.rs @@ -18,5 +18,5 @@ pub mod add_section_sizes; pub mod allocations; +pub mod ed_locks; pub mod paused_storage; -pub mod v8; diff --git a/runtime/vara/src/migrations.rs b/runtime/vara/src/migrations.rs index 42ddef4a44b..8cf4d6afc5b 100644 --- a/runtime/vara/src/migrations.rs +++ b/runtime/vara/src/migrations.rs @@ -24,7 +24,7 @@ pub type Migrations = ( pallet_gear_program::migrations::allocations::MigrateAllocations, // migration for removed paused program storage pallet_gear_program::migrations::paused_storage::RemovePausedProgramStorageMigration, - pallet_gear_program::migrations::v8::MigrateToV8, + pallet_gear_program::migrations::ed_locks::SetLocksOnED, // migration for added section sizes pallet_gear_program::migrations::add_section_sizes::AddSectionSizesMigration, // substrate v1.4.0