From e4d2af638ec01d8d01655c09997a4bd98b430082 Mon Sep 17 00:00:00 2001 From: Tadeo hepperle Date: Tue, 5 Dec 2023 19:14:05 +0100 Subject: [PATCH] move outer enums to their own module --- metadata/src/lib.rs | 2 +- metadata/src/utils/validation.rs | 81 +---------------- .../src/utils/validation/outer_enum_hashes.rs | 87 +++++++++++++++++++ 3 files changed, 92 insertions(+), 78 deletions(-) create mode 100644 metadata/src/utils/validation/outer_enum_hashes.rs diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 715054dd49..4ebc68a44e 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -23,7 +23,7 @@ use scale_info::{form::PortableForm, PortableRegistry, Variant}; use std::collections::HashMap; use std::sync::Arc; use utils::variant_index::VariantIndex; -use utils::{ordered_map::OrderedMap, validation::OuterEnumHashes}; +use utils::{ordered_map::OrderedMap, validation::outer_enum_hashes::OuterEnumHashes}; type ArcStr = Arc; diff --git a/metadata/src/utils/validation.rs b/metadata/src/utils/validation.rs index 439beb7c82..81c50b4593 100644 --- a/metadata/src/utils/validation.rs +++ b/metadata/src/utils/validation.rs @@ -8,9 +8,12 @@ use crate::{ CustomMetadata, CustomValueMetadata, ExtrinsicMetadata, Metadata, PalletMetadata, RuntimeApiMetadata, RuntimeApiMethodMetadata, StorageEntryMetadata, StorageEntryType, }; +use outer_enum_hashes::OuterEnumHashes; use scale_info::{form::PortableForm, Field, PortableRegistry, TypeDef, TypeDefVariant, Variant}; use std::collections::HashMap; +pub mod outer_enum_hashes; + // The number of bytes our `hash` function produces. pub(crate) const HASH_LEN: usize = 32; pub type Hash = [u8; HASH_LEN]; @@ -246,8 +249,7 @@ fn get_type_hash_recurse( cache: &mut HashMap, outer_enum_hashes: &OuterEnumHashes, ) -> Hash { - // If the type is part of `precomputed` hashes, return the precomputed hash instead: - + // If the type is part of precomputed outer enum hashes, the respective hash is used instead: if let Some(hash) = outer_enum_hashes.resolve(id) { return hash; } @@ -308,81 +310,6 @@ fn get_extrinsic_hash( bytes } -/// Hash representations of the `frame_metadata::v15::OuterEnums`. -pub struct OuterEnumHashes { - call_hash: (u32, Hash), - error_hash: (u32, Hash), - event_hash: (u32, Hash), -} - -impl OuterEnumHashes { - /// Constructs new `OuterEnumHashes` from metadata. If `only_these_variants` is set, the enums are stripped down to only these variants, before their hashes are calculated. - pub fn new(metadata: &Metadata, only_these_variants: Option<&[&str]>) -> Self { - fn get_enum_hash( - registry: &PortableRegistry, - id: u32, - only_these_variants: Option<&[&str]>, - ) -> Hash { - let ty = registry - .types - .get(id as usize) - .expect("Metadata should contain enum type in registry"); - - if let TypeDef::Variant(variant) = &ty.ty.type_def { - get_type_def_variant_hash( - registry, - variant, - only_these_variants, - &mut HashMap::new(), - // ignored, because not computed yet... - &OuterEnumHashes::empty(), - ) - } else { - get_type_hash(registry, id, &OuterEnumHashes::empty()) - } - } - let enums = &metadata.outer_enums; - - let call_hash = get_enum_hash(metadata.types(), enums.call_enum_ty, only_these_variants); - let event_hash = get_enum_hash(metadata.types(), enums.event_enum_ty, only_these_variants); - let error_hash = get_enum_hash(metadata.types(), enums.error_enum_ty, only_these_variants); - - Self { - call_hash: (enums.call_enum_ty, call_hash), - error_hash: (enums.error_enum_ty, error_hash), - event_hash: (enums.event_enum_ty, event_hash), - } - } - - /// Constructs empty `OuterEnumHashes` with type ids that are never a real type id. - /// Can be used as a placeholder when outer enum hashes are required but should be ignored. - pub fn empty() -> Self { - Self { - call_hash: (u32::MAX, [0; HASH_LEN]), - error_hash: (u32::MAX, [0; HASH_LEN]), - event_hash: (u32::MAX, [0; HASH_LEN]), - } - } - - /// Returns a combined hash of the top level enums. - pub fn combined_hash(&self) -> Hash { - concat_and_hash3(&self.call_hash.1, &self.error_hash.1, &self.event_hash.1) - } - - /// Checks if a type is one of the 3 top level enum types. If so, returns Some(hash). - /// - /// This is useful, because top level enums are sometimes stripped down to only certain pallets. - /// The hashes of these stripped down types are stored in this struct. - pub fn resolve(&self, id: u32) -> Option<[u8; HASH_LEN]> { - match id { - e if e == self.error_hash.0 => Some(self.error_hash.1), - e if e == self.event_hash.0 => Some(self.event_hash.1), - e if e == self.call_hash.0 => Some(self.call_hash.1), - _ => None, - } - } -} - /// Get the hash corresponding to a single storage entry. fn get_storage_entry_hash( registry: &PortableRegistry, diff --git a/metadata/src/utils/validation/outer_enum_hashes.rs b/metadata/src/utils/validation/outer_enum_hashes.rs new file mode 100644 index 0000000000..33bd4f52c1 --- /dev/null +++ b/metadata/src/utils/validation/outer_enum_hashes.rs @@ -0,0 +1,87 @@ +//! Hash representations of the `frame_metadata::v15::OuterEnums`. + +use std::collections::HashMap; + +use scale_info::{PortableRegistry, TypeDef}; + +use crate::{ + utils::validation::{get_type_def_variant_hash, get_type_hash}, + Metadata, +}; + +use super::{concat_and_hash3, Hash, HASH_LEN}; + +/// Hash representations of the `frame_metadata::v15::OuterEnums`. +pub struct OuterEnumHashes { + call_hash: (u32, Hash), + error_hash: (u32, Hash), + event_hash: (u32, Hash), +} + +impl OuterEnumHashes { + /// Constructs new `OuterEnumHashes` from metadata. If `only_these_variants` is set, the enums are stripped down to only these variants, before their hashes are calculated. + pub fn new(metadata: &Metadata, only_these_variants: Option<&[&str]>) -> Self { + fn get_enum_hash( + registry: &PortableRegistry, + id: u32, + only_these_variants: Option<&[&str]>, + ) -> Hash { + let ty = registry + .types + .get(id as usize) + .expect("Metadata should contain enum type in registry"); + + if let TypeDef::Variant(variant) = &ty.ty.type_def { + get_type_def_variant_hash( + registry, + variant, + only_these_variants, + &mut HashMap::new(), + // ignored, because not computed yet... + &OuterEnumHashes::empty(), + ) + } else { + get_type_hash(registry, id, &OuterEnumHashes::empty()) + } + } + let enums = &metadata.outer_enums; + + let call_hash = get_enum_hash(metadata.types(), enums.call_enum_ty, only_these_variants); + let event_hash = get_enum_hash(metadata.types(), enums.event_enum_ty, only_these_variants); + let error_hash = get_enum_hash(metadata.types(), enums.error_enum_ty, only_these_variants); + + Self { + call_hash: (enums.call_enum_ty, call_hash), + error_hash: (enums.error_enum_ty, error_hash), + event_hash: (enums.event_enum_ty, event_hash), + } + } + + /// Constructs empty `OuterEnumHashes` with type ids that are never a real type id. + /// Can be used as a placeholder when outer enum hashes are required but should be ignored. + pub fn empty() -> Self { + Self { + call_hash: (u32::MAX, [0; HASH_LEN]), + error_hash: (u32::MAX, [0; HASH_LEN]), + event_hash: (u32::MAX, [0; HASH_LEN]), + } + } + + /// Returns a combined hash of the top level enums. + pub fn combined_hash(&self) -> Hash { + concat_and_hash3(&self.call_hash.1, &self.error_hash.1, &self.event_hash.1) + } + + /// Checks if a type is one of the 3 top level enum types. If so, returns Some(hash). + /// + /// This is useful, because top level enums are sometimes stripped down to only certain pallets. + /// The hashes of these stripped down types are stored in this struct. + pub fn resolve(&self, id: u32) -> Option<[u8; HASH_LEN]> { + match id { + e if e == self.error_hash.0 => Some(self.error_hash.1), + e if e == self.event_hash.0 => Some(self.event_hash.1), + e if e == self.call_hash.0 => Some(self.call_hash.1), + _ => None, + } + } +}