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}