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}