avail_rust_core/from_substrate.rs
1use codec::{Decode, Encode};
2use serde::Deserialize;
3
4/// The base fee and adjusted weight and length fees constitute the _inclusion fee_.
5#[derive(Clone, Debug, PartialEq, Deserialize, Decode)]
6#[serde(rename_all = "camelCase")]
7pub struct InclusionFee {
8 /// This is the minimum amount a user pays for a transaction. It is declared
9 /// as a base _weight_ in the runtime and converted to a fee using `WeightToFee`.
10 pub base_fee: u128,
11 /// The length fee, the amount paid for the encoded length (in bytes) of the transaction.
12 pub len_fee: u128,
13 ///
14 /// - `targeted_fee_adjustment`: This is a multiplier that can tune the final fee based on the
15 /// congestion of the network.
16 /// - `weight_fee`: This amount is computed based on the weight of the transaction. Weight
17 /// accounts for the execution time of a transaction.
18 ///
19 /// adjusted_weight_fee = targeted_fee_adjustment * weight_fee
20 pub adjusted_weight_fee: u128,
21}
22
23impl InclusionFee {
24 /// Returns the total of inclusion fee.
25 ///
26 /// ```ignore
27 /// inclusion_fee = base_fee + len_fee + adjusted_weight_fee
28 /// ```
29 pub fn inclusion_fee(&self) -> u128 {
30 self.base_fee
31 .saturating_add(self.len_fee)
32 .saturating_add(self.adjusted_weight_fee)
33 }
34}
35
36/// The `FeeDetails` is composed of:
37/// - (Optional) `inclusion_fee`: Only the `Pays::Yes` transaction can have the inclusion fee.
38/// - `tip`: If included in the transaction, the tip will be added on top. Only signed
39/// transactions can have a tip.
40#[derive(Clone, Debug, PartialEq, Deserialize, Decode)]
41#[serde(rename_all = "camelCase")]
42pub struct FeeDetails {
43 /// The minimum fee for a transaction to be included in a block.
44 pub inclusion_fee: Option<InclusionFee>,
45 // Do not serialize and deserialize `tip` as we actually can not pass any tip to the RPC.
46 #[codec(skip)]
47 pub tip: u128,
48}
49
50impl FeeDetails {
51 /// Returns the final fee.
52 ///
53 /// ```ignore
54 /// final_fee = inclusion_fee + tip;
55 /// ```
56 pub fn final_fee(&self) -> u128 {
57 self.inclusion_fee
58 .as_ref()
59 .map(|i| i.inclusion_fee())
60 .unwrap_or_else(|| 0u128)
61 .saturating_add(self.tip)
62 }
63}
64
65#[derive(Clone, Debug, PartialEq, Deserialize, Decode)]
66#[serde(rename_all = "camelCase")]
67pub struct RuntimeDispatchInfo {
68 /// Weight of this dispatch.
69 pub weight: Weight,
70 /// Class of this dispatch.
71 pub class: DispatchClass,
72 pub partial_fee: u128,
73}
74
75#[derive(Clone, Debug, Copy, PartialEq, Deserialize)]
76#[serde(rename_all = "camelCase")]
77#[repr(u8)]
78pub enum DispatchClass {
79 /// A normal dispatch.
80 Normal = 0,
81 /// An operational dispatch.
82 Operational = 1,
83 /// A mandatory dispatch. These kinds of dispatch are always included regardless of their
84 /// weight, therefore it is critical that they are separately validated to ensure that a
85 /// malicious validator cannot craft a valid but impossibly heavy block. Usually this just
86 /// means ensuring that the extrinsic can only be included once and that it is always very
87 /// light.
88 ///
89 /// Do *NOT* use it for extrinsics that can be heavy.
90 ///
91 /// The only real use case for this is inherent extrinsics that are required to execute in a
92 /// block for the block to be valid, and it solves the issue in the case that the block
93 /// initialization is sufficiently heavy to mean that those inherents do not fit into the
94 /// block. Essentially, we assume that in these exceptional circumstances, it is better to
95 /// allow an overweight block to be created than to not allow any block at all to be created.
96 Mandatory = 2,
97}
98impl Encode for DispatchClass {
99 fn encode_to<T: codec::Output + ?Sized>(&self, dest: &mut T) {
100 let variant: u8 = *self as u8;
101 variant.encode_to(dest);
102 }
103}
104impl Decode for DispatchClass {
105 fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
106 let variant = u8::decode(input)?;
107 match variant {
108 0 => Ok(Self::Normal),
109 1 => Ok(Self::Operational),
110 2 => Ok(Self::Mandatory),
111 _ => Err("Failed to decode DispatchClass. Unknown variant".into()),
112 }
113 }
114}
115
116#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Encode, Decode)]
117pub struct Weight {
118 /// The weight of computational time used based on some reference hardware.
119 #[codec(compact)]
120 pub ref_time: u64,
121 /// The weight of storage space used by proof of validity.
122 #[codec(compact)]
123 pub proof_size: u64,
124}