Skip to content

Commit

Permalink
Enable retrieval of constants from rutnime metadata (#207)
Browse files Browse the repository at this point in the history
  • Loading branch information
emostov authored Dec 17, 2020
1 parent 8a76beb commit 0a926ef
Showing 1 changed file with 69 additions and 1 deletion.
70 changes: 69 additions & 1 deletion src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ pub enum MetadataError {
/// Default error.
#[error("Failed to decode default: {0}")]
DefaultError(CodecError),
/// Failure to decode constant value.
#[error("Failed to decode constant value: {0}")]
ConstantValueError(CodecError),
/// Constant is not in metadata.
#[error("Constant {0} not found")]
ConstantNotFound(&'static str),
}

/// Runtime metadata.
Expand Down Expand Up @@ -166,7 +172,7 @@ pub struct ModuleMetadata {
index: u8,
name: String,
storage: HashMap<String, StorageMetadata>,
// constants
constants: HashMap<String, ModuleConstantMetadata>,
}

impl ModuleMetadata {
Expand All @@ -175,6 +181,16 @@ impl ModuleMetadata {
.get(key)
.ok_or(MetadataError::StorageNotFound(key))
}

/// Get a constant's metadata by name
pub fn constant(
&self,
key: &'static str,
) -> Result<&ModuleConstantMetadata, MetadataError> {
self.constants
.get(key)
.ok_or(MetadataError::ConstantNotFound(key))
}
}

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -463,6 +479,36 @@ impl EventArg {
}
}

#[derive(Clone, Debug)]
pub struct ModuleConstantMetadata {
name: String,
ty: String,
value: Vec<u8>,
documentation: Vec<String>,
}

impl ModuleConstantMetadata {
/// Name
pub fn name(&self) -> &String {
&self.name
}

/// Constant value (decoded)
pub fn value<V: Decode>(&self) -> Result<V, MetadataError> {
Decode::decode(&mut &self.value[..]).map_err(MetadataError::ConstantValueError)
}

/// Type (as defined in the runtime)
pub fn ty(&self) -> &String {
&self.ty
}

/// Documentation
pub fn documentation(&self) -> &Vec<String> {
&self.documentation
}
}

#[derive(Debug, thiserror::Error)]
pub enum ConversionError {
#[error("Invalid prefix")]
Expand Down Expand Up @@ -493,6 +539,12 @@ impl TryFrom<RuntimeMetadataPrefixed> for Metadata {
for module in convert(meta.modules)?.into_iter() {
let module_name = convert(module.name.clone())?;

let mut constant_map = HashMap::new();
for constant in convert(module.constants)?.into_iter() {
let constant_meta = convert_constant(constant)?;
constant_map.insert(constant_meta.name.clone(), constant_meta);
}

let mut storage_map = HashMap::new();
if let Some(storage) = module.storage {
let storage = convert(storage)?;
Expand All @@ -513,6 +565,7 @@ impl TryFrom<RuntimeMetadataPrefixed> for Metadata {
index: module.index,
name: module_name.clone(),
storage: storage_map,
constants: constant_map,
},
);

Expand Down Expand Up @@ -607,3 +660,18 @@ fn convert_error(
) -> Result<String, ConversionError> {
convert(error.name)
}

fn convert_constant(
constant: frame_metadata::ModuleConstantMetadata,
) -> Result<ModuleConstantMetadata, ConversionError> {
let name = convert(constant.name)?;
let ty = convert(constant.ty)?;
let value = convert(constant.value)?;
let documentation = convert(constant.documentation)?;
Ok(ModuleConstantMetadata {
name,
ty,
value,
documentation,
})
}

0 comments on commit 0a926ef

Please sign in to comment.