frame_metadata/
v15.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// SPDX-License-Identifier: Apache-2.0
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// 	http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#[cfg(feature = "decode")]
17use codec::Decode;
18#[cfg(feature = "serde_full")]
19use serde::Serialize;
20
21use super::{RuntimeMetadataPrefixed, META_RESERVED};
22use codec::Encode;
23use scale_info::{
24	form::{Form, MetaForm, PortableForm},
25	prelude::{collections::BTreeMap, vec::Vec},
26	IntoPortable, MetaType, PortableRegistry, Registry,
27};
28
29pub use super::v14::{
30	PalletCallMetadata, PalletConstantMetadata, PalletErrorMetadata, PalletEventMetadata,
31	PalletStorageMetadata, StorageEntryMetadata, StorageEntryModifier, StorageEntryType,
32	StorageHasher,
33};
34
35/// Latest runtime metadata
36pub type RuntimeMetadataLastVersion = RuntimeMetadataV15;
37
38impl From<RuntimeMetadataLastVersion> for super::RuntimeMetadataPrefixed {
39	fn from(metadata: RuntimeMetadataLastVersion) -> RuntimeMetadataPrefixed {
40		RuntimeMetadataPrefixed(META_RESERVED, super::RuntimeMetadata::V15(metadata))
41	}
42}
43
44/// The metadata of a runtime.
45#[derive(Clone, PartialEq, Eq, Encode, Debug)]
46#[cfg_attr(feature = "decode", derive(Decode))]
47#[cfg_attr(feature = "serde_full", derive(Serialize))]
48pub struct RuntimeMetadataV15 {
49	/// Type registry containing all types used in the metadata.
50	pub types: PortableRegistry,
51	/// Metadata of all the pallets.
52	pub pallets: Vec<PalletMetadata<PortableForm>>,
53	/// Metadata of the extrinsic.
54	pub extrinsic: ExtrinsicMetadata<PortableForm>,
55	/// The type of the `Runtime`.
56	pub ty: <PortableForm as Form>::Type,
57	/// Metadata of the Runtime API.
58	pub apis: Vec<RuntimeApiMetadata<PortableForm>>,
59	/// The outer enums types as found in the runtime.
60	pub outer_enums: OuterEnums<PortableForm>,
61	/// Allows users to add custom types to the metadata.
62	pub custom: CustomMetadata<PortableForm>,
63}
64
65impl RuntimeMetadataV15 {
66	/// Create a new instance of [`RuntimeMetadataV15`].
67	pub fn new(
68		pallets: Vec<PalletMetadata>,
69		extrinsic: ExtrinsicMetadata,
70		runtime_type: MetaType,
71		apis: Vec<RuntimeApiMetadata>,
72		outer_enums: OuterEnums,
73		custom: CustomMetadata,
74	) -> Self {
75		let mut registry = Registry::new();
76		let pallets = registry.map_into_portable(pallets);
77		let extrinsic = extrinsic.into_portable(&mut registry);
78		let ty = registry.register_type(&runtime_type);
79		let apis = registry.map_into_portable(apis);
80		let outer_enums = outer_enums.into_portable(&mut registry);
81		let custom = custom.into_portable(&mut registry);
82
83		Self {
84			types: registry.into(),
85			pallets,
86			extrinsic,
87			ty,
88			apis,
89			outer_enums,
90			custom,
91		}
92	}
93}
94
95/// Metadata of a runtime trait.
96#[derive(Clone, PartialEq, Eq, Encode, Debug)]
97#[cfg_attr(feature = "decode", derive(Decode))]
98#[cfg_attr(feature = "serde_full", derive(Serialize))]
99#[cfg_attr(
100	feature = "serde_full",
101	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
102)]
103pub struct RuntimeApiMetadata<T: Form = MetaForm> {
104	/// Trait name.
105	pub name: T::String,
106	/// Trait methods.
107	pub methods: Vec<RuntimeApiMethodMetadata<T>>,
108	/// Trait documentation.
109	pub docs: Vec<T::String>,
110}
111
112impl IntoPortable for RuntimeApiMetadata {
113	type Output = RuntimeApiMetadata<PortableForm>;
114
115	fn into_portable(self, registry: &mut Registry) -> Self::Output {
116		RuntimeApiMetadata {
117			name: self.name.into_portable(registry),
118			methods: registry.map_into_portable(self.methods),
119			docs: registry.map_into_portable(self.docs),
120		}
121	}
122}
123
124/// Metadata of a runtime method.
125#[derive(Clone, PartialEq, Eq, Encode, Debug)]
126#[cfg_attr(feature = "decode", derive(Decode))]
127#[cfg_attr(feature = "serde_full", derive(Serialize))]
128#[cfg_attr(
129	feature = "serde_full",
130	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
131)]
132pub struct RuntimeApiMethodMetadata<T: Form = MetaForm> {
133	/// Method name.
134	pub name: T::String,
135	/// Method parameters.
136	pub inputs: Vec<RuntimeApiMethodParamMetadata<T>>,
137	/// Method output.
138	pub output: T::Type,
139	/// Method documentation.
140	pub docs: Vec<T::String>,
141}
142
143impl IntoPortable for RuntimeApiMethodMetadata {
144	type Output = RuntimeApiMethodMetadata<PortableForm>;
145
146	fn into_portable(self, registry: &mut Registry) -> Self::Output {
147		RuntimeApiMethodMetadata {
148			name: self.name.into_portable(registry),
149			inputs: registry.map_into_portable(self.inputs),
150			output: registry.register_type(&self.output),
151			docs: registry.map_into_portable(self.docs),
152		}
153	}
154}
155
156/// Metadata of a runtime method parameter.
157#[derive(Clone, PartialEq, Eq, Encode, Debug)]
158#[cfg_attr(feature = "decode", derive(Decode))]
159#[cfg_attr(feature = "serde_full", derive(Serialize))]
160#[cfg_attr(
161	feature = "serde_full",
162	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
163)]
164pub struct RuntimeApiMethodParamMetadata<T: Form = MetaForm> {
165	/// Parameter name.
166	pub name: T::String,
167	/// Parameter type.
168	pub ty: T::Type,
169}
170
171impl IntoPortable for RuntimeApiMethodParamMetadata {
172	type Output = RuntimeApiMethodParamMetadata<PortableForm>;
173
174	fn into_portable(self, registry: &mut Registry) -> Self::Output {
175		RuntimeApiMethodParamMetadata {
176			name: self.name.into_portable(registry),
177			ty: registry.register_type(&self.ty),
178		}
179	}
180}
181
182/// Metadata of the extrinsic used by the runtime.
183#[derive(Clone, PartialEq, Eq, Encode, Debug)]
184#[cfg_attr(feature = "decode", derive(Decode))]
185#[cfg_attr(feature = "serde_full", derive(Serialize))]
186#[cfg_attr(
187	feature = "serde_full",
188	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
189)]
190pub struct ExtrinsicMetadata<T: Form = MetaForm> {
191	/// Extrinsic version.
192	pub version: u8,
193	/// The type of the address that signes the extrinsic
194	pub address_ty: T::Type,
195	/// The type of the outermost Call enum.
196	pub call_ty: T::Type,
197	/// The type of the extrinsic's signature.
198	pub signature_ty: T::Type,
199	/// The type of the outermost Extra enum.
200	pub extra_ty: T::Type,
201	/// The signed extensions in the order they appear in the extrinsic.
202	pub signed_extensions: Vec<SignedExtensionMetadata<T>>,
203}
204
205impl IntoPortable for ExtrinsicMetadata {
206	type Output = ExtrinsicMetadata<PortableForm>;
207
208	fn into_portable(self, registry: &mut Registry) -> Self::Output {
209		ExtrinsicMetadata {
210			version: self.version,
211			address_ty: registry.register_type(&self.address_ty),
212			call_ty: registry.register_type(&self.call_ty),
213			signature_ty: registry.register_type(&self.signature_ty),
214			extra_ty: registry.register_type(&self.extra_ty),
215			signed_extensions: registry.map_into_portable(self.signed_extensions),
216		}
217	}
218}
219
220/// Metadata of an extrinsic's signed extension.
221#[derive(Clone, PartialEq, Eq, Encode, Debug)]
222#[cfg_attr(feature = "decode", derive(Decode))]
223#[cfg_attr(feature = "serde_full", derive(Serialize))]
224#[cfg_attr(
225	feature = "serde_full",
226	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
227)]
228pub struct SignedExtensionMetadata<T: Form = MetaForm> {
229	/// The unique signed extension identifier, which may be different from the type name.
230	pub identifier: T::String,
231	/// The type of the signed extension, with the data to be included in the extrinsic.
232	pub ty: T::Type,
233	/// The type of the additional signed data, with the data to be included in the signed payload
234	pub additional_signed: T::Type,
235}
236
237impl IntoPortable for SignedExtensionMetadata {
238	type Output = SignedExtensionMetadata<PortableForm>;
239
240	fn into_portable(self, registry: &mut Registry) -> Self::Output {
241		SignedExtensionMetadata {
242			identifier: self.identifier.into_portable(registry),
243			ty: registry.register_type(&self.ty),
244			additional_signed: registry.register_type(&self.additional_signed),
245		}
246	}
247}
248
249/// All metadata about an runtime pallet.
250#[derive(Clone, PartialEq, Eq, Encode, Debug)]
251#[cfg_attr(feature = "decode", derive(Decode))]
252#[cfg_attr(feature = "serde_full", derive(Serialize))]
253#[cfg_attr(
254	feature = "serde_full",
255	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
256)]
257pub struct PalletMetadata<T: Form = MetaForm> {
258	/// Pallet name.
259	pub name: T::String,
260	/// Pallet storage metadata.
261	pub storage: Option<PalletStorageMetadata<T>>,
262	/// Pallet calls metadata.
263	pub calls: Option<PalletCallMetadata<T>>,
264	/// Pallet event metadata.
265	pub event: Option<PalletEventMetadata<T>>,
266	/// Pallet constants metadata.
267	pub constants: Vec<PalletConstantMetadata<T>>,
268	/// Pallet error metadata.
269	pub error: Option<PalletErrorMetadata<T>>,
270	/// Define the index of the pallet, this index will be used for the encoding of pallet event,
271	/// call and origin variants.
272	pub index: u8,
273	/// Pallet documentation.
274	pub docs: Vec<T::String>,
275}
276
277impl IntoPortable for PalletMetadata {
278	type Output = PalletMetadata<PortableForm>;
279
280	fn into_portable(self, registry: &mut Registry) -> Self::Output {
281		PalletMetadata {
282			name: self.name.into_portable(registry),
283			storage: self.storage.map(|storage| storage.into_portable(registry)),
284			calls: self.calls.map(|calls| calls.into_portable(registry)),
285			event: self.event.map(|event| event.into_portable(registry)),
286			constants: registry.map_into_portable(self.constants),
287			error: self.error.map(|error| error.into_portable(registry)),
288			index: self.index,
289			docs: registry.map_into_portable(self.docs),
290		}
291	}
292}
293
294/// Metadata for custom types.
295///
296/// This map associates a string key to a `CustomValueMetadata`.
297#[derive(Clone, PartialEq, Eq, Encode, Debug)]
298#[cfg_attr(feature = "decode", derive(Decode))]
299#[cfg_attr(feature = "serde_full", derive(Serialize))]
300#[cfg_attr(
301	feature = "serde_full",
302	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
303)]
304pub struct CustomMetadata<T: Form = MetaForm> {
305	/// The custom map.
306	pub map: BTreeMap<T::String, CustomValueMetadata<T>>,
307}
308
309impl IntoPortable for CustomMetadata {
310	type Output = CustomMetadata<PortableForm>;
311
312	fn into_portable(self, registry: &mut Registry) -> Self::Output {
313		let map = self
314			.map
315			.into_iter()
316			.map(|(key, value)| (key.into_portable(registry), value.into_portable(registry)))
317			.collect();
318
319		CustomMetadata { map }
320	}
321}
322
323/// The associated value of a custom metadata type.
324#[derive(Clone, PartialEq, Eq, Encode, Debug)]
325#[cfg_attr(feature = "decode", derive(Decode))]
326#[cfg_attr(feature = "serde_full", derive(Serialize))]
327#[cfg_attr(
328	feature = "serde_full",
329	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
330)]
331pub struct CustomValueMetadata<T: Form = MetaForm> {
332	/// The custom type.
333	pub ty: T::Type,
334	/// The custom value of this type.
335	pub value: Vec<u8>,
336}
337
338impl IntoPortable for CustomValueMetadata {
339	type Output = CustomValueMetadata<PortableForm>;
340
341	fn into_portable(self, registry: &mut Registry) -> Self::Output {
342		CustomValueMetadata {
343			ty: registry.register_type(&self.ty),
344			value: self.value,
345		}
346	}
347}
348
349/// The type of the outer enums.
350#[derive(Clone, PartialEq, Eq, Encode, Debug)]
351#[cfg_attr(feature = "decode", derive(Decode))]
352#[cfg_attr(feature = "serde_full", derive(Serialize))]
353#[cfg_attr(
354	feature = "serde_full",
355	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
356)]
357pub struct OuterEnums<T: Form = MetaForm> {
358	/// The type of the outer `RuntimeCall` enum.
359	pub call_enum_ty: T::Type,
360	/// The type of the outer `RuntimeEvent` enum.
361	pub event_enum_ty: T::Type,
362	/// The module error type of the
363	/// [`DispatchError::Module`](https://docs.rs/sp-runtime/24.0.0/sp_runtime/enum.DispatchError.html#variant.Module) variant.
364	///
365	/// The `Module` variant will be 5 scale encoded bytes which are normally decoded into
366	/// an `{ index: u8, error: [u8; 4] }` struct. This type ID points to an enum type which instead
367	/// interprets the first `index` byte as a pallet variant, and the remaining `error` bytes as the
368	/// appropriate `pallet::Error` type. It is an equally valid way to decode the error bytes, and
369	/// can be more informative.
370	///
371	/// # Note
372	///
373	/// - This type cannot be used directly to decode `sp_runtime::DispatchError` from the
374	///   chain. It provides just the information needed to decode `sp_runtime::DispatchError::Module`.
375	/// - Decoding the 5 error bytes into this type will not always lead to all of the bytes being consumed;
376	///   many error types do not require all of the bytes to represent them fully.
377	pub error_enum_ty: T::Type,
378}
379
380impl IntoPortable for OuterEnums {
381	type Output = OuterEnums<PortableForm>;
382
383	fn into_portable(self, registry: &mut Registry) -> Self::Output {
384		OuterEnums {
385			call_enum_ty: registry.register_type(&self.call_enum_ty),
386			event_enum_ty: registry.register_type(&self.event_enum_ty),
387			error_enum_ty: registry.register_type(&self.error_enum_ty),
388		}
389	}
390}