diff --git a/substrate/srml/support/procedural/src/storage/impls.rs b/substrate/srml/support/procedural/src/storage/impls.rs index 45d7fada9f..4424aa918a 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> 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(key: &#kty, val: &Arg, storage: &mut S) + where + #typ: AsRef, + 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(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 19c4440c85..bc6cd145ce 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 { /// 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>( + fn insert_ref>( 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 f77b4a284a..55bbc73807 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, 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; pub DoubleMap config(double_map): double_map u64, blake2_256(u64) => u64; } } @@ -288,13 +288,13 @@ fn new_test_ext() -> runtime_io::TestExternalities { 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"), is_linked: true, }, default: DecodeDifferent::Encode(