Fix codegen validation when Runtime APIs are stripped (#1000)

* modify code gen

* cargo fmt

* fix return

* move the runtime_apis static

* small layout change

* tidy up metadata UI testing and test validation function too

* fix validation tests to point to metadata

* update codegen

* fix clippy and tests

* tweak a comment

* rename validate_codegen => is_codegen_valid_for

---------

Co-authored-by: James Wilson <james@jsdw.me>
This commit is contained in:
Tadeo Hepperle
2023-06-09 11:10:48 +02:00
committed by GitHub
parent e711dc1582
commit 992ec9ab9b
9 changed files with 323 additions and 212 deletions
+36 -10
View File
@@ -407,6 +407,7 @@ pub fn get_pallet_hash(pallet: PalletMetadata) -> [u8; HASH_LEN] {
pub struct MetadataHasher<'a> {
metadata: &'a Metadata,
specific_pallets: Option<Vec<&'a str>>,
specific_runtime_apis: Option<Vec<&'a str>>,
}
impl<'a> MetadataHasher<'a> {
@@ -415,6 +416,7 @@ impl<'a> MetadataHasher<'a> {
Self {
metadata,
specific_pallets: None,
specific_runtime_apis: None,
}
}
@@ -424,6 +426,16 @@ impl<'a> MetadataHasher<'a> {
self
}
/// Only hash the provided runtime APIs instead of hashing every runtime API
pub fn only_these_runtime_apis<S: AsRef<str>>(
&mut self,
specific_runtime_apis: &'a [S],
) -> &mut Self {
self.specific_runtime_apis =
Some(specific_runtime_apis.iter().map(|n| n.as_ref()).collect());
self
}
/// Hash the given metadata.
pub fn hash(&self) -> [u8; HASH_LEN] {
let mut visited_ids = HashSet::<u32>::new();
@@ -431,23 +443,37 @@ impl<'a> MetadataHasher<'a> {
let metadata = self.metadata;
let pallet_hash = metadata.pallets().fold([0u8; HASH_LEN], |bytes, pallet| {
// If specific pallets are given, only include this pallet if it's
// in the list.
if let Some(specific_pallets) = &self.specific_pallets {
if specific_pallets.iter().all(|&p| p != pallet.name()) {
return bytes;
}
}
// If specific pallets are given, only include this pallet if it is in the specific pallets.
let should_hash = self
.specific_pallets
.as_ref()
.map(|specific_pallets| specific_pallets.contains(&pallet.name()))
.unwrap_or(true);
// We don't care what order the pallets are seen in, so XOR their
// hashes together to be order independent.
xor(bytes, get_pallet_hash(pallet))
if should_hash {
xor(bytes, get_pallet_hash(pallet))
} else {
bytes
}
});
let apis_hash = metadata
.runtime_api_traits()
.fold([0u8; HASH_LEN], |bytes, api| {
// We don't care what order the runtime APIs are seen in, so XOR
xor(bytes, get_runtime_trait_hash(api))
// If specific runtime APIs are given, only include this pallet if it is in the specific runtime APIs.
let should_hash = self
.specific_runtime_apis
.as_ref()
.map(|specific_runtime_apis| specific_runtime_apis.contains(&api.name()))
.unwrap_or(true);
// We don't care what order the runtime APIs are seen in, so XOR their
// hashes together to be order independent.
if should_hash {
xor(bytes, xor(bytes, get_runtime_trait_hash(api)))
} else {
bytes
}
});
let extrinsic_hash = get_extrinsic_hash(&metadata.types, &metadata.extrinsic);