pallet_storage_overlay_checks/
lib.rs

1//! Test pallet to check the overlay changes during the block execution and post block execution.
2
3#![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            // even blocks, storages must be set already and are emptied
75            // odd block, storages must be empty and are set
76            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            // even blocks, storages must be emptied during initialize
90            // odd block, storages must be set during initialize
91            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}