Skip to content

Commit

Permalink
Gov V1 removal: Add manual migration unlock_democracy_funds (#2651)
Browse files Browse the repository at this point in the history
* add manual migration unlock_democracy_funds extrinsic

* account for proof size and add LimitCannotBeZero error

* account for intermediate nodes, add upper limit and no fee charge

* add migration complete tracker

* fix merge (tests)

* cargo fmt

* fix fmt
  • Loading branch information
links234 authored Feb 21, 2024
1 parent d1684cf commit c150245
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 6 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pallets/moonbeam-lazy-migrations/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ scale-info = { workspace = true, features = ["derive"] }
sp-core = { workspace = true }
sp-io = { workspace = true }
sp-runtime = { workspace = true }
pallet-democracy = { workspace = true }
pallet-scheduler = { workspace = true }
sp-std = { workspace = true }

# Frontier
Expand Down
66 changes: 63 additions & 3 deletions pallets/moonbeam-lazy-migrations/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ pub use pallet::*;
pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;
use frame_support::traits::{LockIdentifier, LockableCurrency};
use frame_system::pallet_prelude::*;
use pallet_democracy::VotingOf;
use sp_core::H160;

pub const ARRAY_LIMIT: u32 = 1000;
Expand All @@ -47,6 +49,15 @@ pub mod pallet {
const MAX_LOCAL_ASSETS_STORAGE_ENTRY_SIZE: u64 =
(/* biggest key on moonbeam */136) + (/* biggest value on moonbeam */142);

/// Copied from pallet-democracy
const DEMOCRACY_ID: LockIdentifier = *b"democrac";
const MAX_DEMOCRACY_VOTINGOF_STORAGE_ENTRY_SIZE: u64 =
(/* biggest key on moonbeam */60) + (/* biggest value on moonbeam */1440);
const MAX_BALANCES_LOCKS_STORAGE_ENTRY_SIZE: u64 =
(/* biggest key on moonbeam */60) + (/* biggest value on moonbeam */26 * 3);
const MAX_UNLOCK_PROOF_PER_ACCOUNT: u64 =
MAX_BALANCES_LOCKS_STORAGE_ENTRY_SIZE + MAX_DEMOCRACY_VOTINGOF_STORAGE_ENTRY_SIZE;

/// Pallet for multi block migrations
#[pallet::pallet]
pub struct Pallet<T>(PhantomData<T>);
Expand All @@ -55,24 +66,32 @@ pub mod pallet {
/// If true, it means that LocalAssets storage has been removed.
pub(crate) type LocalAssetsMigrationCompleted<T: Config> = StorageValue<_, bool, ValueQuery>;

#[pallet::storage]
/// If true, it means that Democracy funds have been unlocked.
pub(crate) type DemocracyLocksMigrationCompleted<T: Config> = StorageValue<_, bool, ValueQuery>;

#[pallet::storage]
/// The total number of suicided contracts that were removed
pub(crate) type SuicidedContractsRemoved<T: Config> = StorageValue<_, u32, ValueQuery>;

/// Configuration trait of this pallet.
#[pallet::config]
pub trait Config: frame_system::Config + pallet_evm::Config {
pub trait Config: frame_system::Config + pallet_evm::Config + pallet_democracy::Config {
type WeightInfo: WeightInfo;
}

#[pallet::error]
pub enum Error<T> {
/// There are no more storage entries to be removed
AllStorageEntriesHaveBeenRemoved,
/// There must be at least one address
AddressesLengthCannotBeZero,
/// The limit cannot be zero
LimitCannotBeZero,
/// The limit for unlocking funds is too high
UnlockLimitTooHigh,
/// There are no more VotingOf entries to be removed and democracy funds to be unlocked
AllDemocracyFundsUnlocked,
/// There must be at least one address
AddressesLengthCannotBeZero,
/// The contract is not corrupted (Still exist or properly suicided)
ContractNotCorrupted,
}
Expand Down Expand Up @@ -183,5 +202,46 @@ pub mod pallet {
}
Ok(Pays::No.into())
}

// TODO(alexandru): This extrinsic should be removed once Gov V1 is removed.
// Note: We don't need to unreserve any funds, as they are assumed to be already
// unreserved prior to this operation and the proposal submission disabled.
#[pallet::call_index(2)]
#[pallet::weight(
Weight::from_parts(0,
INTERMEDIATES_NODES_SIZE + MAX_UNLOCK_PROOF_PER_ACCOUNT * <u64>::from(*limit))
.saturating_add(<T as frame_system::Config>::DbWeight::get()
.reads_writes((*limit + 1).into(), (*limit + 1).into()).saturating_mul(2))
)]
pub fn unlock_democracy_funds(
origin: OriginFor<T>,
limit: u32,
) -> DispatchResultWithPostInfo {
ensure_signed(origin)?;
ensure!(limit != 0, Error::<T>::LimitCannotBeZero);
ensure!(limit <= 50, Error::<T>::UnlockLimitTooHigh);

ensure!(
!DemocracyLocksMigrationCompleted::<T>::get(),
Error::<T>::AllDemocracyFundsUnlocked
);

// Unlock staked funds and remove the voting entry. This way we can keep track of what
// is left without extra cost.
let unlocked_accounts = VotingOf::<T>::iter()
.drain()
.take(limit as usize)
.map(|(account, _)| {
<T as pallet_democracy::Config>::Currency::remove_lock(DEMOCRACY_ID, &account)
})
.count() as u32;

if unlocked_accounts < limit {
DemocracyLocksMigrationCompleted::<T>::set(true);
}

log::info!("Unlocked {} accounts 🧹", unlocked_accounts);
Ok(Pays::No.into())
}
}
}
70 changes: 67 additions & 3 deletions pallets/moonbeam-lazy-migrations/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@
use super::*;
use crate as pallet_moonbeam_lazy_migrations;
use frame_support::{
construct_runtime, parameter_types,
traits::Everything,
construct_runtime, ord_parameter_types, parameter_types,
traits::{EqualPrivilegeOnly, Everything, SortedMembers},
weights::{constants::RocksDbWeight, Weight},
};
use frame_system::{EnsureRoot, EnsureSigned};
use pallet_evm::{AddressMapping, EnsureAddressTruncated};
use sp_core::{H160, H256, U256};
use sp_core::{ConstU32, H160, H256, U256};
use sp_runtime::{
traits::{BlakeTwo256, IdentityLookup},
AccountId32, BuildStorage, Perbill,
Expand All @@ -42,6 +43,8 @@ construct_runtime!(
Timestamp: pallet_timestamp,
EVM: pallet_evm,
LazyMigrations: pallet_moonbeam_lazy_migrations::{Pallet, Call},
Democracy: pallet_democracy::{Pallet, Call, Storage, Config<T>, Event<T>},
Scheduler: pallet_scheduler::{Pallet, Call, Storage, Event<T>},
}
);

Expand Down Expand Up @@ -98,6 +101,67 @@ impl pallet_balances::Config for Runtime {
type RuntimeFreezeReason = ();
}

impl pallet_scheduler::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type RuntimeOrigin = RuntimeOrigin;
type PalletsOrigin = OriginCaller;
type RuntimeCall = RuntimeCall;
type MaximumWeight = ();
type ScheduleOrigin = EnsureRoot<Self::AccountId>;
type MaxScheduledPerBlock = ConstU32<100>;
type WeightInfo = ();
type OriginPrivilegeCmp = EqualPrivilegeOnly;
type Preimages = ();
}

ord_parameter_types! {
pub const One: u64 = 1;
pub const Two: u64 = 2;
pub const Three: u64 = 3;
pub const Four: u64 = 4;
pub const Five: u64 = 5;
pub const Six: u64 = 6;
}
pub struct OneToFive;
impl SortedMembers<u64> for OneToFive {
fn sorted_members() -> Vec<u64> {
vec![1, 2, 3, 4, 5]
}
#[cfg(feature = "runtime-benchmarks")]
fn add(_m: &u64) {}
}
impl pallet_democracy::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Currency = pallet_balances::Pallet<Self>;
type EnactmentPeriod = ();
type LaunchPeriod = ();
type VotingPeriod = ();
type VoteLockingPeriod = ();
type FastTrackVotingPeriod = ();
type MinimumDeposit = ();
type MaxDeposits = ();
type MaxBlacklisted = ();
type SubmitOrigin = EnsureSigned<AccountId32>;
type ExternalOrigin = EnsureRoot<AccountId32>;
type ExternalMajorityOrigin = EnsureRoot<AccountId32>;
type ExternalDefaultOrigin = EnsureRoot<AccountId32>;
type FastTrackOrigin = EnsureRoot<AccountId32>;
type CancellationOrigin = EnsureRoot<AccountId32>;
type BlacklistOrigin = EnsureRoot<AccountId32>;
type CancelProposalOrigin = EnsureRoot<AccountId32>;
type VetoOrigin = EnsureSigned<AccountId32>;
type CooloffPeriod = ();
type Slash = ();
type InstantOrigin = EnsureRoot<AccountId32>;
type InstantAllowed = ();
type Scheduler = Scheduler;
type MaxVotes = ();
type PalletsOrigin = OriginCaller;
type WeightInfo = ();
type MaxProposals = ();
type Preimages = ();
}

parameter_types! {
pub const MinimumPeriod: u64 = 6000 / 2;
}
Expand Down

0 comments on commit c150245

Please sign in to comment.