substrate_constructor/
finalize.rs

1use num_bigint::{BigInt, BigUint};
2use parity_scale_codec::{Compact, Encode};
3use primitive_types::H256;
4use sp_arithmetic::{PerU16, Perbill, Percent, Permill, Perquintill};
5use substrate_crypto_light::{
6    common::AccountId32,
7    ecdsa::{Public as PublicEcdsa, Signature as SignatureEcdsa},
8    ed25519::{Public as PublicEd25519, Signature as SignatureEd25519},
9    sr25519::{Public as PublicSr25519, Signature as SignatureSr25519},
10};
11use substrate_parser::additional_types::Era;
12
13use crate::fill_prepare::{
14    ArrayRegularToFill, ArrayU8ToFill, BitSequenceContent, EraToFill, PrimitiveToFill,
15    RegularPrimitiveToFill, SequenceU8ToFill, SpecialTypeToFill, TypeContentToFill, TypeToFill,
16    VariantSelector,
17};
18use crate::traits::Unsigned;
19
20pub trait Finalize {
21    type FinalForm: Encode;
22    fn finalize(&self) -> Option<Self::FinalForm>;
23}
24
25#[derive(Clone, Debug)]
26pub enum RegularPrimitive {
27    Bool(bool),
28    Char(char),
29    I8(i8),
30    I16(i16),
31    I32(i32),
32    I64(i64),
33    I128(i128),
34    I256(BigInt),
35    Str(String),
36    U256(BigUint),
37}
38
39impl Encode for RegularPrimitive {
40    fn encode(&self) -> Vec<u8> {
41        match &self {
42            RegularPrimitive::Bool(a) => a.encode(),
43            RegularPrimitive::Char(a) => u32::from(*a).encode(),
44            RegularPrimitive::I8(a) => a.encode(),
45            RegularPrimitive::I16(a) => a.encode(),
46            RegularPrimitive::I32(a) => a.encode(),
47            RegularPrimitive::I64(a) => a.encode(),
48            RegularPrimitive::I128(a) => a.encode(),
49            RegularPrimitive::I256(a) => a.to_signed_bytes_le(),
50            RegularPrimitive::Str(a) => a.encode(),
51            RegularPrimitive::U256(a) => a.to_bytes_le(),
52        }
53    }
54}
55
56impl Finalize for RegularPrimitiveToFill {
57    type FinalForm = RegularPrimitive;
58    fn finalize(&self) -> Option<Self::FinalForm> {
59        match &self {
60            RegularPrimitiveToFill::Bool(a) => a.map(RegularPrimitive::Bool),
61            RegularPrimitiveToFill::Char(a) => a.map(RegularPrimitive::Char),
62            RegularPrimitiveToFill::I8(a) => a.map(RegularPrimitive::I8),
63            RegularPrimitiveToFill::I16(a) => a.map(RegularPrimitive::I16),
64            RegularPrimitiveToFill::I32(a) => a.map(RegularPrimitive::I32),
65            RegularPrimitiveToFill::I64(a) => a.map(RegularPrimitive::I64),
66            RegularPrimitiveToFill::I128(a) => a.map(RegularPrimitive::I128),
67            RegularPrimitiveToFill::I256(a) => a.clone().map(RegularPrimitive::I256),
68            RegularPrimitiveToFill::Str(a) => Some(RegularPrimitive::Str(a.to_owned())),
69            RegularPrimitiveToFill::U256(a) => a.clone().map(RegularPrimitive::U256),
70        }
71    }
72}
73
74#[derive(Clone, Debug)]
75pub enum Primitive {
76    CompactUnsigned(Unsigned),
77    Regular(RegularPrimitive),
78    Unsigned(Unsigned),
79}
80
81impl Encode for Primitive {
82    fn encode(&self) -> Vec<u8> {
83        match &self {
84            Primitive::CompactUnsigned(unsigned) => match unsigned {
85                Unsigned::U8(a) => Compact(*a).encode(),
86                Unsigned::U16(a) => Compact(*a).encode(),
87                Unsigned::U32(a) => Compact(*a).encode(),
88                Unsigned::U64(a) => Compact(*a).encode(),
89                Unsigned::U128(a) => Compact(*a).encode(),
90            },
91            Primitive::Regular(regular_primitive) => regular_primitive.encode(),
92            Primitive::Unsigned(unsigned) => match unsigned {
93                Unsigned::U8(a) => a.encode(),
94                Unsigned::U16(a) => a.encode(),
95                Unsigned::U32(a) => a.encode(),
96                Unsigned::U64(a) => a.encode(),
97                Unsigned::U128(a) => a.encode(),
98            },
99        }
100    }
101}
102
103impl Finalize for PrimitiveToFill {
104    type FinalForm = Primitive;
105    fn finalize(&self) -> Option<Self::FinalForm> {
106        match &self {
107            PrimitiveToFill::CompactUnsigned(unsigned_to_fill) => unsigned_to_fill
108                .content
109                .into_unsigned()
110                .map(Primitive::CompactUnsigned),
111            PrimitiveToFill::Regular(regular_primitive) => {
112                regular_primitive.finalize().map(Primitive::Regular)
113            }
114            PrimitiveToFill::Unsigned(unsigned_to_fill) => unsigned_to_fill
115                .content
116                .into_unsigned()
117                .map(Primitive::Unsigned),
118        }
119    }
120}
121
122#[derive(Clone, Debug)]
123pub struct ArrayU8(pub Vec<u8>);
124
125impl Encode for ArrayU8 {
126    fn encode(&self) -> Vec<u8> {
127        self.0.to_owned()
128    }
129}
130
131impl Finalize for ArrayU8ToFill {
132    type FinalForm = ArrayU8;
133    fn finalize(&self) -> Option<Self::FinalForm> {
134        if self.content.len() as u32 == self.len {
135            Some(ArrayU8(self.content.to_owned()))
136        } else {
137            None
138        }
139    }
140}
141
142#[derive(Clone, Debug)]
143pub struct ArrayRegular(pub Vec<TypeContent>);
144
145impl Encode for ArrayRegular {
146    fn encode(&self) -> Vec<u8> {
147        let mut out: Vec<u8> = Vec::new();
148        for element in self.0.iter() {
149            out.extend_from_slice(&element.encode())
150        }
151        out
152    }
153}
154
155impl Finalize for ArrayRegularToFill {
156    type FinalForm = ArrayRegular;
157    fn finalize(&self) -> Option<Self::FinalForm> {
158        if self.content.len() as u32 == self.len {
159            let mut array_regular = ArrayRegular(Vec::new());
160            for element in self.content.iter() {
161                match element.finalize() {
162                    Some(a) => array_regular.0.push(a.to_owned()),
163                    None => return None,
164                }
165            }
166            Some(array_regular)
167        } else {
168            None
169        }
170    }
171}
172
173impl Finalize for SequenceU8ToFill {
174    type FinalForm = Vec<u8>;
175    fn finalize(&self) -> Option<Self::FinalForm> {
176        Some(self.content.to_owned())
177    }
178}
179
180#[derive(Clone, Debug)]
181pub enum SpecialType {
182    AccountId32(AccountId32),
183    Era(Era),
184    H256(H256),
185    PerU16 {
186        value: PerU16,
187        is_compact: bool,
188    },
189    Perbill {
190        value: Perbill,
191        is_compact: bool,
192    },
193    Percent {
194        value: Percent,
195        is_compact: bool,
196    },
197    Permill {
198        value: Permill,
199        is_compact: bool,
200    },
201    Perquintill {
202        value: Perquintill,
203        is_compact: bool,
204    },
205    PublicEd25519(PublicEd25519),
206    PublicSr25519(PublicSr25519),
207    PublicEcdsa(PublicEcdsa),
208    SignatureEd25519(SignatureEd25519),
209    SignatureSr25519(SignatureSr25519),
210    SignatureEcdsa(SignatureEcdsa),
211}
212
213impl Encode for SpecialType {
214    fn encode(&self) -> Vec<u8> {
215        match &self {
216            SpecialType::AccountId32(a) => a.0.to_vec(),
217            SpecialType::Era(a) => a.encode(),
218            SpecialType::H256(a) => a.0.to_vec(),
219            SpecialType::PerU16 { value, is_compact } => {
220                if *is_compact {
221                    Compact(*value).encode()
222                } else {
223                    value.encode()
224                }
225            }
226            SpecialType::Perbill { value, is_compact } => {
227                if *is_compact {
228                    Compact(*value).encode()
229                } else {
230                    value.encode()
231                }
232            }
233            SpecialType::Percent { value, is_compact } => {
234                if *is_compact {
235                    Compact(*value).encode()
236                } else {
237                    value.encode()
238                }
239            }
240            SpecialType::Permill { value, is_compact } => {
241                if *is_compact {
242                    Compact(*value).encode()
243                } else {
244                    value.encode()
245                }
246            }
247            SpecialType::Perquintill { value, is_compact } => {
248                if *is_compact {
249                    Compact(*value).encode()
250                } else {
251                    value.encode()
252                }
253            }
254            SpecialType::PublicEd25519(a) => a.0.to_vec(),
255            SpecialType::PublicSr25519(a) => a.0.to_vec(),
256            SpecialType::PublicEcdsa(a) => a.0.to_vec(),
257            SpecialType::SignatureEd25519(a) => a.0.to_vec(),
258            SpecialType::SignatureSr25519(a) => a.0.to_vec(),
259            SpecialType::SignatureEcdsa(a) => a.0.to_vec(),
260        }
261    }
262}
263
264macro_rules! finalize_perthing_compact {
265    ($value:tt, $is_compact:tt, $variant:ident) => {
266        $value.as_ref().map(|a| SpecialType::$variant {
267            value: *a,
268            is_compact: *$is_compact,
269        })
270    };
271}
272
273/// Mortal Era generation, from period and block number. From `sp_runtime::generic::Era`, verbatim.
274///
275/// Create a new era based on a period (which should be a power of two between 4 and 65536
276/// inclusive) and a block number on which it should start (or, for long periods, be shortly
277/// after the start).
278///
279/// If using `Era` in the context of `FRAME` runtime, make sure that `period`
280/// does not exceed `BlockHashCount` parameter passed to `system` module, since that
281/// prunes old blocks and renders transactions immediately invalid.
282pub fn construct_mortal_era(period: u64, current: u64) -> Era {
283    let period = period
284        .checked_next_power_of_two()
285        .unwrap_or(1 << 16)
286        .clamp(4, 1 << 16);
287    let phase = current % period;
288    let quantize_factor = (period >> 12).max(1);
289    let quantized_phase = phase / quantize_factor * quantize_factor;
290
291    Era::Mortal(period, quantized_phase)
292}
293
294impl Finalize for SpecialTypeToFill {
295    type FinalForm = SpecialType;
296    fn finalize(&self) -> Option<Self::FinalForm> {
297        match &self {
298            SpecialTypeToFill::AccountId32(a) => (*a).map(SpecialType::AccountId32),
299            SpecialTypeToFill::Era(a) => match a {
300                EraToFill::Immortal => Some(SpecialType::Era(Era::Immortal)),
301                EraToFill::Mortal {
302                    period_entry,
303                    block_number_entry: optional_block_number_entry,
304                } => optional_block_number_entry
305                    .as_ref()
306                    .map(|block_number_entry| {
307                        SpecialType::Era(construct_mortal_era(*period_entry, *block_number_entry))
308                    }),
309            },
310            SpecialTypeToFill::H256 { hash, specialty: _ } => hash.map(SpecialType::H256),
311            SpecialTypeToFill::PerU16 { value, is_compact } => {
312                finalize_perthing_compact!(value, is_compact, PerU16)
313            }
314            SpecialTypeToFill::Perbill { value, is_compact } => {
315                finalize_perthing_compact!(value, is_compact, Perbill)
316            }
317            SpecialTypeToFill::Percent { value, is_compact } => {
318                finalize_perthing_compact!(value, is_compact, Percent)
319            }
320            SpecialTypeToFill::Permill { value, is_compact } => {
321                finalize_perthing_compact!(value, is_compact, Permill)
322            }
323            SpecialTypeToFill::Perquintill { value, is_compact } => {
324                finalize_perthing_compact!(value, is_compact, Perquintill)
325            }
326            SpecialTypeToFill::PublicEd25519(a) => (*a).map(SpecialType::PublicEd25519),
327            SpecialTypeToFill::PublicSr25519(a) => (*a).map(SpecialType::PublicSr25519),
328            SpecialTypeToFill::PublicEcdsa(a) => (*a).map(SpecialType::PublicEcdsa),
329            SpecialTypeToFill::SignatureEd25519(a) => (*a).map(SpecialType::SignatureEd25519),
330            SpecialTypeToFill::SignatureSr25519(a) => (*a).map(SpecialType::SignatureSr25519),
331            SpecialTypeToFill::SignatureEcdsa(a) => (*a).map(SpecialType::SignatureEcdsa),
332        }
333    }
334}
335
336#[derive(Clone, Debug)]
337pub struct VariantContent {
338    pub index: u8,
339    pub fields_content: Vec<TypeContent>,
340}
341
342impl Encode for VariantContent {
343    fn encode(&self) -> Vec<u8> {
344        let mut out = vec![self.index];
345        for field in self.fields_content.iter() {
346            out.extend_from_slice(&field.encode())
347        }
348        out
349    }
350}
351
352impl Finalize for VariantSelector {
353    type FinalForm = VariantContent;
354    fn finalize(&self) -> Option<Self::FinalForm> {
355        let mut fields_content = Vec::new();
356        for field in self.selected.fields_to_fill.iter() {
357            match field.type_to_fill.finalize() {
358                Some(a) => fields_content.push(a.to_owned()),
359                None => return None,
360            }
361        }
362        Some(VariantContent {
363            index: self.selected.index,
364            fields_content,
365        })
366    }
367}
368
369impl Encode for BitSequenceContent {
370    fn encode(&self) -> Vec<u8> {
371        match &self {
372            BitSequenceContent::BitVecU8Lsb0(a) => a.encode(),
373            BitSequenceContent::BitVecU16Lsb0(a) => a.encode(),
374            BitSequenceContent::BitVecU32Lsb0(a) => a.encode(),
375            #[cfg(target_pointer_width = "64")]
376            BitSequenceContent::BitVecU64Lsb0(a) => a.encode(),
377            BitSequenceContent::BitVecU8Msb0(a) => a.encode(),
378            BitSequenceContent::BitVecU16Msb0(a) => a.encode(),
379            BitSequenceContent::BitVecU32Msb0(a) => a.encode(),
380            #[cfg(target_pointer_width = "64")]
381            BitSequenceContent::BitVecU64Msb0(a) => a.encode(),
382        }
383    }
384}
385
386#[derive(Clone, Debug)]
387pub enum TypeContent {
388    ArrayU8(ArrayU8),
389    ArrayRegular(ArrayRegular),
390    BitSequence(BitSequenceContent),
391    Composite(Vec<TypeContent>),
392    Primitive(Primitive),
393    SequenceRegular(Vec<TypeContent>),
394    SequenceU8(Vec<u8>),
395    SpecialType(SpecialType),
396    Tuple(Vec<TypeContent>),
397    Variant(VariantContent),
398    VariantEmpty,
399}
400
401impl Encode for TypeContent {
402    fn encode(&self) -> Vec<u8> {
403        match &self {
404            TypeContent::ArrayU8(a) => a.encode(),
405            TypeContent::ArrayRegular(a) => a.encode(),
406            TypeContent::BitSequence(a) => a.encode(),
407            TypeContent::Composite(composite_fields) => {
408                let mut out: Vec<u8> = Vec::new();
409                for element in composite_fields.iter() {
410                    out.extend_from_slice(&element.encode())
411                }
412                out
413            }
414            TypeContent::Primitive(a) => a.encode(),
415            TypeContent::SequenceRegular(a) => a.encode(),
416            TypeContent::SequenceU8(a) => a.encode(),
417            TypeContent::SpecialType(a) => a.encode(),
418            TypeContent::Tuple(tuple_fields) => {
419                let mut out: Vec<u8> = Vec::new();
420                for element in tuple_fields.iter() {
421                    out.extend_from_slice(&element.encode())
422                }
423                out
424            }
425            TypeContent::Variant(a) => a.encode(),
426            TypeContent::VariantEmpty => Vec::new(),
427        }
428    }
429}
430
431impl Finalize for TypeContentToFill {
432    type FinalForm = TypeContent;
433    fn finalize(&self) -> Option<Self::FinalForm> {
434        match &self {
435            TypeContentToFill::ArrayU8(array_u8_to_fill) => {
436                array_u8_to_fill.finalize().map(TypeContent::ArrayU8)
437            }
438            TypeContentToFill::ArrayRegular(array_regular_to_fill) => array_regular_to_fill
439                .finalize()
440                .map(TypeContent::ArrayRegular),
441            TypeContentToFill::BitSequence(bit_sequence_content) => {
442                Some(TypeContent::BitSequence(bit_sequence_content.to_owned()))
443            }
444            TypeContentToFill::Composite(fields_set) => {
445                let mut composite_fields = Vec::new();
446                for element in fields_set.iter() {
447                    match element.type_to_fill.content.finalize() {
448                        Some(a) => composite_fields.push(a),
449                        None => return None,
450                    }
451                }
452                Some(TypeContent::Composite(composite_fields))
453            }
454            TypeContentToFill::Primitive(primitive_to_fill) => {
455                primitive_to_fill.finalize().map(TypeContent::Primitive)
456            }
457            TypeContentToFill::SequenceU8(sequence_u8_to_fill) => Some(TypeContent::SequenceU8(
458                sequence_u8_to_fill.content.to_owned(),
459            )),
460            TypeContentToFill::SequenceRegular(sequence_regular_to_fill) => {
461                let mut sequence = Vec::new();
462                for element in sequence_regular_to_fill.content.iter() {
463                    match element.finalize() {
464                        Some(a) => sequence.push(a),
465                        None => return None,
466                    }
467                }
468                Some(TypeContent::SequenceRegular(sequence))
469            }
470            TypeContentToFill::SpecialType(special_type_to_fill) => special_type_to_fill
471                .finalize()
472                .map(TypeContent::SpecialType),
473            TypeContentToFill::Tuple(fields_set) => {
474                let mut tuple_fields = Vec::new();
475                for element in fields_set.iter() {
476                    match element.content.finalize() {
477                        Some(a) => tuple_fields.push(a),
478                        None => return None,
479                    }
480                }
481                Some(TypeContent::Tuple(tuple_fields))
482            }
483            TypeContentToFill::Variant(variant_selector) => {
484                variant_selector.finalize().map(TypeContent::Variant)
485            }
486            TypeContentToFill::VariantEmpty => Some(TypeContent::VariantEmpty),
487        }
488    }
489}
490
491impl Finalize for TypeToFill {
492    type FinalForm = TypeContent;
493    fn finalize(&self) -> Option<Self::FinalForm> {
494        self.content.finalize()
495    }
496}