gear_core/
tasks.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//! The module provides primitives for all available regular or time-dependent tasks.
20
21use crate::ids::{ActorId, CodeId, MessageId, ReservationId};
22use gsys::Gas;
23use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
24use scale_info::TypeInfo;
25
26/// Alias for ScheduledTask used in vara-runtime, generic across AccountId used.
27pub type VaraScheduledTask<AccountId> = ScheduledTask<AccountId, MessageId, bool>;
28
29/// Scheduled task sense and required data for processing action.
30///
31/// CAUTION: NEVER ALLOW `ScheduledTask` BE A BIG DATA.
32/// To avoid redundant migrations only append new variant(s) to the enum
33/// with an explicit corresponding scale codec index.
34#[derive(
35    Copy,
36    Clone,
37    Debug,
38    Eq,
39    PartialEq,
40    PartialOrd,
41    Ord,
42    Hash,
43    Encode,
44    Decode,
45    TypeInfo,
46    MaxEncodedLen,
47)]
48pub enum ScheduledTask<RFM, SD, SUM> {
49    // Rent charging section.
50    // -----
51    /// Pause program as out of rent one.
52    #[codec(index = 0)]
53    PauseProgram(ActorId),
54
55    /// Remove code from code storage as out of rent one.
56    #[codec(index = 1)]
57    RemoveCode(CodeId),
58
59    /// Remove message from mailbox as out of rent one.
60    #[codec(index = 2)]
61    RemoveFromMailbox(RFM, MessageId),
62
63    /// Remove message from waitlist as out of rent one.
64    #[codec(index = 3)]
65    RemoveFromWaitlist(ActorId, MessageId),
66
67    /// Remove paused program as dead one (issue #1014).
68    #[codec(index = 4)]
69    RemovePausedProgram(ActorId),
70
71    // Time chained section.
72    // -----
73    /// Delayed wake of the message at concrete block.
74    #[codec(index = 5)]
75    WakeMessage(ActorId, MessageId),
76
77    /// Delayed message to program sending.
78    ///
79    /// The message itself stored in DispatchStash.
80    #[codec(index = 6)]
81    SendDispatch(SD),
82
83    /// Delayed message to user sending.
84    ///
85    /// The message itself stored in DispatchStash.
86    #[codec(index = 7)]
87    SendUserMessage {
88        /// What message to send.
89        message_id: MessageId,
90        /// Should it be inserted into users mailbox.
91        to_mailbox: SUM,
92    },
93
94    /// Remove gas reservation.
95    #[codec(index = 8)]
96    RemoveGasReservation(ActorId, ReservationId),
97
98    /// Remove resume program session.
99    #[codec(index = 9)]
100    #[deprecated = "Paused program storage was removed in pallet-gear-program"]
101    RemoveResumeSession(u32),
102}
103
104impl<RFM, SD, SUM> ScheduledTask<RFM, SD, SUM> {
105    /// Processing function of current task with given handler.
106    pub fn process_with(self, handler: &mut impl TaskHandler<RFM, SD, SUM>) -> Gas {
107        use ScheduledTask::*;
108
109        match self {
110            PauseProgram(program_id) => handler.pause_program(program_id),
111            RemoveCode(code_id) => handler.remove_code(code_id),
112            RemoveFromMailbox(user_id, message_id) => {
113                handler.remove_from_mailbox(user_id, message_id)
114            }
115            RemoveFromWaitlist(program_id, message_id) => {
116                handler.remove_from_waitlist(program_id, message_id)
117            }
118            RemovePausedProgram(program_id) => handler.remove_paused_program(program_id),
119            WakeMessage(program_id, message_id) => handler.wake_message(program_id, message_id),
120            SendDispatch(message_id) => handler.send_dispatch(message_id),
121            SendUserMessage {
122                message_id,
123                to_mailbox,
124            } => handler.send_user_message(message_id, to_mailbox),
125            RemoveGasReservation(program_id, reservation_id) => {
126                handler.remove_gas_reservation(program_id, reservation_id)
127            }
128            #[allow(deprecated)]
129            RemoveResumeSession(session_id) => handler.remove_resume_session(session_id),
130        }
131    }
132}
133
134/// Task handler trait for dealing with required tasks.
135pub trait TaskHandler<RFM, SD, SUM> {
136    // Rent charging section.
137    // -----
138    /// Pause program action.
139    fn pause_program(&mut self, program_id: ActorId) -> Gas;
140    /// Remove code action.
141    fn remove_code(&mut self, code_id: CodeId) -> Gas;
142    /// Remove from mailbox action.
143    fn remove_from_mailbox(&mut self, user_id: RFM, message_id: MessageId) -> Gas;
144    /// Remove from waitlist action.
145    fn remove_from_waitlist(&mut self, program_id: ActorId, message_id: MessageId) -> Gas;
146    /// Remove paused program action.
147    fn remove_paused_program(&mut self, program_id: ActorId) -> Gas;
148
149    // Time chained section.
150    // -----
151    /// Wake message action.
152    fn wake_message(&mut self, program_id: ActorId, message_id: MessageId) -> Gas;
153
154    /// Send delayed message to program action.
155    fn send_dispatch(&mut self, stashed_message_id: SD) -> Gas;
156
157    /// Send delayed message to user action.
158    fn send_user_message(&mut self, stashed_message_id: MessageId, to_mailbox: SUM) -> Gas;
159
160    /// Remove gas reservation action.
161    fn remove_gas_reservation(&mut self, program_id: ActorId, reservation_id: ReservationId)
162    -> Gas;
163
164    /// Remove data created by resume program session.
165    fn remove_resume_session(&mut self, session_id: u32) -> Gas;
166}
167
168#[test]
169fn task_encoded_size() {
170    // We will force represent task with no more then 2^8 (256) bytes.
171    const MAX_SIZE: usize = 256;
172
173    // For example we will take `AccountId` = `ActorId` from `gear_core`.
174    assert!(VaraScheduledTask::<ActorId>::max_encoded_len() <= MAX_SIZE);
175}