Skip to content

Commit 783f62f

Browse files
committedMar 25, 2025
Vesting pallet block number provider migration
1 parent ff5663f commit 783f62f

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed
 

‎runtimes/polimec/src/custom_migrations/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@
1919

2020
pub mod asset_id_migration;
2121
pub mod linear_release;
22+
pub mod vesting;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
use alloc::vec::Vec;
2+
use frame_support::{traits::Currency, BoundedVec};
3+
use frame_system::pallet_prelude::BlockNumberFor;
4+
use pallet_vesting::{MaxVestingSchedulesGet, VestingInfo};
5+
6+
#[cfg(feature = "try-runtime")]
7+
use parity_scale_codec::{Decode, Encode};
8+
#[cfg(feature = "try-runtime")]
9+
use sp_runtime::DispatchError;
10+
11+
type VestingInfoOf<T> = VestingInfo<
12+
<<T as pallet_vesting::Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance,
13+
BlockNumberFor<T>,
14+
>;
15+
pub type Values<T> = BoundedVec<VestingInfoOf<T>, MaxVestingSchedulesGet<T>>;
16+
17+
pub mod v1 {
18+
use super::*;
19+
use core::marker::PhantomData;
20+
use frame_support::traits::OnRuntimeUpgrade;
21+
use frame_system::pallet_prelude::BlockNumberFor;
22+
use parachains_common::impls::AccountIdOf;
23+
use sp_core::Get;
24+
use sp_runtime::{traits::BlockNumberProvider, Saturating, Weight};
25+
26+
const LOG: &str = "linear_release::migration::v1";
27+
28+
pub struct UncheckedMigrationToV1<T: pallet_vesting::Config + cumulus_pallet_parachain_system::Config>(
29+
PhantomData<T>,
30+
);
31+
32+
impl<T: pallet_vesting::Config + cumulus_pallet_parachain_system::Config> OnRuntimeUpgrade
33+
for UncheckedMigrationToV1<T>
34+
{
35+
#[cfg(feature = "try-runtime")]
36+
fn pre_upgrade() -> Result<Vec<u8>, DispatchError> {
37+
let migration_count = pallet_vesting::Vesting::<T>::iter().count() as u32;
38+
log::info!(target: LOG, "Pre-upgrade: {} UserMigrations entries", migration_count);
39+
40+
let vestings = pallet_vesting::Vesting::<T>::iter().collect::<Vec<_>>();
41+
42+
Ok((migration_count, vestings).encode())
43+
}
44+
45+
fn on_runtime_upgrade() -> Weight {
46+
let mut items = 0u64;
47+
let translate_vesting_info = |_: AccountIdOf<T>, vesting_info: Values<T>| -> Option<Values<T>> {
48+
let migrated: Vec<_> = vesting_info
49+
.iter()
50+
.map(|vesting| {
51+
items = items.saturating_add(1);
52+
53+
// adjust starting block to relay chain block number
54+
let relay_chain_now: BlockNumberFor<T> = T::BlockNumberProvider::current_block_number()
55+
.try_into()
56+
.ok()
57+
.expect("BlockNumber conversion failed");
58+
59+
let polimec_now = frame_system::Pallet::<T>::current_block_number();
60+
let blocks_passed = polimec_now.saturating_sub(vesting.starting_block());
61+
let relay_chain_starting_block = relay_chain_now.saturating_sub(
62+
blocks_passed.saturating_mul(2_u32.try_into().ok().expect("safe to convert; qed")),
63+
);
64+
65+
let adjusted_per_block =
66+
vesting.per_block().saturating_mul(2_u32.try_into().ok().expect("safe to convert; qed"));
67+
68+
VestingInfo::new(vesting.locked(), adjusted_per_block, relay_chain_starting_block)
69+
})
70+
.collect();
71+
72+
Values::<T>::try_from(migrated).ok()
73+
};
74+
75+
log::info!(target: LOG, "Starting vesting time migration to V1");
76+
77+
pallet_vesting::Vesting::<T>::translate(translate_vesting_info);
78+
79+
log::info!(target: LOG, "Migrated {} vesting entries", items);
80+
81+
T::DbWeight::get().reads_writes(items, items)
82+
}
83+
84+
#[cfg(feature = "try-runtime")]
85+
fn post_upgrade(pre_state: Vec<u8>) -> Result<(), DispatchError> {
86+
let (pre_migration_count, pre_vestings): (u32, Vec<(AccountIdOf<T>, Values<T>)>) =
87+
Decode::decode(&mut &pre_state[..]).expect("Failed to decode pre-migration state");
88+
89+
let post_migration_count = pallet_vesting::Vesting::<T>::iter().count() as u32;
90+
91+
if pre_migration_count != post_migration_count {
92+
return Err("Migration count mismatch".into());
93+
}
94+
95+
for (account, pre_vesting) in pre_vestings {
96+
let post_vesting = pallet_vesting::Vesting::<T>::get(&account).unwrap_or_default();
97+
98+
// check that the starting block has been adjusted
99+
let relay_chain_now = T::BlockNumberProvider::current_block_number();
100+
101+
for (pre_vesting_info, post_vesting_info) in pre_vesting.iter().zip(post_vesting.iter()) {
102+
assert_ne!(
103+
pre_vesting_info.starting_block(),
104+
post_vesting_info.starting_block(),
105+
"Starting block not adjusted"
106+
);
107+
assert!(
108+
post_vesting_info.starting_block() <=
109+
relay_chain_now.try_into().ok().expect("safe to convert; qed"),
110+
"Starting block not adjusted correctly"
111+
);
112+
113+
assert!(
114+
post_vesting_info.per_block() ==
115+
pre_vesting_info
116+
.per_block()
117+
.saturating_mul(2_u32.try_into().ok().expect("safe to convert; qed")),
118+
"Per block not adjusted"
119+
);
120+
}
121+
}
122+
123+
Ok(())
124+
}
125+
}
126+
}

‎runtimes/polimec/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ pub mod migrations {
193193
RemovePallet<IdentityPalletName, RuntimeDbWeight>,
194194
pallet_funding::migrations::vesting_info::v7::MigrationToV8<Runtime>,
195195
super::custom_migrations::linear_release::v1::LinearReleaseVestingMigrationV1<Runtime>,
196+
super::custom_migrations::vesting::v1::UncheckedMigrationToV1<Runtime>,
196197
);
197198
}
198199

0 commit comments

Comments
 (0)