gear_core/program.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//! Module for programs.
20
21use crate::{
22 ids::{MessageId, ProgramId},
23 message::DispatchKind,
24 pages::WasmPagesAmount,
25 reservation::GasReservationMap,
26};
27use alloc::collections::BTreeSet;
28use primitive_types::H256;
29use scale_info::{
30 scale::{Decode, Encode},
31 TypeInfo,
32};
33
34/// Program in different states in storage.
35#[derive(Clone, Debug, Decode, Encode, PartialEq, Eq, TypeInfo)]
36pub enum Program<BlockNumber: Copy> {
37 /// Program in active state.
38 Active(ActiveProgram<BlockNumber>),
39 /// Program has been exited (gr_exit was called)
40 Exited(ProgramId),
41 /// Program has been terminated (`init` was failed)
42 Terminated(ProgramId),
43}
44
45impl<BlockNumber: Copy> Program<BlockNumber> {
46 /// Returns whether the program is active.
47 pub fn is_active(&self) -> bool {
48 matches!(self, Program::Active(_))
49 }
50
51 /// Returns whether the program is exited.
52 pub fn is_exited(&self) -> bool {
53 matches!(self, Program::Exited(_))
54 }
55
56 /// Returns whether the program is terminated.
57 pub fn is_terminated(&self) -> bool {
58 matches!(self, Program::Terminated(_))
59 }
60
61 /// Returns whether the program is active and initialized.
62 pub fn is_initialized(&self) -> bool {
63 matches!(
64 self,
65 Program::Active(ActiveProgram {
66 state: ProgramState::Initialized,
67 ..
68 })
69 )
70 }
71}
72
73/// Program is not an active one.
74#[derive(Clone, Debug, derive_more::Display)]
75#[display(fmt = "Program is not an active one")]
76pub struct InactiveProgramError;
77
78impl<BlockNumber: Copy> core::convert::TryFrom<Program<BlockNumber>>
79 for ActiveProgram<BlockNumber>
80{
81 type Error = InactiveProgramError;
82
83 fn try_from(prog_with_status: Program<BlockNumber>) -> Result<Self, Self::Error> {
84 match prog_with_status {
85 Program::Active(p) => Ok(p),
86 _ => Err(InactiveProgramError),
87 }
88 }
89}
90
91/// Active program in storage.
92#[derive(Clone, Debug, Decode, Encode, PartialEq, Eq, TypeInfo)]
93pub struct ActiveProgram<BlockNumber: Copy> {
94 /// Continuous intervals amount in program allocations.
95 pub allocations_tree_len: u32,
96 /// Infix of memory pages storage (is used for memory wake after pausing)
97 pub memory_infix: MemoryInfix,
98 /// Gas reservation map.
99 pub gas_reservation_map: GasReservationMap,
100 /// Code hash of the program.
101 pub code_hash: H256,
102 /// Set of supported dispatch kinds.
103 pub code_exports: BTreeSet<DispatchKind>,
104 /// Amount of static pages.
105 pub static_pages: WasmPagesAmount,
106 /// Initialization state of the program.
107 pub state: ProgramState,
108 /// Block number when the program will be expired.
109 pub expiration_block: BlockNumber,
110}
111
112/// Enumeration contains variants for program state.
113#[derive(Clone, Debug, Decode, Encode, PartialEq, Eq, TypeInfo)]
114pub enum ProgramState {
115 /// `init` method of a program has not yet finished its execution so
116 /// the program is not considered as initialized.
117 Uninitialized {
118 /// identifier of the initialization message.
119 message_id: MessageId,
120 },
121 /// Program has been successfully initialized and can process messages.
122 Initialized,
123}
124
125/// Struct defines infix of memory pages storage.
126#[derive(Clone, Copy, Debug, Default, Decode, Encode, PartialEq, Eq, TypeInfo)]
127#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
128pub struct MemoryInfix(u32);
129
130impl MemoryInfix {
131 /// Constructing function from u32 number.
132 pub const fn new(value: u32) -> Self {
133 Self(value)
134 }
135
136 /// Return inner u32 value.
137 pub fn inner(&self) -> u32 {
138 self.0
139 }
140}