pallet_bags_list/
migrations.rs1use codec::{Decode, Encode};
21use core::marker::PhantomData;
22use frame_election_provider_support::ScoreProvider;
23use frame_support::traits::OnRuntimeUpgrade;
24
25#[cfg(feature = "try-runtime")]
26use frame_support::ensure;
27#[cfg(feature = "try-runtime")]
28use sp_runtime::TryRuntimeError;
29
30#[cfg(feature = "try-runtime")]
31use alloc::vec::Vec;
32
33pub struct CheckCounterPrefix<T: crate::Config<I>, I: 'static>(core::marker::PhantomData<(T, I)>);
35impl<T: crate::Config<I>, I: 'static> OnRuntimeUpgrade for CheckCounterPrefix<T, I> {
36 fn on_runtime_upgrade() -> frame_support::weights::Weight {
37 frame_support::weights::Weight::zero()
38 }
39
40 #[cfg(feature = "try-runtime")]
41 fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError> {
42 #[frame_support::storage_alias]
44 type CounterForListNodes<T: crate::Config<I>, I: 'static> =
45 StorageValue<crate::Pallet<T, I>, u32>;
46
47 ensure!(
49 crate::ListNodes::<T, I>::count() == CounterForListNodes::<T, I>::get().unwrap(),
50 "wrong list node counter"
51 );
52
53 crate::log!(
54 info,
55 "checked bags-list prefix to be correct and have {} nodes",
56 crate::ListNodes::<T, I>::count()
57 );
58
59 Ok(Vec::new())
60 }
61}
62
63mod old {
64 use super::*;
65 use frame_support::pallet_prelude::*;
66
67 #[derive(Encode, Decode)]
68 pub struct PreScoreNode<T: crate::Config<I>, I: 'static = ()> {
69 pub id: T::AccountId,
70 pub prev: Option<T::AccountId>,
71 pub next: Option<T::AccountId>,
72 pub bag_upper: T::Score,
73 #[codec(skip)]
74 pub _phantom: PhantomData<I>,
75 }
76
77 #[frame_support::storage_alias]
78 pub type ListNodes<T: crate::Config<I>, I: 'static> = StorageMap<
79 crate::Pallet<T, I>,
80 Twox64Concat,
81 <T as frame_system::Config>::AccountId,
82 PreScoreNode<T, I>,
83 >;
84
85 #[frame_support::storage_alias]
86 pub type CounterForListNodes<T: crate::Config<I>, I: 'static> =
87 StorageValue<crate::Pallet<T, I>, u32, ValueQuery>;
88}
89
90pub struct AddScore<T: crate::Config<I>, I: 'static = ()>(core::marker::PhantomData<(T, I)>);
92impl<T: crate::Config<I>, I: 'static> OnRuntimeUpgrade for AddScore<T, I> {
93 #[cfg(feature = "try-runtime")]
94 fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError> {
95 ensure!(crate::ListNodes::<T, I>::iter().count() == 0, "list node data is not corrupt");
97 let iter_node_count: u32 = old::ListNodes::<T, I>::iter().count() as u32;
99 let tracked_node_count: u32 = old::CounterForListNodes::<T, I>::get();
100 crate::log!(info, "number of nodes before: {:?} {:?}", iter_node_count, tracked_node_count);
101 ensure!(iter_node_count == tracked_node_count, "Node count is wrong.");
102 Ok(iter_node_count.encode())
103 }
104
105 fn on_runtime_upgrade() -> frame_support::weights::Weight {
106 for (_key, node) in old::ListNodes::<T, I>::iter() {
107 let score = T::ScoreProvider::score(&node.id);
108
109 let new_node = crate::Node {
110 id: node.id.clone(),
111 prev: node.prev,
112 next: node.next,
113 bag_upper: node.bag_upper,
114 score: score.unwrap_or_default(),
115 _phantom: node._phantom,
116 };
117
118 crate::ListNodes::<T, I>::insert(node.id, new_node);
119 }
120
121 return frame_support::weights::Weight::MAX
122 }
123
124 #[cfg(feature = "try-runtime")]
125 fn post_upgrade(node_count_before: Vec<u8>) -> Result<(), TryRuntimeError> {
126 let node_count_before: u32 = Decode::decode(&mut node_count_before.as_slice())
127 .expect("the state parameter should be something that was generated by pre_upgrade");
128 let iter_node_count_after: u32 = crate::ListNodes::<T, I>::iter().count() as u32;
130 let tracked_node_count_after: u32 = crate::ListNodes::<T, I>::count();
131 crate::log!(
132 info,
133 "number of nodes after: {:?} {:?}",
134 iter_node_count_after,
135 tracked_node_count_after,
136 );
137 ensure!(iter_node_count_after == node_count_before, "Not all nodes were migrated.");
138 ensure!(tracked_node_count_after == iter_node_count_after, "Node count is wrong.");
139 Ok(())
140 }
141}