pallet_storage_overlay_checks/
lib.rs1#![cfg_attr(not(feature = "std"), no_std)]
4
5#[cfg(not(feature = "std"))]
6extern crate alloc;
7
8use frame_system::pallet_prelude::BlockNumberFor;
9pub use pallet::*;
10use sp_core::H256;
11
12#[frame_support::pallet]
13mod pallet {
14 use crate::StorageParams;
15 use frame_support::pallet_prelude::*;
16 use frame_system::pallet_prelude::BlockNumberFor;
17 use sp_core::H256;
18 use sp_runtime::traits::Zero;
19
20 #[pallet::config]
21 pub trait Config: frame_system::Config {}
22
23 #[pallet::storage]
24 pub(super) type Svvq<T> = StorageValue<_, H256, ValueQuery>;
25
26 #[pallet::storage]
27 pub(super) type Svoq<T> = StorageValue<_, H256, OptionQuery>;
28
29 #[pallet::storage]
30 pub(super) type Smvq<T> = StorageMap<_, Identity, H256, H256, ValueQuery>;
31
32 #[pallet::storage]
33 pub(super) type Smoq<T> = StorageMap<_, Identity, H256, H256, OptionQuery>;
34
35 #[pallet::storage]
36 pub(super) type Sdmvq<T> =
37 StorageDoubleMap<_, Identity, H256, Identity, H256, H256, ValueQuery>;
38
39 #[pallet::storage]
40 pub(super) type Sdmoq<T> =
41 StorageDoubleMap<_, Identity, H256, Identity, H256, H256, OptionQuery>;
42
43 #[pallet::storage]
44 pub(super) type Snmvq<T> = StorageNMap<
45 _,
46 (
47 NMapKey<Identity, H256>,
48 NMapKey<Identity, H256>,
49 NMapKey<Identity, H256>,
50 ),
51 H256,
52 ValueQuery,
53 >;
54
55 #[pallet::storage]
56 pub(super) type Snmoq<T> = StorageNMap<
57 _,
58 (
59 NMapKey<Identity, H256>,
60 NMapKey<Identity, H256>,
61 NMapKey<Identity, H256>,
62 ),
63 H256,
64 OptionQuery,
65 >;
66
67 #[pallet::pallet]
68 #[pallet::without_storage_info]
69 pub struct Pallet<T>(_);
70
71 #[pallet::hooks]
72 impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
73 fn on_initialize(n: BlockNumberFor<T>) -> Weight {
74 let params = StorageParams::default();
77 if n % BlockNumberFor::<T>::from(2u32) == Zero::zero() {
78 Pallet::<T>::check_storage_exists(n, params);
79 Pallet::<T>::clear_storage(n);
80 } else {
81 Pallet::<T>::check_storage_empty(n, params);
82 Pallet::<T>::set_storage(n, params);
83 }
84
85 Weight::zero()
86 }
87
88 fn on_finalize(n: BlockNumberFor<T>) {
89 let params = StorageParams::default();
92 if n % BlockNumberFor::<T>::from(2u32) == Zero::zero() {
93 Pallet::<T>::check_storage_empty(n, params);
94 } else {
95 Pallet::<T>::check_storage_exists(n, params);
96 }
97 }
98 }
99}
100
101#[derive(Clone, Copy)]
102struct StorageParams {
103 key1: H256,
104 key2: H256,
105 key3: H256,
106 value: H256,
107}
108
109impl Default for StorageParams {
110 fn default() -> Self {
111 Self {
112 key1: H256::repeat_byte(1),
113 key2: H256::repeat_byte(2),
114 key3: H256::repeat_byte(3),
115 value: H256::repeat_byte(4),
116 }
117 }
118}
119
120impl<T: Config> Pallet<T> {
121 fn set_storage(n: BlockNumberFor<T>, params: StorageParams) {
122 log::debug!("Setting storages at: {:?}", n);
123 let StorageParams {
124 key1,
125 key2,
126 key3,
127 value,
128 } = params;
129
130 Svvq::<T>::set(value);
131 Svoq::<T>::set(Some(value));
132 Smvq::<T>::set(key1, value);
133 Smoq::<T>::set(key1, Some(value));
134 Sdmvq::<T>::set(key1, key2, value);
135 Sdmoq::<T>::set(key1, key2, Some(value));
136 Snmvq::<T>::set((key1, key2, key3), value);
137 Snmoq::<T>::set((key1, key2, key3), Some(value));
138 }
139
140 fn clear_storage(n: BlockNumberFor<T>) {
141 log::debug!("Clearing storages at: {:?}", n);
142 Svvq::<T>::kill();
143 Svoq::<T>::kill();
144 let _ = Smvq::<T>::clear(u32::MAX, None);
145 let _ = Smoq::<T>::clear(u32::MAX, None);
146 let _ = Sdmvq::<T>::clear(u32::MAX, None);
147 let _ = Sdmoq::<T>::clear(u32::MAX, None);
148 let _ = Snmvq::<T>::clear(u32::MAX, None);
149 let _ = Snmoq::<T>::clear(u32::MAX, None);
150 }
151
152 fn check_storage_exists(n: BlockNumberFor<T>, params: StorageParams) {
153 log::debug!("Checking storages exists at: {:?}", n);
154 let StorageParams {
155 key1,
156 key2,
157 key3,
158 value,
159 } = params;
160
161 assert_eq!(Svvq::<T>::get(), value);
162 assert_eq!(Svoq::<T>::get(), Some(value));
163 assert_eq!(Smvq::<T>::get(key1), value);
164 assert_eq!(Smoq::<T>::get(key1), Some(value));
165 assert_eq!(Sdmvq::<T>::get(key1, key2), value);
166 assert_eq!(Sdmoq::<T>::get(key1, key2), Some(value));
167 assert_eq!(Snmvq::<T>::get((key1, key2, key3)), value);
168 assert_eq!(Snmoq::<T>::get((key1, key2, key3)), Some(value));
169 }
170
171 fn check_storage_empty(n: BlockNumberFor<T>, params: StorageParams) {
172 log::debug!("Checking storages empty at: {:?}", n);
173 let StorageParams {
174 key1,
175 key2,
176 key3,
177 value: _,
178 } = params;
179
180 assert!(!Svvq::<T>::exists());
181
182 assert!(!Svoq::<T>::exists());
183 assert_eq!(Svoq::<T>::get(), None);
184
185 assert!(!Smvq::<T>::contains_key(key1));
186
187 assert!(!Smoq::<T>::contains_key(key1));
188 assert_eq!(Smoq::<T>::get(key1), None);
189
190 assert!(!Sdmvq::<T>::contains_key(key1, key2));
191
192 assert!(!Sdmoq::<T>::contains_key(key1, key2));
193 assert_eq!(Sdmoq::<T>::get(key1, key2), None);
194
195 assert!(!Snmvq::<T>::contains_key((key1, key2, key3)));
196
197 assert!(!Snmoq::<T>::contains_key((key1, key2, key3)));
198 assert_eq!(Snmoq::<T>::get((key1, key2, key3)), None);
199 }
200}