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