mod common;
mod context;
mod handle;
mod incoming;
mod init;
mod reply;
mod signal;
mod stored;
mod user;
pub use common::{Dispatch, Message, MessageDetails, ReplyDetails, SignalDetails};
pub use context::{
ContextOutcome, ContextOutcomeDrain, ContextSettings, ContextStore, MessageContext,
};
pub use gear_core_errors::{ErrorReplyReason, ReplyCode, SuccessReplyReason};
pub use handle::{HandleMessage, HandlePacket};
pub use incoming::{IncomingDispatch, IncomingMessage};
pub use init::{InitMessage, InitPacket};
pub use reply::{ReplyMessage, ReplyPacket};
pub use signal::SignalMessage;
pub use stored::{StoredDelayedDispatch, StoredDispatch, StoredMessage};
pub use user::{UserMessage, UserStoredMessage};
use super::buffer::LimitedVec;
use alloc::{collections::BTreeSet, string::String, vec::Vec};
use core::fmt::Display;
use gear_wasm_instrument::syscalls::SyscallName;
use scale_info::{
scale::{Decode, Encode},
TypeInfo,
};
pub const MAX_PAYLOAD_SIZE: usize = 8 * 1024 * 1024;
const _: () = assert!(MAX_PAYLOAD_SIZE <= u32::MAX as usize);
#[derive(
Clone, Copy, Default, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Decode, Encode, TypeInfo,
)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
pub struct PayloadSizeError;
impl From<PayloadSizeError> for &str {
fn from(_: PayloadSizeError) -> Self {
"Payload size limit exceeded"
}
}
impl Display for PayloadSizeError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str((*self).into())
}
}
pub type Payload = LimitedVec<u8, PayloadSizeError, MAX_PAYLOAD_SIZE>;
impl Payload {
pub fn len_u32(&self) -> u32 {
self.inner().len() as u32
}
}
pub type GasLimit = u64;
pub type Value = u128;
pub type Salt = LimitedVec<u8, PayloadSizeError, MAX_PAYLOAD_SIZE>;
#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, PartialOrd, Ord, TypeInfo)]
pub enum MessageWaitedType {
Wait,
WaitFor,
WaitUpTo,
WaitUpToFull,
}
#[derive(
Copy, Clone, Default, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Decode, Encode, TypeInfo,
)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
pub enum DispatchKind {
Init,
#[default]
Handle,
Reply,
Signal,
}
pub trait WasmEntryPoint: Sized {
fn as_entry(&self) -> &str;
fn try_from_entry(entry: &str) -> Option<Self>;
fn try_into_kind(&self) -> Option<DispatchKind> {
<DispatchKind as WasmEntryPoint>::try_from_entry(self.as_entry())
}
}
impl WasmEntryPoint for String {
fn as_entry(&self) -> &str {
self
}
fn try_from_entry(entry: &str) -> Option<Self> {
Some(entry.into())
}
}
impl WasmEntryPoint for DispatchKind {
fn as_entry(&self) -> &str {
match self {
Self::Init => "init",
Self::Handle => "handle",
Self::Reply => "handle_reply",
Self::Signal => "handle_signal",
}
}
fn try_from_entry(entry: &str) -> Option<Self> {
let kind = match entry {
"init" => Self::Init,
"handle" => Self::Handle,
"handle_reply" => Self::Reply,
"handle_signal" => Self::Signal,
_ => return None,
};
Some(kind)
}
}
impl DispatchKind {
pub fn is_init(&self) -> bool {
matches!(self, Self::Init)
}
pub fn is_handle(&self) -> bool {
matches!(self, Self::Handle)
}
pub fn is_reply(&self) -> bool {
matches!(self, Self::Reply)
}
pub fn is_signal(&self) -> bool {
matches!(self, Self::Signal)
}
pub fn forbidden_funcs(&self) -> BTreeSet<SyscallName> {
match self {
DispatchKind::Signal => [
SyscallName::Source,
SyscallName::Reply,
SyscallName::ReplyPush,
SyscallName::ReplyCommit,
SyscallName::ReplyCommitWGas,
SyscallName::ReplyInput,
SyscallName::ReplyInputWGas,
SyscallName::ReservationReply,
SyscallName::ReservationReplyCommit,
SyscallName::SystemReserveGas,
]
.into(),
_ => Default::default(),
}
}
}
pub trait Packet {
fn payload_bytes(&self) -> &[u8];
fn payload_len(&self) -> u32;
fn gas_limit(&self) -> Option<GasLimit>;
fn value(&self) -> Value;
fn kind() -> DispatchKind;
}
#[derive(Clone, Debug, Decode, Encode, PartialEq, Eq, TypeInfo)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
pub struct ReplyInfo {
#[cfg_attr(feature = "std", serde(with = "impl_serde::serialize"))]
pub payload: Vec<u8>,
pub value: u128,
pub code: ReplyCode,
}