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, MessageId, ReservationId};
22use gsys::Gas;
23use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
24use scale_decode::DecodeAsType;
25use scale_encode::EncodeAsType;
26use scale_info::TypeInfo;
27
28/// Alias for ScheduledTask used in vara-runtime, generic across AccountId used.
29pub type VaraScheduledTask<AccountId> = ScheduledTask<AccountId, MessageId, bool>;
30
31/// Scheduled task sense and required data for processing action.
32///
33/// CAUTION: NEVER ALLOW `ScheduledTask` BE A BIG DATA.
34/// To avoid redundant migrations only append new variant(s) to the enum
35/// with an explicit corresponding scale codec index.
36#[derive(
37    Copy,
38    Clone,
39    Debug,
40    Eq,
41    PartialEq,
42    PartialOrd,
43    Ord,
44    Hash,
45    Encode,
46    EncodeAsType,
47    Decode,
48    DecodeAsType,
49    TypeInfo,
50    MaxEncodedLen,
51)]
52pub enum ScheduledTask<RFM, SD, SUM> {
53    /// Remove message from mailbox as out of rent one.
54    RemoveFromMailbox(RFM, MessageId),
55
56    /// Remove message from waitlist as out of rent one.
57    RemoveFromWaitlist(ActorId, MessageId),
58
59    // Time chained section.
60    // -----
61    /// Delayed wake of the message at concrete block.
62    WakeMessage(ActorId, MessageId),
63
64    /// Delayed message to program sending.
65    ///
66    /// The message itself stored in DispatchStash.
67    SendDispatch(SD),
68
69    /// Delayed message to user sending.
70    ///
71    /// The message itself stored in DispatchStash.
72    SendUserMessage {
73        /// What message to send.
74        message_id: MessageId,
75        /// Should it be inserted into users mailbox.
76        to_mailbox: SUM,
77    },
78
79    /// Remove gas reservation.
80    RemoveGasReservation(ActorId, ReservationId),
81}
82
83impl<RFM, SD, SUM> ScheduledTask<RFM, SD, SUM> {
84    /// Processing function of current task with given handler.
85    pub fn process_with(self, handler: &mut impl TaskHandler<RFM, SD, SUM>) -> Gas {
86        use ScheduledTask::*;
87
88        match self {
89            RemoveFromMailbox(user_id, message_id) => {
90                handler.remove_from_mailbox(user_id, message_id)
91            }
92            RemoveFromWaitlist(program_id, message_id) => {
93                handler.remove_from_waitlist(program_id, message_id)
94            }
95            WakeMessage(program_id, message_id) => handler.wake_message(program_id, message_id),
96            SendDispatch(message_id) => handler.send_dispatch(message_id),
97            SendUserMessage {
98                message_id,
99                to_mailbox,
100            } => handler.send_user_message(message_id, to_mailbox),
101            RemoveGasReservation(program_id, reservation_id) => {
102                handler.remove_gas_reservation(program_id, reservation_id)
103            }
104        }
105    }
106}
107
108/// Task handler trait for dealing with required tasks.
109pub trait TaskHandler<RFM, SD, SUM> {
110    // Rent charging section.
111    // -----
112    /// Remove from mailbox action.
113    fn remove_from_mailbox(&mut self, user_id: RFM, message_id: MessageId) -> Gas;
114    /// Remove from waitlist action.
115    fn remove_from_waitlist(&mut self, program_id: ActorId, message_id: MessageId) -> Gas;
116
117    // Time chained section.
118    // -----
119    /// Wake message action.
120    fn wake_message(&mut self, program_id: ActorId, message_id: MessageId) -> Gas;
121
122    /// Send delayed message to program action.
123    fn send_dispatch(&mut self, stashed_message_id: SD) -> Gas;
124
125    /// Send delayed message to user action.
126    fn send_user_message(&mut self, stashed_message_id: MessageId, to_mailbox: SUM) -> Gas;
127
128    /// Remove gas reservation action.
129    fn remove_gas_reservation(&mut self, program_id: ActorId, reservation_id: ReservationId)
130    -> Gas;
131}
132
133#[test]
134fn task_encoded_size() {
135    // We will force represent task with no more then 2^8 (256) bytes.
136    const MAX_SIZE: usize = 256;
137
138    // For example we will take `AccountId` = `ActorId` from `gear_core`.
139    assert!(VaraScheduledTask::<ActorId>::max_encoded_len() <= MAX_SIZE);
140}