use alloc::{collections::BTreeSet, string::String};
use scale_info::{
scale::{Decode, Encode},
TypeInfo,
};
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 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::{StoredDispatch, StoredMessage};
pub use user::{UserMessage, UserStoredMessage};
use super::buffer::LimitedVec;
use core::fmt::Display;
use gear_wasm_instrument::syscalls::SysCallName;
pub const MAX_PAYLOAD_SIZE: usize = 8 * 1024 * 1024;
static_assertions::const_assert!(MAX_PAYLOAD_SIZE <= u32::MAX as usize);
#[derive(
Clone, Copy, Default, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Decode, Encode, TypeInfo,
)]
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>;
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,
)]
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 gas_limit(&self) -> Option<GasLimit>;
fn value(&self) -> Value;
}