diff --git a/substrate/srml/support/procedural/src/storage/impls.rs b/substrate/srml/support/procedural/src/storage/impls.rs index 45d7fada9fcaf082783727d7e15b4b69a0889ece..4424aa918a34583092dac141b69c1bd1675d792f 100644 --- a/substrate/srml/support/procedural/src/storage/impls.rs +++ b/substrate/srml/support/procedural/src/storage/impls.rs @@ -615,6 +615,27 @@ impl<'a, I: Iterator<Item=syn::Meta>> Impls<'a, I> { storage.put(key_for, &(val, linkage)) } + /// Store a value under this key into the provided storage instance; this can take any reference + /// type that derefs to `T` (and has `Encode` implemented). + /// Store a value under this key into the provided storage instance. + fn insert_ref<Arg, S>(key: &#kty, val: &Arg, storage: &mut S) + where + #typ: AsRef<Arg>, + Arg: ?Sized + #scrate::codec::Encode, + S: #scrate::HashedStorage<#scrate::#hasher> + { + use self::#inner_module::Utils; + + let key_for = &*#as_map::key_for(key); + let linkage = match Self::read_with_linkage(storage, key_for) { + // overwrite but reuse existing linkage + Some((_data, linkage)) => linkage, + // create new linkage + None => Self::new_head_linkage(storage, key), + }; + storage.put(key_for, &(val, linkage)) + } + /// Mutate the value under a key fn mutate<R, F, S>(key: &#kty, f: F, storage: &mut S) -> R where diff --git a/substrate/srml/support/src/storage/hashed/generator.rs b/substrate/srml/support/src/storage/hashed/generator.rs index 19c4440c8548f8e49e0ce0d398c1b87c47058dd1..bc6cd145ceaea5eac4c0a29842864e9b7ac02fe1 100644 --- a/substrate/srml/support/src/storage/hashed/generator.rs +++ b/substrate/srml/support/src/storage/hashed/generator.rs @@ -246,7 +246,7 @@ pub trait StorageMap<K: codec::Codec, V: codec::Codec> { /// Store a value under this key into the provided storage instance; this can take any reference /// type that derefs to `T` (and has `Encode` implemented). /// Store a value under this key into the provided storage instance. - fn insert_ref<Arg: ?Sized + Encode, S: HashedStorage<Twox128>>( + fn insert_ref<Arg: ?Sized + Encode, S: HashedStorage<Self::Hasher>>( key: &K, val: &Arg, storage: &mut S diff --git a/substrate/srml/support/test/tests/instance.rs b/substrate/srml/support/test/tests/instance.rs index f77b4a284a7f4550a0276efc5c2b6ff7d38537c6..55bbc73807d58d80a74bc55ad4addf9ab6f87e78 100644 --- a/substrate/srml/support/test/tests/instance.rs +++ b/substrate/srml/support/test/tests/instance.rs @@ -27,7 +27,7 @@ use srml_support::{ use inherents::{ ProvideInherent, InherentData, InherentIdentifier, RuntimeString, MakeFatalError }; -use srml_support::{StorageValue, StorageMap, StorageDoubleMap}; +use srml_support::{StorageValue, StorageMap, StorageDoubleMap, EnumerableStorageMap}; use primitives::{H256, sr25519}; mod system; @@ -140,7 +140,7 @@ mod module2 { trait Store for Module<T: Trait<I>, I: Instance=DefaultInstance> as Module2 { pub Value config(value): T::Amount; pub Map config(map): map u64 => u64; - pub LinkedMap config(linked_map): linked_map u64 => u64; + pub LinkedMap config(linked_map): linked_map u64 => Vec<u8>; pub DoubleMap config(double_map): double_map u64, blake2_256(u64) => u64; } } @@ -288,13 +288,13 @@ fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> { module2: Some(module2::GenesisConfig { value: 4, map: vec![(0, 0)], - linked_map: vec![(0, 0)], + linked_map: vec![(0, vec![0])], double_map: vec![(0, 0, 0)], }), module2_Instance1: Some(module2::GenesisConfig { value: 4, map: vec![(0, 0)], - linked_map: vec![(0, 0)], + linked_map: vec![(0, vec![0])], double_map: vec![(0, 0, 0)], }), module2_Instance2: None, @@ -388,15 +388,23 @@ fn storage_with_instance_basic_operation() { assert_eq!(LinkedMap::exists(0), true); assert_eq!(LinkedMap::exists(key), false); - LinkedMap::insert(key, 1); - assert_eq!(LinkedMap::get(key), 1); - assert_eq!(LinkedMap::take(key), 1); - assert_eq!(LinkedMap::get(key), 0); - LinkedMap::mutate(key, |a| *a=2); - assert_eq!(LinkedMap::get(key), 2); + LinkedMap::insert(key, vec![1]); + assert_eq!(LinkedMap::enumerate().count(), 2); + assert_eq!(LinkedMap::get(key), vec![1]); + assert_eq!(LinkedMap::take(key), vec![1]); + assert_eq!(LinkedMap::enumerate().count(), 1); + assert_eq!(LinkedMap::get(key), vec![]); + LinkedMap::mutate(key, |a| *a=vec![2]); + assert_eq!(LinkedMap::enumerate().count(), 2); + assert_eq!(LinkedMap::get(key), vec![2]); LinkedMap::remove(key); + assert_eq!(LinkedMap::enumerate().count(), 1); assert_eq!(LinkedMap::exists(key), false); - assert_eq!(LinkedMap::get(key), 0); + assert_eq!(LinkedMap::get(key), vec![]); + assert_eq!(LinkedMap::exists(key), false); + assert_eq!(LinkedMap::enumerate().count(), 1); + LinkedMap::insert_ref(key, &vec![1]); + assert_eq!(LinkedMap::enumerate().count(), 2); let key1 = 1; let key2 = 1; @@ -454,7 +462,7 @@ const EXPECTED_METADATA: StorageMetadata = StorageMetadata { ty: StorageEntryType::Map { hasher: StorageHasher::Blake2_256, key: DecodeDifferent::Encode("u64"), - value: DecodeDifferent::Encode("u64"), + value: DecodeDifferent::Encode("Vec<u8>"), is_linked: true, }, default: DecodeDifferent::Encode(