referrerpolicy=no-referrer-when-downgrade

frame_support/storage/types/
nmap.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Storage n-map type. Particularly implements `StorageNMap` and `StoragePrefixedMap`
19//! traits and their methods directly.
20
21use crate::{
22	storage::{
23		types::{
24			EncodeLikeTuple, HasKeyPrefix, HasReversibleKeyPrefix, OptionQuery, QueryKindTrait,
25			StorageEntryMetadataBuilder, TupleToEncodedIter,
26		},
27		KeyGenerator, PrefixIterator, StorageAppend, StorageDecodeLength, StoragePrefixedMap,
28		StorageTryAppend,
29	},
30	traits::{Get, GetDefault, StorageInfo, StorageInstance},
31};
32use alloc::{vec, vec::Vec};
33use codec::{Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen};
34use sp_metadata_ir::{StorageEntryMetadataIR, StorageEntryTypeIR};
35use sp_runtime::SaturatedConversion;
36
37/// A type representing an *NMap* in storage. This structure associates an arbitrary number of keys
38/// with a value of a specified type stored on-chain.
39///
40/// For example, [`StorageDoubleMap`](frame_support::storage::types::StorageDoubleMap) is a special
41/// case of an *NMap* with N = 2.
42///
43/// For general information regarding the `#[pallet::storage]` attribute, refer to
44/// [`crate::pallet_macros::storage`].
45///
46/// # Example
47///
48/// ```
49/// #[frame_support::pallet]
50/// mod pallet {
51///     # use frame_support::pallet_prelude::*;
52///     # #[pallet::config]
53///     # pub trait Config: frame_system::Config {}
54///     # #[pallet::pallet]
55///     # pub struct Pallet<T>(_);
56/// 	/// A kitchen-sink StorageNMap, with all possible additional attributes.
57///     #[pallet::storage]
58/// 	#[pallet::getter(fn foo)]
59/// 	#[pallet::storage_prefix = "OtherFoo"]
60/// 	#[pallet::unbounded]
61///     pub type Foo<T> = StorageNMap<
62/// 		_,
63/// 		(
64/// 			NMapKey<Blake2_128Concat, u8>,
65/// 			NMapKey<Identity, u16>,
66/// 			NMapKey<Twox64Concat, u32>
67/// 		),
68/// 		u64,
69/// 		ValueQuery,
70/// 	>;
71///
72/// 	/// Named alternative syntax.
73///     #[pallet::storage]
74///     pub type Bar<T> = StorageNMap<
75/// 		Key = (
76/// 			NMapKey<Blake2_128Concat, u8>,
77/// 			NMapKey<Identity, u16>,
78/// 			NMapKey<Twox64Concat, u32>
79/// 		),
80/// 		Value = u64,
81/// 		QueryKind = ValueQuery,
82/// 	>;
83/// }
84/// ```
85pub struct StorageNMap<
86	Prefix,
87	Key,
88	Value,
89	QueryKind = OptionQuery,
90	OnEmpty = GetDefault,
91	MaxValues = GetDefault,
92>(core::marker::PhantomData<(Prefix, Key, Value, QueryKind, OnEmpty, MaxValues)>);
93
94impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
95	crate::storage::generator::StorageNMap<Key, Value>
96	for StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
97where
98	Prefix: StorageInstance,
99	Key: super::key::KeyGenerator,
100	Value: FullCodec,
101	QueryKind: QueryKindTrait<Value, OnEmpty>,
102	OnEmpty: Get<QueryKind::Query> + 'static,
103	MaxValues: Get<Option<u32>>,
104{
105	type Query = QueryKind::Query;
106	fn pallet_prefix() -> &'static [u8] {
107		Prefix::pallet_prefix().as_bytes()
108	}
109	fn storage_prefix() -> &'static [u8] {
110		Prefix::STORAGE_PREFIX.as_bytes()
111	}
112	fn prefix_hash() -> [u8; 32] {
113		Prefix::prefix_hash()
114	}
115	fn from_optional_value_to_query(v: Option<Value>) -> Self::Query {
116		QueryKind::from_optional_value_to_query(v)
117	}
118	fn from_query_to_optional_value(v: Self::Query) -> Option<Value> {
119		QueryKind::from_query_to_optional_value(v)
120	}
121}
122
123impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> crate::storage::StoragePrefixedMap<Value>
124	for StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
125where
126	Prefix: StorageInstance,
127	Key: super::key::KeyGenerator,
128	Value: FullCodec,
129	QueryKind: QueryKindTrait<Value, OnEmpty>,
130	OnEmpty: Get<QueryKind::Query> + 'static,
131	MaxValues: Get<Option<u32>>,
132{
133	fn pallet_prefix() -> &'static [u8] {
134		<Self as crate::storage::generator::StorageNMap<Key, Value>>::pallet_prefix()
135	}
136	fn storage_prefix() -> &'static [u8] {
137		<Self as crate::storage::generator::StorageNMap<Key, Value>>::storage_prefix()
138	}
139}
140
141impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
142	StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
143where
144	Prefix: StorageInstance,
145	Key: super::key::KeyGenerator,
146	Value: FullCodec,
147	QueryKind: QueryKindTrait<Value, OnEmpty>,
148	OnEmpty: Get<QueryKind::Query> + 'static,
149	MaxValues: Get<Option<u32>>,
150{
151	/// Get the storage key used to fetch a value corresponding to a specific key.
152	pub fn hashed_key_for<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
153		key: KArg,
154	) -> Vec<u8> {
155		<Self as crate::storage::StorageNMap<Key, Value>>::hashed_key_for(key)
156	}
157
158	/// Does the value (explicitly) exist in storage?
159	pub fn contains_key<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(key: KArg) -> bool {
160		<Self as crate::storage::StorageNMap<Key, Value>>::contains_key(key)
161	}
162
163	/// Load the value associated with the given key from the map.
164	pub fn get<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
165		key: KArg,
166	) -> QueryKind::Query {
167		<Self as crate::storage::StorageNMap<Key, Value>>::get(key)
168	}
169
170	/// Try to get the value for the given key from the map.
171	///
172	/// Returns `Ok` if it exists, `Err` if not.
173	pub fn try_get<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
174		key: KArg,
175	) -> Result<Value, ()> {
176		<Self as crate::storage::StorageNMap<Key, Value>>::try_get(key)
177	}
178
179	/// Store or remove the value to be associated with `key` so that `get` returns the `query`.
180	pub fn set<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
181		key: KArg,
182		query: QueryKind::Query,
183	) {
184		<Self as crate::storage::StorageNMap<Key, Value>>::set(key, query)
185	}
186
187	/// Take a value from storage, removing it afterwards.
188	pub fn take<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
189		key: KArg,
190	) -> QueryKind::Query {
191		<Self as crate::storage::StorageNMap<Key, Value>>::take(key)
192	}
193
194	/// Swap the values of two key-pairs.
195	pub fn swap<KOther, KArg1, KArg2>(key1: KArg1, key2: KArg2)
196	where
197		KOther: KeyGenerator,
198		KArg1: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
199		KArg2: EncodeLikeTuple<KOther::KArg> + TupleToEncodedIter,
200	{
201		<Self as crate::storage::StorageNMap<Key, Value>>::swap::<KOther, _, _>(key1, key2)
202	}
203
204	/// Store a value to be associated with the given keys from the map.
205	pub fn insert<KArg, VArg>(key: KArg, val: VArg)
206	where
207		KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
208		VArg: EncodeLike<Value>,
209	{
210		<Self as crate::storage::StorageNMap<Key, Value>>::insert(key, val)
211	}
212
213	/// Remove the value under the given keys.
214	pub fn remove<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(key: KArg) {
215		<Self as crate::storage::StorageNMap<Key, Value>>::remove(key)
216	}
217
218	/// Remove all values starting with `partial_key` in the overlay and up to `limit` in the
219	/// backend.
220	///
221	/// All values in the client overlay will be deleted, if there is some `limit` then up to
222	/// `limit` values are deleted from the client backend, if `limit` is none then all values in
223	/// the client backend are deleted.
224	///
225	/// # Note
226	///
227	/// Calling this multiple times per block with a `limit` set leads always to the same keys being
228	/// removed and the same result being returned. This happens because the keys to delete in the
229	/// overlay are not taken into account when deleting keys in the backend.
230	#[deprecated = "Use `clear_prefix` instead"]
231	pub fn remove_prefix<KP>(partial_key: KP, limit: Option<u32>) -> sp_io::KillStorageResult
232	where
233		Key: HasKeyPrefix<KP>,
234	{
235		#[allow(deprecated)]
236		<Self as crate::storage::StorageNMap<Key, Value>>::remove_prefix(partial_key, limit)
237	}
238
239	/// Attempt to remove items from the map matching a `partial_key` prefix.
240	///
241	/// Returns [`MultiRemovalResults`](sp_io::MultiRemovalResults) to inform about the result. Once
242	/// the resultant `maybe_cursor` field is `None`, then no further items remain to be deleted.
243	///
244	/// NOTE: After the initial call for any given map, it is important that no further items
245	/// are inserted into the map which match the `partial key`. If so, then the map may not be
246	/// empty when the resultant `maybe_cursor` is `None`.
247	///
248	/// # Limit
249	///
250	/// A `limit` must be provided in order to cap the maximum
251	/// amount of deletions done in a single call. This is one fewer than the
252	/// maximum number of backend iterations which may be done by this operation and as such
253	/// represents the maximum number of backend deletions which may happen. A `limit` of zero
254	/// implies that no keys will be deleted, though there may be a single iteration done.
255	///
256	/// # Cursor
257	///
258	/// A *cursor* may be passed in to this operation with `maybe_cursor`. `None` should only be
259	/// passed once (in the initial call) for any given storage map and `partial_key`. Subsequent
260	/// calls operating on the same map/`partial_key` should always pass `Some`, and this should be
261	/// equal to the previous call result's `maybe_cursor` field.
262	pub fn clear_prefix<KP>(
263		partial_key: KP,
264		limit: u32,
265		maybe_cursor: Option<&[u8]>,
266	) -> sp_io::MultiRemovalResults
267	where
268		Key: HasKeyPrefix<KP>,
269	{
270		<Self as crate::storage::StorageNMap<Key, Value>>::clear_prefix(
271			partial_key,
272			limit,
273			maybe_cursor,
274		)
275	}
276
277	/// Iterate over values that share the first key.
278	pub fn iter_prefix_values<KP>(partial_key: KP) -> PrefixIterator<Value>
279	where
280		Key: HasKeyPrefix<KP>,
281	{
282		<Self as crate::storage::StorageNMap<Key, Value>>::iter_prefix_values(partial_key)
283	}
284
285	/// Mutate the value under the given keys.
286	pub fn mutate<KArg, R, F>(key: KArg, f: F) -> R
287	where
288		KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
289		F: FnOnce(&mut QueryKind::Query) -> R,
290	{
291		<Self as crate::storage::StorageNMap<Key, Value>>::mutate(key, f)
292	}
293
294	/// Mutate the value under the given keys when the closure returns `Ok`.
295	pub fn try_mutate<KArg, R, E, F>(key: KArg, f: F) -> Result<R, E>
296	where
297		KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
298		F: FnOnce(&mut QueryKind::Query) -> Result<R, E>,
299	{
300		<Self as crate::storage::StorageNMap<Key, Value>>::try_mutate(key, f)
301	}
302
303	/// Mutate the value under the given keys. Deletes the item if mutated to a `None`.
304	pub fn mutate_exists<KArg, R, F>(key: KArg, f: F) -> R
305	where
306		KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
307		F: FnOnce(&mut Option<Value>) -> R,
308	{
309		<Self as crate::storage::StorageNMap<Key, Value>>::mutate_exists(key, f)
310	}
311
312	/// Mutate the item, only if an `Ok` value is returned. Deletes the item if mutated to a `None`.
313	/// `f` will always be called with an option representing if the storage item exists (`Some<V>`)
314	/// or if the storage item does not exist (`None`), independent of the `QueryType`.
315	pub fn try_mutate_exists<KArg, R, E, F>(key: KArg, f: F) -> Result<R, E>
316	where
317		KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
318		F: FnOnce(&mut Option<Value>) -> Result<R, E>,
319	{
320		<Self as crate::storage::StorageNMap<Key, Value>>::try_mutate_exists(key, f)
321	}
322
323	/// Append the given item to the value in the storage.
324	///
325	/// `Value` is required to implement [`StorageAppend`].
326	///
327	/// # Warning
328	///
329	/// If the storage item is not encoded properly, the storage will be overwritten
330	/// and set to `[item]`. Any default value set for the storage item will be ignored
331	/// on overwrite.
332	pub fn append<Item, EncodeLikeItem, KArg>(key: KArg, item: EncodeLikeItem)
333	where
334		KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
335		Item: Encode,
336		EncodeLikeItem: EncodeLike<Item>,
337		Value: StorageAppend<Item>,
338	{
339		<Self as crate::storage::StorageNMap<Key, Value>>::append(key, item)
340	}
341
342	/// Try and append the given item to the value in the storage.
343	///
344	/// Is only available if `Value` of the storage implements [`StorageTryAppend`].
345	pub fn try_append<KArg, Item, EncodeLikeItem>(key: KArg, item: EncodeLikeItem) -> Result<(), ()>
346	where
347		KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter + Clone,
348		Item: Encode,
349		EncodeLikeItem: EncodeLike<Item>,
350		Value: StorageTryAppend<Item>,
351	{
352		<Self as crate::storage::TryAppendNMap<Key, Value, Item>>::try_append(key, item)
353	}
354
355	/// Read the length of the storage value without decoding the entire value under the
356	/// given `key1` and `key2`.
357	///
358	/// `Value` is required to implement [`StorageDecodeLength`].
359	///
360	/// If the value does not exists or it fails to decode the length, `None` is returned.
361	/// Otherwise `Some(len)` is returned.
362	///
363	/// # Warning
364	///
365	/// `None` does not mean that `get()` does not return a value. The default value is completely
366	/// ignored by this function.
367	pub fn decode_len<KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter>(
368		key: KArg,
369	) -> Option<usize>
370	where
371		Value: StorageDecodeLength,
372	{
373		<Self as crate::storage::StorageNMap<Key, Value>>::decode_len(key)
374	}
375
376	/// Migrate an item with the given `key` from defunct `hash_fns` to the current hashers.
377	///
378	/// If the key doesn't exist, then it's a no-op. If it does, then it returns its value.
379	pub fn migrate_keys<KArg>(key: KArg, hash_fns: Key::HArg) -> Option<Value>
380	where
381		KArg: EncodeLikeTuple<Key::KArg> + TupleToEncodedIter,
382	{
383		<Self as crate::storage::StorageNMap<Key, Value>>::migrate_keys::<_>(key, hash_fns)
384	}
385
386	/// Remove all values in the overlay and up to `limit` in the backend.
387	///
388	/// All values in the client overlay will be deleted, if there is some `limit` then up to
389	/// `limit` values are deleted from the client backend, if `limit` is none then all values in
390	/// the client backend are deleted.
391	///
392	/// # Note
393	///
394	/// Calling this multiple times per block with a `limit` set leads always to the same keys being
395	/// removed and the same result being returned. This happens because the keys to delete in the
396	/// overlay are not taken into account when deleting keys in the backend.
397	#[deprecated = "Use `clear` instead"]
398	pub fn remove_all(limit: Option<u32>) -> sp_io::KillStorageResult {
399		#[allow(deprecated)]
400		<Self as crate::storage::StoragePrefixedMap<Value>>::remove_all(limit).into()
401	}
402
403	/// Attempt to remove all items from the map.
404	///
405	/// Returns [`MultiRemovalResults`](sp_io::MultiRemovalResults) to inform about the result. Once
406	/// the resultant `maybe_cursor` field is `None`, then no further items remain to be deleted.
407	///
408	/// NOTE: After the initial call for any given map, it is important that no further items
409	/// are inserted into the map. If so, then the map may not be empty when the resultant
410	/// `maybe_cursor` is `None`.
411	///
412	/// # Limit
413	///
414	/// A `limit` must always be provided through in order to cap the maximum
415	/// amount of deletions done in a single call. This is one fewer than the
416	/// maximum number of backend iterations which may be done by this operation and as such
417	/// represents the maximum number of backend deletions which may happen. A `limit` of zero
418	/// implies that no keys will be deleted, though there may be a single iteration done.
419	///
420	/// # Cursor
421	///
422	/// A *cursor* may be passed in to this operation with `maybe_cursor`. `None` should only be
423	/// passed once (in the initial call) for any given storage map. Subsequent calls
424	/// operating on the same map should always pass `Some`, and this should be equal to the
425	/// previous call result's `maybe_cursor` field.
426	pub fn clear(limit: u32, maybe_cursor: Option<&[u8]>) -> sp_io::MultiRemovalResults {
427		<Self as crate::storage::StoragePrefixedMap<Value>>::clear(limit, maybe_cursor)
428	}
429
430	/// Iter over all value of the storage.
431	///
432	/// NOTE: If a value failed to decode because storage is corrupted then it is skipped.
433	pub fn iter_values() -> crate::storage::PrefixIterator<Value> {
434		<Self as crate::storage::StoragePrefixedMap<Value>>::iter_values()
435	}
436
437	/// Translate the values of all elements by a function `f`, in the map in no particular order.
438	/// By returning `None` from `f` for an element, you'll remove it from the map.
439	///
440	/// NOTE: If a value fail to decode because storage is corrupted then it is skipped.
441	///
442	/// # Warning
443	///
444	/// This function must be used with care, before being updated the storage still contains the
445	/// old type, thus other calls (such as `get`) will fail at decoding it.
446	///
447	/// # Usage
448	///
449	/// This would typically be called inside the module implementation of on_runtime_upgrade.
450	pub fn translate_values<OldValue: Decode, F: FnMut(OldValue) -> Option<Value>>(f: F) {
451		<Self as crate::storage::StoragePrefixedMap<Value>>::translate_values(f)
452	}
453}
454
455impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
456	StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
457where
458	Prefix: StorageInstance,
459	Key: super::key::ReversibleKeyGenerator,
460	Value: FullCodec,
461	QueryKind: QueryKindTrait<Value, OnEmpty>,
462	OnEmpty: Get<QueryKind::Query> + 'static,
463	MaxValues: Get<Option<u32>>,
464{
465	/// Enumerate all elements in the map with prefix key `kp` in no particular order.
466	///
467	/// If you add or remove values whose prefix key is `kp` to the map while doing this, you'll get
468	/// undefined results.
469	pub fn iter_prefix<KP>(
470		kp: KP,
471	) -> crate::storage::PrefixIterator<(<Key as HasKeyPrefix<KP>>::Suffix, Value)>
472	where
473		Key: HasReversibleKeyPrefix<KP>,
474	{
475		<Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_prefix(kp)
476	}
477
478	/// Enumerate all elements in the map with prefix key `kp` after a specified `starting_raw_key`
479	/// in no particular order.
480	///
481	/// If you add or remove values whose prefix key is `kp` to the map while doing this, you'll get
482	/// undefined results.
483	pub fn iter_prefix_from<KP>(
484		kp: KP,
485		starting_raw_key: Vec<u8>,
486	) -> crate::storage::PrefixIterator<(<Key as HasKeyPrefix<KP>>::Suffix, Value)>
487	where
488		Key: HasReversibleKeyPrefix<KP>,
489	{
490		<Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_prefix_from(
491			kp,
492			starting_raw_key,
493		)
494	}
495
496	/// Enumerate all suffix keys in the map with prefix key `kp` in no particular order.
497	///
498	/// If you add or remove values whose prefix key is `kp` to the map while doing this, you'll get
499	/// undefined results.
500	pub fn iter_key_prefix<KP>(
501		kp: KP,
502	) -> crate::storage::KeyPrefixIterator<<Key as HasKeyPrefix<KP>>::Suffix>
503	where
504		Key: HasReversibleKeyPrefix<KP>,
505	{
506		<Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_key_prefix(kp)
507	}
508
509	/// Enumerate all suffix keys in the map with prefix key `kp` after a specified
510	/// `starting_raw_key` in no particular order.
511	///
512	/// If you add or remove values whose prefix key is `kp` to the map while doing this, you'll get
513	/// undefined results.
514	pub fn iter_key_prefix_from<KP>(
515		kp: KP,
516		starting_raw_key: Vec<u8>,
517	) -> crate::storage::KeyPrefixIterator<<Key as HasKeyPrefix<KP>>::Suffix>
518	where
519		Key: HasReversibleKeyPrefix<KP>,
520	{
521		<Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_key_prefix_from(
522			kp,
523			starting_raw_key,
524		)
525	}
526
527	/// Remove all elements from the map with prefix key `kp` and iterate through them in no
528	/// particular order.
529	///
530	/// If you add elements with prefix key `k1` to the map while doing this, you'll get undefined
531	/// results.
532	pub fn drain_prefix<KP>(
533		kp: KP,
534	) -> crate::storage::PrefixIterator<(<Key as HasKeyPrefix<KP>>::Suffix, Value)>
535	where
536		Key: HasReversibleKeyPrefix<KP>,
537	{
538		<Self as crate::storage::IterableStorageNMap<Key, Value>>::drain_prefix(kp)
539	}
540
541	/// Enumerate all elements in the map in no particular order.
542	///
543	/// If you add or remove values to the map while doing this, you'll get undefined results.
544	pub fn iter() -> crate::storage::PrefixIterator<(Key::Key, Value)> {
545		<Self as crate::storage::IterableStorageNMap<Key, Value>>::iter()
546	}
547
548	/// Enumerate all elements in the map after a specified `starting_key` in no particular order.
549	///
550	/// If you add or remove values to the map while doing this, you'll get undefined results.
551	pub fn iter_from(
552		starting_raw_key: Vec<u8>,
553	) -> crate::storage::PrefixIterator<(Key::Key, Value)> {
554		<Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_from(starting_raw_key)
555	}
556
557	/// Enumerate all keys in the map in no particular order.
558	///
559	/// If you add or remove values to the map while doing this, you'll get undefined results.
560	pub fn iter_keys() -> crate::storage::KeyPrefixIterator<Key::Key> {
561		<Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_keys()
562	}
563
564	/// Enumerate all keys in the map after a specified `starting_raw_key` in no particular order.
565	///
566	/// If you add or remove values to the map while doing this, you'll get undefined results.
567	pub fn iter_keys_from(
568		starting_raw_key: Vec<u8>,
569	) -> crate::storage::KeyPrefixIterator<Key::Key> {
570		<Self as crate::storage::IterableStorageNMap<Key, Value>>::iter_keys_from(starting_raw_key)
571	}
572
573	/// Remove all elements from the map and iterate through them in no particular order.
574	///
575	/// If you add elements to the map while doing this, you'll get undefined results.
576	pub fn drain() -> crate::storage::PrefixIterator<(Key::Key, Value)> {
577		<Self as crate::storage::IterableStorageNMap<Key, Value>>::drain()
578	}
579
580	/// Translate the values of all elements by a function `f`, in the map in no particular order.
581	///
582	/// By returning `None` from `f` for an element, you'll remove it from the map.
583	///
584	/// NOTE: If a value fail to decode because storage is corrupted then it is skipped.
585	pub fn translate<O: Decode, F: FnMut(Key::Key, O) -> Option<Value>>(f: F) {
586		<Self as crate::storage::IterableStorageNMap<Key, Value>>::translate(f)
587	}
588}
589
590impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> StorageEntryMetadataBuilder
591	for StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
592where
593	Prefix: StorageInstance,
594	Key: super::key::KeyGenerator,
595	Value: FullCodec + scale_info::StaticTypeInfo,
596	QueryKind: QueryKindTrait<Value, OnEmpty>,
597	OnEmpty: Get<QueryKind::Query> + 'static,
598	MaxValues: Get<Option<u32>>,
599{
600	fn build_metadata(
601		deprecation_status: sp_metadata_ir::ItemDeprecationInfoIR,
602		docs: Vec<&'static str>,
603		entries: &mut Vec<StorageEntryMetadataIR>,
604	) {
605		let docs = if cfg!(feature = "no-metadata-docs") { vec![] } else { docs };
606
607		let entry = StorageEntryMetadataIR {
608			name: Prefix::STORAGE_PREFIX,
609			modifier: QueryKind::METADATA,
610			ty: StorageEntryTypeIR::Map {
611				key: scale_info::meta_type::<Key::Key>(),
612				hashers: Key::HASHER_METADATA.to_vec(),
613				value: scale_info::meta_type::<Value>(),
614			},
615			default: OnEmpty::get().encode(),
616			docs,
617			deprecation_info: deprecation_status,
618		};
619
620		entries.push(entry);
621	}
622}
623
624impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> crate::traits::StorageInfoTrait
625	for StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
626where
627	Prefix: StorageInstance,
628	Key: super::key::KeyGenerator + super::key::KeyGeneratorMaxEncodedLen,
629	Value: FullCodec + MaxEncodedLen,
630	QueryKind: QueryKindTrait<Value, OnEmpty>,
631	OnEmpty: Get<QueryKind::Query> + 'static,
632	MaxValues: Get<Option<u32>>,
633{
634	fn storage_info() -> Vec<StorageInfo> {
635		vec![StorageInfo {
636			pallet_name: Self::pallet_prefix().to_vec(),
637			storage_name: Self::storage_prefix().to_vec(),
638			prefix: Self::final_prefix().to_vec(),
639			max_values: MaxValues::get(),
640			max_size: Some(
641				Key::key_max_encoded_len()
642					.saturating_add(Value::max_encoded_len())
643					.saturated_into(),
644			),
645		}]
646	}
647}
648
649/// It doesn't require to implement `MaxEncodedLen` and give no information for `max_size`.
650impl<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues> crate::traits::PartialStorageInfoTrait
651	for StorageNMap<Prefix, Key, Value, QueryKind, OnEmpty, MaxValues>
652where
653	Prefix: StorageInstance,
654	Key: super::key::KeyGenerator,
655	Value: FullCodec,
656	QueryKind: QueryKindTrait<Value, OnEmpty>,
657	OnEmpty: Get<QueryKind::Query> + 'static,
658	MaxValues: Get<Option<u32>>,
659{
660	fn partial_storage_info() -> Vec<StorageInfo> {
661		vec![StorageInfo {
662			pallet_name: Self::pallet_prefix().to_vec(),
663			storage_name: Self::storage_prefix().to_vec(),
664			prefix: Self::final_prefix().to_vec(),
665			max_values: MaxValues::get(),
666			max_size: None,
667		}]
668	}
669}
670#[cfg(test)]
671mod test {
672	use super::*;
673	use crate::{
674		hash::{StorageHasher as _, *},
675		storage::types::{Key as NMapKey, ValueQuery},
676	};
677	use alloc::boxed::Box;
678	use sp_io::{hashing::twox_128, TestExternalities};
679	use sp_metadata_ir::{StorageEntryModifierIR, StorageHasherIR};
680
681	struct Prefix;
682	impl StorageInstance for Prefix {
683		fn pallet_prefix() -> &'static str {
684			"test"
685		}
686		const STORAGE_PREFIX: &'static str = "Foo";
687	}
688
689	struct ADefault;
690	impl crate::traits::Get<u32> for ADefault {
691		fn get() -> u32 {
692			98
693		}
694	}
695
696	#[test]
697	fn test_1_key() {
698		type A = StorageNMap<Prefix, NMapKey<Blake2_128Concat, u16>, u32, OptionQuery>;
699		type AValueQueryWithAnOnEmpty =
700			StorageNMap<Prefix, NMapKey<Blake2_128Concat, u16>, u32, ValueQuery, ADefault>;
701		type B = StorageNMap<Prefix, NMapKey<Blake2_256, u16>, u32, ValueQuery>;
702		type C = StorageNMap<Prefix, NMapKey<Blake2_128Concat, u16>, u8, ValueQuery>;
703		type WithLen = StorageNMap<Prefix, NMapKey<Blake2_128Concat, u16>, Vec<u32>>;
704
705		TestExternalities::default().execute_with(|| {
706			let mut k: Vec<u8> = vec![];
707			k.extend(&twox_128(b"test"));
708			k.extend(&twox_128(b"Foo"));
709			k.extend(&3u16.blake2_128_concat());
710			assert_eq!(A::hashed_key_for((&3,)).to_vec(), k);
711
712			assert_eq!(A::contains_key((3,)), false);
713			assert_eq!(A::get((3,)), None);
714			assert_eq!(AValueQueryWithAnOnEmpty::get((3,)), 98);
715
716			A::insert((3,), 10);
717			assert_eq!(A::contains_key((3,)), true);
718			assert_eq!(A::get((3,)), Some(10));
719			assert_eq!(AValueQueryWithAnOnEmpty::get((3,)), 10);
720
721			{
722				#[crate::storage_alias]
723				type Foo = StorageNMap<test, (NMapKey<Blake2_128Concat, u16>), u32>;
724
725				assert_eq!(Foo::contains_key((3,)), true);
726				assert_eq!(Foo::get((3,)), Some(10));
727			}
728
729			A::swap::<NMapKey<Blake2_128Concat, u16>, _, _>((3,), (2,));
730			assert_eq!(A::contains_key((3,)), false);
731			assert_eq!(A::contains_key((2,)), true);
732			assert_eq!(A::get((3,)), None);
733			assert_eq!(AValueQueryWithAnOnEmpty::get((3,)), 98);
734			assert_eq!(A::get((2,)), Some(10));
735			assert_eq!(AValueQueryWithAnOnEmpty::get((2,)), 10);
736
737			A::remove((2,));
738			assert_eq!(A::contains_key((2,)), false);
739			assert_eq!(A::get((2,)), None);
740
741			AValueQueryWithAnOnEmpty::mutate((2,), |v| *v = *v * 2);
742			AValueQueryWithAnOnEmpty::mutate((2,), |v| *v = *v * 2);
743			assert_eq!(A::contains_key((2,)), true);
744			assert_eq!(A::get((2,)), Some(98 * 4));
745
746			A::remove((2,));
747			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2,), |v| {
748				*v = *v * 2;
749				Ok(())
750			});
751			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2,), |v| {
752				*v = *v * 2;
753				Ok(())
754			});
755			assert_eq!(A::contains_key((2,)), true);
756			assert_eq!(A::get((2,)), Some(98 * 4));
757
758			A::remove((2,));
759			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2,), |v| {
760				*v = *v * 2;
761				Err(())
762			});
763			assert_eq!(A::contains_key((2,)), false);
764
765			A::remove((2,));
766			AValueQueryWithAnOnEmpty::mutate_exists((2,), |v| {
767				assert!(v.is_none());
768				*v = Some(10);
769			});
770			assert_eq!(A::contains_key((2,)), true);
771			assert_eq!(A::get((2,)), Some(10));
772			AValueQueryWithAnOnEmpty::mutate_exists((2,), |v| {
773				*v = Some(v.unwrap() * 10);
774			});
775			assert_eq!(A::contains_key((2,)), true);
776			assert_eq!(A::get((2,)), Some(100));
777
778			A::remove((2,));
779			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2,), |v| {
780				assert!(v.is_none());
781				*v = Some(10);
782				Ok(())
783			});
784			assert_eq!(A::contains_key((2,)), true);
785			assert_eq!(A::get((2,)), Some(10));
786			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2,), |v| {
787				*v = Some(v.unwrap() * 10);
788				Ok(())
789			});
790			assert_eq!(A::contains_key((2,)), true);
791			assert_eq!(A::get((2,)), Some(100));
792			assert_eq!(A::try_get((2,)), Ok(100));
793			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2,), |v| {
794				*v = Some(v.unwrap() * 10);
795				Err(())
796			});
797			assert_eq!(A::contains_key((2,)), true);
798			assert_eq!(A::get((2,)), Some(100));
799
800			A::insert((2,), 10);
801			assert_eq!(A::take((2,)), Some(10));
802			assert_eq!(A::contains_key((2,)), false);
803			assert_eq!(AValueQueryWithAnOnEmpty::take((2,)), 98);
804			assert_eq!(A::contains_key((2,)), false);
805			assert_eq!(A::try_get((2,)), Err(()));
806
807			B::insert((2,), 10);
808			assert_eq!(
809				A::migrate_keys((2,), (Box::new(|key| Blake2_256::hash(key).to_vec()),),),
810				Some(10)
811			);
812			assert_eq!(A::contains_key((2,)), true);
813			assert_eq!(A::get((2,)), Some(10));
814
815			A::insert((3,), 10);
816			A::insert((4,), 10);
817			let _ = A::clear(u32::max_value(), None);
818			assert_eq!(A::contains_key((3,)), false);
819			assert_eq!(A::contains_key((4,)), false);
820
821			A::insert((3,), 10);
822			A::insert((4,), 10);
823			assert_eq!(A::iter_values().collect::<Vec<_>>(), vec![10, 10]);
824
825			C::insert((3,), 10);
826			C::insert((4,), 10);
827			A::translate_values::<u8, _>(|v| Some((v * 2).into()));
828			assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 20), (3, 20)]);
829
830			A::insert((3,), 10);
831			A::insert((4,), 10);
832			assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 10), (3, 10)]);
833			assert_eq!(A::drain().collect::<Vec<_>>(), vec![(4, 10), (3, 10)]);
834			assert_eq!(A::iter().collect::<Vec<_>>(), vec![]);
835
836			C::insert((3,), 10);
837			C::insert((4,), 10);
838			A::translate::<u8, _>(|k1, v| Some((k1 as u16 * v as u16).into()));
839			assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 40), (3, 30)]);
840
841			let mut entries = vec![];
842			A::build_metadata(
843				sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
844				vec![],
845				&mut entries,
846			);
847			AValueQueryWithAnOnEmpty::build_metadata(
848				sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
849				vec![],
850				&mut entries,
851			);
852			assert_eq!(
853				entries,
854				vec![
855					StorageEntryMetadataIR {
856						name: "Foo",
857						modifier: StorageEntryModifierIR::Optional,
858						ty: StorageEntryTypeIR::Map {
859							hashers: vec![StorageHasherIR::Blake2_128Concat],
860							key: scale_info::meta_type::<u16>(),
861							value: scale_info::meta_type::<u32>(),
862						},
863						default: Option::<u32>::None.encode(),
864						docs: vec![],
865						deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
866					},
867					StorageEntryMetadataIR {
868						name: "Foo",
869						modifier: StorageEntryModifierIR::Default,
870						ty: StorageEntryTypeIR::Map {
871							hashers: vec![StorageHasherIR::Blake2_128Concat],
872							key: scale_info::meta_type::<u16>(),
873							value: scale_info::meta_type::<u32>(),
874						},
875						default: 98u32.encode(),
876						docs: vec![],
877						deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
878					}
879				]
880			);
881
882			let _ = WithLen::clear(u32::max_value(), None);
883			assert_eq!(WithLen::decode_len((3,)), None);
884			WithLen::append((0,), 10);
885			assert_eq!(WithLen::decode_len((0,)), Some(1));
886		});
887	}
888
889	#[test]
890	fn test_2_keys() {
891		type A = StorageNMap<
892			Prefix,
893			(NMapKey<Blake2_128Concat, u16>, NMapKey<Twox64Concat, u8>),
894			u32,
895			OptionQuery,
896		>;
897		type AValueQueryWithAnOnEmpty = StorageNMap<
898			Prefix,
899			(NMapKey<Blake2_128Concat, u16>, NMapKey<Twox64Concat, u8>),
900			u32,
901			ValueQuery,
902			ADefault,
903		>;
904		type B =
905			StorageNMap<Prefix, (NMapKey<Blake2_256, u16>, NMapKey<Twox128, u8>), u32, ValueQuery>;
906		type C = StorageNMap<
907			Prefix,
908			(NMapKey<Blake2_128Concat, u16>, NMapKey<Twox64Concat, u8>),
909			u8,
910			ValueQuery,
911		>;
912		type WithLen = StorageNMap<
913			Prefix,
914			(NMapKey<Blake2_128Concat, u16>, NMapKey<Twox64Concat, u8>),
915			Vec<u32>,
916		>;
917
918		TestExternalities::default().execute_with(|| {
919			let mut k: Vec<u8> = vec![];
920			k.extend(&twox_128(b"test"));
921			k.extend(&twox_128(b"Foo"));
922			k.extend(&3u16.blake2_128_concat());
923			k.extend(&30u8.twox_64_concat());
924			assert_eq!(A::hashed_key_for((3, 30)).to_vec(), k);
925
926			assert_eq!(A::contains_key((3, 30)), false);
927			assert_eq!(A::get((3, 30)), None);
928			assert_eq!(AValueQueryWithAnOnEmpty::get((3, 30)), 98);
929
930			A::insert((3, 30), 10);
931			assert_eq!(A::contains_key((3, 30)), true);
932			assert_eq!(A::get((3, 30)), Some(10));
933			assert_eq!(AValueQueryWithAnOnEmpty::get((3, 30)), 10);
934
935			A::swap::<(NMapKey<Blake2_128Concat, u16>, NMapKey<Twox64Concat, u8>), _, _>(
936				(3, 30),
937				(2, 20),
938			);
939			assert_eq!(A::contains_key((3, 30)), false);
940			assert_eq!(A::contains_key((2, 20)), true);
941			assert_eq!(A::get((3, 30)), None);
942			assert_eq!(AValueQueryWithAnOnEmpty::get((3, 30)), 98);
943			assert_eq!(A::get((2, 20)), Some(10));
944			assert_eq!(AValueQueryWithAnOnEmpty::get((2, 20)), 10);
945
946			A::remove((2, 20));
947			assert_eq!(A::contains_key((2, 20)), false);
948			assert_eq!(A::get((2, 20)), None);
949
950			AValueQueryWithAnOnEmpty::mutate((2, 20), |v| *v = *v * 2);
951			AValueQueryWithAnOnEmpty::mutate((2, 20), |v| *v = *v * 2);
952			assert_eq!(A::contains_key((2, 20)), true);
953			assert_eq!(A::get((2, 20)), Some(98 * 4));
954
955			A::remove((2, 20));
956			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2, 20), |v| {
957				*v = *v * 2;
958				Err(())
959			});
960			assert_eq!(A::contains_key((2, 20)), false);
961
962			A::remove((2, 20));
963			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2, 20), |v| {
964				*v = *v * 2;
965				Err(())
966			});
967			assert_eq!(A::contains_key((2, 20)), false);
968
969			A::remove((2, 20));
970			AValueQueryWithAnOnEmpty::mutate_exists((2, 20), |v| {
971				assert!(v.is_none());
972				*v = Some(10);
973			});
974			assert_eq!(A::contains_key((2, 20)), true);
975			assert_eq!(A::get((2, 20)), Some(10));
976			AValueQueryWithAnOnEmpty::mutate_exists((2, 20), |v| {
977				*v = Some(v.unwrap() * 10);
978			});
979			assert_eq!(A::contains_key((2, 20)), true);
980			assert_eq!(A::get((2, 20)), Some(100));
981
982			A::remove((2, 20));
983			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20), |v| {
984				assert!(v.is_none());
985				*v = Some(10);
986				Ok(())
987			});
988			assert_eq!(A::contains_key((2, 20)), true);
989			assert_eq!(A::get((2, 20)), Some(10));
990			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20), |v| {
991				*v = Some(v.unwrap() * 10);
992				Ok(())
993			});
994			assert_eq!(A::contains_key((2, 20)), true);
995			assert_eq!(A::get((2, 20)), Some(100));
996			assert_eq!(A::try_get((2, 20)), Ok(100));
997			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20), |v| {
998				*v = Some(v.unwrap() * 10);
999				Err(())
1000			});
1001			assert_eq!(A::contains_key((2, 20)), true);
1002			assert_eq!(A::get((2, 20)), Some(100));
1003
1004			A::insert((2, 20), 10);
1005			assert_eq!(A::take((2, 20)), Some(10));
1006			assert_eq!(A::contains_key((2, 20)), false);
1007			assert_eq!(AValueQueryWithAnOnEmpty::take((2, 20)), 98);
1008			assert_eq!(A::contains_key((2, 20)), false);
1009			assert_eq!(A::try_get((2, 20)), Err(()));
1010
1011			B::insert((2, 20), 10);
1012			assert_eq!(
1013				A::migrate_keys(
1014					(2, 20),
1015					(
1016						Box::new(|key| Blake2_256::hash(key).to_vec()),
1017						Box::new(|key| Twox128::hash(key).to_vec()),
1018					),
1019				),
1020				Some(10)
1021			);
1022			assert_eq!(A::contains_key((2, 20)), true);
1023			assert_eq!(A::get((2, 20)), Some(10));
1024
1025			A::insert((3, 30), 10);
1026			A::insert((4, 40), 10);
1027			let _ = A::clear(u32::max_value(), None);
1028			assert_eq!(A::contains_key((3, 30)), false);
1029			assert_eq!(A::contains_key((4, 40)), false);
1030
1031			A::insert((3, 30), 10);
1032			A::insert((4, 40), 10);
1033			assert_eq!(A::iter_values().collect::<Vec<_>>(), vec![10, 10]);
1034
1035			C::insert((3, 30), 10);
1036			C::insert((4, 40), 10);
1037			A::translate_values::<u8, _>(|v| Some((v * 2).into()));
1038			assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40), 20), ((3, 30), 20)]);
1039
1040			A::insert((3, 30), 10);
1041			A::insert((4, 40), 10);
1042			assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40), 10), ((3, 30), 10)]);
1043			assert_eq!(A::drain().collect::<Vec<_>>(), vec![((4, 40), 10), ((3, 30), 10)]);
1044			assert_eq!(A::iter().collect::<Vec<_>>(), vec![]);
1045
1046			C::insert((3, 30), 10);
1047			C::insert((4, 40), 10);
1048			A::translate::<u8, _>(|(k1, k2), v| Some((k1 * k2 as u16 * v as u16).into()));
1049			assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40), 1600), ((3, 30), 900)]);
1050
1051			let mut entries = vec![];
1052			A::build_metadata(
1053				sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1054				vec![],
1055				&mut entries,
1056			);
1057			AValueQueryWithAnOnEmpty::build_metadata(
1058				sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1059				vec![],
1060				&mut entries,
1061			);
1062			assert_eq!(
1063				entries,
1064				vec![
1065					StorageEntryMetadataIR {
1066						name: "Foo",
1067						modifier: StorageEntryModifierIR::Optional,
1068						ty: StorageEntryTypeIR::Map {
1069							hashers: vec![
1070								StorageHasherIR::Blake2_128Concat,
1071								StorageHasherIR::Twox64Concat
1072							],
1073							key: scale_info::meta_type::<(u16, u8)>(),
1074							value: scale_info::meta_type::<u32>(),
1075						},
1076						default: Option::<u32>::None.encode(),
1077						docs: vec![],
1078						deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1079					},
1080					StorageEntryMetadataIR {
1081						name: "Foo",
1082						modifier: StorageEntryModifierIR::Default,
1083						ty: StorageEntryTypeIR::Map {
1084							hashers: vec![
1085								StorageHasherIR::Blake2_128Concat,
1086								StorageHasherIR::Twox64Concat
1087							],
1088							key: scale_info::meta_type::<(u16, u8)>(),
1089							value: scale_info::meta_type::<u32>(),
1090						},
1091						default: 98u32.encode(),
1092						docs: vec![],
1093						deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1094					}
1095				]
1096			);
1097
1098			let _ = WithLen::clear(u32::max_value(), None);
1099			assert_eq!(WithLen::decode_len((3, 30)), None);
1100			WithLen::append((0, 100), 10);
1101			assert_eq!(WithLen::decode_len((0, 100)), Some(1));
1102
1103			A::insert((3, 30), 11);
1104			A::insert((3, 31), 12);
1105			A::insert((4, 40), 13);
1106			A::insert((4, 41), 14);
1107			assert_eq!(A::iter_prefix_values((3,)).collect::<Vec<_>>(), vec![12, 11]);
1108			assert_eq!(A::iter_prefix_values((4,)).collect::<Vec<_>>(), vec![13, 14]);
1109		});
1110	}
1111
1112	#[test]
1113	fn test_3_keys() {
1114		type A = StorageNMap<
1115			Prefix,
1116			(
1117				NMapKey<Blake2_128Concat, u16>,
1118				NMapKey<Blake2_128Concat, u16>,
1119				NMapKey<Twox64Concat, u16>,
1120			),
1121			u32,
1122			OptionQuery,
1123		>;
1124		type AValueQueryWithAnOnEmpty = StorageNMap<
1125			Prefix,
1126			(
1127				NMapKey<Blake2_128Concat, u16>,
1128				NMapKey<Blake2_128Concat, u16>,
1129				NMapKey<Twox64Concat, u16>,
1130			),
1131			u32,
1132			ValueQuery,
1133			ADefault,
1134		>;
1135		type B = StorageNMap<
1136			Prefix,
1137			(NMapKey<Blake2_256, u16>, NMapKey<Blake2_256, u16>, NMapKey<Twox128, u16>),
1138			u32,
1139			ValueQuery,
1140		>;
1141		type C = StorageNMap<
1142			Prefix,
1143			(
1144				NMapKey<Blake2_128Concat, u16>,
1145				NMapKey<Blake2_128Concat, u16>,
1146				NMapKey<Twox64Concat, u16>,
1147			),
1148			u8,
1149			ValueQuery,
1150		>;
1151		type WithLen = StorageNMap<
1152			Prefix,
1153			(
1154				NMapKey<Blake2_128Concat, u16>,
1155				NMapKey<Blake2_128Concat, u16>,
1156				NMapKey<Twox64Concat, u16>,
1157			),
1158			Vec<u32>,
1159		>;
1160
1161		TestExternalities::default().execute_with(|| {
1162			let mut k: Vec<u8> = vec![];
1163			k.extend(&twox_128(b"test"));
1164			k.extend(&twox_128(b"Foo"));
1165			k.extend(&1u16.blake2_128_concat());
1166			k.extend(&10u16.blake2_128_concat());
1167			k.extend(&100u16.twox_64_concat());
1168			assert_eq!(A::hashed_key_for((1, 10, 100)).to_vec(), k);
1169
1170			assert_eq!(A::contains_key((1, 10, 100)), false);
1171			assert_eq!(A::get((1, 10, 100)), None);
1172			assert_eq!(AValueQueryWithAnOnEmpty::get((1, 10, 100)), 98);
1173
1174			A::insert((1, 10, 100), 30);
1175			assert_eq!(A::contains_key((1, 10, 100)), true);
1176			assert_eq!(A::get((1, 10, 100)), Some(30));
1177			assert_eq!(AValueQueryWithAnOnEmpty::get((1, 10, 100)), 30);
1178
1179			A::swap::<
1180				(
1181					NMapKey<Blake2_128Concat, u16>,
1182					NMapKey<Blake2_128Concat, u16>,
1183					NMapKey<Twox64Concat, u16>,
1184				),
1185				_,
1186				_,
1187			>((1, 10, 100), (2, 20, 200));
1188			assert_eq!(A::contains_key((1, 10, 100)), false);
1189			assert_eq!(A::contains_key((2, 20, 200)), true);
1190			assert_eq!(A::get((1, 10, 100)), None);
1191			assert_eq!(AValueQueryWithAnOnEmpty::get((1, 10, 100)), 98);
1192			assert_eq!(A::get((2, 20, 200)), Some(30));
1193			assert_eq!(AValueQueryWithAnOnEmpty::get((2, 20, 200)), 30);
1194
1195			A::remove((2, 20, 200));
1196			assert_eq!(A::contains_key((2, 20, 200)), false);
1197			assert_eq!(A::get((2, 20, 200)), None);
1198
1199			AValueQueryWithAnOnEmpty::mutate((2, 20, 200), |v| *v = *v * 2);
1200			AValueQueryWithAnOnEmpty::mutate((2, 20, 200), |v| *v = *v * 2);
1201			assert_eq!(A::contains_key((2, 20, 200)), true);
1202			assert_eq!(A::get((2, 20, 200)), Some(98 * 4));
1203
1204			A::remove((2, 20, 200));
1205			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate((2, 20, 200), |v| {
1206				*v = *v * 2;
1207				Err(())
1208			});
1209			assert_eq!(A::contains_key((2, 20, 200)), false);
1210
1211			A::remove((2, 20, 200));
1212			AValueQueryWithAnOnEmpty::mutate_exists((2, 20, 200), |v| {
1213				assert!(v.is_none());
1214				*v = Some(10);
1215			});
1216			assert_eq!(A::contains_key((2, 20, 200)), true);
1217			assert_eq!(A::get((2, 20, 200)), Some(10));
1218			AValueQueryWithAnOnEmpty::mutate_exists((2, 20, 200), |v| {
1219				*v = Some(v.unwrap() * 10);
1220			});
1221			assert_eq!(A::contains_key((2, 20, 200)), true);
1222			assert_eq!(A::get((2, 20, 200)), Some(100));
1223
1224			A::remove((2, 20, 200));
1225			let _: Result<(), ()> =
1226				AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20, 200), |v| {
1227					assert!(v.is_none());
1228					*v = Some(10);
1229					Ok(())
1230				});
1231			assert_eq!(A::contains_key((2, 20, 200)), true);
1232			assert_eq!(A::get((2, 20, 200)), Some(10));
1233			let _: Result<(), ()> =
1234				AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20, 200), |v| {
1235					*v = Some(v.unwrap() * 10);
1236					Ok(())
1237				});
1238			assert_eq!(A::contains_key((2, 20, 200)), true);
1239			assert_eq!(A::get((2, 20, 200)), Some(100));
1240			assert_eq!(A::try_get((2, 20, 200)), Ok(100));
1241			let _: Result<(), ()> =
1242				AValueQueryWithAnOnEmpty::try_mutate_exists((2, 20, 200), |v| {
1243					*v = Some(v.unwrap() * 10);
1244					Err(())
1245				});
1246			assert_eq!(A::contains_key((2, 20, 200)), true);
1247			assert_eq!(A::get((2, 20, 200)), Some(100));
1248
1249			A::insert((2, 20, 200), 10);
1250			assert_eq!(A::take((2, 20, 200)), Some(10));
1251			assert_eq!(A::contains_key((2, 20, 200)), false);
1252			assert_eq!(AValueQueryWithAnOnEmpty::take((2, 20, 200)), 98);
1253			assert_eq!(A::contains_key((2, 20, 200)), false);
1254			assert_eq!(A::try_get((2, 20, 200)), Err(()));
1255
1256			B::insert((2, 20, 200), 10);
1257			assert_eq!(
1258				A::migrate_keys(
1259					(2, 20, 200),
1260					(
1261						Box::new(|key| Blake2_256::hash(key).to_vec()),
1262						Box::new(|key| Blake2_256::hash(key).to_vec()),
1263						Box::new(|key| Twox128::hash(key).to_vec()),
1264					),
1265				),
1266				Some(10)
1267			);
1268			assert_eq!(A::contains_key((2, 20, 200)), true);
1269			assert_eq!(A::get((2, 20, 200)), Some(10));
1270
1271			A::insert((3, 30, 300), 10);
1272			A::insert((4, 40, 400), 10);
1273			let _ = A::clear(u32::max_value(), None);
1274			assert_eq!(A::contains_key((3, 30, 300)), false);
1275			assert_eq!(A::contains_key((4, 40, 400)), false);
1276
1277			A::insert((3, 30, 300), 10);
1278			A::insert((4, 40, 400), 10);
1279			assert_eq!(A::iter_values().collect::<Vec<_>>(), vec![10, 10]);
1280
1281			C::insert((3, 30, 300), 10);
1282			C::insert((4, 40, 400), 10);
1283			A::translate_values::<u8, _>(|v| Some((v * 2).into()));
1284			assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40, 400), 20), ((3, 30, 300), 20)]);
1285
1286			A::insert((3, 30, 300), 10);
1287			A::insert((4, 40, 400), 10);
1288			assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40, 400), 10), ((3, 30, 300), 10)]);
1289			assert_eq!(
1290				A::drain().collect::<Vec<_>>(),
1291				vec![((4, 40, 400), 10), ((3, 30, 300), 10)]
1292			);
1293			assert_eq!(A::iter().collect::<Vec<_>>(), vec![]);
1294
1295			C::insert((3, 30, 300), 10);
1296			C::insert((4, 40, 400), 10);
1297			A::translate::<u8, _>(|(k1, k2, k3), v| {
1298				Some((k1 * k2 as u16 * v as u16 / k3 as u16).into())
1299			});
1300			assert_eq!(A::iter().collect::<Vec<_>>(), vec![((4, 40, 400), 4), ((3, 30, 300), 3)]);
1301
1302			let mut entries = vec![];
1303			A::build_metadata(
1304				sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1305				vec![],
1306				&mut entries,
1307			);
1308			AValueQueryWithAnOnEmpty::build_metadata(
1309				sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1310				vec![],
1311				&mut entries,
1312			);
1313			assert_eq!(
1314				entries,
1315				vec![
1316					StorageEntryMetadataIR {
1317						name: "Foo",
1318						modifier: StorageEntryModifierIR::Optional,
1319						ty: StorageEntryTypeIR::Map {
1320							hashers: vec![
1321								StorageHasherIR::Blake2_128Concat,
1322								StorageHasherIR::Blake2_128Concat,
1323								StorageHasherIR::Twox64Concat
1324							],
1325							key: scale_info::meta_type::<(u16, u16, u16)>(),
1326							value: scale_info::meta_type::<u32>(),
1327						},
1328						default: Option::<u32>::None.encode(),
1329						docs: vec![],
1330						deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1331					},
1332					StorageEntryMetadataIR {
1333						name: "Foo",
1334						modifier: StorageEntryModifierIR::Default,
1335						ty: StorageEntryTypeIR::Map {
1336							hashers: vec![
1337								StorageHasherIR::Blake2_128Concat,
1338								StorageHasherIR::Blake2_128Concat,
1339								StorageHasherIR::Twox64Concat
1340							],
1341							key: scale_info::meta_type::<(u16, u16, u16)>(),
1342							value: scale_info::meta_type::<u32>(),
1343						},
1344						default: 98u32.encode(),
1345						docs: vec![],
1346						deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
1347					}
1348				]
1349			);
1350
1351			let _ = WithLen::clear(u32::max_value(), None);
1352			assert_eq!(WithLen::decode_len((3, 30, 300)), None);
1353			WithLen::append((0, 100, 1000), 10);
1354			assert_eq!(WithLen::decode_len((0, 100, 1000)), Some(1));
1355
1356			A::insert((3, 30, 300), 11);
1357			A::insert((3, 30, 301), 12);
1358			A::insert((4, 40, 400), 13);
1359			A::insert((4, 40, 401), 14);
1360			assert_eq!(A::iter_prefix_values((3,)).collect::<Vec<_>>(), vec![11, 12]);
1361			assert_eq!(A::iter_prefix_values((4,)).collect::<Vec<_>>(), vec![14, 13]);
1362			assert_eq!(A::iter_prefix_values((3, 30)).collect::<Vec<_>>(), vec![11, 12]);
1363			assert_eq!(A::iter_prefix_values((4, 40)).collect::<Vec<_>>(), vec![14, 13]);
1364		});
1365	}
1366}