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
// 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/>.
use crate::{common::errors::Result, ActorId, MessageId};
/// Provide gas deposit from current message to handle reply message on given
/// message id.
///
/// This message id should be sent within the execution. Once destination actor
/// or system sends reply on it, the gas limit ignores, if the program gave
/// deposit - the only it will be used for execution of `handle_reply`.
///
/// # Examples
///
/// ```
/// use gcore::{exec, msg};
///
/// #[no_mangle]
/// extern "C" fn handle() {
/// let message_id =
/// msg::send(msg::source(), b"Outgoing message", 0).expect("Failed to send message");
///
/// exec::reply_deposit(message_id, 100_000).expect("Failed to deposit reply");
/// }
///
/// #[no_mangle]
/// extern "C" fn handle_reply() {
/// // I will be executed for pre-defined (deposited) 100_000 of gas!
/// }
/// ```
pub fn reply_deposit(message_id: MessageId, amount: u64) -> Result<()> {
gcore::exec::reply_deposit(message_id.into(), amount).map_err(Into::into)
}
/// Terminate the execution of a program.
///
/// The program and all corresponding data are removed from the storage. It may
/// be called in the `init` method as well. One can consider this function as
/// some analog of `std::process::exit`.
///
/// `inheritor_id` specifies the address to which all available program value
/// should be transferred.
///
/// # Examples
///
/// Terminate the program and transfer the available value to the message
/// sender:
///
/// ```
/// use gstd::{exec, msg};
///
/// #[no_mangle]
/// extern "C" fn handle() {
/// // ...
/// exec::exit(msg::source());
/// }
/// ```
pub fn exit(inheritor_id: ActorId) -> ! {
gcore::exec::exit(inheritor_id.into())
}
/// Resume previously paused message handling.
///
/// Suppose a message has been paused using the [`crate::exec::wait`] function,
/// it is possible to continue its execution by calling this function.
///
/// `message_id` specifies a particular message to be taken out of the *waiting
/// queue* and put into the *processing queue*.
///
/// # Examples
///
/// ```
/// use gstd::{exec, msg, MessageId};
///
/// static mut MSG_ID: MessageId = MessageId::zero();
///
/// #[no_mangle]
/// extern "C" fn init() {
/// unsafe { MSG_ID = msg::id() };
/// exec::wait();
/// }
///
/// #[no_mangle]
/// extern "C" fn handle() {
/// exec::wake(unsafe { MSG_ID }).expect("Unable to wake");
/// }
/// ```
pub fn wake(message_id: MessageId) -> Result<()> {
wake_delayed(message_id, 0)
}
/// Same as [`wake`], but executes after the `delay` expressed in block count.
pub fn wake_delayed(message_id: MessageId, delay: u32) -> Result<()> {
gcore::exec::wake_delayed(message_id.into(), delay).map_err(Into::into)
}
/// Return the identifier of the current program.
///
/// # Examples
///
/// ```
/// use gstd::exec;
///
/// #[no_mangle]
/// extern "C" fn handle() {
/// let whoami = exec::program_id();
/// }
/// ```
pub fn program_id() -> ActorId {
gcore::exec::program_id().into()
}