diff --git a/src/metadata.rs b/src/metadata.rs index ac60b97a89..59ef133ef4 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -200,6 +200,29 @@ pub struct StorageMetadata { } impl StorageMetadata { + pub fn get_double_map(&self) -> Result, MetadataError> { + match &self.ty { + StorageEntryType::DoubleMap { hasher, key2_hasher, .. } => { + let module_prefix = self.module_prefix.as_bytes().to_vec(); + let storage_prefix = self.storage_prefix.as_bytes().to_vec(); + let hasher1 = hasher.to_owned(); + let hasher2 = key2_hasher.to_owned(); + let default = Decode::decode(&mut &self.default[..]) + .map_err(|_| MetadataError::MapValueTypeError)?; + Ok(StorageDoubleMap { + _marker: PhantomData, + _marker2: PhantomData, + module_prefix, + storage_prefix, + hasher: hasher1, + key2_hasher: hasher2, + default, + }) + } + _ => Err(MetadataError::StorageTypeError), + } + } + pub fn get_map( &self, ) -> Result, MetadataError> { @@ -221,6 +244,33 @@ impl StorageMetadata { _ => Err(MetadataError::StorageTypeError), } } + pub fn get_value(&self) -> Result { + match &self.ty { + StorageEntryType::Plain { .. } => { + let module_prefix = self.module_prefix.as_bytes().to_vec(); + let storage_prefix = self.storage_prefix.as_bytes().to_vec(); + Ok(StorageValue { + module_prefix, + storage_prefix, + }) + } + _ => Err(MetadataError::StorageTypeError), + } + } +} + +#[derive(Clone, Debug)] +pub struct StorageValue { + module_prefix: Vec, + storage_prefix: Vec, +} + +impl StorageValue { + pub fn key(&self) -> StorageKey { + let mut bytes = sp_core::twox_128(&self.module_prefix).to_vec(); + bytes.extend(&sp_core::twox_128(&self.storage_prefix)[..]); + StorageKey(bytes) + } } #[derive(Clone, Debug)] @@ -236,24 +286,32 @@ impl StorageMap { pub fn key(&self, key: K) -> StorageKey { let mut bytes = sp_core::twox_128(&self.module_prefix).to_vec(); bytes.extend(&sp_core::twox_128(&self.storage_prefix)[..]); - let encoded_key = key.encode(); - let hash = match self.hasher { - StorageHasher::Identity => encoded_key.to_vec(), - StorageHasher::Blake2_128 => sp_core::blake2_128(&encoded_key).to_vec(), - StorageHasher::Blake2_128Concat => { - // copied from substrate Blake2_128Concat::hash since StorageHasher is not public - sp_core::blake2_128(&encoded_key) - .iter() - .chain(&encoded_key) - .cloned() - .collect::>() - } - StorageHasher::Blake2_256 => sp_core::blake2_256(&encoded_key).to_vec(), - StorageHasher::Twox128 => sp_core::twox_128(&encoded_key).to_vec(), - StorageHasher::Twox256 => sp_core::twox_256(&encoded_key).to_vec(), - StorageHasher::Twox64Concat => sp_core::twox_64(&encoded_key).to_vec(), - }; - bytes.extend(hash); + bytes.extend(key_hash(&key, &self.hasher)); + StorageKey(bytes) + } + + pub fn default(&self) -> V { + self.default.clone() + } +} + +#[derive(Clone, Debug)] +pub struct StorageDoubleMap { + _marker: PhantomData, + _marker2: PhantomData, + module_prefix: Vec, + storage_prefix: Vec, + hasher: StorageHasher, + key2_hasher: StorageHasher, + default: V, +} + +impl StorageDoubleMap { + pub fn key(&self, key1: K, key2: Q) -> StorageKey { + let mut bytes = sp_core::twox_128(&self.module_prefix).to_vec(); + bytes.extend(&sp_core::twox_128(&self.storage_prefix)[..]); + bytes.extend(key_hash(&key1, &self.hasher)); + bytes.extend(key_hash(&key2, &self.key2_hasher)); StorageKey(bytes) } @@ -459,3 +517,25 @@ fn convert_entry( default, }) } + +/// genertes the key's hash depending on the StorageHasher selected +fn key_hash(key: &K, hasher: &StorageHasher) -> Vec { + let encoded_key = key.encode(); + match hasher { + StorageHasher::Identity => encoded_key.to_vec(), + StorageHasher::Blake2_128 => sp_core::blake2_128(&encoded_key).to_vec(), + StorageHasher::Blake2_128Concat => { + // copied from substrate Blake2_128Concat::hash since StorageHasher is not public + let x: &[u8] = encoded_key.as_slice(); + sp_core::blake2_128(x) + .iter() + .chain(x.into_iter()) + .cloned() + .collect::>() + } + StorageHasher::Blake2_256 => sp_core::blake2_256(&encoded_key).to_vec(), + StorageHasher::Twox128 => sp_core::twox_128(&encoded_key).to_vec(), + StorageHasher::Twox256 => sp_core::twox_256(&encoded_key).to_vec(), + StorageHasher::Twox64Concat => sp_core::twox_64(&encoded_key).to_vec(), + } +} \ No newline at end of file