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