Skip to main content

gear_core/
tasks.rs

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