gear_common/
lib.rs

1// This file is part of Gear.
2
3// Copyright (C) 2021-2025 Gear Technologies Inc.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19#![cfg_attr(not(feature = "std"), no_std)]
20#![doc(html_logo_url = "https://docs.gear.rs/logo.svg")]
21#![doc(html_favicon_url = "https://gear-tech.io/favicons/favicon.ico")]
22
23#[macro_use]
24extern crate gear_common_codegen;
25
26#[cfg(feature = "std")]
27pub mod auxiliary;
28pub mod event;
29pub mod scheduler;
30pub mod storage;
31
32pub mod code_storage;
33pub use code_storage::{CodeStorage, Error as CodeStorageError};
34
35pub mod program_storage;
36pub use program_storage::{Error as ProgramStorageError, ProgramStorage};
37
38pub mod gas_provider;
39
40#[cfg(feature = "runtime-benchmarks")]
41pub mod benchmarking;
42
43#[cfg(feature = "std")]
44pub mod pallet_tests;
45
46use core::fmt;
47use frame_support::{
48    pallet_prelude::MaxEncodedLen,
49    sp_runtime::{
50        self,
51        generic::{CheckedExtrinsic, UncheckedExtrinsic},
52        traits::{Dispatchable, SignedExtension},
53    },
54    traits::Get,
55};
56pub use gear_core::{
57    ids::{CodeId, MessageId, ProgramId, ReservationId},
58    memory::PageBuf,
59    pages::GearPage,
60    program::{ActiveProgram, MemoryInfix, Program},
61};
62use primitive_types::H256;
63use sp_arithmetic::traits::{BaseArithmetic, One, Saturating, UniqueSaturatedInto, Unsigned};
64use sp_runtime::{
65    codec::{self, Decode, Encode},
66    scale_info::{self, TypeInfo},
67};
68use sp_std::{collections::btree_map::BTreeMap, prelude::*};
69
70use storage::ValueStorage;
71extern crate alloc;
72
73pub use gas_provider::{
74    LockId, LockableTree, Provider as GasProvider, ReservableTree, Tree as GasTree,
75};
76
77/// Type alias for gas entity.
78pub type Gas = u64;
79
80/// NOTE: Implementation of this for `u64` places bytes from idx=0.
81pub trait Origin: Sized {
82    fn into_origin(self) -> H256;
83    fn from_origin(val: H256) -> Self;
84    fn cast<T: Origin>(self) -> T {
85        T::from_origin(self.into_origin())
86    }
87}
88
89impl Origin for u64 {
90    fn into_origin(self) -> H256 {
91        let mut result = H256::zero();
92        result[0..8].copy_from_slice(&self.to_le_bytes());
93        result
94    }
95
96    fn from_origin(v: H256) -> Self {
97        // h256 -> u64 should not be used anywhere other than in tests!
98        let mut val = [0u8; 8];
99        val.copy_from_slice(&v[0..8]);
100        Self::from_le_bytes(val)
101    }
102}
103
104impl Origin for sp_runtime::AccountId32 {
105    fn into_origin(self) -> H256 {
106        H256::from(self.as_ref())
107    }
108
109    fn from_origin(v: H256) -> Self {
110        Self::new(v.0)
111    }
112}
113
114impl Origin for H256 {
115    fn into_origin(self) -> H256 {
116        self
117    }
118
119    fn from_origin(val: H256) -> Self {
120        val
121    }
122}
123
124impl Origin for MessageId {
125    fn into_origin(self) -> H256 {
126        H256(self.into())
127    }
128
129    fn from_origin(val: H256) -> Self {
130        val.to_fixed_bytes().into()
131    }
132}
133
134impl Origin for ProgramId {
135    fn into_origin(self) -> H256 {
136        H256(self.into())
137    }
138
139    fn from_origin(val: H256) -> Self {
140        val.to_fixed_bytes().into()
141    }
142}
143
144impl Origin for CodeId {
145    fn into_origin(self) -> H256 {
146        H256(self.into())
147    }
148
149    fn from_origin(val: H256) -> Self {
150        val.to_fixed_bytes().into()
151    }
152}
153
154impl Origin for ReservationId {
155    fn into_origin(self) -> H256 {
156        H256(self.into())
157    }
158
159    fn from_origin(val: H256) -> Self {
160        val.to_fixed_bytes().into()
161    }
162}
163
164#[derive(
165    Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Encode, Decode, MaxEncodedLen, TypeInfo,
166)]
167#[codec(crate = codec)]
168#[scale_info(crate = scale_info)]
169/// Type representing converter between gas and value in different relations.
170pub enum GasMultiplier<Balance, Gas> {
171    ValuePerGas(Balance),
172    GasPerValue(Gas),
173}
174
175impl<Balance: One, Gas> Default for GasMultiplier<Balance, Gas> {
176    fn default() -> Self {
177        Self::ValuePerGas(One::one())
178    }
179}
180
181impl<Balance, Gas> GasMultiplier<Balance, Gas>
182where
183    Balance: BaseArithmetic + Copy + Unsigned,
184    Gas: BaseArithmetic + Copy + Unsigned + UniqueSaturatedInto<Balance>,
185{
186    /// Converts given gas amount into its value equivalent.
187    pub fn gas_to_value(&self, gas: Gas) -> Balance {
188        let gas: Balance = gas.unique_saturated_into();
189
190        match self {
191            Self::ValuePerGas(multiplier) => gas.saturating_mul(*multiplier),
192            Self::GasPerValue(_multiplier) => {
193                // Consider option to return `(*cost*, *amount of gas to be bought*)`.
194                unimplemented!("Currently unsupported that 1 Value > 1 Gas");
195            }
196        }
197    }
198}
199
200impl<Balance, Gas> From<GasMultiplier<Balance, Gas>> for gsys::GasMultiplier
201where
202    Balance: Copy + UniqueSaturatedInto<gsys::Value>,
203    Gas: Copy + UniqueSaturatedInto<gsys::Gas>,
204{
205    fn from(multiplier: GasMultiplier<Balance, Gas>) -> Self {
206        match multiplier {
207            GasMultiplier::ValuePerGas(multiplier) => {
208                Self::from_value_per_gas((multiplier).unique_saturated_into())
209            }
210            GasMultiplier::GasPerValue(multiplier) => {
211                Self::from_gas_per_value((multiplier).unique_saturated_into())
212            }
213        }
214    }
215}
216
217pub trait QueueRunner {
218    type Gas;
219
220    fn run_queue(initial_gas: Self::Gas) -> Self::Gas;
221}
222
223/// Contains various limits for the block.
224pub trait BlockLimiter {
225    /// The maximum amount of gas that can be used within a single block.
226    type BlockGasLimit: Get<Self::Balance>;
227
228    /// Type representing a quantity of value.
229    type Balance;
230
231    /// Type manages a gas that is available at the moment of call.
232    type GasAllowance: storage::Limiter<Value = Self::Balance>;
233}
234
235#[derive(Clone, Debug, Decode, Encode, PartialEq, Eq, TypeInfo)]
236#[codec(crate = codec)]
237#[scale_info(crate = scale_info)]
238pub struct CodeMetadata {
239    pub author: H256,
240    #[codec(compact)]
241    pub block_number: u32,
242}
243
244impl CodeMetadata {
245    pub fn new(author: H256, block_number: u32) -> Self {
246        CodeMetadata {
247            author,
248            block_number,
249        }
250    }
251}
252
253/// A trait whose purpose is to extract the `Call` variant of an extrinsic
254pub trait ExtractCall<Call> {
255    fn extract_call(&self) -> Call;
256}
257
258/// Implementation for unchecked extrinsic.
259impl<Address, Call, Signature, Extra> ExtractCall<Call>
260    for UncheckedExtrinsic<Address, Call, Signature, Extra>
261where
262    Call: Dispatchable + Clone,
263    Extra: SignedExtension,
264{
265    fn extract_call(&self) -> Call {
266        self.function.clone()
267    }
268}
269
270/// Implementation for checked extrinsic.
271impl<Address, Call, Extra> ExtractCall<Call> for CheckedExtrinsic<Address, Call, Extra>
272where
273    Call: Dispatchable + Clone,
274{
275    fn extract_call(&self) -> Call {
276        self.function.clone()
277    }
278}
279
280/// Trait that the RuntimeApi should implement in order to allow deconstruction and reconstruction
281/// to and from its components.
282#[cfg(any(feature = "std", test))]
283pub trait Deconstructable<Call> {
284    type Params: Send;
285
286    fn into_parts(self) -> (&'static Call, Self::Params);
287
288    fn from_parts(call: &Call, params: Self::Params) -> Self;
289}
290
291/// Trait that is used to "delegate fee" by optionally changing
292/// the payer target (account id) for the applied call.
293pub trait DelegateFee<Call, Acc> {
294    fn delegate_fee(call: &Call, who: &Acc) -> Option<Acc>;
295}
296
297impl<Call, Acc> DelegateFee<Call, Acc> for () {
298    fn delegate_fee(_call: &Call, _who: &Acc) -> Option<Acc> {
299        None
300    }
301}