Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 76efb19

Browse files
committed
implement DoubleMap
1 parent 9af109d commit 76efb19

File tree

10 files changed

+587
-453
lines changed

10 files changed

+587
-453
lines changed

frame/support/procedural/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ use proc_macro::TokenStream;
6767
/// * Map: `Foo: map hasher($hash) type => type`: Implements the
6868
/// [`StorageMap`](../frame_support/storage/trait.StorageMap.html) trait using the
6969
/// [`StorageMap generator`](../frame_support/storage/generator/trait.StorageMap.html).
70-
/// And [`StoragePrefixedMap`](../frame_support/storage/trait.StoragePrefixedMap.html).
7170
///
7271
/// `$hash` representing a choice of hashing algorithms available in the
7372
/// [`Hashable`](../frame_support/trait.Hashable.html) trait. You will generally want to use one
@@ -106,7 +105,6 @@ use proc_macro::TokenStream;
106105
/// * Double map: `Foo: double_map hasher($hash1) u32, hasher($hash2) u32 => u32`: Implements the
107106
/// [`StorageDoubleMap`](../frame_support/storage/trait.StorageDoubleMap.html) trait using the
108107
/// [`StorageDoubleMap generator`](../frame_support/storage/generator/trait.StorageDoubleMap.html).
109-
/// And [`StoragePrefixedMap`](../frame_support/storage/trait.StoragePrefixedMap.html).
110108
///
111109
/// `$hash1` and `$hash2` representing choices of hashing algorithms available in the
112110
/// [`Hashable`](../frame_support/trait.Hashable.html) trait. They must be chosen with care, see

frame/support/procedural/src/storage/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,6 @@ pub fn decl_storage_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStr
414414
StorageValue as _,
415415
StorageMap as _,
416416
StorageDoubleMap as _,
417-
StoragePrefixedMap as _,
418417
};
419418

420419
#scrate_decl

frame/support/procedural/src/storage/storage_struct.rs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -122,18 +122,6 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
122122
StorageLineTypeDef::Map(map) => {
123123
let hasher = map.hasher.to_storage_hasher_struct();
124124
quote!(
125-
impl<#impl_trait> #scrate::storage::StoragePrefixedMap<#value_type>
126-
for #storage_struct #optional_storage_where_clause
127-
{
128-
fn module_prefix() -> &'static [u8] {
129-
#instance_or_inherent::PREFIX.as_bytes()
130-
}
131-
132-
fn storage_prefix() -> &'static [u8] {
133-
#storage_name_str.as_bytes()
134-
}
135-
}
136-
137125
impl<#impl_trait> #scrate::#storage_generator_trait for #storage_struct
138126
#optional_storage_where_clause
139127
{
@@ -162,18 +150,6 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre
162150
let hasher1 = map.hasher1.to_storage_hasher_struct();
163151
let hasher2 = map.hasher2.to_storage_hasher_struct();
164152
quote!(
165-
impl<#impl_trait> #scrate::storage::StoragePrefixedMap<#value_type>
166-
for #storage_struct #optional_storage_where_clause
167-
{
168-
fn module_prefix() -> &'static [u8] {
169-
#instance_or_inherent::PREFIX.as_bytes()
170-
}
171-
172-
fn storage_prefix() -> &'static [u8] {
173-
#storage_name_str.as_bytes()
174-
}
175-
}
176-
177153
impl<#impl_trait> #scrate::#storage_generator_trait for #storage_struct
178154
#optional_storage_where_clause
179155
{

frame/support/src/hash.rs

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
//! Hash utilities.
1818
19-
use codec::Codec;
19+
use codec::{Codec, Decode};
2020
use sp_std::prelude::Vec;
2121
use sp_io::hashing::{blake2_128, blake2_256, twox_64, twox_128, twox_256};
2222

@@ -64,6 +64,20 @@ pub trait ReversibleStorageHasher: StorageHasher {
6464
fn reverse(x: &[u8]) -> &[u8];
6565
}
6666

67+
/// Trait to retrieve some info from hash of type `Key` encoded.
68+
pub trait StorageHasherInfo<Key> {
69+
/// Some info contained in the hash of type `Key` encoded.
70+
type Info;
71+
72+
/// Decode the hash and then decode the info from the decoded hash.
73+
///
74+
/// # WARNING
75+
///
76+
/// Even if info is (), input must be modified to have read the entire encoded hash.
77+
fn decode_hash_and_then_info<I: codec::Input>(input: &mut I)
78+
-> Result<Self::Info, codec::Error>;
79+
}
80+
6781
/// Store the key directly.
6882
pub struct Identity;
6983
impl StorageHasher for Identity {
@@ -77,6 +91,14 @@ impl ReversibleStorageHasher for Identity {
7791
x
7892
}
7993
}
94+
impl<Key: Decode> StorageHasherInfo<Key> for Identity {
95+
type Info = Key;
96+
fn decode_hash_and_then_info<I: codec::Input>(input: &mut I)
97+
-> Result<Self::Info, codec::Error>
98+
{
99+
Key::decode(input)
100+
}
101+
}
80102

81103
/// Hash storage keys with `concat(twox64(key), key)`
82104
pub struct Twox64Concat;
@@ -95,6 +117,15 @@ impl ReversibleStorageHasher for Twox64Concat {
95117
&x[8..]
96118
}
97119
}
120+
impl<Key: Decode> StorageHasherInfo<Key> for Twox64Concat {
121+
type Info = Key;
122+
fn decode_hash_and_then_info<I: codec::Input>(input: &mut I)
123+
-> Result<Self::Info, codec::Error>
124+
{
125+
input.read(&mut [0u8; 8])?;
126+
Key::decode(input)
127+
}
128+
}
98129

99130
/// Hash storage keys with `concat(blake2_128(key), key)`
100131
pub struct Blake2_128Concat;
@@ -113,6 +144,15 @@ impl ReversibleStorageHasher for Blake2_128Concat {
113144
&x[16..]
114145
}
115146
}
147+
impl<Key: Decode> StorageHasherInfo<Key> for Blake2_128Concat {
148+
type Info = Key;
149+
fn decode_hash_and_then_info<I: codec::Input>(input: &mut I)
150+
-> Result<Self::Info, codec::Error>
151+
{
152+
input.read(&mut [0u8; 16])?;
153+
Key::decode(input)
154+
}
155+
}
116156

117157
/// Hash storage keys with blake2 128
118158
pub struct Blake2_128;
@@ -122,6 +162,15 @@ impl StorageHasher for Blake2_128 {
122162
blake2_128(x)
123163
}
124164
}
165+
impl<Key> StorageHasherInfo<Key> for Blake2_128 {
166+
type Info = ();
167+
fn decode_hash_and_then_info<I: codec::Input>(input: &mut I)
168+
-> Result<Self::Info, codec::Error>
169+
{
170+
input.read(&mut [0u8; 16])?;
171+
Ok(())
172+
}
173+
}
125174

126175
/// Hash storage keys with blake2 256
127176
pub struct Blake2_256;
@@ -131,6 +180,15 @@ impl StorageHasher for Blake2_256 {
131180
blake2_256(x)
132181
}
133182
}
183+
impl<Key> StorageHasherInfo<Key> for Blake2_256 {
184+
type Info = ();
185+
fn decode_hash_and_then_info<I: codec::Input>(input: &mut I)
186+
-> Result<Self::Info, codec::Error>
187+
{
188+
input.read(&mut [0u8; 32])?;
189+
Ok(())
190+
}
191+
}
134192

135193
/// Hash storage keys with twox 128
136194
pub struct Twox128;
@@ -140,6 +198,15 @@ impl StorageHasher for Twox128 {
140198
twox_128(x)
141199
}
142200
}
201+
impl<Key> StorageHasherInfo<Key> for Twox128 {
202+
type Info = ();
203+
fn decode_hash_and_then_info<I: codec::Input>(input: &mut I)
204+
-> Result<Self::Info, codec::Error>
205+
{
206+
input.read(&mut [0u8; 16])?;
207+
Ok(())
208+
}
209+
}
143210

144211
/// Hash storage keys with twox 256
145212
pub struct Twox256;
@@ -149,10 +216,20 @@ impl StorageHasher for Twox256 {
149216
twox_256(x)
150217
}
151218
}
219+
impl<Key> StorageHasherInfo<Key> for Twox256 {
220+
type Info = ();
221+
fn decode_hash_and_then_info<I: codec::Input>(input: &mut I)
222+
-> Result<Self::Info, codec::Error>
223+
{
224+
input.read(&mut [0u8; 32])?;
225+
Ok(())
226+
}
227+
}
152228

153229
#[cfg(test)]
154230
mod tests {
155231
use super::*;
232+
use codec::Encode;
156233

157234
#[test]
158235
fn test_twox_64_concat() {
@@ -165,4 +242,38 @@ mod tests {
165242
let r = Blake2_128Concat::hash(b"foo");
166243
assert_eq!(r.split_at(16), (&blake2_128(b"foo")[..], &b"foo"[..]))
167244
}
245+
246+
#[test]
247+
fn test_storage_hasher_info() {
248+
type KeyType = [u8; 15];
249+
let key: KeyType = [3u8; 15];
250+
251+
let mut r = &Identity::hash(&(&key).encode()[..])[..];
252+
assert_eq!(<Identity as StorageHasherInfo<KeyType>>::decode_hash_and_then_info(&mut r), Ok(key));
253+
assert_eq!(r.len(), 0); // Assert input has indeed decoded the hash.
254+
255+
let mut r = &Twox64Concat::hash(&(&key).encode()[..])[..];
256+
assert_eq!(<Twox64Concat as StorageHasherInfo<KeyType>>::decode_hash_and_then_info(&mut r), Ok(key));
257+
assert_eq!(r.len(), 0); // Assert input has indeed decoded the hash.
258+
259+
let mut r = &Twox128::hash(&(&key).encode()[..])[..];
260+
assert_eq!(<Twox128 as StorageHasherInfo<KeyType>>::decode_hash_and_then_info(&mut r), Ok(()));
261+
assert_eq!(r.len(), 0); // Assert input has indeed decoded the hash.
262+
263+
let mut r = &Twox256::hash(&(&key).encode()[..])[..];
264+
assert_eq!(<Twox256 as StorageHasherInfo<KeyType>>::decode_hash_and_then_info(&mut r), Ok(()));
265+
assert_eq!(r.len(), 0); // Assert input has indeed decoded the hash.
266+
267+
let mut r = &Blake2_128Concat::hash(&(&key).encode()[..])[..];
268+
assert_eq!(<Blake2_128Concat as StorageHasherInfo<KeyType>>::decode_hash_and_then_info(&mut r), Ok(key));
269+
assert_eq!(r.len(), 0); // Assert input has indeed decoded the hash.
270+
271+
let mut r = &Blake2_128::hash(&(&key).encode()[..])[..];
272+
assert_eq!(<Blake2_128 as StorageHasherInfo<KeyType>>::decode_hash_and_then_info(&mut r), Ok(()));
273+
assert_eq!(r.len(), 0); // Assert input has indeed decoded the hash.
274+
275+
let mut r = &Blake2_256::hash(&(&key).encode()[..])[..];
276+
assert_eq!(<Blake2_256 as StorageHasherInfo<KeyType>>::decode_hash_and_then_info(&mut r), Ok(()));
277+
assert_eq!(r.len(), 0); // Assert input has indeed decoded the hash.
278+
}
168279
}

frame/support/src/lib.rs

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,7 @@ pub use self::hash::{
7070
Twox256, Twox128, Blake2_256, Blake2_128, Identity, Twox64Concat, Blake2_128Concat, Hashable,
7171
StorageHasher
7272
};
73-
pub use self::storage::{
74-
StorageValue, StorageMap, StorageDoubleMap, StoragePrefixedMap, IterableStorageMap,
75-
IterableStorageDoubleMap,
76-
};
73+
pub use self::storage::{StorageValue, StorageMap, StorageDoubleMap};
7774
pub use self::dispatch::{Parameter, Callable, IsSubType};
7875
pub use sp_runtime::{self, ConsensusEngineId, print, traits::Printable};
7976

@@ -313,7 +310,7 @@ mod tests {
313310
OptionLinkedMap::insert(2, 2);
314311
OptionLinkedMap::insert(3, 3);
315312

316-
let collect = || OptionLinkedMap::iter().collect::<Vec<_>>().sorted();
313+
let collect = || OptionLinkedMap::iter_key_value().collect::<Vec<_>>().sorted();
317314
assert_eq!(collect(), vec![(0, 0), (1, 1), (2, 2), (3, 3)]);
318315

319316
// Two existing
@@ -393,43 +390,43 @@ mod tests {
393390
#[test]
394391
fn map_iteration_should_work() {
395392
new_test_ext().execute_with(|| {
396-
assert_eq!(Map::iter().collect::<Vec<_>>().sorted(), vec![(15, 42)]);
393+
assert_eq!(Map::iter_key_value().collect::<Vec<_>>().sorted(), vec![(15, 42)]);
397394
// insert / remove
398395
let key = 17u32;
399396
Map::insert(key, 4u64);
400-
assert_eq!(Map::iter().collect::<Vec<_>>().sorted(), vec![(15, 42), (key, 4)]);
397+
assert_eq!(Map::iter_key_value().collect::<Vec<_>>().sorted(), vec![(15, 42), (key, 4)]);
401398
assert_eq!(Map::take(&15), 42u64);
402399
assert_eq!(Map::take(&key), 4u64);
403-
assert_eq!(Map::iter().collect::<Vec<_>>().sorted(), vec![]);
400+
assert_eq!(Map::iter_key_value().collect::<Vec<_>>().sorted(), vec![]);
404401

405402
// Add couple of more elements
406403
Map::insert(key, 42u64);
407-
assert_eq!(Map::iter().collect::<Vec<_>>().sorted(), vec![(key, 42)]);
404+
assert_eq!(Map::iter_key_value().collect::<Vec<_>>().sorted(), vec![(key, 42)]);
408405
Map::insert(key + 1, 43u64);
409-
assert_eq!(Map::iter().collect::<Vec<_>>().sorted(), vec![(key, 42), (key + 1, 43)]);
406+
assert_eq!(Map::iter_key_value().collect::<Vec<_>>().sorted(), vec![(key, 42), (key + 1, 43)]);
410407

411408
// mutate
412409
let key = key + 2;
413410
Map::mutate(&key, |val| {
414411
*val = 15;
415412
});
416-
assert_eq!(Map::iter().collect::<Vec<_>>().sorted(), vec![(key - 2, 42), (key - 1, 43), (key, 15)]);
413+
assert_eq!(Map::iter_key_value().collect::<Vec<_>>().sorted(), vec![(key - 2, 42), (key - 1, 43), (key, 15)]);
417414
Map::mutate(&key, |val| {
418415
*val = 17;
419416
});
420-
assert_eq!(Map::iter().collect::<Vec<_>>().sorted(), vec![(key - 2, 42), (key - 1, 43), (key, 17)]);
417+
assert_eq!(Map::iter_key_value().collect::<Vec<_>>().sorted(), vec![(key - 2, 42), (key - 1, 43), (key, 17)]);
421418

422419
// remove first
423420
Map::remove(&key);
424-
assert_eq!(Map::iter().collect::<Vec<_>>().sorted(), vec![(key - 2, 42), (key - 1, 43)]);
421+
assert_eq!(Map::iter_key_value().collect::<Vec<_>>().sorted(), vec![(key - 2, 42), (key - 1, 43)]);
425422

426423
// remove last from the list
427424
Map::remove(&(key - 2));
428-
assert_eq!(Map::iter().collect::<Vec<_>>().sorted(), vec![(key - 1, 43)]);
425+
assert_eq!(Map::iter_key_value().collect::<Vec<_>>().sorted(), vec![(key - 1, 43)]);
429426

430427
// remove the last element
431428
Map::remove(&(key - 1));
432-
assert_eq!(Map::iter().collect::<Vec<_>>().sorted(), vec![]);
429+
assert_eq!(Map::iter_key_value().collect::<Vec<_>>().sorted(), vec![]);
433430
});
434431
}
435432

0 commit comments

Comments
 (0)