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 scale_info::TypeInfo;
24use serde::{Deserialize, Serialize};
25use sp_core::RuntimeDebug;
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, RuntimeDebug, 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, RuntimeDebug, 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, RuntimeDebug, TypeInfo, Serialize, Deserialize,
201)]
202#[serde(rename_all = "camelCase")]
203pub enum DispatchClass {
204 /// A normal dispatch.
205 Normal,
206 /// An operational dispatch.
207 Operational,
208 /// A mandatory dispatch. These kinds of dispatch are always included regardless of their
209 /// weight, therefore it is critical that they are separately validated to ensure that a
210 /// malicious validator cannot craft a valid but impossibly heavy block. Usually this just
211 /// means ensuring that the extrinsic can only be included once and that it is always very
212 /// light.
213 ///
214 /// Do *NOT* use it for extrinsics that can be heavy.
215 ///
216 /// The only real use case for this is inherent extrinsics that are required to execute in a
217 /// block for the block to be valid, and it solves the issue in the case that the block
218 /// initialization is sufficiently heavy to mean that those inherents do not fit into the
219 /// block. Essentially, we assume that in these exceptional circumstances, it is better to
220 /// allow an overweight block to be created than to not allow any block at all to be created.
221 Mandatory,
222}
223
224impl Default for DispatchClass {
225 fn default() -> Self {
226 Self::Normal
227 }
228}
229
230impl DispatchClass {
231 /// Returns an array containing all dispatch classes.
232 pub fn all() -> &'static [DispatchClass] {
233 &[DispatchClass::Normal, DispatchClass::Operational, DispatchClass::Mandatory]
234 }
235
236 /// Returns an array of all dispatch classes except `Mandatory`.
237 pub fn non_mandatory() -> &'static [DispatchClass] {
238 &[DispatchClass::Normal, DispatchClass::Operational]
239 }
240}
241
242/// A destination account for payment.
243#[derive(
244 PartialEq, Eq, Copy, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen, Default,
245)]
246pub enum RewardDestination<AccountId> {
247 /// Pay into the stash account, increasing the amount at stake accordingly.
248 #[default]
249 Staked,
250 /// Pay into the stash account, not increasing the amount at stake.
251 Stash,
252 /// Pay into the controller account.
253 Controller,
254 /// Pay into a specified account.
255 Account(AccountId),
256 /// Receive no reward.
257 None,
258}
259
260/// Health struct returned by the RPC
261// https://github.com/paritytech/substrate/blob/c172d0f683fab3792b90d876fd6ca27056af9fe9/client/rpc-api/src/system/helpers.rs#L40-L58
262#[derive(Debug, PartialEq, Serialize, Deserialize)]
263#[serde(rename_all = "camelCase")]
264pub struct Health {
265 /// Number of connected peers
266 pub peers: usize,
267 /// Is the node syncing
268 pub is_syncing: bool,
269 /// Should this node have any peers
270 ///
271 /// Might be false for local chains or when running without discovery.
272 pub should_have_peers: bool,
273}
274
275impl core::fmt::Display for Health {
276 fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
277 write!(fmt, "{} peers ({})", self.peers, if self.is_syncing { "syncing" } else { "idle" })
278 }
279}
280
281/// The type of a chain.
282///
283/// This can be used by tools to determine the type of a chain for displaying
284/// additional information or enabling additional features.
285// https://github.com/paritytech/substrate/blob/c172d0f683fab3792b90d876fd6ca27056af9fe9/client/chain-spec/src/lib.rs#L193-L207
286#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
287pub enum ChainType {
288 /// A development chain that runs mainly on one node.
289 Development,
290 /// A local chain that runs locally on multiple nodes for testing purposes.
291 Local,
292 /// A live chain.
293 Live,
294 /// Some custom chain type.
295 Custom(String),
296}
297
298/// Arbitrary properties defined in chain spec as a JSON object
299// https://github.com/paritytech/substrate/blob/c172d0f683fab3792b90d876fd6ca27056af9fe9/client/chain-spec/src/lib.rs#L215-L216
300pub type Properties = serde_json::map::Map<String, serde_json::Value>;
301
302// Merkle-mountain-range primitives. sp-mmr-primitives does not seem to be no-std compatible as of now.
303// Might be caused by the thiserror import in the toml. Parity probably will accept a PR if opened.
304
305/// A type-safe wrapper for the concrete leaf type.
306///
307/// This structure serves merely to avoid passing raw `Vec<u8>` around.
308/// It must be `Vec<u8>`-encoding compatible.
309// https://github.com/paritytech/polkadot-sdk/blob/a190e0e9253562fdca9c1b6e9541a7ea0a50c018/substrate/primitives/merkle-mountain-range/src/lib.rs#L138-L146
310#[derive(codec::Encode, codec::Decode, PartialEq, Eq, TypeInfo, Clone)]
311pub struct EncodableOpaqueLeaf(pub Vec<u8>);
312
313/// An MMR proof data for a group of leaves.
314// https://github.com/paritytech/polkadot-sdk/blob/a190e0e9253562fdca9c1b6e9541a7ea0a50c018/substrate/primitives/merkle-mountain-range/src/lib.rs#L351-L360
315#[derive(codec::Encode, codec::Decode, RuntimeDebug, Clone, PartialEq, Eq, TypeInfo)]
316pub struct Proof<Hash> {
317 /// The indices of the leaves the proof is for.
318 pub leaf_indices: Vec<LeafIndex>,
319 /// Number of leaves in MMR, when the proof was generated.
320 pub leaf_count: NodeIndex,
321 /// Proof elements (hashes of siblings of inner nodes on the path to the leaf).
322 pub items: Vec<Hash>,
323}
324
325/// A type to describe leaf position in the MMR.
326///
327/// Note this is different from [`NodeIndex`], which can be applied to
328/// both leafs and inner nodes. Leafs will always have consecutive `LeafIndex`,
329/// but might be actually at different positions in the MMR `NodeIndex`.
330// https://github.com/paritytech/polkadot-sdk/blob/a190e0e9253562fdca9c1b6e9541a7ea0a50c018/substrate/primitives/merkle-mountain-range/src/lib.rs#L45
331pub type LeafIndex = u64;
332/// A type to describe node position in the MMR (node index).
333// https://github.com/paritytech/polkadot-sdk/blob/a190e0e9253562fdca9c1b6e9541a7ea0a50c018/substrate/primitives/merkle-mountain-range/src/lib.rs#L138-L146
334pub type NodeIndex = u64;
335
336/// Merkle Mountain Range operation error.
337// https://github.com/paritytech/polkadot-sdk/blob/a190e0e9253562fdca9c1b6e9541a7ea0a50c018/substrate/primitives/merkle-mountain-range/src/lib.rs#L362-L396
338#[derive(Encode, Decode, PartialEq, Eq, TypeInfo, RuntimeDebug)]
339pub enum MmrError {
340 /// Error during translation of a block number into a leaf index.
341 InvalidNumericOp,
342 /// Error while pushing new node.
343 Push,
344 /// Error getting the new root.
345 GetRoot,
346 /// Error committing changes.
347 Commit,
348 /// Error during proof generation.
349 GenerateProof,
350 /// Proof verification error.
351 Verify,
352 /// Leaf not found in the storage.
353 LeafNotFound,
354 /// Mmr Pallet not included in runtime
355 PalletNotIncluded,
356 /// Cannot find the requested leaf index
357 InvalidLeafIndex,
358 /// The provided best know block number is invalid.
359 InvalidBestKnownBlock,
360}
361
362/// Defines the required determinism level of a wasm blob when either running or uploading code.
363#[derive(Clone, Copy, Encode, Decode, TypeInfo, MaxEncodedLen, RuntimeDebug, PartialEq, Eq)]
364pub enum Determinism {
365 /// The execution should be deterministic and hence no indeterministic instructions are
366 /// allowed.
367 ///
368 /// Dispatchables always use this mode in order to make on-chain execution deterministic.
369 Enforced,
370 /// Allow calling or uploading an indeterministic code.
371 ///
372 /// This is only possible when calling into `pallet-contracts` directly via
373 /// [`crate::Pallet::bare_call`].
374 ///
375 /// # Note
376 ///
377 /// **Never** use this mode for on-chain execution.
378 Relaxed,
379}