subxt_metadata/from_into/
v15.rs

1// Copyright 2019-2023 Parity Technologies (UK) Ltd.
2// This file is dual-licensed as Apache-2.0 or GPL-3.0.
3// see LICENSE for license details.
4
5use 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
19// Converting from V15 metadata into our Subxt repr.
20mod 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
231// Converting from our metadata repr to V15 metadata.
232mod 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}