Skip to main content

gear_core/
program.rs

1// Copyright (C) Gear Technologies Inc.
2// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
3
4//! Module for programs.
5
6use crate::{
7    ids::{ActorId, MessageId},
8    reservation::GasReservationMap,
9};
10use gprimitives::CodeId;
11use scale_decode::DecodeAsType;
12use scale_encode::EncodeAsType;
13use scale_info::{
14    TypeInfo,
15    scale::{Decode, Encode},
16};
17
18/// Program in different states in storage.
19#[derive(Clone, Debug, Decode, Encode, PartialEq, Eq, TypeInfo)]
20pub enum Program<BlockNumber: Copy> {
21    /// Program in active state.
22    Active(ActiveProgram<BlockNumber>),
23    /// Program has been exited (gr_exit was called)
24    Exited(ActorId),
25    /// Program has been terminated (`init` was failed)
26    Terminated(ActorId),
27}
28
29impl<BlockNumber: Copy> Program<BlockNumber> {
30    /// Returns whether the program is active.
31    pub fn is_active(&self) -> bool {
32        matches!(self, Program::Active(_))
33    }
34
35    /// Returns whether the program is exited.
36    pub fn is_exited(&self) -> bool {
37        matches!(self, Program::Exited(_))
38    }
39
40    /// Returns whether the program is terminated.
41    pub fn is_terminated(&self) -> bool {
42        matches!(self, Program::Terminated(_))
43    }
44
45    /// Returns whether the program is active and initialized.
46    pub fn is_initialized(&self) -> bool {
47        matches!(
48            self,
49            Program::Active(ActiveProgram {
50                state: ProgramState::Initialized,
51                ..
52            })
53        )
54    }
55}
56
57/// Program is not an active one.
58#[derive(Clone, Debug, derive_more::Display)]
59#[display("Program is not an active one")]
60pub struct InactiveProgramError;
61
62impl<BlockNumber: Copy> core::convert::TryFrom<Program<BlockNumber>>
63    for ActiveProgram<BlockNumber>
64{
65    type Error = InactiveProgramError;
66
67    fn try_from(prog_with_status: Program<BlockNumber>) -> Result<Self, Self::Error> {
68        match prog_with_status {
69            Program::Active(p) => Ok(p),
70            _ => Err(InactiveProgramError),
71        }
72    }
73}
74
75/// Active program in storage.
76#[derive(Clone, Debug, Decode, Encode, PartialEq, Eq, TypeInfo)]
77pub struct ActiveProgram<BlockNumber: Copy> {
78    /// Continuous intervals amount in program allocations.
79    pub allocations_tree_len: u32,
80    /// Infix of memory pages storage (is used for memory wake after pausing)
81    pub memory_infix: MemoryInfix,
82    /// Gas reservation map.
83    pub gas_reservation_map: GasReservationMap,
84    /// Code id of the program.
85    pub code_id: CodeId,
86    /// Initialization state of the program.
87    pub state: ProgramState,
88    /// Block number when the program will be expired.
89    pub expiration_block: BlockNumber,
90}
91
92/// Enumeration contains variants for program state.
93#[derive(Clone, Debug, Decode, DecodeAsType, Encode, EncodeAsType, PartialEq, Eq, TypeInfo)]
94pub enum ProgramState {
95    /// `init` method of a program has not yet finished its execution so
96    /// the program is not considered as initialized.
97    Uninitialized {
98        /// identifier of the initialization message.
99        message_id: MessageId,
100    },
101    /// Program has been successfully initialized and can process messages.
102    Initialized,
103}
104
105/// Struct defines infix of memory pages storage.
106#[derive(
107    Clone,
108    Copy,
109    Debug,
110    Default,
111    Decode,
112    DecodeAsType,
113    Encode,
114    EncodeAsType,
115    PartialEq,
116    Eq,
117    Hash,
118    TypeInfo,
119)]
120#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
121pub struct MemoryInfix(u32);
122
123impl MemoryInfix {
124    /// Constructing function from u32 number.
125    pub const fn new(value: u32) -> Self {
126        Self(value)
127    }
128
129    /// Return inner u32 value.
130    pub fn inner(&self) -> u32 {
131        self.0
132    }
133}