referrerpolicy=no-referrer-when-downgrade

frame_support/storage/types/
map.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 map type. Implements StorageMap, StorageIterableMap, StoragePrefixedMap traits and their
19//! methods directly.
20
21use crate::{
22	storage::{
23		types::{OptionQuery, QueryKindTrait, StorageEntryMetadataBuilder},
24		KeyLenOf, StorageAppend, StorageDecodeLength, StoragePrefixedMap, StorageTryAppend,
25	},
26	traits::{Get, GetDefault, StorageInfo, StorageInstance},
27	StorageHasher, Twox128,
28};
29use alloc::{vec, vec::Vec};
30use codec::{Decode, Encode, EncodeLike, FullCodec, MaxEncodedLen};
31use frame_support::storage::StorageDecodeNonDedupLength;
32use sp_arithmetic::traits::SaturatedConversion;
33use sp_metadata_ir::{StorageEntryMetadataIR, StorageEntryTypeIR};
34
35/// A type representing a *map* in storage. A *storage map* is a mapping of keys to values of a
36/// given type stored on-chain.
37///
38/// For general information regarding the `#[pallet::storage]` attribute, refer to
39/// [`crate::pallet_macros::storage`].
40///
41/// # Example
42///
43/// ```
44/// #[frame_support::pallet]
45/// mod pallet {
46///     # use frame_support::pallet_prelude::*;
47///     # #[pallet::config]
48///     # pub trait Config: frame_system::Config {}
49///     # #[pallet::pallet]
50///     # pub struct Pallet<T>(_);
51/// 	/// A kitchen-sink StorageMap, with all possible additional attributes.
52///     #[pallet::storage]
53/// 	#[pallet::getter(fn foo)]
54/// 	#[pallet::storage_prefix = "OtherFoo"]
55/// 	#[pallet::unbounded]
56///     pub type Foo<T> = StorageMap<
57/// 		_,
58/// 		Blake2_128Concat,
59/// 		u32,
60/// 		u32,
61/// 		ValueQuery
62/// 	>;
63///
64/// 	/// Alternative named syntax.
65///     #[pallet::storage]
66///     pub type Bar<T> = StorageMap<
67/// 		Hasher = Blake2_128Concat,
68/// 		Key = u32,
69/// 		Value = u32,
70/// 		QueryKind = ValueQuery
71/// 	>;
72/// }
73/// ```
74pub struct StorageMap<
75	Prefix,
76	Hasher,
77	Key,
78	Value,
79	QueryKind = OptionQuery,
80	OnEmpty = GetDefault,
81	MaxValues = GetDefault,
82>(core::marker::PhantomData<(Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues)>);
83
84impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> Get<u32>
85	for KeyLenOf<StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>>
86where
87	Prefix: StorageInstance,
88	Hasher: crate::hash::StorageHasher,
89	Key: FullCodec + MaxEncodedLen,
90{
91	fn get() -> u32 {
92		// The `max_len` of the key hash plus the pallet prefix and storage prefix (which both are
93		// hashed with `Twox128`).
94		let z = Hasher::max_len::<Key>() + Twox128::max_len::<()>() * 2;
95		z as u32
96	}
97}
98
99impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
100	crate::storage::generator::StorageMap<Key, Value>
101	for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
102where
103	Prefix: StorageInstance,
104	Hasher: crate::hash::StorageHasher,
105	Key: FullCodec,
106	Value: FullCodec,
107	QueryKind: QueryKindTrait<Value, OnEmpty>,
108	OnEmpty: Get<QueryKind::Query> + 'static,
109	MaxValues: Get<Option<u32>>,
110{
111	type Query = QueryKind::Query;
112	type Hasher = Hasher;
113	fn pallet_prefix() -> &'static [u8] {
114		Prefix::pallet_prefix().as_bytes()
115	}
116	fn storage_prefix() -> &'static [u8] {
117		Prefix::STORAGE_PREFIX.as_bytes()
118	}
119	fn prefix_hash() -> [u8; 32] {
120		Prefix::prefix_hash()
121	}
122	fn from_optional_value_to_query(v: Option<Value>) -> Self::Query {
123		QueryKind::from_optional_value_to_query(v)
124	}
125	fn from_query_to_optional_value(v: Self::Query) -> Option<Value> {
126		QueryKind::from_query_to_optional_value(v)
127	}
128}
129
130impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> StoragePrefixedMap<Value>
131	for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
132where
133	Prefix: StorageInstance,
134	Hasher: crate::hash::StorageHasher,
135	Key: FullCodec,
136	Value: FullCodec,
137	QueryKind: QueryKindTrait<Value, OnEmpty>,
138	OnEmpty: Get<QueryKind::Query> + 'static,
139	MaxValues: Get<Option<u32>>,
140{
141	fn pallet_prefix() -> &'static [u8] {
142		<Self as crate::storage::generator::StorageMap<Key, Value>>::pallet_prefix()
143	}
144	fn storage_prefix() -> &'static [u8] {
145		<Self as crate::storage::generator::StorageMap<Key, Value>>::storage_prefix()
146	}
147}
148
149impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
150	StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
151where
152	Prefix: StorageInstance,
153	Hasher: crate::hash::StorageHasher,
154	Key: FullCodec,
155	Value: FullCodec,
156	QueryKind: QueryKindTrait<Value, OnEmpty>,
157	OnEmpty: Get<QueryKind::Query> + 'static,
158	MaxValues: Get<Option<u32>>,
159{
160	/// Get the storage key used to fetch a value corresponding to a specific key.
161	pub fn hashed_key_for<KeyArg: EncodeLike<Key>>(key: KeyArg) -> Vec<u8> {
162		<Self as crate::storage::StorageMap<Key, Value>>::hashed_key_for(key)
163	}
164
165	/// Does the value (explicitly) exist in storage?
166	pub fn contains_key<KeyArg: EncodeLike<Key>>(key: KeyArg) -> bool {
167		<Self as crate::storage::StorageMap<Key, Value>>::contains_key(key)
168	}
169
170	/// Load the value associated with the given key from the map.
171	pub fn get<KeyArg: EncodeLike<Key>>(key: KeyArg) -> QueryKind::Query {
172		<Self as crate::storage::StorageMap<Key, Value>>::get(key)
173	}
174
175	/// Try to get the value for the given key from the map.
176	///
177	/// Returns `Ok` if it exists, `Err` if not.
178	pub fn try_get<KeyArg: EncodeLike<Key>>(key: KeyArg) -> Result<Value, ()> {
179		<Self as crate::storage::StorageMap<Key, Value>>::try_get(key)
180	}
181
182	/// Swap the values of two keys.
183	pub fn swap<KeyArg1: EncodeLike<Key>, KeyArg2: EncodeLike<Key>>(key1: KeyArg1, key2: KeyArg2) {
184		<Self as crate::storage::StorageMap<Key, Value>>::swap(key1, key2)
185	}
186
187	/// Store or remove the value to be associated with `key` so that `get` returns the `query`.
188	pub fn set<KeyArg: EncodeLike<Key>>(key: KeyArg, q: QueryKind::Query) {
189		<Self as crate::storage::StorageMap<Key, Value>>::set(key, q)
190	}
191
192	/// Store a value to be associated with the given key from the map.
193	pub fn insert<KeyArg: EncodeLike<Key>, ValArg: EncodeLike<Value>>(key: KeyArg, val: ValArg) {
194		<Self as crate::storage::StorageMap<Key, Value>>::insert(key, val)
195	}
196
197	/// Remove the value under a key.
198	pub fn remove<KeyArg: EncodeLike<Key>>(key: KeyArg) {
199		<Self as crate::storage::StorageMap<Key, Value>>::remove(key)
200	}
201
202	/// Mutate the value under a key.
203	pub fn mutate<KeyArg: EncodeLike<Key>, R, F: FnOnce(&mut QueryKind::Query) -> R>(
204		key: KeyArg,
205		f: F,
206	) -> R {
207		<Self as crate::storage::StorageMap<Key, Value>>::mutate(key, f)
208	}
209
210	/// Mutate the item, only if an `Ok` value is returned.
211	pub fn try_mutate<KeyArg, R, E, F>(key: KeyArg, f: F) -> Result<R, E>
212	where
213		KeyArg: EncodeLike<Key>,
214		F: FnOnce(&mut QueryKind::Query) -> Result<R, E>,
215	{
216		<Self as crate::storage::StorageMap<Key, Value>>::try_mutate(key, f)
217	}
218
219	/// Mutate the value under a key iff it exists. Do nothing and return the default value if not.
220	pub fn mutate_extant<KeyArg: EncodeLike<Key>, R: Default, F: FnOnce(&mut Value) -> R>(
221		key: KeyArg,
222		f: F,
223	) -> R {
224		<Self as crate::storage::StorageMap<Key, Value>>::mutate_extant(key, f)
225	}
226
227	/// Mutate the value under a key. Deletes the item if mutated to a `None`.
228	pub fn mutate_exists<KeyArg: EncodeLike<Key>, R, F: FnOnce(&mut Option<Value>) -> R>(
229		key: KeyArg,
230		f: F,
231	) -> R {
232		<Self as crate::storage::StorageMap<Key, Value>>::mutate_exists(key, f)
233	}
234
235	/// Mutate the item, only if an `Ok` value is returned. Deletes the item if mutated to a `None`.
236	/// `f` will always be called with an option representing if the storage item exists (`Some<V>`)
237	/// or if the storage item does not exist (`None`), independent of the `QueryType`.
238	pub fn try_mutate_exists<KeyArg, R, E, F>(key: KeyArg, f: F) -> Result<R, E>
239	where
240		KeyArg: EncodeLike<Key>,
241		F: FnOnce(&mut Option<Value>) -> Result<R, E>,
242	{
243		<Self as crate::storage::StorageMap<Key, Value>>::try_mutate_exists(key, f)
244	}
245
246	/// Take the value under a key.
247	pub fn take<KeyArg: EncodeLike<Key>>(key: KeyArg) -> QueryKind::Query {
248		<Self as crate::storage::StorageMap<Key, Value>>::take(key)
249	}
250
251	/// Append the given items to the value in the storage.
252	///
253	/// `Value` is required to implement `codec::EncodeAppend`.
254	///
255	/// # Warning
256	///
257	/// If the storage item is not encoded properly, the storage will be overwritten
258	/// and set to `[item]`. Any default value set for the storage item will be ignored
259	/// on overwrite.
260	pub fn append<Item, EncodeLikeItem, EncodeLikeKey>(key: EncodeLikeKey, item: EncodeLikeItem)
261	where
262		EncodeLikeKey: EncodeLike<Key>,
263		Item: Encode,
264		EncodeLikeItem: EncodeLike<Item>,
265		Value: StorageAppend<Item>,
266	{
267		<Self as crate::storage::StorageMap<Key, Value>>::append(key, item)
268	}
269
270	/// Read the length of the storage value without decoding the entire value under the
271	/// given `key`.
272	///
273	/// `Value` is required to implement [`StorageDecodeLength`].
274	///
275	/// If the value does not exists or it fails to decode the length, `None` is returned.
276	/// Otherwise `Some(len)` is returned.
277	///
278	/// # Warning
279	///
280	/// `None` does not mean that `get()` does not return a value. The default value is completely
281	/// ignored by this function.
282	pub fn decode_len<KeyArg: EncodeLike<Key>>(key: KeyArg) -> Option<usize>
283	where
284		Value: StorageDecodeLength,
285	{
286		<Self as crate::storage::StorageMap<Key, Value>>::decode_len(key)
287	}
288
289	/// Read the length of the storage value without decoding the entire value.
290	///
291	/// `Value` is required to implement [`StorageDecodeNonDedupLength`].
292	///
293	/// If the value does not exists or it fails to decode the length, `None` is returned.
294	/// Otherwise `Some(len)` is returned.
295	///
296	/// # Warning
297	///
298	///  - `None` does not mean that `get()` does not return a value. The default value is
299	///    completely
300	/// ignored by this function.
301	///
302	/// - The value returned is the non-deduplicated length of the underlying Vector in storage.This
303	/// means that any duplicate items are included.
304	pub fn decode_non_dedup_len<KeyArg: EncodeLike<Key>>(key: KeyArg) -> Option<usize>
305	where
306		Value: StorageDecodeNonDedupLength,
307	{
308		<Self as crate::storage::StorageMap<Key, Value>>::decode_non_dedup_len(key)
309	}
310
311	/// Migrate an item with the given `key` from a defunct `OldHasher` to the current hasher.
312	///
313	/// If the key doesn't exist, then it's a no-op. If it does, then it returns its value.
314	pub fn migrate_key<OldHasher: crate::hash::StorageHasher, KeyArg: EncodeLike<Key>>(
315		key: KeyArg,
316	) -> Option<Value> {
317		<Self as crate::storage::StorageMap<Key, Value>>::migrate_key::<OldHasher, _>(key)
318	}
319
320	/// Remove all values of the storage in the overlay and up to `limit` in the backend.
321	///
322	/// All values in the client overlay will be deleted, if there is some `limit` then up to
323	/// `limit` values are deleted from the client backend, if `limit` is none then all values in
324	/// the client backend are deleted.
325	///
326	/// # Note
327	///
328	/// Calling this multiple times per block with a `limit` set leads always to the same keys being
329	/// removed and the same result being returned. This happens because the keys to delete in the
330	/// overlay are not taken into account when deleting keys in the backend.
331	#[deprecated = "Use `clear` instead"]
332	pub fn remove_all(limit: Option<u32>) -> sp_io::KillStorageResult {
333		#[allow(deprecated)]
334		<Self as crate::storage::StoragePrefixedMap<Value>>::remove_all(limit)
335	}
336
337	/// Attempt to remove all items from the map.
338	///
339	/// Returns [`MultiRemovalResults`](sp_io::MultiRemovalResults) to inform about the result. Once
340	/// the resultant `maybe_cursor` field is `None`, then no further items remain to be deleted.
341	///
342	/// NOTE: After the initial call for any given map, it is important that no further items
343	/// are inserted into the map. If so, then the map may not be empty when the resultant
344	/// `maybe_cursor` is `None`.
345	///
346	/// # Limit
347	///
348	/// A `limit` must always be provided through in order to cap the maximum
349	/// amount of deletions done in a single call. This is one fewer than the
350	/// maximum number of backend iterations which may be done by this operation and as such
351	/// represents the maximum number of backend deletions which may happen. A `limit` of zero
352	/// implies that no keys will be deleted, though there may be a single iteration done.
353	///
354	/// # Cursor
355	///
356	/// A *cursor* may be passed in to this operation with `maybe_cursor`. `None` should only be
357	/// passed once (in the initial call) for any given storage map. Subsequent calls
358	/// operating on the same map should always pass `Some`, and this should be equal to the
359	/// previous call result's `maybe_cursor` field.
360	pub fn clear(limit: u32, maybe_cursor: Option<&[u8]>) -> sp_io::MultiRemovalResults {
361		<Self as crate::storage::StoragePrefixedMap<Value>>::clear(limit, maybe_cursor)
362	}
363
364	/// Iter over all value of the storage.
365	///
366	/// NOTE: If a value failed to decode because storage is corrupted then it is skipped.
367	pub fn iter_values() -> crate::storage::PrefixIterator<Value> {
368		<Self as crate::storage::StoragePrefixedMap<Value>>::iter_values()
369	}
370
371	/// Translate the values of all elements by a function `f`, in the map in no particular order.
372	///
373	/// By returning `None` from `f` for an element, you'll remove it from the map.
374	///
375	/// NOTE: If a value fail to decode because storage is corrupted then it is skipped.
376	///
377	/// # Warning
378	///
379	/// This function must be used with care, before being updated the storage still contains the
380	/// old type, thus other calls (such as `get`) will fail at decoding it.
381	///
382	/// # Usage
383	///
384	/// This would typically be called inside the module implementation of on_runtime_upgrade.
385	pub fn translate_values<OldValue: Decode, F: FnMut(OldValue) -> Option<Value>>(f: F) {
386		<Self as crate::storage::StoragePrefixedMap<Value>>::translate_values(f)
387	}
388
389	/// Try and append the given item to the value in the storage.
390	///
391	/// Is only available if `Value` of the storage implements [`StorageTryAppend`].
392	pub fn try_append<KArg, Item, EncodeLikeItem>(key: KArg, item: EncodeLikeItem) -> Result<(), ()>
393	where
394		KArg: EncodeLike<Key> + Clone,
395		Item: Encode,
396		EncodeLikeItem: EncodeLike<Item>,
397		Value: StorageTryAppend<Item>,
398	{
399		<Self as crate::storage::TryAppendMap<Key, Value, Item>>::try_append(key, item)
400	}
401}
402
403impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
404	StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
405where
406	Prefix: StorageInstance,
407	Hasher: crate::hash::StorageHasher + crate::ReversibleStorageHasher,
408	Key: FullCodec,
409	Value: FullCodec,
410	QueryKind: QueryKindTrait<Value, OnEmpty>,
411	OnEmpty: Get<QueryKind::Query> + 'static,
412	MaxValues: Get<Option<u32>>,
413{
414	/// Enumerate all elements in the map in no particular order.
415	///
416	/// If you alter the map while doing this, you'll get undefined results.
417	pub fn iter() -> crate::storage::PrefixIterator<(Key, Value)> {
418		<Self as crate::storage::IterableStorageMap<Key, Value>>::iter()
419	}
420
421	/// Enumerate all elements in the map after a specified `starting_raw_key` in no
422	/// particular order.
423	///
424	/// If you alter the map while doing this, you'll get undefined results.
425	pub fn iter_from(starting_raw_key: Vec<u8>) -> crate::storage::PrefixIterator<(Key, Value)> {
426		<Self as crate::storage::IterableStorageMap<Key, Value>>::iter_from(starting_raw_key)
427	}
428
429	/// Enumerate all elements in the map after a specified `starting_key` in no
430	/// particular order.
431	///
432	/// If you alter the map while doing this, you'll get undefined results.
433	pub fn iter_from_key(
434		starting_key: impl EncodeLike<Key>,
435	) -> crate::storage::PrefixIterator<(Key, Value)> {
436		Self::iter_from(Self::hashed_key_for(starting_key))
437	}
438
439	/// Enumerate all keys in the map in no particular order.
440	///
441	/// If you alter the map while doing this, you'll get undefined results.
442	pub fn iter_keys() -> crate::storage::KeyPrefixIterator<Key> {
443		<Self as crate::storage::IterableStorageMap<Key, Value>>::iter_keys()
444	}
445
446	/// Enumerate all keys in the map after a specified `starting_raw_key` in no particular
447	/// order.
448	///
449	/// If you alter the map while doing this, you'll get undefined results.
450	pub fn iter_keys_from(starting_raw_key: Vec<u8>) -> crate::storage::KeyPrefixIterator<Key> {
451		<Self as crate::storage::IterableStorageMap<Key, Value>>::iter_keys_from(starting_raw_key)
452	}
453
454	/// Enumerate all keys in the map after a specified `starting_key` in no particular
455	/// order.
456	///
457	/// If you alter the map while doing this, you'll get undefined results.
458	pub fn iter_keys_from_key(
459		starting_key: impl EncodeLike<Key>,
460	) -> crate::storage::KeyPrefixIterator<Key> {
461		Self::iter_keys_from(Self::hashed_key_for(starting_key))
462	}
463
464	/// Remove all elements from the map and iterate through them in no particular order.
465	///
466	/// If you add elements to the map while doing this, you'll get undefined results.
467	pub fn drain() -> crate::storage::PrefixIterator<(Key, Value)> {
468		<Self as crate::storage::IterableStorageMap<Key, Value>>::drain()
469	}
470
471	/// Translate the values of all elements by a function `f`, in the map in no particular order.
472	///
473	/// By returning `None` from `f` for an element, you'll remove it from the map.
474	///
475	/// NOTE: If a value fails to decode because storage is corrupted, then it will log an error and
476	/// be skipped in production, or panic in development.
477	pub fn translate<O: Decode, F: FnMut(Key, O) -> Option<Value>>(f: F) {
478		<Self as crate::storage::IterableStorageMap<Key, Value>>::translate(f)
479	}
480}
481
482impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> StorageEntryMetadataBuilder
483	for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
484where
485	Prefix: StorageInstance,
486	Hasher: crate::hash::StorageHasher,
487	Key: FullCodec + scale_info::StaticTypeInfo,
488	Value: FullCodec + scale_info::StaticTypeInfo,
489	QueryKind: QueryKindTrait<Value, OnEmpty>,
490	OnEmpty: Get<QueryKind::Query> + 'static,
491	MaxValues: Get<Option<u32>>,
492{
493	fn build_metadata(
494		deprecation_status: sp_metadata_ir::ItemDeprecationInfoIR,
495		docs: Vec<&'static str>,
496		entries: &mut Vec<StorageEntryMetadataIR>,
497	) {
498		let docs = if cfg!(feature = "no-metadata-docs") { vec![] } else { docs };
499
500		let entry = StorageEntryMetadataIR {
501			name: Prefix::STORAGE_PREFIX,
502			modifier: QueryKind::METADATA,
503			ty: StorageEntryTypeIR::Map {
504				hashers: vec![Hasher::METADATA],
505				key: scale_info::meta_type::<Key>(),
506				value: scale_info::meta_type::<Value>(),
507			},
508			default: OnEmpty::get().encode(),
509			docs,
510			deprecation_info: deprecation_status,
511		};
512
513		entries.push(entry);
514	}
515}
516
517impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues> crate::traits::StorageInfoTrait
518	for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
519where
520	Prefix: StorageInstance,
521	Hasher: crate::hash::StorageHasher,
522	Key: FullCodec + MaxEncodedLen,
523	Value: FullCodec + MaxEncodedLen,
524	QueryKind: QueryKindTrait<Value, OnEmpty>,
525	OnEmpty: Get<QueryKind::Query> + 'static,
526	MaxValues: Get<Option<u32>>,
527{
528	fn storage_info() -> Vec<StorageInfo> {
529		vec![StorageInfo {
530			pallet_name: Self::pallet_prefix().to_vec(),
531			storage_name: Self::storage_prefix().to_vec(),
532			prefix: Self::final_prefix().to_vec(),
533			max_values: MaxValues::get(),
534			max_size: Some(
535				Hasher::max_len::<Key>()
536					.saturating_add(Value::max_encoded_len())
537					.saturated_into(),
538			),
539		}]
540	}
541}
542
543/// It doesn't require to implement `MaxEncodedLen` and give no information for `max_size`.
544impl<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
545	crate::traits::PartialStorageInfoTrait
546	for StorageMap<Prefix, Hasher, Key, Value, QueryKind, OnEmpty, MaxValues>
547where
548	Prefix: StorageInstance,
549	Hasher: crate::hash::StorageHasher,
550	Key: FullCodec,
551	Value: FullCodec,
552	QueryKind: QueryKindTrait<Value, OnEmpty>,
553	OnEmpty: Get<QueryKind::Query> + 'static,
554	MaxValues: Get<Option<u32>>,
555{
556	fn partial_storage_info() -> Vec<StorageInfo> {
557		vec![StorageInfo {
558			pallet_name: Self::pallet_prefix().to_vec(),
559			storage_name: Self::storage_prefix().to_vec(),
560			prefix: Self::final_prefix().to_vec(),
561			max_values: MaxValues::get(),
562			max_size: None,
563		}]
564	}
565}
566
567#[cfg(test)]
568mod test {
569	use super::*;
570	use crate::{
571		hash::*,
572		storage::{types::ValueQuery, IterableStorageMap},
573	};
574	use sp_io::{hashing::twox_128, TestExternalities};
575	use sp_metadata_ir::{StorageEntryModifierIR, StorageEntryTypeIR, StorageHasherIR};
576
577	struct Prefix;
578	impl StorageInstance for Prefix {
579		fn pallet_prefix() -> &'static str {
580			"test"
581		}
582		const STORAGE_PREFIX: &'static str = "foo";
583	}
584
585	struct ADefault;
586	impl crate::traits::Get<u32> for ADefault {
587		fn get() -> u32 {
588			97
589		}
590	}
591
592	#[test]
593	fn keylenof_works() {
594		// Works with Blake2_128Concat.
595		type A = StorageMap<Prefix, Blake2_128Concat, u32, u32>;
596		let size = 16 * 2 // Two Twox128
597			+ 16 + 4; // Blake2_128Concat = hash + key
598		assert_eq!(KeyLenOf::<A>::get(), size);
599
600		// Works with Blake2_256.
601		type B = StorageMap<Prefix, Blake2_256, u32, u32>;
602		let size = 16 * 2 // Two Twox128
603			+ 32; // Blake2_256
604		assert_eq!(KeyLenOf::<B>::get(), size);
605
606		// Works with Twox64Concat.
607		type C = StorageMap<Prefix, Twox64Concat, u32, u32>;
608		let size = 16 * 2 // Two Twox128
609			+ 8 + 4; // Twox64Concat = hash + key
610		assert_eq!(KeyLenOf::<C>::get(), size);
611	}
612
613	#[test]
614	fn test() {
615		type A = StorageMap<Prefix, Blake2_128Concat, u16, u32, OptionQuery>;
616		type AValueQueryWithAnOnEmpty =
617			StorageMap<Prefix, Blake2_128Concat, u16, u32, ValueQuery, ADefault>;
618		type B = StorageMap<Prefix, Blake2_256, u16, u32, ValueQuery>;
619		type C = StorageMap<Prefix, Blake2_128Concat, u16, u8, ValueQuery>;
620		type WithLen = StorageMap<Prefix, Blake2_128Concat, u16, Vec<u32>>;
621
622		TestExternalities::default().execute_with(|| {
623			let mut k: Vec<u8> = vec![];
624			k.extend(&twox_128(b"test"));
625			k.extend(&twox_128(b"foo"));
626			k.extend(&3u16.blake2_128_concat());
627			assert_eq!(A::hashed_key_for(3).to_vec(), k);
628
629			assert_eq!(A::contains_key(3), false);
630			assert_eq!(A::get(3), None);
631			assert_eq!(AValueQueryWithAnOnEmpty::get(3), 97);
632
633			A::insert(3, 10);
634			assert_eq!(A::contains_key(3), true);
635			assert_eq!(A::get(3), Some(10));
636			assert_eq!(A::try_get(3), Ok(10));
637			assert_eq!(AValueQueryWithAnOnEmpty::get(3), 10);
638
639			A::swap(3, 2);
640			assert_eq!(A::contains_key(3), false);
641			assert_eq!(A::contains_key(2), true);
642			assert_eq!(A::get(3), None);
643			assert_eq!(A::try_get(3), Err(()));
644			assert_eq!(AValueQueryWithAnOnEmpty::get(3), 97);
645			assert_eq!(A::get(2), Some(10));
646			assert_eq!(AValueQueryWithAnOnEmpty::get(2), 10);
647
648			A::remove(2);
649			assert_eq!(A::contains_key(2), false);
650			assert_eq!(A::get(2), None);
651
652			AValueQueryWithAnOnEmpty::mutate(2, |v| *v = *v * 2);
653			AValueQueryWithAnOnEmpty::mutate(2, |v| *v = *v * 2);
654			assert_eq!(AValueQueryWithAnOnEmpty::contains_key(2), true);
655			assert_eq!(AValueQueryWithAnOnEmpty::get(2), 97 * 4);
656
657			A::remove(2);
658			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate(2, |v| {
659				*v = *v * 2;
660				Ok(())
661			});
662			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate(2, |v| {
663				*v = *v * 2;
664				Ok(())
665			});
666			assert_eq!(A::contains_key(2), true);
667			assert_eq!(A::get(2), Some(97 * 4));
668
669			A::remove(2);
670			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate(2, |v| {
671				*v = *v * 2;
672				Err(())
673			});
674			assert_eq!(A::contains_key(2), false);
675
676			A::remove(2);
677			AValueQueryWithAnOnEmpty::mutate_exists(2, |v| {
678				assert!(v.is_none());
679				*v = Some(10);
680			});
681			assert_eq!(A::contains_key(2), true);
682			assert_eq!(A::get(2), Some(10));
683			AValueQueryWithAnOnEmpty::mutate_exists(2, |v| {
684				*v = Some(v.unwrap() * 10);
685			});
686			assert_eq!(A::contains_key(2), true);
687			assert_eq!(A::get(2), Some(100));
688
689			A::remove(2);
690			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists(2, |v| {
691				assert!(v.is_none());
692				*v = Some(10);
693				Ok(())
694			});
695			assert_eq!(A::contains_key(2), true);
696			assert_eq!(A::get(2), Some(10));
697			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists(2, |v| {
698				*v = Some(v.unwrap() * 10);
699				Ok(())
700			});
701			assert_eq!(A::contains_key(2), true);
702			assert_eq!(A::get(2), Some(100));
703			let _: Result<(), ()> = AValueQueryWithAnOnEmpty::try_mutate_exists(2, |v| {
704				*v = Some(v.unwrap() * 10);
705				Err(())
706			});
707			assert_eq!(A::contains_key(2), true);
708			assert_eq!(A::get(2), Some(100));
709
710			A::insert(2, 10);
711			assert_eq!(A::take(2), Some(10));
712			assert_eq!(A::contains_key(2), false);
713			assert_eq!(AValueQueryWithAnOnEmpty::take(2), 97);
714			assert_eq!(A::contains_key(2), false);
715
716			// Set non-existing.
717			B::set(30, 100);
718
719			assert_eq!(B::contains_key(30), true);
720			assert_eq!(B::get(30), 100);
721			assert_eq!(B::try_get(30), Ok(100));
722
723			// Set existing.
724			B::set(30, 101);
725
726			assert_eq!(B::contains_key(30), true);
727			assert_eq!(B::get(30), 101);
728			assert_eq!(B::try_get(30), Ok(101));
729
730			// Set non-existing.
731			A::set(30, Some(100));
732
733			assert_eq!(A::contains_key(30), true);
734			assert_eq!(A::get(30), Some(100));
735			assert_eq!(A::try_get(30), Ok(100));
736
737			// Set existing.
738			A::set(30, Some(101));
739
740			assert_eq!(A::contains_key(30), true);
741			assert_eq!(A::get(30), Some(101));
742			assert_eq!(A::try_get(30), Ok(101));
743
744			// Unset existing.
745			A::set(30, None);
746
747			assert_eq!(A::contains_key(30), false);
748			assert_eq!(A::get(30), None);
749			assert_eq!(A::try_get(30), Err(()));
750
751			// Unset non-existing.
752			A::set(31, None);
753
754			assert_eq!(A::contains_key(31), false);
755			assert_eq!(A::get(31), None);
756			assert_eq!(A::try_get(31), Err(()));
757
758			B::insert(2, 10);
759			assert_eq!(A::migrate_key::<Blake2_256, _>(2), Some(10));
760			assert_eq!(A::contains_key(2), true);
761			assert_eq!(A::get(2), Some(10));
762
763			A::insert(3, 10);
764			A::insert(4, 10);
765			let _ = A::clear(u32::max_value(), None);
766			assert_eq!(A::contains_key(3), false);
767			assert_eq!(A::contains_key(4), false);
768
769			A::insert(3, 10);
770			A::insert(4, 10);
771			assert_eq!(A::iter_values().collect::<Vec<_>>(), vec![10, 10]);
772
773			C::insert(3, 10);
774			C::insert(4, 10);
775			A::translate_values::<u8, _>(|v| Some((v * 2).into()));
776			assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 20), (3, 20)]);
777
778			A::insert(3, 10);
779			A::insert(4, 10);
780			assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 10), (3, 10)]);
781			assert_eq!(A::drain().collect::<Vec<_>>(), vec![(4, 10), (3, 10)]);
782			assert_eq!(A::iter().collect::<Vec<_>>(), vec![]);
783
784			C::insert(3, 10);
785			C::insert(4, 10);
786			A::translate::<u8, _>(|k, v| Some((k * v as u16).into()));
787			assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 40), (3, 30)]);
788
789			let translate_next = |k: u16, v: u8| Some((v as u16 / k).into());
790			let k = A::translate_next::<u8, _>(None, translate_next);
791			let k = A::translate_next::<u8, _>(k, translate_next);
792			assert_eq!(None, A::translate_next::<u8, _>(k, translate_next));
793			assert_eq!(A::iter().collect::<Vec<_>>(), vec![(4, 10), (3, 10)]);
794
795			let _ = A::translate_next::<u8, _>(None, |_, _| None);
796			assert_eq!(A::iter().collect::<Vec<_>>(), vec![(3, 10)]);
797
798			let mut entries = vec![];
799			A::build_metadata(
800				sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
801				vec![],
802				&mut entries,
803			);
804			AValueQueryWithAnOnEmpty::build_metadata(
805				sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated,
806				vec![],
807				&mut entries,
808			);
809			assert_eq!(
810				entries,
811				vec![
812					StorageEntryMetadataIR {
813						name: "foo",
814						modifier: StorageEntryModifierIR::Optional,
815						ty: StorageEntryTypeIR::Map {
816							hashers: vec![StorageHasherIR::Blake2_128Concat],
817							key: scale_info::meta_type::<u16>(),
818							value: scale_info::meta_type::<u32>(),
819						},
820						default: Option::<u32>::None.encode(),
821						docs: vec![],
822						deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated
823					},
824					StorageEntryMetadataIR {
825						name: "foo",
826						modifier: StorageEntryModifierIR::Default,
827						ty: StorageEntryTypeIR::Map {
828							hashers: vec![StorageHasherIR::Blake2_128Concat],
829							key: scale_info::meta_type::<u16>(),
830							value: scale_info::meta_type::<u32>(),
831						},
832						default: 97u32.encode(),
833						docs: vec![],
834						deprecation_info: sp_metadata_ir::ItemDeprecationInfoIR::NotDeprecated
835					}
836				]
837			);
838
839			let _ = WithLen::clear(u32::max_value(), None);
840			assert_eq!(WithLen::decode_len(3), None);
841			WithLen::append(0, 10);
842			assert_eq!(WithLen::decode_len(0), Some(1));
843		})
844	}
845}