Skip to main content

gear_common/
lib.rs

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