referrerpolicy=no-referrer-when-downgrade

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