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
26pub mod event;
27pub mod scheduler;
28pub mod storage;
29
30pub mod code_storage;
31pub use code_storage::{CodeStorage, Error as CodeStorageError};
32
33pub mod program_storage;
34pub use program_storage::{Error as ProgramStorageError, ProgramStorage};
35
36pub mod gas_provider;
37
38#[cfg(feature = "runtime-benchmarks")]
39pub mod benchmarking;
40
41#[cfg(feature = "std")]
42pub mod pallet_tests;
43
44use core::fmt;
45use frame_support::{
46    pallet_prelude::MaxEncodedLen,
47    sp_runtime::{
48        self,
49        generic::{CheckedExtrinsic, UncheckedExtrinsic},
50        traits::{Dispatchable, SignedExtension},
51    },
52    traits::Get,
53};
54pub use gear_core::{
55    ids::{ActorId, CodeId, MessageId, ReservationId},
56    memory::PageBuf,
57    pages::GearPage,
58    program::{ActiveProgram, MemoryInfix, Program},
59};
60use primitive_types::H256;
61use sp_arithmetic::traits::{BaseArithmetic, Saturating, UniqueSaturatedInto, Unsigned};
62use sp_runtime::{
63    codec::{self, Decode, Encode},
64    scale_info::{self, TypeInfo},
65};
66use sp_std::{collections::btree_map::BTreeMap, prelude::*};
67
68use storage::ValueStorage;
69extern crate alloc;
70
71pub use gas_provider::{
72    LockId, LockableTree, Provider as GasProvider, ReservableTree, Tree as GasTree,
73};
74
75/// Type alias for gas entity.
76pub type Gas = u64;
77
78/// NOTE: Implementation of this for `u64` places bytes from idx=0.
79pub trait Origin: Sized {
80    fn into_origin(self) -> H256;
81    fn from_origin(val: H256) -> Self;
82    fn cast<T: Origin>(self) -> T {
83        T::from_origin(self.into_origin())
84    }
85}
86
87impl Origin for u64 {
88    fn into_origin(self) -> H256 {
89        let mut result = H256::zero();
90        result[0..8].copy_from_slice(&self.to_le_bytes());
91        result
92    }
93
94    fn from_origin(v: H256) -> Self {
95        // h256 -> u64 should not be used anywhere other than in tests!
96        let mut val = [0u8; 8];
97        val.copy_from_slice(&v[0..8]);
98        Self::from_le_bytes(val)
99    }
100}
101
102impl Origin for sp_runtime::AccountId32 {
103    fn into_origin(self) -> H256 {
104        H256::from(self.as_ref())
105    }
106
107    fn from_origin(v: H256) -> Self {
108        Self::new(v.0)
109    }
110}
111
112impl Origin for H256 {
113    fn into_origin(self) -> H256 {
114        self
115    }
116
117    fn from_origin(val: H256) -> Self {
118        val
119    }
120}
121
122impl Origin for MessageId {
123    fn into_origin(self) -> H256 {
124        H256(self.into())
125    }
126
127    fn from_origin(val: H256) -> Self {
128        val.to_fixed_bytes().into()
129    }
130}
131
132impl Origin for ActorId {
133    fn into_origin(self) -> H256 {
134        H256(self.into())
135    }
136
137    fn from_origin(val: H256) -> Self {
138        val.to_fixed_bytes().into()
139    }
140}
141
142impl Origin for CodeId {
143    fn into_origin(self) -> H256 {
144        H256(self.into())
145    }
146
147    fn from_origin(val: H256) -> Self {
148        val.to_fixed_bytes().into()
149    }
150}
151
152impl Origin for ReservationId {
153    fn into_origin(self) -> H256 {
154        H256(self.into())
155    }
156
157    fn from_origin(val: H256) -> Self {
158        val.to_fixed_bytes().into()
159    }
160}
161
162#[derive(
163    Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Encode, Decode, MaxEncodedLen, TypeInfo,
164)]
165#[codec(crate = codec)]
166#[scale_info(crate = scale_info)]
167/// Type representing converter between gas and value in different relations.
168pub enum GasMultiplier<Balance, Gas> {
169    ValuePerGas(Balance),
170    GasPerValue(Gas),
171}
172
173impl<Balance, Gas> GasMultiplier<Balance, Gas>
174where
175    Balance: BaseArithmetic + Copy + Unsigned,
176    Gas: BaseArithmetic + Copy + Unsigned + UniqueSaturatedInto<Balance>,
177{
178    /// Converts given gas amount into its value equivalent.
179    pub fn gas_to_value(&self, gas: Gas) -> Balance {
180        let gas: Balance = gas.unique_saturated_into();
181
182        match self {
183            Self::ValuePerGas(multiplier) => gas.saturating_mul(*multiplier),
184            Self::GasPerValue(_multiplier) => {
185                // Consider option to return `(*cost*, *amount of gas to be bought*)`.
186                unimplemented!("Currently unsupported that 1 Value > 1 Gas");
187            }
188        }
189    }
190}
191
192impl<Balance, Gas> From<GasMultiplier<Balance, Gas>> for gsys::GasMultiplier
193where
194    Balance: Copy + UniqueSaturatedInto<gsys::Value>,
195    Gas: Copy + UniqueSaturatedInto<gsys::Gas>,
196{
197    fn from(multiplier: GasMultiplier<Balance, Gas>) -> Self {
198        match multiplier {
199            GasMultiplier::ValuePerGas(multiplier) => {
200                Self::from_value_per_gas((multiplier).unique_saturated_into())
201            }
202            GasMultiplier::GasPerValue(multiplier) => {
203                Self::from_gas_per_value((multiplier).unique_saturated_into())
204            }
205        }
206    }
207}
208
209pub trait QueueRunner {
210    type Gas;
211
212    fn run_queue(initial_gas: Self::Gas) -> Self::Gas;
213}
214
215/// Contains various limits for the block.
216pub trait BlockLimiter {
217    /// The maximum amount of gas that can be used within a single block.
218    type BlockGasLimit: Get<Self::Balance>;
219
220    /// Type representing a quantity of value.
221    type Balance;
222
223    /// Type manages a gas that is available at the moment of call.
224    type GasAllowance: storage::Limiter<Value = Self::Balance>;
225}
226
227/// A trait whose purpose is to extract the `Call` variant of an extrinsic
228pub trait ExtractCall<Call> {
229    fn extract_call(&self) -> Call;
230}
231
232/// Implementation for unchecked extrinsic.
233impl<Address, Call, Signature, Extra> ExtractCall<Call>
234    for UncheckedExtrinsic<Address, Call, Signature, Extra>
235where
236    Call: Dispatchable + Clone,
237    Extra: SignedExtension,
238{
239    fn extract_call(&self) -> Call {
240        self.function.clone()
241    }
242}
243
244/// Implementation for checked extrinsic.
245impl<Address, Call, Extra> ExtractCall<Call> for CheckedExtrinsic<Address, Call, Extra>
246where
247    Call: Dispatchable + Clone,
248{
249    fn extract_call(&self) -> Call {
250        self.function.clone()
251    }
252}
253
254/// Trait that the RuntimeApi should implement in order to allow deconstruction and reconstruction
255/// to and from its components.
256#[cfg(any(feature = "std", test))]
257pub trait Deconstructable<Call> {
258    type Params: Send;
259
260    fn into_parts(self) -> (&'static Call, Self::Params);
261
262    fn from_parts(call: &Call, params: Self::Params) -> Self;
263}
264
265/// Trait that is used to "delegate fee" by optionally changing
266/// the payer target (account id) for the applied call.
267pub trait DelegateFee<Call, Acc> {
268    fn delegate_fee(call: &Call, who: &Acc) -> Option<Acc>;
269}
270
271impl<Call, Acc> DelegateFee<Call, Acc> for () {
272    fn delegate_fee(_call: &Call, _who: &Acc) -> Option<Acc> {
273        None
274    }
275}