Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding support for StorageValue and StorageDoubleMap #95

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 98 additions & 18 deletions src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,29 @@ pub struct StorageMetadata {
}

impl StorageMetadata {
pub fn get_double_map<K: Encode, Q:Encode, V: Decode + Clone>(&self) -> Result<StorageDoubleMap<K, Q, V>, 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<K: Encode, V: Decode + Clone>(
&self,
) -> Result<StorageMap<K, V>, MetadataError> {
Expand All @@ -221,6 +244,33 @@ impl StorageMetadata {
_ => Err(MetadataError::StorageTypeError),
}
}
pub fn get_value(&self) -> Result<StorageValue, MetadataError> {
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<u8>,
storage_prefix: Vec<u8>,
}

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)]
Expand All @@ -236,24 +286,32 @@ impl<K: Encode, V: Decode + Clone> StorageMap<K, V> {
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::<Vec<_>>()
}
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<K, Q, V> {
_marker: PhantomData<K>,
_marker2: PhantomData<Q>,
module_prefix: Vec<u8>,
storage_prefix: Vec<u8>,
hasher: StorageHasher,
key2_hasher: StorageHasher,
default: V,
}

impl<K: Encode, Q: Encode, V: Decode + Clone> StorageDoubleMap<K, Q, V> {
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)
}

Expand Down Expand Up @@ -459,3 +517,25 @@ fn convert_entry(
default,
})
}

/// genertes the key's hash depending on the StorageHasher selected
fn key_hash<K: Encode>(key: &K, hasher: &StorageHasher) -> Vec<u8> {
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::<Vec<_>>()
}
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(),
}
}