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}