referrerpolicy=no-referrer-when-downgrade
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Intermediate representation of the runtime metadata.

#![cfg_attr(not(feature = "std"), no_std)]
#![warn(missing_docs)]

extern crate alloc;

// Re-export.
#[doc(hidden)]
pub use frame_metadata;

mod types;
use frame_metadata::RuntimeMetadataPrefixed;
pub use types::*;

mod unstable;
mod v14;
mod v15;

/// Metadata V14.
const V14: u32 = 14;

/// Metadata V15.
const V15: u32 = 15;

/// Unstable metadata V16.
const UNSTABLE_V16: u32 = u32::MAX;

/// Transform the IR to the specified version.
///
/// Use [`supported_versions`] to find supported versions.
pub fn into_version(metadata: MetadataIR, version: u32) -> Option<RuntimeMetadataPrefixed> {
	// Note: Unstable metadata version is `u32::MAX` until stabilized.
	match version {
		// Version V14. This needs to be around until the
		// deprecation of the `Metadata_metadata` runtime call in favor of
		// `Metadata_metadata_at_version.
		V14 => Some(into_v14(metadata)),

		// Version V15 - latest stable.
		V15 => Some(into_latest(metadata)),

		// Unstable metadata under `u32::MAX`.
		UNSTABLE_V16 => Some(into_unstable(metadata)),

		_ => None,
	}
}

/// Returns the supported metadata versions.
pub fn supported_versions() -> alloc::vec::Vec<u32> {
	alloc::vec![V14, V15, UNSTABLE_V16]
}

/// Transform the IR to the latest stable metadata version.
pub fn into_latest(metadata: MetadataIR) -> RuntimeMetadataPrefixed {
	let latest: frame_metadata::v15::RuntimeMetadataV15 = metadata.into();
	latest.into()
}

/// Transform the IR to metadata version 14.
pub fn into_v14(metadata: MetadataIR) -> RuntimeMetadataPrefixed {
	let latest: frame_metadata::v14::RuntimeMetadataV14 = metadata.into();
	latest.into()
}

/// Transform the IR to unstable metadata version 16.
pub fn into_unstable(metadata: MetadataIR) -> RuntimeMetadataPrefixed {
	let latest: frame_metadata::v16::RuntimeMetadataV16 = metadata.into();
	latest.into()
}

/// INTERNAL USE ONLY
///
/// Special trait that is used together with `InternalConstructRuntime` by `construct_runtime!` to
/// fetch the runtime api metadata without exploding when there is no runtime api implementation
/// available.
#[doc(hidden)]
pub trait InternalImplRuntimeApis {
	fn runtime_metadata(&self) -> alloc::vec::Vec<RuntimeApiMetadataIR>;
}

#[cfg(test)]
mod test {
	use super::*;
	use frame_metadata::{v14::META_RESERVED, RuntimeMetadata};
	use scale_info::meta_type;

	fn ir_metadata() -> MetadataIR {
		MetadataIR {
			pallets: vec![],
			extrinsic: ExtrinsicMetadataIR {
				ty: meta_type::<()>(),
				versions: vec![0],
				address_ty: meta_type::<()>(),
				call_ty: meta_type::<()>(),
				signature_ty: meta_type::<()>(),
				extra_ty: meta_type::<()>(),
				extensions: vec![],
			},
			ty: meta_type::<()>(),
			apis: vec![],
			outer_enums: OuterEnumsIR {
				call_enum_ty: meta_type::<()>(),
				event_enum_ty: meta_type::<()>(),
				error_enum_ty: meta_type::<()>(),
			},
		}
	}

	#[test]
	fn into_version_14() {
		let ir = ir_metadata();
		let metadata = into_version(ir, V14).expect("Should return prefixed metadata");

		assert_eq!(metadata.0, META_RESERVED);

		assert!(matches!(metadata.1, RuntimeMetadata::V14(_)));
	}

	#[test]
	fn into_version_15() {
		let ir = ir_metadata();
		let metadata = into_version(ir, V15).expect("Should return prefixed metadata");

		assert_eq!(metadata.0, META_RESERVED);

		assert!(matches!(metadata.1, RuntimeMetadata::V15(_)));
	}
}