1use crate::{
19 hash::{ReversibleStorageHasher, StorageHasher},
20 storage::{self, storage_prefix, unhashed, KeyPrefixIterator, PrefixIterator, StorageAppend},
21 Never,
22};
23use alloc::vec::Vec;
24use codec::{Decode, Encode, EncodeLike, FullCodec, FullEncode};
25
26pub trait StorageMap<K: FullEncode, V: FullCodec> {
38 type Query;
40
41 type Hasher: StorageHasher;
43
44 fn pallet_prefix() -> &'static [u8];
46
47 fn storage_prefix() -> &'static [u8];
49
50 fn prefix_hash() -> [u8; 32];
53
54 fn from_optional_value_to_query(v: Option<V>) -> Self::Query;
56
57 fn from_query_to_optional_value(v: Self::Query) -> Option<V>;
59
60 fn storage_map_final_key<KeyArg>(key: KeyArg) -> Vec<u8>
62 where
63 KeyArg: EncodeLike<K>,
64 {
65 let storage_prefix = storage_prefix(Self::pallet_prefix(), Self::storage_prefix());
66 let key_hashed = key.using_encoded(Self::Hasher::hash);
67
68 let mut final_key = Vec::with_capacity(storage_prefix.len() + key_hashed.as_ref().len());
69
70 final_key.extend_from_slice(&storage_prefix);
71 final_key.extend_from_slice(key_hashed.as_ref());
72
73 final_key
74 }
75}
76
77impl<K: FullCodec, V: FullCodec, G: StorageMap<K, V>> storage::IterableStorageMap<K, V> for G
78where
79 G::Hasher: ReversibleStorageHasher,
80{
81 type Iterator = PrefixIterator<(K, V)>;
82 type KeyIterator = KeyPrefixIterator<K>;
83
84 fn iter() -> Self::Iterator {
86 let prefix = G::prefix_hash().to_vec();
87 PrefixIterator {
88 prefix: prefix.clone(),
89 previous_key: prefix,
90 drain: false,
91 closure: |raw_key_without_prefix, mut raw_value| {
92 let mut key_material = G::Hasher::reverse(raw_key_without_prefix);
93 Ok((K::decode(&mut key_material)?, V::decode(&mut raw_value)?))
94 },
95 phantom: Default::default(),
96 }
97 }
98
99 fn iter_from(starting_raw_key: Vec<u8>) -> Self::Iterator {
101 let mut iter = Self::iter();
102 iter.set_last_raw_key(starting_raw_key);
103 iter
104 }
105
106 fn iter_keys() -> Self::KeyIterator {
108 let prefix = G::prefix_hash().to_vec();
109 KeyPrefixIterator {
110 prefix: prefix.clone(),
111 previous_key: prefix,
112 drain: false,
113 closure: |raw_key_without_prefix| {
114 let mut key_material = G::Hasher::reverse(raw_key_without_prefix);
115 K::decode(&mut key_material)
116 },
117 }
118 }
119
120 fn iter_keys_from(starting_raw_key: Vec<u8>) -> Self::KeyIterator {
122 let mut iter = Self::iter_keys();
123 iter.set_last_raw_key(starting_raw_key);
124 iter
125 }
126
127 fn drain() -> Self::Iterator {
129 let mut iterator = Self::iter();
130 iterator.drain = true;
131 iterator
132 }
133
134 fn translate<O: Decode, F: FnMut(K, O) -> Option<V>>(mut f: F) {
135 let mut previous_key = None;
136 loop {
137 previous_key = Self::translate_next(previous_key, &mut f);
138 if previous_key.is_none() {
139 break;
140 }
141 }
142 }
143
144 fn translate_next<O: Decode, F: FnMut(K, O) -> Option<V>>(
145 previous_key: Option<Vec<u8>>,
146 mut f: F,
147 ) -> Option<Vec<u8>> {
148 let prefix = G::prefix_hash().to_vec();
149 let previous_key = previous_key.unwrap_or_else(|| prefix.clone());
150
151 let current_key =
152 sp_io::storage::next_key(&previous_key).filter(|n| n.starts_with(&prefix))?;
153
154 let value = match unhashed::get::<O>(¤t_key) {
155 Some(value) => value,
156 None => {
157 crate::defensive!(
158 "Invalid translation: failed to decode old value for key",
159 array_bytes::bytes2hex("0x", ¤t_key)
160 );
161 return Some(current_key);
162 },
163 };
164
165 let mut key_material = G::Hasher::reverse(¤t_key[prefix.len()..]);
166 let key = match K::decode(&mut key_material) {
167 Ok(key) => key,
168 Err(_) => {
169 crate::defensive!(
170 "Invalid translation: failed to decode key",
171 array_bytes::bytes2hex("0x", ¤t_key)
172 );
173 return Some(current_key);
174 },
175 };
176
177 match f(key, value) {
178 Some(new) => unhashed::put::<V>(¤t_key, &new),
179 None => unhashed::kill(¤t_key),
180 }
181
182 Some(current_key)
183 }
184}
185
186impl<K: FullEncode, V: FullCodec, G: StorageMap<K, V>> storage::StorageMap<K, V> for G {
187 type Query = G::Query;
188
189 fn hashed_key_for<KeyArg: EncodeLike<K>>(key: KeyArg) -> Vec<u8> {
190 Self::storage_map_final_key(key)
191 }
192
193 fn swap<KeyArg1: EncodeLike<K>, KeyArg2: EncodeLike<K>>(key1: KeyArg1, key2: KeyArg2) {
194 let k1 = Self::storage_map_final_key(key1);
195 let k2 = Self::storage_map_final_key(key2);
196
197 let v1 = unhashed::get_raw(k1.as_ref());
198 if let Some(val) = unhashed::get_raw(k2.as_ref()) {
199 unhashed::put_raw(k1.as_ref(), &val);
200 } else {
201 unhashed::kill(k1.as_ref())
202 }
203 if let Some(val) = v1 {
204 unhashed::put_raw(k2.as_ref(), &val);
205 } else {
206 unhashed::kill(k2.as_ref())
207 }
208 }
209
210 fn contains_key<KeyArg: EncodeLike<K>>(key: KeyArg) -> bool {
211 unhashed::exists(Self::storage_map_final_key(key).as_ref())
212 }
213
214 fn get<KeyArg: EncodeLike<K>>(key: KeyArg) -> Self::Query {
215 G::from_optional_value_to_query(unhashed::get(Self::storage_map_final_key(key).as_ref()))
216 }
217
218 fn try_get<KeyArg: EncodeLike<K>>(key: KeyArg) -> Result<V, ()> {
219 unhashed::get(Self::storage_map_final_key(key).as_ref()).ok_or(())
220 }
221
222 fn set<KeyArg: EncodeLike<K>>(key: KeyArg, q: Self::Query) {
223 match G::from_query_to_optional_value(q) {
224 Some(v) => Self::insert(key, v),
225 None => Self::remove(key),
226 }
227 }
228
229 fn insert<KeyArg: EncodeLike<K>, ValArg: EncodeLike<V>>(key: KeyArg, val: ValArg) {
230 unhashed::put(Self::storage_map_final_key(key).as_ref(), &val)
231 }
232
233 fn remove<KeyArg: EncodeLike<K>>(key: KeyArg) {
234 unhashed::kill(Self::storage_map_final_key(key).as_ref())
235 }
236
237 fn mutate<KeyArg: EncodeLike<K>, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R {
238 Self::try_mutate(key, |v| Ok::<R, Never>(f(v)))
239 .expect("`Never` can not be constructed; qed")
240 }
241
242 fn mutate_exists<KeyArg: EncodeLike<K>, R, F: FnOnce(&mut Option<V>) -> R>(
243 key: KeyArg,
244 f: F,
245 ) -> R {
246 Self::try_mutate_exists(key, |v| Ok::<R, Never>(f(v)))
247 .expect("`Never` can not be constructed; qed")
248 }
249
250 fn try_mutate<KeyArg: EncodeLike<K>, R, E, F: FnOnce(&mut Self::Query) -> Result<R, E>>(
251 key: KeyArg,
252 f: F,
253 ) -> Result<R, E> {
254 let final_key = Self::storage_map_final_key(key);
255 let mut val = G::from_optional_value_to_query(unhashed::get(final_key.as_ref()));
256
257 let ret = f(&mut val);
258 if ret.is_ok() {
259 match G::from_query_to_optional_value(val) {
260 Some(ref val) => unhashed::put(final_key.as_ref(), &val),
261 None => unhashed::kill(final_key.as_ref()),
262 }
263 }
264 ret
265 }
266
267 fn try_mutate_exists<KeyArg: EncodeLike<K>, R, E, F: FnOnce(&mut Option<V>) -> Result<R, E>>(
268 key: KeyArg,
269 f: F,
270 ) -> Result<R, E> {
271 let final_key = Self::storage_map_final_key(key);
272 let mut val = unhashed::get(final_key.as_ref());
273
274 let ret = f(&mut val);
275 if ret.is_ok() {
276 match val {
277 Some(ref val) => unhashed::put(final_key.as_ref(), &val),
278 None => unhashed::kill(final_key.as_ref()),
279 }
280 }
281 ret
282 }
283
284 fn take<KeyArg: EncodeLike<K>>(key: KeyArg) -> Self::Query {
285 let key = Self::storage_map_final_key(key);
286 let value = unhashed::take(key.as_ref());
287 G::from_optional_value_to_query(value)
288 }
289
290 fn append<Item, EncodeLikeItem, EncodeLikeKey>(key: EncodeLikeKey, item: EncodeLikeItem)
291 where
292 EncodeLikeKey: EncodeLike<K>,
293 Item: Encode,
294 EncodeLikeItem: EncodeLike<Item>,
295 V: StorageAppend<Item>,
296 {
297 let key = Self::storage_map_final_key(key);
298 sp_io::storage::append(&key, item.encode());
299 }
300
301 fn migrate_key<OldHasher: StorageHasher, KeyArg: EncodeLike<K>>(key: KeyArg) -> Option<V> {
302 let old_key = {
303 let storage_prefix = storage_prefix(Self::pallet_prefix(), Self::storage_prefix());
304 let key_hashed = key.using_encoded(OldHasher::hash);
305
306 let mut final_key =
307 Vec::with_capacity(storage_prefix.len() + key_hashed.as_ref().len());
308
309 final_key.extend_from_slice(&storage_prefix);
310 final_key.extend_from_slice(key_hashed.as_ref());
311
312 final_key
313 };
314 unhashed::take(old_key.as_ref()).inspect(|value| {
315 unhashed::put(Self::storage_map_final_key(key).as_ref(), &value);
316 })
317 }
318}
319
320#[cfg(test)]
322mod test_iterators {
323 use crate::{
324 hash::StorageHasher,
325 storage::{
326 generator::{tests::*, StorageMap},
327 unhashed,
328 },
329 };
330 use alloc::vec;
331 use codec::Encode;
332
333 #[test]
334 fn map_iter_from() {
335 sp_io::TestExternalities::default().execute_with(|| {
336 use crate::hash::Identity;
337 #[crate::storage_alias]
338 type MyMap = StorageMap<MyModule, Identity, u64, u64>;
339
340 MyMap::insert(1, 10);
341 MyMap::insert(2, 20);
342 MyMap::insert(3, 30);
343 MyMap::insert(4, 40);
344 MyMap::insert(5, 50);
345
346 let starting_raw_key = MyMap::storage_map_final_key(3);
347 let iter = MyMap::iter_from(starting_raw_key);
348 assert_eq!(iter.collect::<Vec<_>>(), vec![(4, 40), (5, 50)]);
349
350 let starting_raw_key = MyMap::storage_map_final_key(2);
351 let iter = MyMap::iter_keys_from(starting_raw_key);
352 assert_eq!(iter.collect::<Vec<_>>(), vec![3, 4, 5]);
353 });
354 }
355
356 #[cfg(debug_assertions)]
357 #[test]
358 #[should_panic]
359 fn map_translate_with_bad_key_in_debug_mode() {
360 sp_io::TestExternalities::default().execute_with(|| {
361 type Map = self::frame_system::Map<Runtime>;
362 let prefix = Map::prefix_hash().to_vec();
363
364 unhashed::put(&[prefix.clone(), vec![1, 2, 3]].concat(), &3u64.encode());
366
367 Map::translate(|_k1, v: u64| Some(v * 2));
369 assert_eq!(Map::iter().collect::<Vec<_>>(), vec![(3, 6), (0, 0), (2, 4), (1, 2)]);
370 })
371 }
372
373 #[cfg(debug_assertions)]
374 #[test]
375 #[should_panic]
376 fn map_translate_with_bad_value_in_debug_mode() {
377 sp_io::TestExternalities::default().execute_with(|| {
378 type Map = self::frame_system::Map<Runtime>;
379 let prefix = Map::prefix_hash().to_vec();
380
381 unhashed::put(
383 &[prefix.clone(), crate::Blake2_128Concat::hash(&6u16.encode())].concat(),
384 &vec![1],
385 );
386
387 Map::translate(|_k1, v: u64| Some(v * 2));
388 assert_eq!(Map::iter().collect::<Vec<_>>(), vec![(3, 6), (0, 0), (2, 4), (1, 2)]);
389 })
390 }
391
392 #[cfg(not(debug_assertions))]
393 #[test]
394 fn map_translate_with_bad_key_in_production_mode() {
395 sp_io::TestExternalities::default().execute_with(|| {
396 type Map = self::frame_system::Map<Runtime>;
397 let prefix = Map::prefix_hash().to_vec();
398
399 unhashed::put(&[prefix.clone(), vec![1, 2, 3]].concat(), &3u64.encode());
401
402 Map::translate(|_k1, v: u64| Some(v * 2));
403 assert_eq!(Map::iter().collect::<Vec<_>>(), vec![]);
404 })
405 }
406
407 #[cfg(not(debug_assertions))]
408 #[test]
409 fn map_translate_with_bad_value_in_production_mode() {
410 sp_io::TestExternalities::default().execute_with(|| {
411 type Map = self::frame_system::Map<Runtime>;
412 let prefix = Map::prefix_hash().to_vec();
413
414 unhashed::put(
416 &[prefix.clone(), crate::Blake2_128Concat::hash(&6u16.encode())].concat(),
417 &vec![1],
418 );
419
420 Map::translate(|_k1, v: u64| Some(v * 2));
421 assert_eq!(Map::iter().collect::<Vec<_>>(), vec![]);
422 })
423 }
424
425 #[test]
426 fn map_reversible_reversible_iteration() {
427 sp_io::TestExternalities::default().execute_with(|| {
428 type Map = self::frame_system::Map<Runtime>;
429
430 let prefix = Map::prefix_hash().to_vec();
432
433 unhashed::put(&key_before_prefix(prefix.clone()), &1u64);
434 unhashed::put(&key_after_prefix(prefix.clone()), &1u64);
435
436 for i in 0..4 {
437 Map::insert(i as u16, i as u64);
438 }
439
440 assert_eq!(Map::iter().collect::<Vec<_>>(), vec![(3, 3), (0, 0), (2, 2), (1, 1)]);
441
442 assert_eq!(Map::iter_keys().collect::<Vec<_>>(), vec![3, 0, 2, 1]);
443
444 assert_eq!(Map::iter_values().collect::<Vec<_>>(), vec![3, 0, 2, 1]);
445
446 assert_eq!(Map::drain().collect::<Vec<_>>(), vec![(3, 3), (0, 0), (2, 2), (1, 1)]);
447
448 assert_eq!(Map::iter().collect::<Vec<_>>(), vec![]);
449 assert_eq!(unhashed::get(&key_before_prefix(prefix.clone())), Some(1u64));
450 assert_eq!(unhashed::get(&key_after_prefix(prefix.clone())), Some(1u64));
451
452 let prefix = Map::prefix_hash().to_vec();
454
455 unhashed::put(&key_before_prefix(prefix.clone()), &1u64);
456 unhashed::put(&key_after_prefix(prefix.clone()), &1u64);
457 for i in 0..4 {
458 Map::insert(i as u16, i as u64);
459 }
460
461 Map::translate(|_k1, v: u64| Some(v * 2));
462 assert_eq!(Map::iter().collect::<Vec<_>>(), vec![(3, 6), (0, 0), (2, 4), (1, 2)]);
463 })
464 }
465}