ac_primitives/types.rs
1/*
2 Copyright 2019 Supercomputing Systems AG
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15
16*/
17
18//! Re-defintion of substrate primitives.
19//! Needed because substrate pallets compile to wasm in no_std.
20
21use alloc::{string::String, vec::Vec};
22use codec::{Decode, Encode, MaxEncodedLen};
23use core::fmt::Debug;
24use scale_info::TypeInfo;
25use serde::{Deserialize, Serialize};
26use sp_runtime::traits::{AtLeast32BitUnsigned, Zero};
27
28/// Type used to encode the number of references an account has.
29pub type RefCount = u32;
30
31/// All balance information for an account.
32//https://github.com/paritytech/substrate/blob/d6f278b9685ac871c79e45551b66111b77cb1b71/frame/balances/src/types.rs#L95
33#[derive(Encode, Decode, Clone, PartialEq, Eq, Default, Debug, MaxEncodedLen, TypeInfo)]
34pub struct AccountData<Balance> {
35 /// Non-reserved part of the balance which the account holder may be able to control.
36 ///
37 /// This is the only balance that matters in terms of most operations on tokens.
38 pub free: Balance,
39 /// Balance which is has active holds on it and may not be used at all.
40 ///
41 /// This is the sum of all individual holds together with any sums still under the (deprecated)
42 /// reserves API.
43 pub reserved: Balance,
44 /// The amount that `free` may not drop below when reducing the balance, except for actions
45 /// where the account owner cannot reasonably benefit from thr balance reduction, such as
46 /// slashing.
47 pub frozen: Balance,
48 /// Extra information about this account. The MSB is a flag indicating whether the new ref-
49 /// counting logic is in place for this account.
50 pub flags: ExtraFlags,
51}
52
53const IS_NEW_LOGIC: u128 = 0x80000000_00000000_00000000_00000000u128;
54
55#[derive(Encode, Decode, Clone, PartialEq, Eq, Debug, MaxEncodedLen, TypeInfo)]
56pub struct ExtraFlags(u128);
57impl Default for ExtraFlags {
58 fn default() -> Self {
59 Self(IS_NEW_LOGIC)
60 }
61}
62impl ExtraFlags {
63 pub fn old_logic() -> Self {
64 Self(0)
65 }
66 pub fn set_new_logic(&mut self) {
67 self.0 |= IS_NEW_LOGIC
68 }
69 pub fn is_new_logic(&self) -> bool {
70 (self.0 & IS_NEW_LOGIC) == IS_NEW_LOGIC
71 }
72}
73
74/// Information of an account.
75// https://github.com/paritytech/substrate/blob/416a331399452521f3e9cf7e1394d020373a95c5/frame/system/src/lib.rs#L735-L753
76#[derive(Clone, Eq, PartialEq, Default, Encode, Decode, TypeInfo, MaxEncodedLen)]
77pub struct AccountInfo<Index, AccountData> {
78 /// The number of transactions this account has sent.
79 pub nonce: Index,
80 /// The number of other modules that currently depend on this account's existence. The account
81 /// cannot be reaped until this is zero.
82 pub consumers: RefCount,
83 /// The number of other modules that allow this account to exist. The account may not be reaped
84 /// until this and `sufficients` are both zero.
85 pub providers: RefCount,
86 /// The number of modules that allow this account to exist for their own purposes only. The
87 /// account may not be reaped until this and `providers` are both zero.
88 pub sufficients: RefCount,
89 /// The additional data that belongs to this account. Used to store the balance(s) in a lot of
90 /// chains.
91 pub data: AccountData,
92}
93
94/// The base fee and adjusted weight and length fees constitute the _inclusion fee_.
95// https://github.com/paritytech/substrate/blob/a1c1286d2ca6360a16d772cc8bea2190f77f4d8f/frame/transaction-payment/src/types.rs#L29-L60
96#[derive(Encode, Decode, Clone, Eq, PartialEq, Serialize, Deserialize, Debug)]
97#[serde(rename_all = "camelCase")]
98pub struct InclusionFee<Balance> {
99 /// This is the minimum amount a user pays for a transaction. It is declared
100 /// as a base _weight_ in the runtime and converted to a fee using `WeightToFee`.
101 pub base_fee: Balance,
102 /// The length fee, the amount paid for the encoded length (in bytes) of the transaction.
103 pub len_fee: Balance,
104 ///
105 /// - `targeted_fee_adjustment`: This is a multiplier that can tune the final fee based on the
106 /// congestion of the network.
107 /// - `weight_fee`: This amount is computed based on the weight of the transaction. Weight
108 /// accounts for the execution time of a transaction.
109 /// - `adjusted_weight_fee`` = targeted_fee_adjustment * weight_fee
110 pub adjusted_weight_fee: Balance,
111}
112
113impl<Balance: AtLeast32BitUnsigned + Copy> InclusionFee<Balance> {
114 /// Returns the total of inclusion fee.
115 ///
116 /// ```ignore
117 /// inclusion_fee = base_fee + len_fee + adjusted_weight_fee
118 /// ```
119 pub fn inclusion_fee(&self) -> Balance {
120 self.base_fee
121 .saturating_add(self.len_fee)
122 .saturating_add(self.adjusted_weight_fee)
123 }
124}
125
126/// The `FeeDetails` is composed of:
127/// - (Optional) `inclusion_fee`: Only the `Pays::Yes` transaction can have the inclusion fee.
128/// - `tip`: If included in the transaction, the tip will be added on top. Only signed
129/// transactions can have a tip.
130// https://github.com/paritytech/substrate/blob/a1c1286d2ca6360a16d772cc8bea2190f77f4d8f/frame/transaction-payment/src/types.rs#L62-L90
131#[derive(Encode, Decode, Clone, Eq, PartialEq, Serialize, Deserialize, Debug)]
132#[serde(rename_all = "camelCase")]
133pub struct FeeDetails<Balance> {
134 /// The minimum fee for a transaction to be included in a block.
135 pub inclusion_fee: Option<InclusionFee<Balance>>,
136 #[serde(skip)]
137 pub tip: Balance,
138}
139
140impl<Balance: AtLeast32BitUnsigned + Copy> FeeDetails<Balance> {
141 /// Returns the final fee.
142 ///
143 /// ```ignore
144 /// final_fee = inclusion_fee + tip;
145 /// ```
146 pub fn final_fee(&self) -> Balance {
147 self.inclusion_fee
148 .as_ref()
149 .map(|i| i.inclusion_fee())
150 .unwrap_or_else(|| Zero::zero())
151 .saturating_add(self.tip)
152 }
153}
154
155/// Information related to a dispatchable's class, weight, and fee that can be queried from the
156/// runtime.
157// https://github.com/paritytech/substrate/blob/a1c1286d2ca6360a16d772cc8bea2190f77f4d8f/frame/transaction-payment/src/types.rs#L92-L116
158#[derive(Eq, PartialEq, Encode, Decode, Default, Debug, Serialize, Deserialize)]
159#[serde(rename_all = "camelCase")]
160#[serde(bound(serialize = "Balance: core::fmt::Display, Weight: Serialize"))]
161#[serde(bound(deserialize = "Balance: core::str::FromStr, Weight: Deserialize<'de>"))]
162pub struct RuntimeDispatchInfo<Balance, Weight = sp_weights::Weight> {
163 /// Weight of this dispatch.
164 pub weight: Weight,
165 /// Class of this dispatch.
166 pub class: DispatchClass,
167 /// The inclusion fee of this dispatch.
168 ///
169 /// This does not include a tip or anything else that
170 /// depends on the signature (i.e. depends on a `SignedExtension`).
171 #[serde(with = "serde_balance")]
172 pub partial_fee: Balance,
173}
174
175mod serde_balance {
176 use alloc::string::ToString;
177 use serde::{Deserialize, Deserializer, Serializer};
178
179 pub fn serialize<S: Serializer, T: core::fmt::Display>(
180 t: &T,
181 serializer: S,
182 ) -> Result<S::Ok, S::Error> {
183 serializer.serialize_str(&t.to_string())
184 }
185
186 pub fn deserialize<'de, D: Deserializer<'de>, T: core::str::FromStr>(
187 deserializer: D,
188 ) -> Result<T, D::Error> {
189 let s = alloc::string::String::deserialize(deserializer)?;
190 s.parse::<T>().map_err(|_| serde::de::Error::custom("Parse from string failed"))
191 }
192}
193
194/// A generalized group of dispatch types.
195///
196/// NOTE whenever upgrading the enum make sure to also update
197/// [DispatchClass::all] and [DispatchClass::non_mandatory] helper functions.
198// https://github.com/paritytech/substrate/blob/a1c1286d2ca6360a16d772cc8bea2190f77f4d8f/frame/support/src/dispatch.rs#L133-L177
199#[derive(
200 PartialEq, Eq, Clone, Copy, Encode, Decode, Debug, TypeInfo, Serialize, Deserialize, Default,
201)]
202#[serde(rename_all = "camelCase")]
203pub enum DispatchClass {
204 /// A normal dispatch.
205 #[default]
206 Normal,
207 /// An operational dispatch.
208 Operational,
209 /// A mandatory dispatch. These kinds of dispatch are always included regardless of their
210 /// weight, therefore it is critical that they are separately validated to ensure that a
211 /// malicious validator cannot craft a valid but impossibly heavy block. Usually this just
212 /// means ensuring that the extrinsic can only be included once and that it is always very
213 /// light.
214 ///
215 /// Do *NOT* use it for extrinsics that can be heavy.
216 ///
217 /// The only real use case for this is inherent extrinsics that are required to execute in a
218 /// block for the block to be valid, and it solves the issue in the case that the block
219 /// initialization is sufficiently heavy to mean that those inherents do not fit into the
220 /// block. Essentially, we assume that in these exceptional circumstances, it is better to
221 /// allow an overweight block to be created than to not allow any block at all to be created.
222 Mandatory,
223}
224
225impl DispatchClass {
226 /// Returns an array containing all dispatch classes.
227 pub fn all() -> &'static [DispatchClass] {
228 &[DispatchClass::Normal, DispatchClass::Operational, DispatchClass::Mandatory]
229 }
230
231 /// Returns an array of all dispatch classes except `Mandatory`.
232 pub fn non_mandatory() -> &'static [DispatchClass] {
233 &[DispatchClass::Normal, DispatchClass::Operational]
234 }
235}
236
237/// A destination account for payment.
238#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, Debug, TypeInfo, MaxEncodedLen, Default)]
239pub enum RewardDestination<AccountId> {
240 /// Pay into the stash account, increasing the amount at stake accordingly.
241 #[default]
242 Staked,
243 /// Pay into the stash account, not increasing the amount at stake.
244 Stash,
245 /// Pay into the controller account.
246 Controller,
247 /// Pay into a specified account.
248 Account(AccountId),
249 /// Receive no reward.
250 None,
251}
252
253/// Health struct returned by the RPC
254// https://github.com/paritytech/substrate/blob/c172d0f683fab3792b90d876fd6ca27056af9fe9/client/rpc-api/src/system/helpers.rs#L40-L58
255#[derive(Debug, PartialEq, Serialize, Deserialize)]
256#[serde(rename_all = "camelCase")]
257pub struct Health {
258 /// Number of connected peers
259 pub peers: usize,
260 /// Is the node syncing
261 pub is_syncing: bool,
262 /// Should this node have any peers
263 ///
264 /// Might be false for local chains or when running without discovery.
265 pub should_have_peers: bool,
266}
267
268impl core::fmt::Display for Health {
269 fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
270 write!(fmt, "{} peers ({})", self.peers, if self.is_syncing { "syncing" } else { "idle" })
271 }
272}
273
274/// The type of a chain.
275///
276/// This can be used by tools to determine the type of a chain for displaying
277/// additional information or enabling additional features.
278// https://github.com/paritytech/substrate/blob/c172d0f683fab3792b90d876fd6ca27056af9fe9/client/chain-spec/src/lib.rs#L193-L207
279#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
280pub enum ChainType {
281 /// A development chain that runs mainly on one node.
282 Development,
283 /// A local chain that runs locally on multiple nodes for testing purposes.
284 Local,
285 /// A live chain.
286 Live,
287 /// Some custom chain type.
288 Custom(String),
289}
290
291/// Arbitrary properties defined in chain spec as a JSON object
292// https://github.com/paritytech/substrate/blob/c172d0f683fab3792b90d876fd6ca27056af9fe9/client/chain-spec/src/lib.rs#L215-L216
293pub type Properties = serde_json::map::Map<String, serde_json::Value>;
294
295// Merkle-mountain-range primitives. sp-mmr-primitives does not seem to be no-std compatible as of now.
296// Might be caused by the thiserror import in the toml. Parity probably will accept a PR if opened.
297
298/// A type-safe wrapper for the concrete leaf type.
299///
300/// This structure serves merely to avoid passing raw `Vec<u8>` around.
301/// It must be `Vec<u8>`-encoding compatible.
302// https://github.com/paritytech/polkadot-sdk/blob/a190e0e9253562fdca9c1b6e9541a7ea0a50c018/substrate/primitives/merkle-mountain-range/src/lib.rs#L138-L146
303#[derive(codec::Encode, codec::Decode, PartialEq, Eq, TypeInfo, Clone)]
304pub struct EncodableOpaqueLeaf(pub Vec<u8>);
305
306/// An MMR proof data for a group of leaves.
307// https://github.com/paritytech/polkadot-sdk/blob/a190e0e9253562fdca9c1b6e9541a7ea0a50c018/substrate/primitives/merkle-mountain-range/src/lib.rs#L351-L360
308#[derive(codec::Encode, codec::Decode, Debug, Clone, PartialEq, Eq, TypeInfo)]
309pub struct Proof<Hash> {
310 /// The indices of the leaves the proof is for.
311 pub leaf_indices: Vec<LeafIndex>,
312 /// Number of leaves in MMR, when the proof was generated.
313 pub leaf_count: NodeIndex,
314 /// Proof elements (hashes of siblings of inner nodes on the path to the leaf).
315 pub items: Vec<Hash>,
316}
317
318/// A type to describe leaf position in the MMR.
319///
320/// Note this is different from [`NodeIndex`], which can be applied to
321/// both leafs and inner nodes. Leafs will always have consecutive `LeafIndex`,
322/// but might be actually at different positions in the MMR `NodeIndex`.
323// https://github.com/paritytech/polkadot-sdk/blob/a190e0e9253562fdca9c1b6e9541a7ea0a50c018/substrate/primitives/merkle-mountain-range/src/lib.rs#L45
324pub type LeafIndex = u64;
325/// A type to describe node position in the MMR (node index).
326// https://github.com/paritytech/polkadot-sdk/blob/a190e0e9253562fdca9c1b6e9541a7ea0a50c018/substrate/primitives/merkle-mountain-range/src/lib.rs#L138-L146
327pub type NodeIndex = u64;
328
329/// Merkle Mountain Range operation error.
330// https://github.com/paritytech/polkadot-sdk/blob/a190e0e9253562fdca9c1b6e9541a7ea0a50c018/substrate/primitives/merkle-mountain-range/src/lib.rs#L362-L396
331#[derive(Encode, Decode, PartialEq, Eq, TypeInfo, Debug)]
332pub enum MmrError {
333 /// Error during translation of a block number into a leaf index.
334 InvalidNumericOp,
335 /// Error while pushing new node.
336 Push,
337 /// Error getting the new root.
338 GetRoot,
339 /// Error committing changes.
340 Commit,
341 /// Error during proof generation.
342 GenerateProof,
343 /// Proof verification error.
344 Verify,
345 /// Leaf not found in the storage.
346 LeafNotFound,
347 /// Mmr Pallet not included in runtime
348 PalletNotIncluded,
349 /// Cannot find the requested leaf index
350 InvalidLeafIndex,
351 /// The provided best know block number is invalid.
352 InvalidBestKnownBlock,
353}
354
355/// Defines the required determinism level of a wasm blob when either running or uploading code.
356#[derive(Clone, Copy, Encode, Decode, TypeInfo, MaxEncodedLen, Debug, PartialEq, Eq)]
357pub enum Determinism {
358 /// The execution should be deterministic and hence no indeterministic instructions are
359 /// allowed.
360 ///
361 /// Dispatchables always use this mode in order to make on-chain execution deterministic.
362 Enforced,
363 /// Allow calling or uploading an indeterministic code.
364 ///
365 /// This is only possible when calling into `pallet-contracts` directly via
366 /// [`crate::Pallet::bare_call`].
367 ///
368 /// # Note
369 ///
370 /// **Never** use this mode for on-chain execution.
371 Relaxed,
372}