Codegen for custom values in metadata (#1117)

* work in progress

* add custom types access

* nit

* custom values client

* adjust light client

* adjust doc comments

* adjust book for custom values in code gen

* format and check docs

* work in progress

* add custom types access

* nit

* custom values client

* adjust light client

* codegen and validation

* adjust docs

* use ignore in docs in book

* change iter implementation

* use validation hash and other codegen changes

* add ui test for custom values codegen

* allow 'latest' metadata to be returned from the fallback code (#1127)

* nits

* fix validation check

* fix comments

* nits

---------

Co-authored-by: James Wilson <james@jsdw.me>
This commit is contained in:
Tadeo Hepperle
2023-08-24 09:50:44 +02:00
committed by GitHub
parent a8dbd9d6d5
commit b413e5e84e
12 changed files with 354 additions and 43 deletions
+76
View File
@@ -0,0 +1,76 @@
// Copyright 2019-2023 Parity Technologies (UK) Ltd.
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
// see LICENSE for license details.
use codec::Encode;
use frame_metadata::v15::{CustomMetadata, ExtrinsicMetadata, OuterEnums, RuntimeMetadataV15};
use frame_metadata::RuntimeMetadataPrefixed;
use scale_info::form::PortableForm;
use scale_info::TypeInfo;
use scale_info::{meta_type, IntoPortable};
use std::collections::BTreeMap;
/// Generate metadata which contains a `Foo { a: u8, b: &str }` custom value.
pub fn metadata_custom_values_foo() -> RuntimeMetadataPrefixed {
let mut registry = scale_info::Registry::new();
// create foo value and type:
#[derive(TypeInfo, Encode)]
struct Foo {
a: u8,
b: &'static str,
}
let foo_value_metadata: frame_metadata::v15::CustomValueMetadata<PortableForm> = {
let value = Foo { a: 0, b: "Hello" };
let foo_ty = scale_info::MetaType::new::<Foo>();
let foo_ty_id = registry.register_type(&foo_ty);
frame_metadata::v15::CustomValueMetadata {
ty: foo_ty_id,
value: value.encode(),
}
};
// We don't care about the extrinsic type.
let extrinsic = ExtrinsicMetadata {
version: 0,
signed_extensions: vec![],
address_ty: meta_type::<()>(),
call_ty: meta_type::<()>(),
signature_ty: meta_type::<()>(),
extra_ty: meta_type::<()>(),
};
let pallets = vec![];
let extrinsic = extrinsic.into_portable(&mut registry);
let unit_ty = registry.register_type(&meta_type::<()>());
// Metadata needs to contain this DispatchError, since codegen looks for it.
registry.register_type(&meta_type::<crate::utils::dispatch_error::ArrayDispatchError>());
let metadata = RuntimeMetadataV15 {
types: registry.into(),
pallets,
extrinsic,
ty: unit_ty,
apis: vec![],
outer_enums: OuterEnums {
call_enum_ty: unit_ty,
event_enum_ty: unit_ty,
error_enum_ty: unit_ty,
},
custom: CustomMetadata {
// provide foo twice, to make sure nothing breaks in these cases:
map: BTreeMap::from_iter([
("Foo".into(), foo_value_metadata.clone()),
("foo".into(), foo_value_metadata.clone()),
("12".into(), foo_value_metadata.clone()),
("&Hello".into(), foo_value_metadata.clone()),
]),
},
};
RuntimeMetadataPrefixed::from(metadata)
}
+7
View File
@@ -11,6 +11,7 @@
//! Use with `TRYBUILD=overwrite` after updating codebase (see `trybuild` docs for more details on that)
//! to automatically regenerate `stderr` files, but don't forget to check that new files make sense.
mod custom_values;
mod dispatch_errors;
mod storage;
mod utils;
@@ -51,6 +52,12 @@ fn ui_tests() {
.build(dispatch_errors::metadata_array_dispatch_error()),
);
t.pass(
m.new_test_case()
.name("custom_values_foo")
.build(custom_values::metadata_custom_values_foo()),
);
// Test retaining only specific pallets and ensure that works.
for pallet in ["Babe", "Claims", "Grandpa", "Balances"] {
let mut metadata = MetadataTestRunner::load_metadata();