1use super::TryFromError;
6
7use crate::utils::variant_index::VariantIndex;
8use crate::{
9 utils::ordered_map::OrderedMap, ArcStr, ConstantMetadata, ExtrinsicMetadata, Metadata,
10 OuterEnumsMetadata, PalletMetadataInner, RuntimeApiMetadataInner, RuntimeApiMethodMetadata,
11 RuntimeApiMethodParamMetadata, StorageEntryMetadata, StorageEntryModifier, StorageEntryType,
12 StorageHasher, StorageMetadata, TransactionExtensionMetadata,
13};
14use alloc::borrow::ToOwned;
15use alloc::vec;
16use frame_metadata::v15;
17use hashbrown::HashMap;
18use scale_info::form::PortableForm;
19
20mod from_v15 {
22 use super::*;
23
24 impl TryFrom<v15::RuntimeMetadataV15> for Metadata {
25 type Error = TryFromError;
26 fn try_from(m: v15::RuntimeMetadataV15) -> Result<Self, TryFromError> {
27 let mut pallets = OrderedMap::new();
28 let mut pallets_by_index = HashMap::new();
29 for (pos, p) in m.pallets.into_iter().enumerate() {
30 let name: ArcStr = p.name.into();
31
32 let storage = p.storage.map(|s| StorageMetadata {
33 prefix: s.prefix,
34 entries: s
35 .entries
36 .into_iter()
37 .map(|s| {
38 let name: ArcStr = s.name.clone().into();
39 (name.clone(), from_storage_entry_metadata(name, s))
40 })
41 .collect(),
42 });
43 let constants = p.constants.into_iter().map(|c| {
44 let name: ArcStr = c.name.clone().into();
45 (name.clone(), from_constant_metadata(name, c))
46 });
47
48 let call_variant_index =
49 VariantIndex::build(p.calls.as_ref().map(|c| c.ty.id), &m.types);
50 let error_variant_index =
51 VariantIndex::build(p.error.as_ref().map(|e| e.ty.id), &m.types);
52 let event_variant_index =
53 VariantIndex::build(p.event.as_ref().map(|e| e.ty.id), &m.types);
54
55 pallets_by_index.insert(p.index, pos);
56 pallets.push_insert(
57 name.clone(),
58 PalletMetadataInner {
59 name,
60 index: p.index,
61 storage,
62 call_ty: p.calls.map(|c| c.ty.id),
63 call_variant_index,
64 event_ty: p.event.map(|e| e.ty.id),
65 event_variant_index,
66 error_ty: p.error.map(|e| e.ty.id),
67 error_variant_index,
68 constants: constants.collect(),
69 docs: p.docs,
70 },
71 );
72 }
73
74 let apis = m.apis.into_iter().map(|api| {
75 let name: ArcStr = api.name.clone().into();
76 (name.clone(), from_runtime_api_metadata(name, api))
77 });
78
79 let dispatch_error_ty = m
80 .types
81 .types
82 .iter()
83 .find(|ty| ty.ty.path.segments == ["sp_runtime", "DispatchError"])
84 .map(|ty| ty.id);
85
86 Ok(Metadata {
87 types: m.types,
88 pallets,
89 pallets_by_index,
90 extrinsic: from_extrinsic_metadata(m.extrinsic),
91 runtime_ty: m.ty.id,
92 dispatch_error_ty,
93 apis: apis.collect(),
94 outer_enums: OuterEnumsMetadata {
95 call_enum_ty: m.outer_enums.call_enum_ty.id,
96 event_enum_ty: m.outer_enums.event_enum_ty.id,
97 error_enum_ty: m.outer_enums.error_enum_ty.id,
98 },
99 custom: m.custom,
100 })
101 }
102 }
103
104 fn from_signed_extension_metadata(
105 value: v15::SignedExtensionMetadata<PortableForm>,
106 ) -> TransactionExtensionMetadata {
107 TransactionExtensionMetadata {
108 identifier: value.identifier,
109 extra_ty: value.ty.id,
110 additional_ty: value.additional_signed.id,
111 }
112 }
113
114 fn from_extrinsic_metadata(value: v15::ExtrinsicMetadata<PortableForm>) -> ExtrinsicMetadata {
115 ExtrinsicMetadata {
116 supported_versions: vec![value.version],
117 transaction_extensions: value
118 .signed_extensions
119 .into_iter()
120 .map(from_signed_extension_metadata)
121 .collect(),
122 address_ty: value.address_ty.id,
123 call_ty: value.call_ty.id,
124 signature_ty: value.signature_ty.id,
125 extra_ty: value.extra_ty.id,
126 transaction_extensions_version: 0,
127 }
128 }
129
130 fn from_storage_hasher(value: v15::StorageHasher) -> StorageHasher {
131 match value {
132 v15::StorageHasher::Blake2_128 => StorageHasher::Blake2_128,
133 v15::StorageHasher::Blake2_256 => StorageHasher::Blake2_256,
134 v15::StorageHasher::Blake2_128Concat => StorageHasher::Blake2_128Concat,
135 v15::StorageHasher::Twox128 => StorageHasher::Twox128,
136 v15::StorageHasher::Twox256 => StorageHasher::Twox256,
137 v15::StorageHasher::Twox64Concat => StorageHasher::Twox64Concat,
138 v15::StorageHasher::Identity => StorageHasher::Identity,
139 }
140 }
141
142 fn from_storage_entry_type(value: v15::StorageEntryType<PortableForm>) -> StorageEntryType {
143 match value {
144 v15::StorageEntryType::Plain(ty) => StorageEntryType::Plain(ty.id),
145 v15::StorageEntryType::Map {
146 hashers,
147 key,
148 value,
149 } => StorageEntryType::Map {
150 hashers: hashers.into_iter().map(from_storage_hasher).collect(),
151 key_ty: key.id,
152 value_ty: value.id,
153 },
154 }
155 }
156
157 fn from_storage_entry_modifier(value: v15::StorageEntryModifier) -> StorageEntryModifier {
158 match value {
159 v15::StorageEntryModifier::Optional => StorageEntryModifier::Optional,
160 v15::StorageEntryModifier::Default => StorageEntryModifier::Default,
161 }
162 }
163
164 fn from_storage_entry_metadata(
165 name: ArcStr,
166 s: v15::StorageEntryMetadata<PortableForm>,
167 ) -> StorageEntryMetadata {
168 StorageEntryMetadata {
169 name,
170 modifier: from_storage_entry_modifier(s.modifier),
171 entry_type: from_storage_entry_type(s.ty),
172 default: s.default,
173 docs: s.docs,
174 }
175 }
176
177 fn from_constant_metadata(
178 name: ArcStr,
179 s: v15::PalletConstantMetadata<PortableForm>,
180 ) -> ConstantMetadata {
181 ConstantMetadata {
182 name,
183 ty: s.ty.id,
184 value: s.value,
185 docs: s.docs,
186 }
187 }
188
189 fn from_runtime_api_metadata(
190 name: ArcStr,
191 s: v15::RuntimeApiMetadata<PortableForm>,
192 ) -> RuntimeApiMetadataInner {
193 RuntimeApiMetadataInner {
194 name,
195 docs: s.docs,
196 methods: s
197 .methods
198 .into_iter()
199 .map(|m| {
200 let name: ArcStr = m.name.clone().into();
201 (name.clone(), from_runtime_api_method_metadata(name, m))
202 })
203 .collect(),
204 }
205 }
206
207 fn from_runtime_api_method_metadata(
208 name: ArcStr,
209 s: v15::RuntimeApiMethodMetadata<PortableForm>,
210 ) -> RuntimeApiMethodMetadata {
211 RuntimeApiMethodMetadata {
212 name,
213 inputs: s
214 .inputs
215 .into_iter()
216 .map(from_runtime_api_method_param_metadata)
217 .collect(),
218 output_ty: s.output.id,
219 docs: s.docs,
220 }
221 }
222
223 fn from_runtime_api_method_param_metadata(
224 s: v15::RuntimeApiMethodParamMetadata<PortableForm>,
225 ) -> RuntimeApiMethodParamMetadata {
226 RuntimeApiMethodParamMetadata {
227 name: s.name,
228 ty: s.ty.id,
229 }
230 }
231}
232
233mod into_v15 {
235 use super::*;
236
237 impl From<Metadata> for v15::RuntimeMetadataV15 {
238 fn from(m: Metadata) -> Self {
239 let pallets = m.pallets.into_values().into_iter().map(|p| {
240 let storage = p.storage.map(|s| v15::PalletStorageMetadata {
241 prefix: s.prefix,
242 entries: s
243 .entries
244 .into_values()
245 .into_iter()
246 .map(from_storage_entry_metadata)
247 .collect(),
248 });
249
250 v15::PalletMetadata {
251 name: (*p.name).to_owned(),
252 calls: p
253 .call_ty
254 .map(|id| v15::PalletCallMetadata { ty: id.into() }),
255 event: p
256 .event_ty
257 .map(|id| v15::PalletEventMetadata { ty: id.into() }),
258 error: p
259 .error_ty
260 .map(|id| v15::PalletErrorMetadata { ty: id.into() }),
261 storage,
262 constants: p
263 .constants
264 .into_values()
265 .into_iter()
266 .map(from_constant_metadata)
267 .collect(),
268 index: p.index,
269 docs: p.docs,
270 }
271 });
272
273 v15::RuntimeMetadataV15 {
274 types: m.types,
275 pallets: pallets.collect(),
276 ty: m.runtime_ty.into(),
277 extrinsic: from_extrinsic_metadata(m.extrinsic),
278 apis: m
279 .apis
280 .into_values()
281 .into_iter()
282 .map(from_runtime_api_metadata)
283 .collect(),
284 outer_enums: v15::OuterEnums {
285 call_enum_ty: m.outer_enums.call_enum_ty.into(),
286 event_enum_ty: m.outer_enums.event_enum_ty.into(),
287 error_enum_ty: m.outer_enums.error_enum_ty.into(),
288 },
289 custom: m.custom,
290 }
291 }
292 }
293
294 fn from_runtime_api_metadata(
295 r: RuntimeApiMetadataInner,
296 ) -> v15::RuntimeApiMetadata<PortableForm> {
297 v15::RuntimeApiMetadata {
298 name: (*r.name).to_owned(),
299 methods: r
300 .methods
301 .into_values()
302 .into_iter()
303 .map(from_runtime_api_method_metadata)
304 .collect(),
305 docs: r.docs,
306 }
307 }
308
309 fn from_runtime_api_method_metadata(
310 m: RuntimeApiMethodMetadata,
311 ) -> v15::RuntimeApiMethodMetadata<PortableForm> {
312 v15::RuntimeApiMethodMetadata {
313 name: (*m.name).to_owned(),
314 inputs: m
315 .inputs
316 .into_iter()
317 .map(from_runtime_api_method_param_metadata)
318 .collect(),
319 output: m.output_ty.into(),
320 docs: m.docs,
321 }
322 }
323
324 fn from_runtime_api_method_param_metadata(
325 p: RuntimeApiMethodParamMetadata,
326 ) -> v15::RuntimeApiMethodParamMetadata<PortableForm> {
327 v15::RuntimeApiMethodParamMetadata {
328 name: p.name,
329 ty: p.ty.into(),
330 }
331 }
332
333 fn from_extrinsic_metadata(e: ExtrinsicMetadata) -> v15::ExtrinsicMetadata<PortableForm> {
334 v15::ExtrinsicMetadata {
335 version: *e
346 .supported_versions
347 .iter()
348 .min()
349 .expect("at least one extrinsic version expected"),
350 signed_extensions: e
351 .transaction_extensions
352 .into_iter()
353 .map(from_signed_extension_metadata)
354 .collect(),
355 address_ty: e.address_ty.into(),
356 call_ty: e.call_ty.into(),
357 signature_ty: e.signature_ty.into(),
358 extra_ty: e.extra_ty.into(),
359 }
360 }
361
362 fn from_signed_extension_metadata(
363 s: TransactionExtensionMetadata,
364 ) -> v15::SignedExtensionMetadata<PortableForm> {
365 v15::SignedExtensionMetadata {
366 identifier: s.identifier,
367 ty: s.extra_ty.into(),
368 additional_signed: s.additional_ty.into(),
369 }
370 }
371
372 fn from_constant_metadata(c: ConstantMetadata) -> v15::PalletConstantMetadata<PortableForm> {
373 v15::PalletConstantMetadata {
374 name: (*c.name).to_owned(),
375 ty: c.ty.into(),
376 value: c.value,
377 docs: c.docs,
378 }
379 }
380
381 fn from_storage_entry_metadata(
382 s: StorageEntryMetadata,
383 ) -> v15::StorageEntryMetadata<PortableForm> {
384 v15::StorageEntryMetadata {
385 docs: s.docs,
386 default: s.default,
387 name: (*s.name).to_owned(),
388 ty: from_storage_entry_type(s.entry_type),
389 modifier: from_storage_entry_modifier(s.modifier),
390 }
391 }
392
393 fn from_storage_entry_modifier(s: StorageEntryModifier) -> v15::StorageEntryModifier {
394 match s {
395 StorageEntryModifier::Default => v15::StorageEntryModifier::Default,
396 StorageEntryModifier::Optional => v15::StorageEntryModifier::Optional,
397 }
398 }
399
400 fn from_storage_entry_type(s: StorageEntryType) -> v15::StorageEntryType<PortableForm> {
401 match s {
402 StorageEntryType::Plain(ty) => v15::StorageEntryType::Plain(ty.into()),
403 StorageEntryType::Map {
404 hashers,
405 key_ty,
406 value_ty,
407 } => v15::StorageEntryType::Map {
408 hashers: hashers.into_iter().map(from_storage_hasher).collect(),
409 key: key_ty.into(),
410 value: value_ty.into(),
411 },
412 }
413 }
414
415 fn from_storage_hasher(s: StorageHasher) -> v15::StorageHasher {
416 match s {
417 StorageHasher::Blake2_128 => v15::StorageHasher::Blake2_128,
418 StorageHasher::Blake2_256 => v15::StorageHasher::Blake2_256,
419 StorageHasher::Blake2_128Concat => v15::StorageHasher::Blake2_128Concat,
420 StorageHasher::Twox128 => v15::StorageHasher::Twox128,
421 StorageHasher::Twox256 => v15::StorageHasher::Twox256,
422 StorageHasher::Twox64Concat => v15::StorageHasher::Twox64Concat,
423 StorageHasher::Identity => v15::StorageHasher::Identity,
424 }
425 }
426}