fabric_metadata/
lib.rs

1// This file is part of Tetcore.
2
3// Copyright (C) 2018-2021 Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Decodable variant of the RuntimeMetadata.
19//!
20//! This really doesn't belong here, but is necessary for the moment. In the future
21//! it should be removed entirely to an external module for shimming on to the
22//! codec-encoded metadata.
23
24#![cfg_attr(not(feature = "std"), no_std)]
25
26#[cfg(feature = "std")]
27use serde::Serialize;
28#[cfg(feature = "std")]
29use codec::{Decode, Input, Error};
30use codec::{Encode, Output};
31use tetcore_std::vec::Vec;
32use tet_core::RuntimeDebug;
33
34#[cfg(feature = "std")]
35type StringBuf = String;
36
37/// Current prefix of metadata
38pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness
39
40/// On `no_std` we do not support `Decode` and thus `StringBuf` is just `&'static str`.
41/// So, if someone tries to decode this stuff on `no_std`, they will get a compilation error.
42#[cfg(not(feature = "std"))]
43type StringBuf = &'static str;
44
45/// A type that decodes to a different type than it encodes.
46/// The user needs to make sure that both types use the same encoding.
47///
48/// For example a `&'static [ &'static str ]` can be decoded to a `Vec<String>`.
49#[derive(Clone)]
50pub enum DecodeDifferent<B, O> where B: 'static, O: 'static {
51	Encode(B),
52	Decoded(O),
53}
54
55impl<B, O> Encode for DecodeDifferent<B, O> where B: Encode + 'static, O: Encode + 'static {
56	fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
57		match self {
58			DecodeDifferent::Encode(b) => b.encode_to(dest),
59			DecodeDifferent::Decoded(o) => o.encode_to(dest),
60		}
61	}
62}
63
64impl<B, O> codec::EncodeLike for DecodeDifferent<B, O> where B: Encode + 'static, O: Encode + 'static {}
65
66#[cfg(feature = "std")]
67impl<B, O> Decode for DecodeDifferent<B, O> where B: 'static, O: Decode + 'static {
68	fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
69		<O>::decode(input).map(|val| {
70			DecodeDifferent::Decoded(val)
71		})
72	}
73}
74
75impl<B, O> PartialEq for DecodeDifferent<B, O>
76where
77	B: Encode + Eq + PartialEq + 'static,
78	O: Encode + Eq + PartialEq + 'static,
79{
80	fn eq(&self, other: &Self) -> bool {
81		self.encode() == other.encode()
82	}
83}
84
85impl<B, O> Eq for DecodeDifferent<B, O>
86	where B: Encode + Eq + PartialEq + 'static, O: Encode + Eq + PartialEq + 'static
87{}
88
89impl<B, O> tetcore_std::fmt::Debug for DecodeDifferent<B, O>
90	where
91		B: tetcore_std::fmt::Debug + Eq + 'static,
92		O: tetcore_std::fmt::Debug + Eq + 'static,
93{
94	fn fmt(&self, f: &mut tetcore_std::fmt::Formatter) -> tetcore_std::fmt::Result {
95		match self {
96			DecodeDifferent::Encode(b) => b.fmt(f),
97			DecodeDifferent::Decoded(o) => o.fmt(f),
98		}
99	}
100}
101
102#[cfg(feature = "std")]
103impl<B, O> serde::Serialize for DecodeDifferent<B, O>
104	where
105		B: serde::Serialize + 'static,
106		O: serde::Serialize + 'static,
107{
108	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
109		match self {
110			DecodeDifferent::Encode(b) => b.serialize(serializer),
111			DecodeDifferent::Decoded(o) => o.serialize(serializer),
112		}
113	}
114}
115
116pub type DecodeDifferentArray<B, O=B> = DecodeDifferent<&'static [B], Vec<O>>;
117
118type DecodeDifferentStr = DecodeDifferent<&'static str, StringBuf>;
119
120/// All the metadata about a function.
121#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)]
122#[cfg_attr(feature = "std", derive(Decode, Serialize))]
123pub struct FunctionMetadata {
124	pub name: DecodeDifferentStr,
125	pub arguments: DecodeDifferentArray<FunctionArgumentMetadata>,
126	pub documentation: DecodeDifferentArray<&'static str, StringBuf>,
127}
128
129/// All the metadata about a function argument.
130#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)]
131#[cfg_attr(feature = "std", derive(Decode, Serialize))]
132pub struct FunctionArgumentMetadata {
133	pub name: DecodeDifferentStr,
134	pub ty: DecodeDifferentStr,
135}
136
137/// Newtype wrapper for support encoding functions (actual the result of the function).
138#[derive(Clone, Eq)]
139pub struct FnEncode<E>(pub fn() -> E) where E: Encode + 'static;
140
141impl<E: Encode> Encode for FnEncode<E> {
142	fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
143		self.0().encode_to(dest);
144	}
145}
146
147impl<E: Encode> codec::EncodeLike for FnEncode<E> {}
148
149impl<E: Encode + PartialEq> PartialEq for FnEncode<E> {
150	fn eq(&self, other: &Self) -> bool {
151		self.0().eq(&other.0())
152	}
153}
154
155impl<E: Encode + tetcore_std::fmt::Debug> tetcore_std::fmt::Debug for FnEncode<E> {
156	fn fmt(&self, f: &mut tetcore_std::fmt::Formatter) -> tetcore_std::fmt::Result {
157		self.0().fmt(f)
158	}
159}
160
161#[cfg(feature = "std")]
162impl<E: Encode + serde::Serialize> serde::Serialize for FnEncode<E> {
163	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
164		self.0().serialize(serializer)
165	}
166}
167
168/// All the metadata about an outer event.
169#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)]
170#[cfg_attr(feature = "std", derive(Decode, Serialize))]
171pub struct OuterEventMetadata {
172	pub name: DecodeDifferentStr,
173	pub events: DecodeDifferentArray<
174		(&'static str, FnEncode<&'static [EventMetadata]>),
175		(StringBuf, Vec<EventMetadata>)
176	>,
177}
178
179/// All the metadata about an event.
180#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)]
181#[cfg_attr(feature = "std", derive(Decode, Serialize))]
182pub struct EventMetadata {
183	pub name: DecodeDifferentStr,
184	pub arguments: DecodeDifferentArray<&'static str, StringBuf>,
185	pub documentation: DecodeDifferentArray<&'static str, StringBuf>,
186}
187
188/// All the metadata about one storage entry.
189#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)]
190#[cfg_attr(feature = "std", derive(Decode, Serialize))]
191pub struct StorageEntryMetadata {
192	pub name: DecodeDifferentStr,
193	pub modifier: StorageEntryModifier,
194	pub ty: StorageEntryType,
195	pub default: ByteGetter,
196	pub documentation: DecodeDifferentArray<&'static str, StringBuf>,
197}
198
199/// All the metadata about one module constant.
200#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)]
201#[cfg_attr(feature = "std", derive(Decode, Serialize))]
202pub struct ModuleConstantMetadata {
203	pub name: DecodeDifferentStr,
204	pub ty: DecodeDifferentStr,
205	pub value: ByteGetter,
206	pub documentation: DecodeDifferentArray<&'static str, StringBuf>,
207}
208
209/// All the metadata about a module error.
210#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)]
211#[cfg_attr(feature = "std", derive(Decode, Serialize))]
212pub struct ErrorMetadata {
213	pub name: DecodeDifferentStr,
214	pub documentation: DecodeDifferentArray<&'static str, StringBuf>,
215}
216
217/// All the metadata about errors in a module.
218pub trait ModuleErrorMetadata {
219	fn metadata() -> &'static [ErrorMetadata];
220}
221
222impl ModuleErrorMetadata for &'static str {
223	fn metadata() -> &'static [ErrorMetadata] {
224		&[]
225	}
226}
227
228/// A technical trait to store lazy initiated vec value as static dyn pointer.
229pub trait DefaultByte: Send + Sync {
230	fn default_byte(&self) -> Vec<u8>;
231}
232
233/// Wrapper over dyn pointer for accessing a cached once byte value.
234#[derive(Clone)]
235pub struct DefaultByteGetter(pub &'static dyn DefaultByte);
236
237/// Decode different for static lazy initiated byte value.
238pub type ByteGetter = DecodeDifferent<DefaultByteGetter, Vec<u8>>;
239
240impl Encode for DefaultByteGetter {
241	fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
242		self.0.default_byte().encode_to(dest)
243	}
244}
245
246impl codec::EncodeLike for DefaultByteGetter {}
247
248impl PartialEq<DefaultByteGetter> for DefaultByteGetter {
249	fn eq(&self, other: &DefaultByteGetter) -> bool {
250		let left = self.0.default_byte();
251		let right = other.0.default_byte();
252		left.eq(&right)
253	}
254}
255
256impl Eq for DefaultByteGetter { }
257
258#[cfg(feature = "std")]
259impl serde::Serialize for DefaultByteGetter {
260	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
261		self.0.default_byte().serialize(serializer)
262	}
263}
264
265impl tetcore_std::fmt::Debug for DefaultByteGetter {
266	fn fmt(&self, f: &mut tetcore_std::fmt::Formatter) -> tetcore_std::fmt::Result {
267		self.0.default_byte().fmt(f)
268	}
269}
270
271/// Hasher used by storage maps
272#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)]
273#[cfg_attr(feature = "std", derive(Decode, Serialize))]
274pub enum StorageHasher {
275	Blake2_128,
276	Blake2_256,
277	Blake2_128Concat,
278	Twox128,
279	Twox256,
280	Twox64Concat,
281	Identity,
282}
283
284/// A storage entry type.
285#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)]
286#[cfg_attr(feature = "std", derive(Decode, Serialize))]
287pub enum StorageEntryType {
288	Plain(DecodeDifferentStr),
289	Map {
290		hasher: StorageHasher,
291		key: DecodeDifferentStr,
292		value: DecodeDifferentStr,
293		// is_linked flag previously, unused now to keep backwards compat
294		unused: bool,
295	},
296	DoubleMap {
297		hasher: StorageHasher,
298		key1: DecodeDifferentStr,
299		key2: DecodeDifferentStr,
300		value: DecodeDifferentStr,
301		key2_hasher: StorageHasher,
302	},
303}
304
305/// A storage entry modifier.
306#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)]
307#[cfg_attr(feature = "std", derive(Decode, Serialize))]
308pub enum StorageEntryModifier {
309	Optional,
310	Default,
311}
312
313/// All metadata of the storage.
314#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)]
315#[cfg_attr(feature = "std", derive(Decode, Serialize))]
316pub struct StorageMetadata {
317	/// The common prefix used by all storage entries.
318	pub prefix: DecodeDifferent<&'static str, StringBuf>,
319	pub entries: DecodeDifferent<&'static [StorageEntryMetadata], Vec<StorageEntryMetadata>>,
320}
321
322/// Metadata prefixed by a u32 for reserved usage
323#[derive(Eq, Encode, PartialEq, RuntimeDebug)]
324#[cfg_attr(feature = "std", derive(Decode, Serialize))]
325pub struct RuntimeMetadataPrefixed(pub u32, pub RuntimeMetadata);
326
327/// Metadata of the extrinsic used by the runtime.
328#[derive(Eq, Encode, PartialEq, RuntimeDebug)]
329#[cfg_attr(feature = "std", derive(Decode, Serialize))]
330pub struct ExtrinsicMetadata {
331	/// Extrinsic version.
332	pub version: u8,
333	/// The signed extensions in the order they appear in the extrinsic.
334	pub signed_extensions: Vec<DecodeDifferentStr>,
335}
336
337/// The metadata of a runtime.
338/// The version ID encoded/decoded through
339/// the enum nature of `RuntimeMetadata`.
340#[derive(Eq, Encode, PartialEq, RuntimeDebug)]
341#[cfg_attr(feature = "std", derive(Decode, Serialize))]
342pub enum RuntimeMetadata {
343	/// Unused; enum filler.
344	V0(RuntimeMetadataDeprecated),
345	/// Version 1 for runtime metadata. No longer used.
346	V1(RuntimeMetadataDeprecated),
347	/// Version 2 for runtime metadata. No longer used.
348	V2(RuntimeMetadataDeprecated),
349	/// Version 3 for runtime metadata. No longer used.
350	V3(RuntimeMetadataDeprecated),
351	/// Version 4 for runtime metadata. No longer used.
352	V4(RuntimeMetadataDeprecated),
353	/// Version 5 for runtime metadata. No longer used.
354	V5(RuntimeMetadataDeprecated),
355	/// Version 6 for runtime metadata. No longer used.
356	V6(RuntimeMetadataDeprecated),
357	/// Version 7 for runtime metadata. No longer used.
358	V7(RuntimeMetadataDeprecated),
359	/// Version 8 for runtime metadata. No longer used.
360	V8(RuntimeMetadataDeprecated),
361	/// Version 9 for runtime metadata. No longer used.
362	V9(RuntimeMetadataDeprecated),
363	/// Version 10 for runtime metadata. No longer used.
364	V10(RuntimeMetadataDeprecated),
365	/// Version 11 for runtime metadata. No longer used.
366	V11(RuntimeMetadataDeprecated),
367	/// Version 12 for runtime metadata.
368	V12(RuntimeMetadataV12),
369}
370
371/// Enum that should fail.
372#[derive(Eq, PartialEq, RuntimeDebug)]
373#[cfg_attr(feature = "std", derive(Serialize))]
374pub enum RuntimeMetadataDeprecated { }
375
376impl Encode for RuntimeMetadataDeprecated {
377	fn encode_to<W: Output + ?Sized>(&self, _dest: &mut W) {}
378}
379
380impl codec::EncodeLike for RuntimeMetadataDeprecated {}
381
382#[cfg(feature = "std")]
383impl Decode for RuntimeMetadataDeprecated {
384	fn decode<I: Input>(_input: &mut I) -> Result<Self, Error> {
385		Err("Decoding is not supported".into())
386	}
387}
388
389/// The metadata of a runtime.
390#[derive(Eq, Encode, PartialEq, RuntimeDebug)]
391#[cfg_attr(feature = "std", derive(Decode, Serialize))]
392pub struct RuntimeMetadataV12 {
393	/// Metadata of all the modules.
394	pub modules: DecodeDifferentArray<ModuleMetadata>,
395	/// Metadata of the extrinsic.
396	pub extrinsic: ExtrinsicMetadata,
397}
398
399/// The latest version of the metadata.
400pub type RuntimeMetadataLastVersion = RuntimeMetadataV12;
401
402/// All metadata about an runtime module.
403#[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)]
404#[cfg_attr(feature = "std", derive(Decode, Serialize))]
405pub struct ModuleMetadata {
406	pub name: DecodeDifferentStr,
407	pub storage: Option<DecodeDifferent<FnEncode<StorageMetadata>, StorageMetadata>>,
408	pub calls: ODFnA<FunctionMetadata>,
409	pub event: ODFnA<EventMetadata>,
410	pub constants: DFnA<ModuleConstantMetadata>,
411	pub errors: DFnA<ErrorMetadata>,
412	/// Define the index of the module, this index will be used for the encoding of module event,
413	/// call and origin variants.
414	pub index: u8,
415}
416
417type ODFnA<T> = Option<DFnA<T>>;
418type DFnA<T> = DecodeDifferent<FnEncode<&'static [T]>, Vec<T>>;
419
420impl Into<tet_core::OpaqueMetadata> for RuntimeMetadataPrefixed {
421	fn into(self) -> tet_core::OpaqueMetadata {
422		tet_core::OpaqueMetadata::new(self.encode())
423	}
424}
425
426impl Into<RuntimeMetadataPrefixed> for RuntimeMetadataLastVersion {
427	fn into(self) -> RuntimeMetadataPrefixed {
428		RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V12(self))
429	}
430}