frame_metadata/
v14.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;
22use codec::Encode;
23use scale_info::prelude::vec::Vec;
24use scale_info::{
25	form::{Form, MetaForm, PortableForm},
26	IntoPortable, MetaType, PortableRegistry, Registry,
27};
28
29/// Current prefix of metadata
30pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness
31
32/// Latest runtime metadata
33pub type RuntimeMetadataLastVersion = RuntimeMetadataV14;
34
35impl From<RuntimeMetadataLastVersion> for super::RuntimeMetadataPrefixed {
36	fn from(metadata: RuntimeMetadataLastVersion) -> RuntimeMetadataPrefixed {
37		RuntimeMetadataPrefixed(META_RESERVED, super::RuntimeMetadata::V14(metadata))
38	}
39}
40
41/// The metadata of a runtime.
42#[derive(Clone, PartialEq, Eq, Encode, Debug)]
43#[cfg_attr(feature = "decode", derive(Decode))]
44#[cfg_attr(feature = "serde_full", derive(Serialize))]
45pub struct RuntimeMetadataV14 {
46	/// Type registry containing all types used in the metadata.
47	pub types: PortableRegistry,
48	/// Metadata of all the pallets.
49	pub pallets: Vec<PalletMetadata<PortableForm>>,
50	/// Metadata of the extrinsic.
51	pub extrinsic: ExtrinsicMetadata<PortableForm>,
52	/// The type of the `Runtime`.
53	pub ty: <PortableForm as Form>::Type,
54}
55
56impl RuntimeMetadataV14 {
57	/// Create a new instance of [`RuntimeMetadataV14`].
58	pub fn new(
59		pallets: Vec<PalletMetadata>,
60		extrinsic: ExtrinsicMetadata,
61		runtime_type: MetaType,
62	) -> Self {
63		let mut registry = Registry::new();
64		let pallets = registry.map_into_portable(pallets);
65		let extrinsic = extrinsic.into_portable(&mut registry);
66		let ty = registry.register_type(&runtime_type);
67		Self {
68			types: registry.into(),
69			pallets,
70			extrinsic,
71			ty,
72		}
73	}
74}
75
76/// Metadata of the extrinsic used by the runtime.
77#[derive(Clone, PartialEq, Eq, Encode, Debug)]
78#[cfg_attr(feature = "decode", derive(Decode))]
79#[cfg_attr(feature = "serde_full", derive(Serialize))]
80#[cfg_attr(
81	feature = "serde_full",
82	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
83)]
84pub struct ExtrinsicMetadata<T: Form = MetaForm> {
85	/// The type of the extrinsic.
86	pub ty: T::Type,
87	/// Extrinsic version.
88	pub version: u8,
89	/// The signed extensions in the order they appear in the extrinsic.
90	pub signed_extensions: Vec<SignedExtensionMetadata<T>>,
91}
92
93impl IntoPortable for ExtrinsicMetadata {
94	type Output = ExtrinsicMetadata<PortableForm>;
95
96	fn into_portable(self, registry: &mut Registry) -> Self::Output {
97		ExtrinsicMetadata {
98			ty: registry.register_type(&self.ty),
99			version: self.version,
100			signed_extensions: registry.map_into_portable(self.signed_extensions),
101		}
102	}
103}
104
105/// Metadata of an extrinsic's signed extension.
106#[derive(Clone, PartialEq, Eq, Encode, Debug)]
107#[cfg_attr(feature = "decode", derive(Decode))]
108#[cfg_attr(feature = "serde_full", derive(Serialize))]
109#[cfg_attr(
110	feature = "serde_full",
111	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
112)]
113pub struct SignedExtensionMetadata<T: Form = MetaForm> {
114	/// The unique signed extension identifier, which may be different from the type name.
115	pub identifier: T::String,
116	/// The type of the signed extension, with the data to be included in the extrinsic.
117	pub ty: T::Type,
118	/// The type of the additional signed data, with the data to be included in the signed payload
119	pub additional_signed: T::Type,
120}
121
122impl IntoPortable for SignedExtensionMetadata {
123	type Output = SignedExtensionMetadata<PortableForm>;
124
125	fn into_portable(self, registry: &mut Registry) -> Self::Output {
126		SignedExtensionMetadata {
127			identifier: self.identifier.into_portable(registry),
128			ty: registry.register_type(&self.ty),
129			additional_signed: registry.register_type(&self.additional_signed),
130		}
131	}
132}
133
134/// All metadata about an runtime pallet.
135#[derive(Clone, PartialEq, Eq, Encode, Debug)]
136#[cfg_attr(feature = "decode", derive(Decode))]
137#[cfg_attr(feature = "serde_full", derive(Serialize))]
138#[cfg_attr(
139	feature = "serde_full",
140	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
141)]
142pub struct PalletMetadata<T: Form = MetaForm> {
143	/// Pallet name.
144	pub name: T::String,
145	/// Pallet storage metadata.
146	pub storage: Option<PalletStorageMetadata<T>>,
147	/// Pallet calls metadata.
148	pub calls: Option<PalletCallMetadata<T>>,
149	/// Pallet event metadata.
150	pub event: Option<PalletEventMetadata<T>>,
151	/// Pallet constants metadata.
152	pub constants: Vec<PalletConstantMetadata<T>>,
153	/// Pallet error metadata.
154	pub error: Option<PalletErrorMetadata<T>>,
155	/// Define the index of the pallet, this index will be used for the encoding of pallet event,
156	/// call and origin variants.
157	pub index: u8,
158}
159
160impl IntoPortable for PalletMetadata {
161	type Output = PalletMetadata<PortableForm>;
162
163	fn into_portable(self, registry: &mut Registry) -> Self::Output {
164		PalletMetadata {
165			name: self.name.into_portable(registry),
166			storage: self.storage.map(|storage| storage.into_portable(registry)),
167			calls: self.calls.map(|calls| calls.into_portable(registry)),
168			event: self.event.map(|event| event.into_portable(registry)),
169			constants: registry.map_into_portable(self.constants),
170			error: self.error.map(|error| error.into_portable(registry)),
171			index: self.index,
172		}
173	}
174}
175
176/// All metadata of the pallet's storage.
177#[derive(Clone, PartialEq, Eq, Encode, Debug)]
178#[cfg_attr(feature = "decode", derive(Decode))]
179#[cfg_attr(feature = "serde_full", derive(Serialize))]
180#[cfg_attr(
181	feature = "serde_full",
182	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
183)]
184pub struct PalletStorageMetadata<T: Form = MetaForm> {
185	/// The common prefix used by all storage entries.
186	pub prefix: T::String,
187	/// Metadata for all storage entries.
188	pub entries: Vec<StorageEntryMetadata<T>>,
189}
190
191impl IntoPortable for PalletStorageMetadata {
192	type Output = PalletStorageMetadata<PortableForm>;
193
194	fn into_portable(self, registry: &mut Registry) -> Self::Output {
195		PalletStorageMetadata {
196			prefix: self.prefix.into_portable(registry),
197			entries: registry.map_into_portable(self.entries),
198		}
199	}
200}
201
202/// Metadata about one storage entry.
203#[derive(Clone, PartialEq, Eq, Encode, Debug)]
204#[cfg_attr(feature = "decode", derive(Decode))]
205#[cfg_attr(feature = "serde_full", derive(Serialize))]
206#[cfg_attr(
207	feature = "serde_full",
208	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
209)]
210pub struct StorageEntryMetadata<T: Form = MetaForm> {
211	/// Variable name of the storage entry.
212	pub name: T::String,
213	/// An `Option` modifier of that storage entry.
214	pub modifier: StorageEntryModifier,
215	/// Type of the value stored in the entry.
216	pub ty: StorageEntryType<T>,
217	/// Default value (SCALE encoded).
218	pub default: Vec<u8>,
219	/// Storage entry documentation.
220	pub docs: Vec<T::String>,
221}
222
223impl IntoPortable for StorageEntryMetadata {
224	type Output = StorageEntryMetadata<PortableForm>;
225
226	fn into_portable(self, registry: &mut Registry) -> Self::Output {
227		StorageEntryMetadata {
228			name: self.name.into_portable(registry),
229			modifier: self.modifier,
230			ty: self.ty.into_portable(registry),
231			default: self.default,
232			docs: registry.map_into_portable(self.docs),
233		}
234	}
235}
236
237/// A storage entry modifier indicates how a storage entry is returned when fetched and what the value will be if the key is not present.
238/// Specifically this refers to the "return type" when fetching a storage entry, and what the value will be if the key is not present.
239///
240/// `Optional` means you should expect an `Option<T>`, with `None` returned if the key is not present.
241/// `Default` means you should expect a `T` with the default value of default if the key is not present.
242#[derive(Clone, PartialEq, Eq, Encode, Debug)]
243#[cfg_attr(feature = "decode", derive(Decode))]
244#[cfg_attr(feature = "serde_full", derive(Serialize))]
245pub enum StorageEntryModifier {
246	/// The storage entry returns an `Option<T>`, with `None` if the key is not present.
247	Optional,
248	/// The storage entry returns `T::Default` if the key is not present.
249	Default,
250}
251
252/// Hasher used by storage maps
253#[derive(Clone, PartialEq, Eq, Encode, Debug)]
254#[cfg_attr(feature = "decode", derive(Decode))]
255#[cfg_attr(feature = "serde_full", derive(Serialize))]
256pub enum StorageHasher {
257	/// 128-bit Blake2 hash.
258	Blake2_128,
259	/// 256-bit Blake2 hash.
260	Blake2_256,
261	/// Multiple 128-bit Blake2 hashes concatenated.
262	Blake2_128Concat,
263	/// 128-bit XX hash.
264	Twox128,
265	/// 256-bit XX hash.
266	Twox256,
267	/// Multiple 64-bit XX hashes concatenated.
268	Twox64Concat,
269	/// Identity hashing (no hashing).
270	Identity,
271}
272
273/// A type of storage value.
274#[derive(Clone, PartialEq, Eq, Encode, Debug)]
275#[cfg_attr(feature = "decode", derive(Decode))]
276#[cfg_attr(feature = "serde_full", derive(Serialize))]
277#[cfg_attr(
278	feature = "serde_full",
279	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
280)]
281pub enum StorageEntryType<T: Form = MetaForm> {
282	/// Plain storage entry (just the value).
283	Plain(T::Type),
284	/// A storage map.
285	Map {
286		/// One or more hashers, should be one hasher per key element.
287		hashers: Vec<StorageHasher>,
288		/// The type of the key, can be a tuple with elements for each of the hashers.
289		key: T::Type,
290		/// The type of the value.
291		value: T::Type,
292	},
293}
294
295impl IntoPortable for StorageEntryType {
296	type Output = StorageEntryType<PortableForm>;
297
298	fn into_portable(self, registry: &mut Registry) -> Self::Output {
299		match self {
300			Self::Plain(plain) => StorageEntryType::Plain(registry.register_type(&plain)),
301			Self::Map {
302				hashers,
303				key,
304				value,
305			} => StorageEntryType::Map {
306				hashers,
307				key: registry.register_type(&key),
308				value: registry.register_type(&value),
309			},
310		}
311	}
312}
313
314/// Metadata for all calls in a pallet
315#[derive(Clone, PartialEq, Eq, Encode, Debug)]
316#[cfg_attr(feature = "decode", derive(Decode))]
317#[cfg_attr(feature = "serde_full", derive(Serialize))]
318#[cfg_attr(
319	feature = "serde_full",
320	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
321)]
322pub struct PalletCallMetadata<T: Form = MetaForm> {
323	/// The corresponding enum type for the pallet call.
324	pub ty: T::Type,
325}
326
327impl IntoPortable for PalletCallMetadata {
328	type Output = PalletCallMetadata<PortableForm>;
329
330	fn into_portable(self, registry: &mut Registry) -> Self::Output {
331		PalletCallMetadata {
332			ty: registry.register_type(&self.ty),
333		}
334	}
335}
336
337impl From<MetaType> for PalletCallMetadata {
338	fn from(ty: MetaType) -> Self {
339		Self { ty }
340	}
341}
342
343/// Metadata about the pallet Event type.
344#[derive(Clone, PartialEq, Eq, Encode, Debug)]
345#[cfg_attr(feature = "decode", derive(Decode))]
346#[cfg_attr(feature = "serde_full", derive(Serialize))]
347pub struct PalletEventMetadata<T: Form = MetaForm> {
348	/// The Event type.
349	pub ty: T::Type,
350}
351
352impl IntoPortable for PalletEventMetadata {
353	type Output = PalletEventMetadata<PortableForm>;
354
355	fn into_portable(self, registry: &mut Registry) -> Self::Output {
356		PalletEventMetadata {
357			ty: registry.register_type(&self.ty),
358		}
359	}
360}
361
362impl From<MetaType> for PalletEventMetadata {
363	fn from(ty: MetaType) -> Self {
364		Self { ty }
365	}
366}
367
368/// Metadata about one pallet constant.
369#[derive(Clone, PartialEq, Eq, Encode, Debug)]
370#[cfg_attr(feature = "decode", derive(Decode))]
371#[cfg_attr(feature = "serde_full", derive(Serialize))]
372#[cfg_attr(
373	feature = "serde_full",
374	serde(bound(serialize = "T::Type: Serialize, T::String: Serialize"))
375)]
376pub struct PalletConstantMetadata<T: Form = MetaForm> {
377	/// Name of the pallet constant.
378	pub name: T::String,
379	/// Type of the pallet constant.
380	pub ty: T::Type,
381	/// Value stored in the constant (SCALE encoded).
382	pub value: Vec<u8>,
383	/// Documentation of the constant.
384	pub docs: Vec<T::String>,
385}
386
387impl IntoPortable for PalletConstantMetadata {
388	type Output = PalletConstantMetadata<PortableForm>;
389
390	fn into_portable(self, registry: &mut Registry) -> Self::Output {
391		PalletConstantMetadata {
392			name: self.name.into_portable(registry),
393			ty: registry.register_type(&self.ty),
394			value: self.value,
395			docs: registry.map_into_portable(self.docs),
396		}
397	}
398}
399
400/// Metadata about a pallet error.
401#[derive(Clone, PartialEq, Eq, Encode, Debug)]
402#[cfg_attr(feature = "decode", derive(Decode))]
403#[cfg_attr(feature = "serde_full", derive(Serialize))]
404#[cfg_attr(feature = "serde_full", serde(bound(serialize = "T::Type: Serialize")))]
405pub struct PalletErrorMetadata<T: Form = MetaForm> {
406	/// The error type information.
407	pub ty: T::Type,
408}
409
410impl IntoPortable for PalletErrorMetadata {
411	type Output = PalletErrorMetadata<PortableForm>;
412
413	fn into_portable(self, registry: &mut Registry) -> Self::Output {
414		PalletErrorMetadata {
415			ty: registry.register_type(&self.ty),
416		}
417	}
418}
419
420impl From<MetaType> for PalletErrorMetadata {
421	fn from(ty: MetaType) -> Self {
422		Self { ty }
423	}
424}