Skip to content

Commit e8626a6

Browse files
Add migrate_fee_rate migration.
1 parent 5648f93 commit e8626a6

File tree

7 files changed

+122
-1
lines changed

7 files changed

+122
-1
lines changed

pallets/swap/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub use pallet::*;
1212
#[cfg(feature = "runtime-benchmarks")]
1313
pub mod benchmarking;
1414

15+
mod migrations;
1516
#[cfg(test)]
1617
pub(crate) mod mock;
1718

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use crate::HasMigrationRun;
2+
use crate::{Config, pallet};
3+
use frame_support::traits::Get;
4+
use frame_support::weights::Weight;
5+
use scale_info::prelude::string::String;
6+
use sp_std::collections::btree_map::BTreeMap;
7+
8+
pub const MAX_FEE_RATE: u16 = 1310; // 2 %
9+
10+
pub fn migrate_fee_rate<T: Config>() -> Weight {
11+
let migration_name = b"migrate_fee_rate".to_vec();
12+
13+
// Initialize the weight with one read operation.
14+
let mut weight = T::DbWeight::get().reads(1);
15+
16+
// Check if the migration has already run
17+
if HasMigrationRun::<T>::get(&migration_name) {
18+
log::info!(
19+
"Migration '{:?}' has already run. Skipping.",
20+
String::from_utf8_lossy(&migration_name)
21+
);
22+
return weight;
23+
}
24+
log::info!(
25+
"Running migration '{}'",
26+
String::from_utf8_lossy(&migration_name)
27+
);
28+
29+
let keypairs = pallet::FeeRate::<T>::iter().collect::<BTreeMap<_, _>>();
30+
weight = weight.saturating_add(T::DbWeight::get().reads(keypairs.len() as u64));
31+
32+
for (netuid, rate) in keypairs {
33+
if rate > MAX_FEE_RATE {
34+
pallet::FeeRate::<T>::mutate(netuid, |rate| *rate = MAX_FEE_RATE);
35+
weight = weight.saturating_add(T::DbWeight::get().writes(1));
36+
}
37+
}
38+
39+
// Mark the migration as completed
40+
HasMigrationRun::<T>::insert(&migration_name, true);
41+
weight = weight.saturating_add(T::DbWeight::get().writes(1));
42+
43+
log::info!(
44+
"Migration '{:?}' completed.",
45+
String::from_utf8_lossy(&migration_name)
46+
);
47+
48+
weight
49+
}

pallets/swap/src/migrations/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub(crate) mod fee_rate_migration;

pallets/swap/src/mock.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use core::num::NonZeroU64;
44

55
use frame_support::construct_runtime;
66
use frame_support::pallet_prelude::*;
7+
use frame_support::weights::constants::RocksDbWeight;
78
use frame_support::{
89
PalletId, parameter_types,
910
traits::{ConstU32, Everything},
@@ -50,7 +51,7 @@ impl system::Config for Test {
5051
type BaseCallFilter = Everything;
5152
type BlockWeights = ();
5253
type BlockLength = ();
53-
type DbWeight = ();
54+
type DbWeight = RocksDbWeight;
5455
type RuntimeOrigin = RuntimeOrigin;
5556
type RuntimeCall = RuntimeCall;
5657
type Hash = H256;

pallets/swap/src/pallet/hooks.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use frame_support::pallet_macros::pallet_section;
2+
3+
/// A [`pallet_section`] that defines the events for a pallet.
4+
/// This can later be imported into the pallet using [`import_section`].
5+
#[pallet_section]
6+
mod hooks {
7+
// ================
8+
// ==== Hooks =====
9+
// ================
10+
#[pallet::hooks]
11+
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
12+
fn on_runtime_upgrade() -> frame_support::weights::Weight {
13+
migrations::fee_rate_migration::migrate_fee_rate::<T>()
14+
}
15+
}
16+
}

pallets/swap/src/pallet/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,22 @@ use crate::{
1616

1717
pub use pallet::*;
1818

19+
mod hooks;
1920
mod impls;
2021
mod swap_step;
2122
#[cfg(test)]
2223
mod tests;
2324

25+
use crate::migrations;
26+
27+
#[import_section(hooks::hooks)]
2428
#[allow(clippy::module_inception)]
2529
#[frame_support::pallet]
2630
#[allow(clippy::expect_used)]
2731
mod pallet {
2832
use super::*;
2933
use frame_system::{ensure_root, ensure_signed};
34+
use sp_std::vec::Vec;
3035

3136
#[pallet::pallet]
3237
pub struct Pallet<T>(_);
@@ -78,6 +83,11 @@ mod pallet {
7883
33 // ~0.05 %
7984
}
8085

86+
/// Storage for migration run status
87+
#[pallet::storage]
88+
#[pallet::unbounded]
89+
pub type HasMigrationRun<T: Config> = StorageMap<_, Identity, Vec<u8>, bool, ValueQuery>;
90+
8191
/// The fee rate applied to swaps per subnet, normalized value between 0 and u16::MAX
8292
#[pallet::storage]
8393
pub type FeeRate<T> = StorageMap<_, Twox64Concat, NetUid, u16, ValueQuery, DefaultFeeRate>;

pallets/swap/src/pallet/tests.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use subtensor_runtime_common::NetUid;
1414
use subtensor_swap_interface::Order as OrderT;
1515

1616
use super::*;
17+
use crate::migrations::fee_rate_migration::MAX_FEE_RATE;
1718
use crate::pallet::swap_step::*;
1819
use crate::{SqrtPrice, mock::*};
1920

@@ -2913,3 +2914,45 @@ fn adjust_protocol_liquidity_uses_and_sets_scrap_reservoirs() {
29132914
);
29142915
});
29152916
}
2917+
2918+
#[test]
2919+
fn test_migrate_fee_rate() {
2920+
new_test_ext().execute_with(|| {
2921+
let migration_name = b"migrate_fee_rate".to_vec();
2922+
2923+
assert!(
2924+
!HasMigrationRun::<Test>::get(migration_name.clone()),
2925+
"HasMigrationRun should be false before migration"
2926+
);
2927+
2928+
let netuid1 = NetUid::from(1);
2929+
let netuid2 = NetUid::from(2);
2930+
let value1 = 1000u16;
2931+
let value2 = 2000u16;
2932+
2933+
FeeRate::<Test>::insert(netuid1, value1);
2934+
FeeRate::<Test>::insert(netuid2, value2);
2935+
2936+
// run migration
2937+
let weight = migrations::fee_rate_migration::migrate_fee_rate::<Test>();
2938+
assert!(!weight.is_zero(), "migration weight should be > 0");
2939+
2940+
// check results
2941+
2942+
assert_eq!(FeeRate::<Test>::get(netuid1), value1);
2943+
assert_eq!(FeeRate::<Test>::get(netuid2), MAX_FEE_RATE);
2944+
2945+
// running the migration again should do nothing
2946+
FeeRate::<Test>::insert(netuid1, value1);
2947+
FeeRate::<Test>::insert(netuid2, value2);
2948+
2949+
let _weight2 = migrations::fee_rate_migration::migrate_fee_rate::<Test>();
2950+
2951+
assert!(
2952+
HasMigrationRun::<Test>::get(migration_name.clone()),
2953+
"HasMigrationRun remains true on second run"
2954+
);
2955+
assert_eq!(FeeRate::<Test>::get(netuid1), value1);
2956+
assert_eq!(FeeRate::<Test>::get(netuid2), value2);
2957+
});
2958+
}

0 commit comments

Comments
 (0)