1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
// This file is part of Gear.
// Copyright (C) 2021-2024 Gear Technologies Inc.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//! The module provides primitives for all available regular or time-dependent tasks.
use crate::ids::{CodeId, MessageId, ProgramId, ReservationId};
use gsys::Gas;
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
/// Alias for ScheduledTask used in vara-runtime, generic across AccountId used.
pub type VaraScheduledTask<AccountId> = ScheduledTask<AccountId, MessageId, bool>;
/// Scheduled task sense and required data for processing action.
///
/// CAUTION: NEVER ALLOW `ScheduledTask` BE A BIG DATA.
/// To avoid redundant migrations only append new variant(s) to the enum
/// with an explicit corresponding scale codec index.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Encode, Decode, TypeInfo, MaxEncodedLen)]
pub enum ScheduledTask<RFM, SD, SUM> {
// Rent charging section.
// -----
/// Pause program as out of rent one.
#[codec(index = 0)]
PauseProgram(ProgramId),
/// Remove code from code storage as out of rent one.
#[codec(index = 1)]
RemoveCode(CodeId),
/// Remove message from mailbox as out of rent one.
#[codec(index = 2)]
RemoveFromMailbox(RFM, MessageId),
/// Remove message from waitlist as out of rent one.
#[codec(index = 3)]
RemoveFromWaitlist(ProgramId, MessageId),
/// Remove paused program as dead one (issue #1014).
#[codec(index = 4)]
RemovePausedProgram(ProgramId),
// Time chained section.
// -----
/// Delayed wake of the message at concrete block.
#[codec(index = 5)]
WakeMessage(ProgramId, MessageId),
/// Delayed message to program sending.
///
/// The message itself stored in DispatchStash.
#[codec(index = 6)]
SendDispatch(SD),
/// Delayed message to user sending.
///
/// The message itself stored in DispatchStash.
#[codec(index = 7)]
SendUserMessage {
/// What message to send.
message_id: MessageId,
/// Should it be inserted into users mailbox.
to_mailbox: SUM,
},
/// Remove gas reservation.
#[codec(index = 8)]
RemoveGasReservation(ProgramId, ReservationId),
/// Remove resume program session.
#[codec(index = 9)]
#[deprecated = "Paused program storage was removed in pallet-gear-program"]
RemoveResumeSession(u32),
}
impl<RFM, SD, SUM> ScheduledTask<RFM, SD, SUM> {
/// Processing function of current task with given handler.
pub fn process_with(self, handler: &mut impl TaskHandler<RFM, SD, SUM>) -> Gas {
use ScheduledTask::*;
match self {
PauseProgram(program_id) => handler.pause_program(program_id),
RemoveCode(code_id) => handler.remove_code(code_id),
RemoveFromMailbox(user_id, message_id) => {
handler.remove_from_mailbox(user_id, message_id)
}
RemoveFromWaitlist(program_id, message_id) => {
handler.remove_from_waitlist(program_id, message_id)
}
RemovePausedProgram(program_id) => handler.remove_paused_program(program_id),
WakeMessage(program_id, message_id) => handler.wake_message(program_id, message_id),
SendDispatch(message_id) => handler.send_dispatch(message_id),
SendUserMessage {
message_id,
to_mailbox,
} => handler.send_user_message(message_id, to_mailbox),
RemoveGasReservation(program_id, reservation_id) => {
handler.remove_gas_reservation(program_id, reservation_id)
}
#[allow(deprecated)]
RemoveResumeSession(session_id) => handler.remove_resume_session(session_id),
}
}
}
/// Task handler trait for dealing with required tasks.
pub trait TaskHandler<RFM, SD, SUM> {
// Rent charging section.
// -----
/// Pause program action.
fn pause_program(&mut self, program_id: ProgramId) -> Gas;
/// Remove code action.
fn remove_code(&mut self, code_id: CodeId) -> Gas;
/// Remove from mailbox action.
fn remove_from_mailbox(&mut self, user_id: RFM, message_id: MessageId) -> Gas;
/// Remove from waitlist action.
fn remove_from_waitlist(&mut self, program_id: ProgramId, message_id: MessageId) -> Gas;
/// Remove paused program action.
fn remove_paused_program(&mut self, program_id: ProgramId) -> Gas;
// Time chained section.
// -----
/// Wake message action.
fn wake_message(&mut self, program_id: ProgramId, message_id: MessageId) -> Gas;
/// Send delayed message to program action.
fn send_dispatch(&mut self, stashed_message_id: SD) -> Gas;
/// Send delayed message to user action.
fn send_user_message(&mut self, stashed_message_id: MessageId, to_mailbox: SUM) -> Gas;
/// Remove gas reservation action.
fn remove_gas_reservation(
&mut self,
program_id: ProgramId,
reservation_id: ReservationId,
) -> Gas;
/// Remove data created by resume program session.
fn remove_resume_session(&mut self, session_id: u32) -> Gas;
}
#[test]
fn task_encoded_size() {
// We will force represent task with no more then 2^8 (256) bytes.
const MAX_SIZE: usize = 256;
// For example we will take `AccountId` = `ProgramId` from `gear_core`.
assert!(VaraScheduledTask::<ProgramId>::max_encoded_len() <= MAX_SIZE);
}