1use bitvec::prelude::{BitVec, Lsb0, Msb0};
2use external_memory_tools::ExternalMemory;
3use num_bigint::{BigInt, BigUint};
4use parity_scale_codec::Encode;
5use primitive_types::H256;
6use scale_info::{
7 form::PortableForm, interner::UntrackedSymbol, Field, Type, TypeDef, TypeDefBitSequence,
8 TypeDefPrimitive, Variant,
9};
10use sp_arithmetic::{PerU16, Perbill, Percent, Permill, Perquintill};
11use substrate_crypto_light::{
12 common::AccountId32,
13 ecdsa::{Public as PublicEcdsa, Signature as SignatureEcdsa},
14 ed25519::{Public as PublicEd25519, Signature as SignatureEd25519},
15 sr25519::{Public as PublicSr25519, Signature as SignatureSr25519},
16};
17use substrate_parser::{
18 cards::{Documented, Info},
19 decoding_sci::{find_bit_order_ty, husk_type, FoundBitOrder, ResolvedTy, Ty},
20 error::{ExtensionsError, RegistryError, RegistryInternalError},
21 propagated::{Checker, Propagated, SpecialtySet},
22 special_indicators::{
23 SignatureIndicator, SpecialtyH256, SpecialtyTypeHinted, SpecialtyUnsignedInteger,
24 },
25 traits::ResolveType,
26};
27
28use std::any::TypeId;
29
30use crate::{
31 error::ErrorFixMe,
32 finalize::{Finalize, TypeContent},
33 traits::{AsFillMetadata, AsPalletMetadata, Unsigned},
34 try_fill::TryFill,
35};
36
37#[derive(Clone, Debug)]
38pub struct VariantSelected {
39 pub selector_index: usize,
40 pub docs: String,
41 pub fields_to_fill: Vec<FieldToFill>,
42 pub index: u8,
43 pub name: String,
44}
45
46#[derive(Clone, Debug)]
47pub struct FieldToFill {
48 pub type_to_fill: TypeToFill,
49 pub field_docs: String,
50 pub field_name: Option<String>,
51 pub type_name: Option<String>,
52}
53
54#[derive(Clone, Debug)]
55pub struct TypeToFill {
56 pub content: TypeContentToFill,
57 pub info: Vec<Info>,
58}
59
60#[derive(Clone, Debug)]
61pub enum TypeContentToFill {
62 ArrayU8(ArrayU8ToFill),
63 ArrayRegular(ArrayRegularToFill),
64 BitSequence(BitSequenceContent),
65 Composite(Vec<FieldToFill>),
66 Primitive(PrimitiveToFill),
67 SequenceRegular(SequenceRegularToFill),
68 SequenceU8(SequenceU8ToFill),
69 SpecialType(SpecialTypeToFill),
70 Tuple(Vec<TypeToFill>),
71 Variant(VariantSelector),
72 VariantEmpty,
73}
74
75#[derive(Clone, Debug)]
76pub struct VariantSelector {
77 pub available_variants: Vec<Variant<PortableForm>>,
78 pub selected: VariantSelected,
79}
80
81impl VariantSelector {
82 pub fn init<E: ExternalMemory, M: AsFillMetadata<E>>(
83 variants: &[Variant<PortableForm>],
84 ext_memory: &mut E,
85 registry: &M::TypeRegistry,
86 ) -> Result<Self, RegistryError<E>> {
87 Self::new_at::<E, M>(variants, ext_memory, registry, 0)
88 }
89 pub fn new_at<E: ExternalMemory, M: AsFillMetadata<E>>(
90 variants: &[Variant<PortableForm>],
91 ext_memory: &mut E,
92 registry: &M::TypeRegistry,
93 selector_index: usize,
94 ) -> Result<Self, RegistryError<E>> {
95 let variant = &variants[selector_index];
97 let name = variant.name.to_owned();
98 let docs = variant.collect_docs();
99 let fields_to_fill =
100 prepare_fields::<E, M>(&variant.fields, ext_memory, registry, Checker::new())?;
101 let selected = VariantSelected {
102 selector_index,
103 docs,
104 fields_to_fill,
105 index: variant.index,
106 name,
107 };
108 Ok(Self {
109 available_variants: variants.to_owned(),
110 selected,
111 })
112 }
113 pub fn selector_up<E: ExternalMemory, M: AsFillMetadata<E>>(
114 &mut self,
115 ext_memory: &mut E,
116 registry: &M::TypeRegistry,
117 ) -> Result<(), RegistryError<E>> {
118 let new_selector_index = {
119 if self.selected.selector_index + 1 == self.available_variants.len() {
120 0
121 } else {
122 self.selected.selector_index + 1
123 }
124 };
125 *self = VariantSelector::new_at::<E, M>(
126 &self.available_variants,
127 ext_memory,
128 registry,
129 new_selector_index,
130 )?;
131 Ok(())
132 }
133 pub fn selector_down<E: ExternalMemory, M: AsFillMetadata<E>>(
134 &mut self,
135 ext_memory: &mut E,
136 registry: &M::TypeRegistry,
137 ) -> Result<(), RegistryError<E>> {
138 let new_selector_index = {
139 if self.selected.selector_index == 0 {
140 self.available_variants.len() - 1
141 } else {
142 self.selected.selector_index - 1
143 }
144 };
145 *self = VariantSelector::new_at::<E, M>(
146 &self.available_variants,
147 ext_memory,
148 registry,
149 new_selector_index,
150 )?;
151 Ok(())
152 }
153}
154
155#[derive(Clone, Debug)]
156pub enum BitSequenceContent {
157 BitVecU8Lsb0(BitVec<u8, Lsb0>),
158 BitVecU16Lsb0(BitVec<u16, Lsb0>),
159 BitVecU32Lsb0(BitVec<u32, Lsb0>),
160 #[cfg(target_pointer_width = "64")]
161 BitVecU64Lsb0(BitVec<u64, Lsb0>),
162 BitVecU8Msb0(BitVec<u8, Msb0>),
163 BitVecU16Msb0(BitVec<u16, Msb0>),
164 BitVecU32Msb0(BitVec<u32, Msb0>),
165 #[cfg(target_pointer_width = "64")]
166 BitVecU64Msb0(BitVec<u64, Msb0>),
167}
168
169#[derive(Clone, Debug)]
170pub enum PrimitiveToFill {
171 CompactUnsigned(SpecialtyUnsignedToFill),
172 Regular(RegularPrimitiveToFill),
173 Unsigned(SpecialtyUnsignedToFill),
174}
175
176#[derive(Clone, Debug)]
177pub enum RegularPrimitiveToFill {
178 Bool(Option<bool>),
179 Char(Option<char>),
180 I8(Option<i8>),
181 I16(Option<i16>),
182 I32(Option<i32>),
183 I64(Option<i64>),
184 I128(Option<i128>),
185 I256(Option<BigInt>),
186 Str(String),
187 U256(Option<BigUint>),
188}
189
190#[derive(Clone, Debug)]
191pub enum UnsignedToFill {
192 U8(Option<u8>),
193 U16(Option<u16>),
194 U32(Option<u32>),
195 U64(Option<u64>),
196 U128(Option<u128>),
197}
198
199impl UnsignedToFill {
200 pub fn into_unsigned(&self) -> Option<Unsigned> {
201 match &self {
202 UnsignedToFill::U8(a) => a.map(Unsigned::U8),
203 UnsignedToFill::U16(a) => a.map(Unsigned::U16),
204 UnsignedToFill::U32(a) => a.map(Unsigned::U32),
205 UnsignedToFill::U64(a) => a.map(Unsigned::U64),
206 UnsignedToFill::U128(a) => a.map(Unsigned::U128),
207 }
208 }
209}
210
211#[derive(Clone, Debug)]
212pub struct SpecialtyUnsignedToFill {
213 pub content: UnsignedToFill,
214 pub specialty: SpecialtyUnsignedInteger,
215}
216
217#[derive(Debug)]
218pub enum SequenceDraft {
219 U8(SequenceDraftContent),
220 Regular(SequenceDraftContent),
221}
222
223#[derive(Debug)]
224pub struct SequenceDraftContent {
225 pub info_element: Vec<Info>,
226 pub resolved_ty: ResolvedTy,
227 pub checker: Checker,
228}
229
230#[derive(Clone, Debug)]
231pub struct SequenceU8ToFill {
232 pub content: Vec<u8>,
233 pub info_element: Vec<Info>,
234}
235
236#[derive(Clone, Debug)]
237pub struct SequenceRegularToFill {
238 pub content: Vec<TypeContentToFill>,
239 pub info_element: Vec<Info>,
240 pub ty: Type<PortableForm>,
241 pub id: u32,
242}
243
244impl SequenceRegularToFill {
245 pub fn remove_last_element(&mut self) {
246 self.content.pop();
247 }
248 pub fn add_new_element<E: ExternalMemory, M: AsFillMetadata<E>>(
249 &mut self,
250 ext_memory: &mut E,
251 registry: &M::TypeRegistry,
252 ) -> Result<(), RegistryError<E>> {
253 let element = prepare_type::<E, M>(
254 &Ty::Resolved(ResolvedTy {
255 ty: self.ty.to_owned(),
256 id: self.id,
257 }),
258 ext_memory,
259 registry,
260 Propagated::new(),
261 )?;
262 self.content.push(element.content);
263 Ok(())
264 }
265 pub fn set_number_of_elements<E: ExternalMemory, M: AsFillMetadata<E>>(
266 &mut self,
267 ext_memory: &mut E,
268 registry: &M::TypeRegistry,
269 number_of_elements: usize,
270 ) -> Result<(), RegistryError<E>> {
271 if self.content.len() <= number_of_elements {
272 for _i in 0..number_of_elements - self.content.len() {
273 self.add_new_element::<E, M>(ext_memory, registry)?;
274 }
275 } else {
276 self.content.truncate(number_of_elements);
277 }
278 Ok(())
279 }
280}
281
282#[derive(Clone, Debug)]
283pub struct ArrayU8ToFill {
284 pub content: Vec<u8>,
285 pub info_element: Vec<Info>,
286 pub len: u32,
287}
288
289#[derive(Clone, Debug)]
290pub struct ArrayRegularToFill {
291 pub content: Vec<TypeContentToFill>,
292 pub info_element: Vec<Info>,
293 pub len: u32,
294}
295
296#[derive(Clone, Debug)]
297pub enum SpecialTypeToFill {
298 AccountId32(Option<AccountId32>),
299 Era(EraToFill),
300 H256 {
301 hash: Option<H256>,
302 specialty: SpecialtyH256,
303 },
304 PerU16 {
305 value: Option<PerU16>,
306 is_compact: bool,
307 },
308 Perbill {
309 value: Option<Perbill>,
310 is_compact: bool,
311 },
312 Percent {
313 value: Option<Percent>,
314 is_compact: bool,
315 },
316 Permill {
317 value: Option<Permill>,
318 is_compact: bool,
319 },
320 Perquintill {
321 value: Option<Perquintill>,
322 is_compact: bool,
323 },
324 PublicEd25519(Option<PublicEd25519>),
325 PublicSr25519(Option<PublicSr25519>),
326 PublicEcdsa(Option<PublicEcdsa>),
327 SignatureEd25519(Option<SignatureEd25519>),
328 SignatureSr25519(Option<SignatureSr25519>),
329 SignatureEcdsa(Option<SignatureEcdsa>),
330}
331
332#[derive(Clone, Debug)]
333pub enum EraToFill {
334 Immortal,
335 Mortal {
336 period_entry: u64,
337 block_number_entry: Option<u64>,
338 },
339}
340
341pub const DEFAULT_PERIOD: u64 = 64;
342
343pub trait FillPrimitive {
344 fn primitive_to_fill(
345 specialty_set: &SpecialtySet,
346 ) -> Result<PrimitiveToFill, RegistryInternalError>;
347}
348
349macro_rules! impl_regular_fill_primitive {
350 ($($ty:ty, $variant:ident), *) => {
351 $(
352 impl FillPrimitive for $ty {
353 fn primitive_to_fill(specialty_set: &SpecialtySet) -> Result<PrimitiveToFill, RegistryInternalError> {
354 if let Some(id) = specialty_set.compact_at {Err(RegistryInternalError::UnexpectedCompactInsides{id})}
355 else {Ok(PrimitiveToFill::Regular(RegularPrimitiveToFill::$variant(None)))}
356 }
357 }
358 )*
359 }
360}
361
362impl_regular_fill_primitive!(bool, Bool);
363impl_regular_fill_primitive!(char, Char);
364impl_regular_fill_primitive!(i8, I8);
365impl_regular_fill_primitive!(i16, I16);
366impl_regular_fill_primitive!(i32, I32);
367impl_regular_fill_primitive!(i64, I64);
368impl_regular_fill_primitive!(i128, I128);
369impl_regular_fill_primitive!(BigInt, I256);
370impl_regular_fill_primitive!(BigUint, U256);
371
372impl FillPrimitive for String {
373 fn primitive_to_fill(
374 specialty_set: &SpecialtySet,
375 ) -> Result<PrimitiveToFill, RegistryInternalError> {
376 specialty_set.reject_compact()?;
377 Ok(PrimitiveToFill::Regular(RegularPrimitiveToFill::Str(
378 String::new(),
379 )))
380 }
381}
382
383macro_rules! impl_unsigned_fill_primitive {
384 ($($ty:ty, $variant:ident), *) => {
385 $(
386 impl FillPrimitive for $ty {
387 fn primitive_to_fill(specialty_set: &SpecialtySet) -> Result<PrimitiveToFill, RegistryInternalError> {
388 let specialty = specialty_set.unsigned_integer();
389 let specialty_unsigned_to_fill = SpecialtyUnsignedToFill {
390 content: UnsignedToFill::$variant(None),
391 specialty,
392 };
393 if specialty_set.compact_at.is_some() {
394 Ok(PrimitiveToFill::CompactUnsigned(specialty_unsigned_to_fill))
395 }
396 else {
397 Ok(PrimitiveToFill::Unsigned(specialty_unsigned_to_fill))
398 }
399 }
400 }
401 )*
402 }
403}
404
405impl_unsigned_fill_primitive!(u8, U8);
406impl_unsigned_fill_primitive!(u16, U16);
407impl_unsigned_fill_primitive!(u32, U32);
408impl_unsigned_fill_primitive!(u64, U64);
409impl_unsigned_fill_primitive!(u128, U128);
410
411pub trait FillSpecial {
412 fn special_to_fill(
413 specialty_set: &SpecialtySet,
414 ) -> Result<SpecialTypeToFill, RegistryInternalError>;
415}
416
417macro_rules! impl_fill_special {
418 ($($ty:tt), *) => {
419 $(
420 impl FillSpecial for $ty {
421 fn special_to_fill(specialty_set: &SpecialtySet) -> Result<SpecialTypeToFill, RegistryInternalError> {
422 specialty_set.reject_compact()?;
423 Ok(SpecialTypeToFill::$ty(None))
424 }
425 }
426 )*
427 }
428}
429
430impl_fill_special!(
431 AccountId32,
432 PublicEd25519,
433 PublicSr25519,
434 PublicEcdsa,
435 SignatureEd25519,
436 SignatureSr25519,
437 SignatureEcdsa
438);
439
440impl FillSpecial for EraToFill {
441 fn special_to_fill(
442 specialty_set: &SpecialtySet,
443 ) -> Result<SpecialTypeToFill, RegistryInternalError> {
444 specialty_set.reject_compact()?;
445 Ok(SpecialTypeToFill::Era(EraToFill::Immortal))
446 }
447}
448
449impl EraToFill {
450 pub fn selector(&mut self) {
451 match &self {
452 EraToFill::Immortal => {
453 *self = EraToFill::Mortal {
454 period_entry: DEFAULT_PERIOD,
455 block_number_entry: None,
456 }
457 }
458 EraToFill::Mortal { .. } => *self = EraToFill::Immortal,
459 }
460 }
461}
462
463impl FillSpecial for H256 {
464 fn special_to_fill(
465 specialty_set: &SpecialtySet,
466 ) -> Result<SpecialTypeToFill, RegistryInternalError> {
467 specialty_set.reject_compact()?;
468 let specialty = specialty_set.hint.hash256();
469 Ok(SpecialTypeToFill::H256 {
470 hash: None,
471 specialty,
472 })
473 }
474}
475
476macro_rules! impl_fill_special_with_compact {
477 ($($ty:tt), *) => {
478 $(
479 impl FillSpecial for $ty {
480 fn special_to_fill(specialty_set: &SpecialtySet) -> Result<SpecialTypeToFill, RegistryInternalError> {
481 Ok(SpecialTypeToFill::$ty{value: None, is_compact: specialty_set.compact_at.is_some()})
482 }
483 }
484 )*
485 }
486}
487
488impl_fill_special_with_compact!(PerU16, Perbill, Percent, Permill, Perquintill);
489
490pub fn prepare_primitive(
491 found_ty: &TypeDefPrimitive,
492 specialty_set: &SpecialtySet,
493) -> Result<PrimitiveToFill, RegistryInternalError> {
494 match found_ty {
495 TypeDefPrimitive::Bool => bool::primitive_to_fill(specialty_set),
496 TypeDefPrimitive::Char => char::primitive_to_fill(specialty_set),
497 TypeDefPrimitive::Str => String::primitive_to_fill(specialty_set),
498 TypeDefPrimitive::I8 => i8::primitive_to_fill(specialty_set),
499 TypeDefPrimitive::I16 => i16::primitive_to_fill(specialty_set),
500 TypeDefPrimitive::I32 => i32::primitive_to_fill(specialty_set),
501 TypeDefPrimitive::I64 => i64::primitive_to_fill(specialty_set),
502 TypeDefPrimitive::I128 => i128::primitive_to_fill(specialty_set),
503 TypeDefPrimitive::I256 => BigInt::primitive_to_fill(specialty_set),
504 TypeDefPrimitive::U8 => u8::primitive_to_fill(specialty_set),
505 TypeDefPrimitive::U16 => u16::primitive_to_fill(specialty_set),
506 TypeDefPrimitive::U32 => u32::primitive_to_fill(specialty_set),
507 TypeDefPrimitive::U64 => u64::primitive_to_fill(specialty_set),
508 TypeDefPrimitive::U128 => u128::primitive_to_fill(specialty_set),
509 TypeDefPrimitive::U256 => BigUint::primitive_to_fill(specialty_set),
510 }
511}
512
513#[derive(Clone, Debug)]
514pub struct TransactionToFill {
515 pub author: TypeToFill,
516 pub call: TypeToFill,
517 pub extensions: Vec<TypeToFill>,
518 pub signature: TypeToFill,
519 pub extra: Vec<usize>,
520 pub genesis_hash: H256,
521}
522
523impl TransactionToFill {
524 pub fn init<E, M>(
525 ext_memory: &mut E,
526 metadata: &M,
527 genesis_hash: H256,
528 ) -> Result<Self, ErrorFixMe<E, M>>
529 where
530 E: ExternalMemory,
531 M: AsFillMetadata<E>,
532 {
533 let registry = metadata.types();
534 let extrinsic_type_params = metadata
535 .extrinsic_type_params()
536 .map_err(ErrorFixMe::MetaStructure)?;
537 let signed_extensions = metadata
538 .signed_extensions()
539 .map_err(ErrorFixMe::MetaStructure)?;
540
541 let author = prepare_type::<E, M>(
542 &Ty::Symbol(&extrinsic_type_params.address_ty),
543 ext_memory,
544 ®istry,
545 Propagated::new(),
546 )?;
547
548 let call = prepare_type::<E, M>(
549 &Ty::Symbol(&extrinsic_type_params.call_ty),
550 ext_memory,
551 ®istry,
552 Propagated::new(),
553 )?;
554
555 let signature = prepare_type::<E, M>(
556 &Ty::Symbol(&extrinsic_type_params.signature_ty),
557 ext_memory,
558 ®istry,
559 Propagated::new(),
560 )?;
561
562 let mut extensions = Vec::new();
563 let mut extensions_ty_ids = Vec::new();
564
565 for signed_extensions_metadata in signed_extensions.iter() {
566 extensions_ty_ids.push(signed_extensions_metadata.ty.id);
567 extensions.push(prepare_type::<E, M>(
568 &Ty::Symbol(&signed_extensions_metadata.ty),
569 ext_memory,
570 ®istry,
571 Propagated::from_ext_meta(signed_extensions_metadata),
572 )?)
573 }
574 for signed_extensions_metadata in signed_extensions.iter() {
575 extensions_ty_ids.push(signed_extensions_metadata.additional_signed.id);
576 extensions.push(prepare_type::<E, M>(
577 &Ty::Symbol(&signed_extensions_metadata.additional_signed),
578 ext_memory,
579 ®istry,
580 Propagated::from_ext_meta(signed_extensions_metadata),
581 )?)
582 }
583
584 check_extensions(&extensions).map_err(ErrorFixMe::ExtensionsList)?;
585
586 let extra = extra_indices_in_extensions::<E, M>(
587 ext_memory,
588 ®istry,
589 &extrinsic_type_params.extra_ty,
590 &extensions_ty_ids,
591 )?;
592
593 let mut out = TransactionToFill {
594 author,
595 call,
596 extensions,
597 signature,
598 extra,
599 genesis_hash,
600 };
601 out.populate_genesis_hash(genesis_hash);
602 out.populate_spec_version(&metadata.spec_version().map_err(ErrorFixMe::MetaStructure)?);
603 if let Some(tx_version) = &metadata.defined_tx_version() {
604 out.populate_tx_version(tx_version)
605 }
606 out.try_default_tip();
607 out.try_default_signature_to_sr25519(ext_memory, metadata)
608 .map_err(ErrorFixMe::Registry)?;
609 Ok(out)
610 }
611
612 pub fn populate_block_info(
613 &mut self,
614 optional_block_hash: Option<H256>,
615 optional_block_number: Option<u64>,
616 ) {
617 if era_is_immortal(&self.extensions) {
618 self.populate_block_hash_helper(self.genesis_hash)
619 } else if let Some(block_hash) = optional_block_hash {
620 if let Some(block_number) = optional_block_number {
621 self.populate_block_hash_helper(block_hash);
622 fill_mortal_block_number(&mut self.extensions, block_number)
623 }
624 }
625 }
626
627 pub fn try_default_tip(&mut self) {
628 for extension in self.extensions.iter_mut() {
629 try_default_tip(&mut extension.content);
630 if let TypeContentToFill::Composite(ref mut fields_to_fill) = extension.content {
631 for field in fields_to_fill.iter_mut() {
632 try_default_tip(&mut field.type_to_fill.content);
633 }
634 }
635 }
636 }
637
638 pub fn try_default_tip_assets_in_given_asset<E: ExternalMemory, M: AsFillMetadata<E>>(
639 &mut self,
640 ext_memory: &mut E,
641 metadata: &M,
642 known_asset_id: u32,
643 ) {
644 let mut pallet_assets_id = None;
645 for pallet in metadata.pallets() {
646 if pallet.name() == "Assets" {
647 pallet_assets_id = Some(pallet.index());
648 break;
649 }
650 }
651
652 if let Some(pallet_assets_id) = pallet_assets_id {
653 let registry = metadata.types();
654
655 for extension in self.extensions.iter_mut() {
656 try_default_tip(&mut extension.content);
658 if let TypeContentToFill::Composite(ref mut fields_to_fill) = extension.content {
659 let mut has_tip_related_field = false;
662 for field in fields_to_fill.iter() {
663 match &field.type_to_fill.content {
664 TypeContentToFill::Primitive(PrimitiveToFill::CompactUnsigned(
665 specialty_unsigned_to_fill,
666 )) => {
667 has_tip_related_field = specialty_unsigned_to_fill.specialty
668 == SpecialtyUnsignedInteger::TipAsset;
669 }
670 TypeContentToFill::Primitive(PrimitiveToFill::Unsigned(
671 specialty_unsigned_to_fill,
672 )) => {
673 has_tip_related_field = specialty_unsigned_to_fill.specialty
674 == SpecialtyUnsignedInteger::TipAsset;
675 }
676 _ => {}
677 }
678 if has_tip_related_field {
679 break;
680 }
681 }
682 if has_tip_related_field {
684 for field in fields_to_fill.iter_mut() {
685 try_default_tip_assets_in_given_asset::<E, M>(
686 &mut field.type_to_fill.content,
687 ext_memory,
688 ®istry,
689 known_asset_id,
690 pallet_assets_id,
691 );
692 }
693 }
694 }
695 }
696 }
697 }
698
699 pub fn try_default_signature_to_sr25519<E, M>(
704 &mut self,
705 ext_memory: &mut E,
706 metadata: &M,
707 ) -> Result<(), RegistryError<E>>
708 where
709 E: ExternalMemory,
710 M: AsFillMetadata<E>,
711 {
712 if let TypeContentToFill::Variant(ref mut variant_selector) = self.signature.content {
713 let mut found_index = None;
714 let registry = metadata.types();
715 for (i, variant) in variant_selector.available_variants.iter().enumerate() {
716 if variant.fields.len() == 1 {
717 if let SignatureIndicator::Sr25519 = SignatureIndicator::from_field::<E, M>(
718 &variant.fields[0],
719 ext_memory,
720 ®istry,
721 ) {
722 found_index = Some(i);
723 break;
724 } else {
725 let ty = registry.resolve_ty(variant.fields[0].ty.id, ext_memory)?;
726 if let SpecialtyTypeHinted::SignatureSr25519 =
727 SpecialtyTypeHinted::from_type(&ty)
728 {
729 found_index = Some(i);
730 break;
731 }
732 }
733 }
734 }
735 if let Some(new_selector_index) = found_index {
736 *variant_selector = VariantSelector::new_at::<E, M>(
737 &variant_selector.available_variants,
738 ext_memory,
739 ®istry,
740 new_selector_index,
741 )?;
742 }
743 }
744 Ok(())
745 }
746
747 pub fn signature_is_sr25519(&self) -> bool {
751 match self.signature.content {
752 TypeContentToFill::Composite(ref fields_to_fill) => {
753 if fields_to_fill.len() == 1 {
754 matches!(
755 fields_to_fill[0].type_to_fill.content,
756 TypeContentToFill::SpecialType(SpecialTypeToFill::SignatureSr25519(_))
757 )
758 } else {
759 false
760 }
761 }
762 TypeContentToFill::SpecialType(SpecialTypeToFill::SignatureSr25519(_)) => true,
763 TypeContentToFill::Variant(ref variant_selector) => {
764 if variant_selector.selected.fields_to_fill.len() == 1 {
765 matches!(
766 variant_selector.selected.fields_to_fill[0]
767 .type_to_fill
768 .content,
769 TypeContentToFill::SpecialType(SpecialTypeToFill::SignatureSr25519(_))
770 )
771 } else {
772 false
773 }
774 }
775 _ => false,
776 }
777 }
778
779 pub fn author_as_sr25519_compatible(&self) -> Option<[u8; 32]> {
783 match &self.author.content {
784 TypeContentToFill::Composite(ref fields_to_fill) => {
785 if fields_to_fill.len() == 1 {
786 match &fields_to_fill[0].type_to_fill.content {
787 TypeContentToFill::SpecialType(SpecialTypeToFill::AccountId32(a)) => {
788 (*a).map(|b| b.0)
789 }
790 TypeContentToFill::SpecialType(SpecialTypeToFill::PublicSr25519(a)) => {
791 (*a).map(|b| b.0)
792 }
793 _ => None,
794 }
795 } else {
796 None
797 }
798 }
799 TypeContentToFill::SpecialType(SpecialTypeToFill::AccountId32(a)) => (*a).map(|b| b.0),
800 TypeContentToFill::SpecialType(SpecialTypeToFill::PublicSr25519(a)) => {
801 (*a).map(|b| b.0)
802 }
803 TypeContentToFill::Variant(ref variant_selector) => {
804 if variant_selector.selected.fields_to_fill.len() == 1 {
805 match &variant_selector.selected.fields_to_fill[0]
806 .type_to_fill
807 .content
808 {
809 TypeContentToFill::SpecialType(SpecialTypeToFill::AccountId32(a)) => {
810 (*a).map(|b| b.0)
811 }
812 TypeContentToFill::SpecialType(SpecialTypeToFill::PublicSr25519(a)) => {
813 (*a).map(|b| b.0)
814 }
815 _ => None,
816 }
817 } else {
818 None
819 }
820 }
821 _ => None,
822 }
823 }
824
825 pub fn extrinsic_to_sign(&self) -> Option<ExtrinsicToSign> {
826 if let Some(call) = self.call.finalize() {
827 let mut extensions = Vec::new();
828 for ext in self.extensions.iter() {
829 if let Some(a) = ext.finalize() {
830 extensions.push(a);
831 } else {
832 return None;
833 }
834 }
835 Some(ExtrinsicToSign {
836 call: call.to_owned(),
837 extensions,
838 })
839 } else {
840 None
841 }
842 }
843
844 pub fn sign_this(&self) -> Option<Vec<u8>> {
845 if let Some(extrinsic_to_sign) = self.extrinsic_to_sign() {
846 let mut out = extrinsic_to_sign.call.encode();
847 for ext in extrinsic_to_sign.extensions.iter() {
848 out.extend_from_slice(&ext.encode())
849 }
850 Some(out)
851 } else {
852 None
853 }
854 }
855
856 pub fn into_signer_transaction_format(&self) -> Option<Vec<u8>> {
857 if let Some(extrinsic_to_sign) = self.extrinsic_to_sign() {
858 let mut out = extrinsic_to_sign.call.encode().encode(); for ext in extrinsic_to_sign.extensions.iter() {
860 out.extend_from_slice(&ext.encode())
861 }
862 Some(out)
863 } else {
864 None
865 }
866 }
867
868 pub fn output_qr_data_signer_style(&self) -> Option<Vec<u8>> {
869 if let Some(author) = self.author_as_sr25519_compatible() {
870 if let Some(signable) = self.into_signer_transaction_format() {
871 let mut out = vec![0x53, 0x01, 0x00];
872 out.extend_from_slice(&author);
873 out.extend_from_slice(&signable);
874 out.extend_from_slice(&self.genesis_hash.0);
875 Some(out)
876 } else {
877 None
878 }
879 } else {
880 None
881 }
882 }
883
884 pub fn signed_unchecked_extrinsic<E, M>(
885 &self,
886 metadata: &M,
887 ) -> Result<Option<SignedUncheckedExtrinsic>, ErrorFixMe<E, M>>
888 where
889 E: ExternalMemory,
890 M: AsFillMetadata<E>,
891 {
892 if let Some(author) = self.author.finalize() {
893 if let Some(signature) = self.signature.finalize() {
894 if let Some(call) = self.call.finalize() {
895 let mut extra = Vec::new();
896 for extra_index in self.extra.iter() {
897 let addition = self.extensions[*extra_index]
898 .finalize()
899 .ok_or(ErrorFixMe::UnfinalizedExtension)?;
900 extra.push(addition);
901 }
902 let extrinsic_version = metadata
903 .extrinsic_version()
904 .map_err(ErrorFixMe::MetaStructure)?;
905 return Ok(Some(SignedUncheckedExtrinsic {
906 version_byte: extrinsic_version | 0b1000_0000,
907 author: author.to_owned(),
908 signature: signature.to_owned(),
909 extra,
910 call: call.to_owned(),
911 }));
912 }
913 }
914 }
915 Ok(None)
916 }
917
918 pub fn send_this_signed<E, M>(&self, metadata: &M) -> Result<Option<Vec<u8>>, ErrorFixMe<E, M>>
919 where
920 E: ExternalMemory,
921 M: AsFillMetadata<E>,
922 {
923 if let Some(signed_unchecked_extrinsic) = self.signed_unchecked_extrinsic(metadata)? {
924 let mut out = vec![signed_unchecked_extrinsic.version_byte];
925 out.extend_from_slice(&signed_unchecked_extrinsic.author.encode());
926 out.extend_from_slice(&signed_unchecked_extrinsic.signature.encode());
927 for extra_element in signed_unchecked_extrinsic.extra.iter() {
928 out.extend_from_slice(&extra_element.encode());
929 }
930 out.extend_from_slice(&signed_unchecked_extrinsic.call.encode());
931 Ok(Some(out.encode()))
932 } else {
933 Ok(None)
934 }
935 }
936
937 pub fn unsigned_unchecked_extrinsic<E, M>(
938 &self,
939 metadata: &M,
940 ) -> Result<Option<UnsignedUncheckedExtrinsic>, ErrorFixMe<E, M>>
941 where
942 E: ExternalMemory,
943 M: AsFillMetadata<E>,
944 {
945 if let Some(call) = self.call.finalize() {
946 let extrinsic_version = metadata
947 .extrinsic_version()
948 .map_err(ErrorFixMe::MetaStructure)?;
949 Ok(Some(UnsignedUncheckedExtrinsic {
950 version_byte: extrinsic_version,
951 call: call.to_owned(),
952 }))
953 } else {
954 Ok(None)
955 }
956 }
957
958 pub fn send_this_unsigned<E, M>(
959 &self,
960 metadata: &M,
961 ) -> Result<Option<Vec<u8>>, ErrorFixMe<E, M>>
962 where
963 E: ExternalMemory,
964 M: AsFillMetadata<E>,
965 {
966 if let Some(unsigned_unchecked_extrinsic) = self.unsigned_unchecked_extrinsic(metadata)? {
967 let mut out = vec![unsigned_unchecked_extrinsic.version_byte];
968 out.extend_from_slice(&unsigned_unchecked_extrinsic.call.encode());
969 Ok(Some(out.encode()))
970 } else {
971 Ok(None)
972 }
973 }
974}
975
976pub fn extra_indices_in_extensions<E: ExternalMemory, M: AsFillMetadata<E>>(
977 ext_memory: &mut E,
978 registry: &M::TypeRegistry,
979 extra_symbol: &UntrackedSymbol<TypeId>,
980 extensions_ty_ids: &[u32],
981) -> Result<Vec<usize>, ErrorFixMe<E, M>> {
982 let extra_ty = registry
983 .resolve_ty(extra_symbol.id, ext_memory)
984 .map_err(ErrorFixMe::Registry)?;
985 let extra_ty_ids: Vec<u32> = match &extra_ty.type_def {
986 TypeDef::Composite(composite) => composite.fields.iter().map(|field| field.ty.id).collect(),
987 TypeDef::Tuple(tuple) => tuple.fields.iter().map(|ty| ty.id).collect(),
988 _ => return Err(ErrorFixMe::WrongExtraStructure),
989 };
990 let mut out = Vec::new();
991 for extra_ty_id in extra_ty_ids.iter() {
992 let new = extensions_ty_ids
993 .iter()
994 .position(|extension_ty_id| extension_ty_id == extra_ty_id)
995 .ok_or(ErrorFixMe::ExtraNotInExtensions)?;
996 out.push(new);
997 }
998 Ok(out)
999}
1000
1001#[derive(Clone, Debug)]
1002pub struct ExtrinsicToSign {
1003 pub call: TypeContent,
1004 pub extensions: Vec<TypeContent>,
1005}
1006
1007#[derive(Clone, Debug)]
1008pub struct SignedUncheckedExtrinsic {
1009 pub version_byte: u8,
1010 pub author: TypeContent,
1011 pub signature: TypeContent,
1012 pub extra: Vec<TypeContent>,
1013 pub call: TypeContent,
1014}
1015
1016#[derive(Clone, Debug)]
1017pub struct UnsignedUncheckedExtrinsic {
1018 pub version_byte: u8,
1019 pub call: TypeContent,
1020}
1021
1022macro_rules! populate {
1023 ($($func:ident, $filler:ty, $helper_func:ident), *) => {
1024 $(
1025 impl TransactionToFill {
1026 pub fn $func(&mut self, filler: $filler) {
1027 for extension in self.extensions.iter_mut() {
1028 if $helper_func(&mut extension.content, filler) {
1029 break;
1030 } else if let TypeContentToFill::Composite(ref mut fields_to_fill) = extension.content {
1031 if fields_to_fill.len() == 1
1032 && $helper_func(
1033 &mut fields_to_fill[0].type_to_fill.content,
1034 filler,
1035 )
1036 {
1037 break;
1038 }
1039 }
1040 }
1041 }
1042 }
1043 )*
1044 }
1045}
1046
1047populate!(populate_genesis_hash, H256, genesis_hash_got_filled);
1048populate!(populate_block_hash_helper, H256, block_hash_got_filled);
1049populate!(populate_spec_version, &Unsigned, spec_version_got_filled);
1050populate!(populate_tx_version, &Unsigned, tx_version_got_filled);
1051populate!(populate_nonce, u32, nonce_got_filled);
1052
1053macro_rules! got_filled_unsigned {
1054 ($($func:ident, $unsigned:ident), *) => {
1055 $(
1056 fn $func(content: &mut TypeContentToFill, unsigned: &Unsigned) -> bool {
1057 match content {
1058 TypeContentToFill::Primitive(PrimitiveToFill::CompactUnsigned(
1059 ref mut specialty_unsigned_to_fill,
1060 )) => {
1061 if let SpecialtyUnsignedInteger::$unsigned = specialty_unsigned_to_fill.specialty {
1062 specialty_unsigned_to_fill
1063 .content
1064 .upd_from_unsigned(unsigned);
1065 true
1066 } else {
1067 false
1068 }
1069 }
1070 TypeContentToFill::Primitive(PrimitiveToFill::Unsigned(
1071 ref mut specialty_unsigned_to_fill,
1072 )) => {
1073 if let SpecialtyUnsignedInteger::$unsigned = specialty_unsigned_to_fill.specialty {
1074 specialty_unsigned_to_fill
1075 .content
1076 .upd_from_unsigned(unsigned);
1077 true
1078 } else {
1079 false
1080 }
1081 }
1082 _ => false,
1083 }
1084 }
1085 )*
1086 }
1087}
1088
1089got_filled_unsigned!(spec_version_got_filled, SpecVersion);
1090got_filled_unsigned!(tx_version_got_filled, TxVersion);
1091
1092fn nonce_got_filled(content: &mut TypeContentToFill, rpc_u32: u32) -> bool {
1093 match content {
1094 TypeContentToFill::Primitive(PrimitiveToFill::CompactUnsigned(
1095 ref mut specialty_unsigned_to_fill,
1096 )) => {
1097 if let SpecialtyUnsignedInteger::Nonce = specialty_unsigned_to_fill.specialty {
1098 specialty_unsigned_to_fill.content.upd_from_u32(rpc_u32);
1099 true
1100 } else {
1101 false
1102 }
1103 }
1104 TypeContentToFill::Primitive(PrimitiveToFill::Unsigned(
1105 ref mut specialty_unsigned_to_fill,
1106 )) => {
1107 if let SpecialtyUnsignedInteger::Nonce = specialty_unsigned_to_fill.specialty {
1108 specialty_unsigned_to_fill.content.upd_from_u32(rpc_u32);
1109 true
1110 } else {
1111 false
1112 }
1113 }
1114 _ => false,
1115 }
1116}
1117
1118fn try_default_tip(content: &mut TypeContentToFill) {
1119 match content {
1120 TypeContentToFill::Primitive(PrimitiveToFill::CompactUnsigned(
1121 ref mut specialty_unsigned_to_fill,
1122 )) => {
1123 if specialty_unsigned_to_fill.specialty == SpecialtyUnsignedInteger::Tip
1124 || specialty_unsigned_to_fill.specialty == SpecialtyUnsignedInteger::TipAsset
1125 {
1126 specialty_unsigned_to_fill.content.upd_from_str("0");
1127 }
1128 }
1129 TypeContentToFill::Primitive(PrimitiveToFill::Unsigned(
1130 ref mut specialty_unsigned_to_fill,
1131 )) => {
1132 if specialty_unsigned_to_fill.specialty == SpecialtyUnsignedInteger::Tip
1133 || specialty_unsigned_to_fill.specialty == SpecialtyUnsignedInteger::TipAsset
1134 {
1135 specialty_unsigned_to_fill.content.upd_from_str("0");
1136 }
1137 }
1138 _ => {}
1139 }
1140}
1141
1142fn try_default_tip_assets_in_given_asset<E: ExternalMemory, M: AsFillMetadata<E>>(
1148 content: &mut TypeContentToFill,
1149 ext_memory: &mut E,
1150 registry: &M::TypeRegistry,
1151 asset_id: u32,
1152 pallet_assets_id: u8,
1153) {
1154 match content {
1155 TypeContentToFill::Primitive(PrimitiveToFill::CompactUnsigned(
1156 ref mut specialty_unsigned_to_fill,
1157 )) => {
1158 if specialty_unsigned_to_fill.specialty == SpecialtyUnsignedInteger::TipAsset {
1159 specialty_unsigned_to_fill.content.upd_from_str("0");
1160 }
1161 }
1162 TypeContentToFill::Primitive(PrimitiveToFill::Unsigned(
1163 ref mut specialty_unsigned_to_fill,
1164 )) => {
1165 if specialty_unsigned_to_fill.specialty == SpecialtyUnsignedInteger::TipAsset {
1166 specialty_unsigned_to_fill.content.upd_from_str("0");
1167 }
1168 }
1169 TypeContentToFill::Variant(ref mut variant_selector) => {
1170 let mut index_of_some = None;
1171
1172 for (index, variant) in variant_selector.available_variants.iter().enumerate() {
1173 if variant.name == "Some" {
1174 index_of_some = Some(index);
1175 break;
1176 }
1177 }
1178
1179 if let Some(index) = index_of_some {
1180 if let Ok(new_variant_selector) = VariantSelector::new_at::<E, M>(
1181 &variant_selector.available_variants,
1182 ext_memory,
1183 registry,
1184 index,
1185 ) {
1186 *variant_selector = new_variant_selector;
1187 if variant_selector.selected.fields_to_fill.len() == 1 {
1188 if let TypeContentToFill::Composite(ref mut fields_to_fill) =
1189 variant_selector.selected.fields_to_fill[0]
1190 .type_to_fill
1191 .content
1192 {
1193 for field_to_fill in fields_to_fill.iter_mut() {
1194 if let Some(field_name) = &field_to_fill.field_name {
1195 match field_name.as_str() {
1196 "parents" => {
1197 if let TypeContentToFill::Primitive(
1198 PrimitiveToFill::Unsigned(
1199 ref mut specialty_unsigned_to_fill,
1200 ),
1201 ) = field_to_fill.type_to_fill.content
1202 {
1203 specialty_unsigned_to_fill.content.upd_from_u8(0);
1204 }
1205 }
1206 "interior" => {
1207 if let TypeContentToFill::Variant(
1208 ref mut variant_selector_interior,
1209 ) = field_to_fill.type_to_fill.content
1210 {
1211 default_x2_junctions_assets_tip::<E, M>(
1212 variant_selector_interior,
1213 ext_memory,
1214 registry,
1215 asset_id,
1216 pallet_assets_id,
1217 )
1218 }
1219 }
1220 _ => {}
1221 }
1222 }
1223 }
1224 }
1225 }
1226 }
1227 }
1228 }
1229 _ => {}
1230 }
1231}
1232
1233fn autofill_x2_selector_pallet_instance<E: ExternalMemory, M: AsFillMetadata<E>>(
1234 selector0: &mut TypeContentToFill,
1235 ext_memory: &mut E,
1236 registry: &M::TypeRegistry,
1237 pallet_assets_id: u8,
1238) {
1239 if let TypeContentToFill::Variant(ref mut junction_variant_selector_0) = selector0 {
1240 let mut index_pallet_instance = None;
1241 for (index, variant) in junction_variant_selector_0
1242 .available_variants
1243 .iter()
1244 .enumerate()
1245 {
1246 if variant.name == "PalletInstance" {
1247 index_pallet_instance = Some(index);
1248 break;
1249 }
1250 }
1251 if let Some(index_pallet_instance) = index_pallet_instance {
1252 if let Ok(new_junction_variant_selector_0) = VariantSelector::new_at::<E, M>(
1253 &junction_variant_selector_0.available_variants,
1254 ext_memory,
1255 registry,
1256 index_pallet_instance,
1257 ) {
1258 *junction_variant_selector_0 = new_junction_variant_selector_0;
1259 if junction_variant_selector_0.selected.fields_to_fill.len() == 1 {
1260 if let TypeContentToFill::Primitive(PrimitiveToFill::Unsigned(
1261 ref mut specialty_unsigned_to_fill,
1262 )) = junction_variant_selector_0.selected.fields_to_fill[0]
1263 .type_to_fill
1264 .content
1265 {
1266 specialty_unsigned_to_fill
1267 .content
1268 .upd_from_u8(pallet_assets_id)
1269 }
1270 }
1271 }
1272 }
1273 }
1274}
1275
1276fn autofill_x2_selector_general_index<E: ExternalMemory, M: AsFillMetadata<E>>(
1277 selector1: &mut TypeContentToFill,
1278 ext_memory: &mut E,
1279 registry: &M::TypeRegistry,
1280 asset_id: u32,
1281) {
1282 if let TypeContentToFill::Variant(ref mut junction_variant_selector_1) = selector1 {
1283 let mut index_general_index = None;
1284 for (index, variant) in junction_variant_selector_1
1285 .available_variants
1286 .iter()
1287 .enumerate()
1288 {
1289 if variant.name == "GeneralIndex" {
1290 index_general_index = Some(index);
1291 break;
1292 }
1293 }
1294 if let Some(index_general_index) = index_general_index {
1295 if let Ok(new_junction_variant_selector_1) = VariantSelector::new_at::<E, M>(
1296 &junction_variant_selector_1.available_variants,
1297 ext_memory,
1298 registry,
1299 index_general_index,
1300 ) {
1301 *junction_variant_selector_1 = new_junction_variant_selector_1;
1302 if junction_variant_selector_1.selected.fields_to_fill.len() == 1 {
1303 match junction_variant_selector_1.selected.fields_to_fill[0]
1304 .type_to_fill
1305 .content
1306 {
1307 TypeContentToFill::Primitive(PrimitiveToFill::Unsigned(
1308 ref mut specialty_unsigned_to_fill,
1309 )) => specialty_unsigned_to_fill.content.upd_from_u32(asset_id),
1310 TypeContentToFill::Primitive(PrimitiveToFill::CompactUnsigned(
1311 ref mut specialty_unsigned_to_fill,
1312 )) => specialty_unsigned_to_fill.content.upd_from_u32(asset_id),
1313 _ => {}
1314 }
1315 }
1316 }
1317 }
1318 }
1319}
1320
1321fn default_x2_junctions_assets_tip<E: ExternalMemory, M: AsFillMetadata<E>>(
1322 variant_selector_interior: &mut VariantSelector,
1323 ext_memory: &mut E,
1324 registry: &M::TypeRegistry,
1325 asset_id: u32,
1326 pallet_assets_id: u8,
1327) {
1328 let mut index_of_x2 = None;
1330
1331 for (index, variant) in variant_selector_interior
1332 .available_variants
1333 .iter()
1334 .enumerate()
1335 {
1336 if variant.name == "X2" {
1337 index_of_x2 = Some(index);
1338 break;
1339 }
1340 }
1341
1342 if let Some(index_x2) = index_of_x2 {
1343 if let Ok(new_variant_selector_interior) = VariantSelector::new_at::<E, M>(
1344 &variant_selector_interior.available_variants,
1345 ext_memory,
1346 registry,
1347 index_x2,
1348 ) {
1349 *variant_selector_interior = new_variant_selector_interior;
1350 match variant_selector_interior.selected.fields_to_fill.len() {
1351 1 => {
1352 if let TypeContentToFill::ArrayRegular(ref mut array) =
1354 variant_selector_interior.selected.fields_to_fill[0]
1355 .type_to_fill
1356 .content
1357 {
1358 if array.len == 2 {
1360 autofill_x2_selector_pallet_instance::<E, M>(
1361 &mut array.content[0],
1362 ext_memory,
1363 registry,
1364 pallet_assets_id,
1365 );
1366 autofill_x2_selector_general_index::<E, M>(
1367 &mut array.content[1],
1368 ext_memory,
1369 registry,
1370 asset_id,
1371 );
1372 }
1373 }
1374 }
1375 2 => {
1376 autofill_x2_selector_pallet_instance::<E, M>(
1378 &mut variant_selector_interior.selected.fields_to_fill[0]
1379 .type_to_fill
1380 .content,
1381 ext_memory,
1382 registry,
1383 pallet_assets_id,
1384 );
1385 autofill_x2_selector_general_index::<E, M>(
1386 &mut variant_selector_interior.selected.fields_to_fill[1]
1387 .type_to_fill
1388 .content,
1389 ext_memory,
1390 registry,
1391 asset_id,
1392 );
1393 }
1394 _ => {}
1395 }
1396 }
1397 }
1398}
1399
1400fn era_is_immortal(extensions: &[TypeToFill]) -> bool {
1401 let mut era_is_immortal = true;
1402 for extension in extensions.iter() {
1403 if let TypeContentToFill::SpecialType(SpecialTypeToFill::Era(era_to_fill)) =
1404 &extension.content
1405 {
1406 if let EraToFill::Mortal { .. } = era_to_fill {
1407 era_is_immortal = false;
1408 }
1409 break;
1410 }
1411 if let TypeContentToFill::Composite(fields_to_fill) = &extension.content {
1412 if fields_to_fill.len() == 1 {
1413 if let TypeContentToFill::SpecialType(SpecialTypeToFill::Era(era_to_fill)) =
1414 &fields_to_fill[0].type_to_fill.content
1415 {
1416 if let EraToFill::Mortal { .. } = era_to_fill {
1417 era_is_immortal = false;
1418 }
1419 break;
1420 }
1421 }
1422 }
1423 }
1424 era_is_immortal
1425}
1426
1427fn fill_mortal_block_number(extensions: &mut [TypeToFill], block_number: u64) {
1428 for extension in extensions.iter_mut() {
1429 if let TypeContentToFill::SpecialType(SpecialTypeToFill::Era(ref mut era_to_fill)) =
1430 extension.content
1431 {
1432 if let EraToFill::Mortal {
1433 period_entry: _,
1434 ref mut block_number_entry,
1435 } = era_to_fill
1436 {
1437 *block_number_entry = Some(block_number);
1438 }
1439 break;
1440 }
1441 if let TypeContentToFill::Composite(ref mut fields_to_fill) = extension.content {
1442 if fields_to_fill.len() == 1 {
1443 if let TypeContentToFill::SpecialType(SpecialTypeToFill::Era(ref mut era_to_fill)) =
1444 fields_to_fill[0].type_to_fill.content
1445 {
1446 if let EraToFill::Mortal {
1447 period_entry: _,
1448 ref mut block_number_entry,
1449 } = era_to_fill
1450 {
1451 *block_number_entry = Some(block_number);
1452 }
1453 break;
1454 }
1455 }
1456 }
1457 }
1458}
1459
1460macro_rules! got_filled_hash {
1461 ($($func:ident, $hash:ident), *) => {
1462 $(
1463 fn $func(content: &mut TypeContentToFill, hash: H256) -> bool {
1464 if let TypeContentToFill::SpecialType(SpecialTypeToFill::H256{hash: ref mut hash_to_fill, specialty: SpecialtyH256::$hash}) =
1465 content
1466 {
1467 *hash_to_fill = Some(hash);
1468 true
1469 }
1470 else {false}
1471 }
1472 )*
1473 }
1474}
1475
1476got_filled_hash!(genesis_hash_got_filled, GenesisHash);
1477got_filled_hash!(block_hash_got_filled, BlockHash);
1478
1479struct CheckExtensions {
1480 found_block_hash: bool,
1481 found_era: bool,
1482 found_genesis_hash: bool,
1483 found_spec_version: bool,
1484}
1485
1486impl CheckExtensions {
1487 fn init() -> Self {
1488 Self {
1489 found_block_hash: false,
1490 found_era: false,
1491 found_genesis_hash: false,
1492 found_spec_version: false,
1493 }
1494 }
1495 fn check_iteration(&mut self, content: &TypeContentToFill) -> Result<(), ExtensionsError> {
1496 match content {
1497 TypeContentToFill::SpecialType(SpecialTypeToFill::Era(_)) => {
1498 if self.found_era {
1499 return Err(ExtensionsError::EraTwice);
1500 } else {
1501 self.found_era = true;
1502 }
1503 }
1504 TypeContentToFill::SpecialType(SpecialTypeToFill::H256 { hash: _, specialty }) => {
1505 match specialty {
1506 SpecialtyH256::BlockHash => {
1507 if self.found_block_hash {
1508 return Err(ExtensionsError::GenesisHashTwice);
1509 } else {
1510 self.found_block_hash = true;
1511 }
1512 }
1513 SpecialtyH256::GenesisHash => {
1514 if self.found_genesis_hash {
1515 return Err(ExtensionsError::GenesisHashTwice);
1516 } else {
1517 self.found_genesis_hash = true;
1518 }
1519 }
1520 SpecialtyH256::None => {}
1521 }
1522 }
1523 TypeContentToFill::Primitive(PrimitiveToFill::CompactUnsigned(
1524 specialty_unsigned_to_fill,
1525 )) => {
1526 if let SpecialtyUnsignedInteger::SpecVersion = specialty_unsigned_to_fill.specialty
1527 {
1528 if self.found_spec_version {
1529 return Err(ExtensionsError::SpecVersionTwice);
1530 } else {
1531 self.found_spec_version = true;
1532 }
1533 }
1534 }
1535 TypeContentToFill::Primitive(PrimitiveToFill::Unsigned(specialty_unsigned_to_fill)) => {
1536 if let SpecialtyUnsignedInteger::SpecVersion = specialty_unsigned_to_fill.specialty
1537 {
1538 if self.found_spec_version {
1539 return Err(ExtensionsError::SpecVersionTwice);
1540 } else {
1541 self.found_spec_version = true;
1542 }
1543 }
1544 }
1545 _ => {}
1546 }
1547 Ok(())
1548 }
1549}
1550
1551fn check_extensions(extensions: &[TypeToFill]) -> Result<(), ExtensionsError> {
1552 let mut check_extensions = CheckExtensions::init();
1553 for ext in extensions.iter() {
1554 check_extensions.check_iteration(&ext.content)?;
1555 if let TypeContentToFill::Composite(fields_to_fill) = &ext.content {
1556 if fields_to_fill.len() == 1 {
1557 check_extensions.check_iteration(&fields_to_fill[0].type_to_fill.content)?;
1558 }
1559 }
1560 }
1561 if !check_extensions.found_genesis_hash {
1562 return Err(ExtensionsError::NoGenesisHash);
1563 }
1564 if !check_extensions.found_spec_version {
1565 return Err(ExtensionsError::NoSpecVersion);
1566 }
1567 Ok(())
1568}
1569
1570pub fn prepare_type<E, M>(
1571 ty_input: &Ty,
1572 ext_memory: &mut E,
1573 registry: &M::TypeRegistry,
1574 mut propagated: Propagated,
1575) -> Result<TypeToFill, RegistryError<E>>
1576where
1577 E: ExternalMemory,
1578 M: AsFillMetadata<E>,
1579{
1580 let (ty, id) = match ty_input {
1581 Ty::Resolved(resolved_ty) => (resolved_ty.ty.to_owned(), resolved_ty.id),
1582 Ty::Symbol(ty_symbol) => (registry.resolve_ty(ty_symbol.id, ext_memory)?, ty_symbol.id),
1583 };
1584 let info_ty = Info::from_ty(&ty);
1585 propagated.add_info(&info_ty);
1586
1587 match SpecialtyTypeHinted::from_type(&ty) {
1588 SpecialtyTypeHinted::AccountId32 => Ok(TypeToFill {
1589 content: TypeContentToFill::SpecialType(AccountId32::special_to_fill(
1590 &propagated.checker.specialty_set,
1591 )?),
1592 info: propagated.info,
1593 }),
1594 SpecialtyTypeHinted::Era => Ok(TypeToFill {
1595 content: TypeContentToFill::SpecialType(EraToFill::special_to_fill(
1596 &propagated.checker.specialty_set,
1597 )?),
1598 info: propagated.info,
1599 }),
1600 SpecialtyTypeHinted::H256 => Ok(TypeToFill {
1601 content: TypeContentToFill::SpecialType(H256::special_to_fill(
1602 &propagated.checker.specialty_set,
1603 )?),
1604 info: propagated.info,
1605 }),
1606 SpecialtyTypeHinted::PerU16 => Ok(TypeToFill {
1607 content: TypeContentToFill::SpecialType(PerU16::special_to_fill(
1608 &propagated.checker.specialty_set,
1609 )?),
1610 info: propagated.info,
1611 }),
1612 SpecialtyTypeHinted::Perbill => Ok(TypeToFill {
1613 content: TypeContentToFill::SpecialType(Perbill::special_to_fill(
1614 &propagated.checker.specialty_set,
1615 )?),
1616 info: propagated.info,
1617 }),
1618 SpecialtyTypeHinted::Percent => Ok(TypeToFill {
1619 content: TypeContentToFill::SpecialType(Percent::special_to_fill(
1620 &propagated.checker.specialty_set,
1621 )?),
1622 info: propagated.info,
1623 }),
1624 SpecialtyTypeHinted::Permill => Ok(TypeToFill {
1625 content: TypeContentToFill::SpecialType(Permill::special_to_fill(
1626 &propagated.checker.specialty_set,
1627 )?),
1628 info: propagated.info,
1629 }),
1630 SpecialtyTypeHinted::Perquintill => Ok(TypeToFill {
1631 content: TypeContentToFill::SpecialType(Perquintill::special_to_fill(
1632 &propagated.checker.specialty_set,
1633 )?),
1634 info: propagated.info,
1635 }),
1636 SpecialtyTypeHinted::PublicEd25519 => Ok(TypeToFill {
1637 content: TypeContentToFill::SpecialType(PublicEd25519::special_to_fill(
1638 &propagated.checker.specialty_set,
1639 )?),
1640 info: propagated.info,
1641 }),
1642 SpecialtyTypeHinted::PublicSr25519 => Ok(TypeToFill {
1643 content: TypeContentToFill::SpecialType(PublicSr25519::special_to_fill(
1644 &propagated.checker.specialty_set,
1645 )?),
1646 info: propagated.info,
1647 }),
1648 SpecialtyTypeHinted::PublicEcdsa => Ok(TypeToFill {
1649 content: TypeContentToFill::SpecialType(PublicEcdsa::special_to_fill(
1650 &propagated.checker.specialty_set,
1651 )?),
1652 info: propagated.info,
1653 }),
1654 SpecialtyTypeHinted::SignatureEd25519 => Ok(TypeToFill {
1655 content: TypeContentToFill::SpecialType(SignatureEd25519::special_to_fill(
1656 &propagated.checker.specialty_set,
1657 )?),
1658 info: propagated.info,
1659 }),
1660 SpecialtyTypeHinted::SignatureSr25519 => Ok(TypeToFill {
1661 content: TypeContentToFill::SpecialType(SignatureSr25519::special_to_fill(
1662 &propagated.checker.specialty_set,
1663 )?),
1664 info: propagated.info,
1665 }),
1666 SpecialtyTypeHinted::SignatureEcdsa => Ok(TypeToFill {
1667 content: TypeContentToFill::SpecialType(SignatureEcdsa::special_to_fill(
1668 &propagated.checker.specialty_set,
1669 )?),
1670 info: propagated.info,
1671 }),
1672 _ => match &ty.type_def {
1673 TypeDef::Composite(x) => Ok(TypeToFill {
1674 content: TypeContentToFill::Composite(prepare_fields::<E, M>(
1675 &x.fields,
1676 ext_memory,
1677 registry,
1678 propagated.checker,
1679 )?),
1680 info: propagated.info,
1681 }),
1682 TypeDef::Variant(x) => {
1683 if x.variants.is_empty() {
1684 Ok(TypeToFill {
1685 content: TypeContentToFill::VariantEmpty,
1686 info: propagated.info,
1687 })
1688 } else {
1689 Ok(TypeToFill {
1690 content: TypeContentToFill::Variant(VariantSelector::init::<E, M>(
1691 &x.variants,
1692 ext_memory,
1693 registry,
1694 )?),
1695 info: propagated.info,
1696 })
1697 }
1698 }
1699 TypeDef::Sequence(x) => {
1700 let mut info = Vec::new();
1701 info.append(&mut propagated.info);
1702 let sequence_draft =
1703 prepare_elements_set::<E, M>(&x.type_param, ext_memory, registry, propagated)?;
1704 match sequence_draft {
1705 SequenceDraft::U8(sequence_draft_content) => Ok(TypeToFill {
1706 content: TypeContentToFill::SequenceU8(SequenceU8ToFill {
1707 content: Vec::new(),
1708 info_element: sequence_draft_content.info_element,
1709 }),
1710 info,
1711 }),
1712 SequenceDraft::Regular(sequence_draft_content) => Ok(TypeToFill {
1713 content: TypeContentToFill::SequenceRegular(SequenceRegularToFill {
1714 content: Vec::new(),
1715 info_element: sequence_draft_content.info_element,
1716 ty: sequence_draft_content.resolved_ty.ty,
1717 id: sequence_draft_content.resolved_ty.id,
1718 }),
1719 info,
1720 }),
1721 }
1722 }
1723 TypeDef::Array(x) => {
1724 let mut info = Vec::new();
1725 info.append(&mut propagated.info);
1726 let sequence_draft =
1727 prepare_elements_set::<E, M>(&x.type_param, ext_memory, registry, propagated)?;
1728 match sequence_draft {
1729 SequenceDraft::U8(sequence_draft_content) => Ok(TypeToFill {
1730 content: TypeContentToFill::ArrayU8(ArrayU8ToFill {
1731 content: Vec::new(),
1732 info_element: sequence_draft_content.info_element,
1733 len: x.len,
1734 }),
1735 info,
1736 }),
1737 SequenceDraft::Regular(sequence_draft_content) => {
1738 let array_element = prepare_type::<E, M>(
1739 &Ty::Resolved(sequence_draft_content.resolved_ty),
1740 ext_memory,
1741 registry,
1742 Propagated::new(),
1743 )?;
1744 Ok(TypeToFill {
1745 content: TypeContentToFill::ArrayRegular(ArrayRegularToFill {
1746 content: vec![array_element.content; x.len as usize],
1747 info_element: sequence_draft_content.info_element,
1748 len: x.len,
1749 }),
1750 info,
1751 })
1752 }
1753 }
1754 }
1755 TypeDef::Tuple(x) => {
1756 if x.fields.len() > 1 {
1757 propagated.reject_compact()?;
1758 propagated.forget_hint();
1759 }
1760 let mut tuple_set = Vec::new();
1761 for inner_ty_symbol in x.fields.iter() {
1762 let id = inner_ty_symbol.id;
1763 let ty = registry.resolve_ty(id, ext_memory)?;
1764 let tuple_element = prepare_type::<E, M>(
1765 &Ty::Resolved(ResolvedTy {
1766 ty: ty.to_owned(),
1767 id,
1768 }),
1769 ext_memory,
1770 registry,
1771 Propagated::for_ty(&propagated.checker, &ty, id)?,
1772 )?;
1773 tuple_set.push(tuple_element);
1774 }
1775 Ok(TypeToFill {
1776 content: TypeContentToFill::Tuple(tuple_set),
1777 info: propagated.info,
1778 })
1779 }
1780 TypeDef::Primitive(x) => Ok(TypeToFill {
1781 content: TypeContentToFill::Primitive(prepare_primitive(
1782 x,
1783 &propagated.checker.specialty_set,
1784 )?),
1785 info: propagated.info,
1786 }),
1787 TypeDef::Compact(x) => {
1788 propagated.reject_compact()?;
1789 propagated.checker.specialty_set.compact_at = Some(id);
1790 propagated.checker.check_id(x.type_param.id)?;
1791 prepare_type::<E, M>(&Ty::Symbol(&x.type_param), ext_memory, registry, propagated)
1792 }
1793 TypeDef::BitSequence(x) => {
1794 propagated.reject_compact()?;
1795 let bit_sequence = prepare_bit_sequence::<E, M>(x, id, ext_memory, registry)?;
1796 Ok(TypeToFill {
1797 content: TypeContentToFill::BitSequence(bit_sequence),
1798 info: propagated.info,
1799 })
1800 }
1801 },
1802 }
1803}
1804
1805pub fn prepare_fields<E, M>(
1806 fields: &[Field<PortableForm>],
1807 ext_memory: &mut E,
1808 registry: &M::TypeRegistry,
1809 mut checker: Checker,
1810) -> Result<Vec<FieldToFill>, RegistryError<E>>
1811where
1812 E: ExternalMemory,
1813 M: AsFillMetadata<E>,
1814{
1815 if fields.len() > 1 {
1816 checker.reject_compact()?;
1820
1821 checker.forget_hint();
1824 }
1825 let mut out: Vec<FieldToFill> = Vec::new();
1826 for field in fields.iter() {
1827 let field_name = field.name.to_owned();
1828 let type_name = field.type_name.to_owned();
1829 let type_to_fill = prepare_type::<E, M>(
1830 &Ty::Symbol(&field.ty),
1831 ext_memory,
1832 registry,
1833 Propagated::for_field(&checker, field)?,
1834 )?;
1835 out.push(FieldToFill {
1836 type_to_fill,
1837 field_docs: field.collect_docs(),
1838 field_name,
1839 type_name,
1840 })
1841 }
1842 Ok(out)
1843}
1844
1845pub fn prepare_elements_set<E, M>(
1846 element: &UntrackedSymbol<TypeId>,
1847 ext_memory: &mut E,
1848 registry: &M::TypeRegistry,
1849 propagated: Propagated,
1850) -> Result<SequenceDraft, RegistryError<E>>
1851where
1852 E: ExternalMemory,
1853 M: AsFillMetadata<E>,
1854{
1855 propagated.reject_compact()?;
1856
1857 let husked = husk_type::<E, M>(element, registry, ext_memory, propagated.checker)?;
1858 let resolved_ty = ResolvedTy {
1859 ty: husked.ty.to_owned(),
1860 id: husked.id,
1861 };
1862 let sequence_draft_content = SequenceDraftContent {
1863 info_element: husked.info.to_owned(),
1864 resolved_ty,
1865 checker: husked.checker,
1866 };
1867 if husked.ty.type_def == TypeDef::Primitive(TypeDefPrimitive::U8) {
1868 Ok(SequenceDraft::U8(sequence_draft_content))
1869 } else {
1870 Ok(SequenceDraft::Regular(sequence_draft_content))
1871 }
1872}
1873
1874pub fn prepare_bit_sequence<E, M>(
1875 bit_ty: &TypeDefBitSequence<PortableForm>,
1876 id: u32,
1877 ext_memory: &mut E,
1878 registry: &M::TypeRegistry,
1879) -> Result<BitSequenceContent, RegistryError<E>>
1880where
1881 E: ExternalMemory,
1882 M: AsFillMetadata<E>,
1883{
1884 let bitorder = find_bit_order_ty::<E, M>(bit_ty, id, ext_memory, registry)?;
1886
1887 let bitstore_type = registry.resolve_ty(bit_ty.bit_store_type.id, ext_memory)?;
1889
1890 match bitstore_type.type_def {
1891 TypeDef::Primitive(TypeDefPrimitive::U8) => match bitorder {
1892 FoundBitOrder::Lsb0 => Ok(BitSequenceContent::BitVecU8Lsb0(BitVec::new())),
1893 FoundBitOrder::Msb0 => Ok(BitSequenceContent::BitVecU8Msb0(BitVec::new())),
1894 },
1895 TypeDef::Primitive(TypeDefPrimitive::U16) => match bitorder {
1896 FoundBitOrder::Lsb0 => Ok(BitSequenceContent::BitVecU16Lsb0(BitVec::new())),
1897 FoundBitOrder::Msb0 => Ok(BitSequenceContent::BitVecU16Msb0(BitVec::new())),
1898 },
1899 TypeDef::Primitive(TypeDefPrimitive::U32) => match bitorder {
1900 FoundBitOrder::Lsb0 => Ok(BitSequenceContent::BitVecU32Lsb0(BitVec::new())),
1901 FoundBitOrder::Msb0 => Ok(BitSequenceContent::BitVecU32Msb0(BitVec::new())),
1902 },
1903 #[cfg(target_pointer_width = "64")]
1904 TypeDef::Primitive(TypeDefPrimitive::U64) => match bitorder {
1905 FoundBitOrder::Lsb0 => Ok(BitSequenceContent::BitVecU64Lsb0(BitVec::new())),
1906 FoundBitOrder::Msb0 => Ok(BitSequenceContent::BitVecU64Msb0(BitVec::new())),
1907 },
1908 _ => Err(RegistryError::Internal(
1909 RegistryInternalError::NotBitStoreType { id },
1910 )),
1911 }
1912}