1use crate::{
22 buffer::PayloadSlice,
23 env_vars::EnvVars,
24 ids::{ActorId, MessageId, ReservationId},
25 memory::Memory,
26 message::{DispatchKind, HandlePacket, InitPacket, MessageContext, ReplyPacket},
27 pages::WasmPage,
28};
29use alloc::{collections::BTreeSet, string::String};
30use core::fmt::Display;
31use gear_core_errors::{ReplyCode, SignalCode};
32use gear_wasm_instrument::syscalls::SyscallName;
33use parity_scale_codec::{Decode, Encode};
34use scale_decode::DecodeAsType;
35use scale_encode::EncodeAsType;
36use scale_info::TypeInfo;
37
38pub trait Externalities {
42 type UnrecoverableError;
44
45 type FallibleError;
47
48 type AllocError: Display;
50
51 fn alloc<Context>(
55 &mut self,
56 ctx: &mut Context,
57 mem: &mut impl Memory<Context>,
58 pages_num: u32,
59 ) -> Result<WasmPage, Self::AllocError>;
60
61 fn free(&mut self, page: WasmPage) -> Result<(), Self::AllocError>;
63
64 fn free_range(&mut self, start: WasmPage, end: WasmPage) -> Result<(), Self::AllocError>;
66
67 fn env_vars(&self, version: u32) -> Result<EnvVars, Self::UnrecoverableError>;
70
71 fn block_height(&self) -> Result<u32, Self::UnrecoverableError>;
73
74 fn block_timestamp(&self) -> Result<u64, Self::UnrecoverableError>;
76
77 fn send_init(&mut self) -> Result<u32, Self::FallibleError>;
79
80 fn send_push(&mut self, handle: u32, buffer: &[u8]) -> Result<(), Self::FallibleError>;
82
83 fn send_commit(
85 &mut self,
86 handle: u32,
87 msg: HandlePacket,
88 delay: u32,
89 ) -> Result<MessageId, Self::FallibleError>;
90
91 fn send(&mut self, msg: HandlePacket, delay: u32) -> Result<MessageId, Self::FallibleError> {
93 let handle = self.send_init()?;
94 self.send_commit(handle, msg, delay)
95 }
96
97 fn send_push_input(
99 &mut self,
100 handle: u32,
101 offset: u32,
102 len: u32,
103 ) -> Result<(), Self::FallibleError>;
104
105 fn reservation_send_commit(
107 &mut self,
108 id: ReservationId,
109 handle: u32,
110 msg: HandlePacket,
111 delay: u32,
112 ) -> Result<MessageId, Self::FallibleError>;
113
114 fn reservation_send(
116 &mut self,
117 id: ReservationId,
118 msg: HandlePacket,
119 delay: u32,
120 ) -> Result<MessageId, Self::FallibleError> {
121 let handle = self.send_init()?;
122 self.reservation_send_commit(id, handle, msg, delay)
123 }
124
125 fn reply_push(&mut self, buffer: &[u8]) -> Result<(), Self::FallibleError>;
127
128 fn reply_commit(&mut self, msg: ReplyPacket) -> Result<MessageId, Self::FallibleError>;
130
131 fn reservation_reply_commit(
133 &mut self,
134 id: ReservationId,
135 msg: ReplyPacket,
136 ) -> Result<MessageId, Self::FallibleError>;
137
138 fn reply(&mut self, msg: ReplyPacket) -> Result<MessageId, Self::FallibleError> {
140 self.reply_commit(msg)
141 }
142
143 fn reservation_reply(
145 &mut self,
146 id: ReservationId,
147 msg: ReplyPacket,
148 ) -> Result<MessageId, Self::FallibleError> {
149 self.reservation_reply_commit(id, msg)
150 }
151
152 fn reply_to(&self) -> Result<MessageId, Self::FallibleError>;
154
155 fn signal_from(&self) -> Result<MessageId, Self::FallibleError>;
157
158 fn reply_push_input(&mut self, offset: u32, len: u32) -> Result<(), Self::FallibleError>;
160
161 fn source(&self) -> Result<ActorId, Self::UnrecoverableError>;
163
164 fn reply_code(&self) -> Result<ReplyCode, Self::FallibleError>;
166
167 fn signal_code(&self) -> Result<SignalCode, Self::FallibleError>;
169
170 fn message_id(&self) -> Result<MessageId, Self::UnrecoverableError>;
172
173 fn program_id(&self) -> Result<ActorId, Self::UnrecoverableError>;
175
176 fn debug(&self, data: &str) -> Result<(), Self::UnrecoverableError>;
180
181 fn payload_slice(&mut self, at: u32, len: u32) -> Result<PayloadSlice, Self::FallibleError>;
183
184 fn size(&self) -> Result<usize, Self::UnrecoverableError>;
186
187 fn random(&self) -> Result<(&[u8], u32), Self::UnrecoverableError>;
189
190 fn reserve_gas(
192 &mut self,
193 amount: u64,
194 duration: u32,
195 ) -> Result<ReservationId, Self::FallibleError>;
196
197 fn unreserve_gas(&mut self, id: ReservationId) -> Result<u64, Self::FallibleError>;
199
200 fn system_reserve_gas(&mut self, amount: u64) -> Result<(), Self::FallibleError>;
202
203 fn gas_available(&self) -> Result<u64, Self::UnrecoverableError>;
205
206 fn value(&self) -> Result<u128, Self::UnrecoverableError>;
208
209 fn value_available(&self) -> Result<u128, Self::UnrecoverableError>;
211
212 fn wait(&mut self) -> Result<(), Self::UnrecoverableError>;
214
215 fn wait_for(&mut self, duration: u32) -> Result<(), Self::UnrecoverableError>;
217
218 fn wait_up_to(&mut self, duration: u32) -> Result<bool, Self::UnrecoverableError>;
221
222 fn wake(&mut self, waker_id: MessageId, delay: u32) -> Result<(), Self::FallibleError>;
224
225 fn create_program(
227 &mut self,
228 packet: InitPacket,
229 delay: u32,
230 ) -> Result<(MessageId, ActorId), Self::FallibleError>;
231
232 fn reply_deposit(
234 &mut self,
235 message_id: MessageId,
236 amount: u64,
237 ) -> Result<(), Self::FallibleError>;
238
239 fn forbidden_funcs(&self) -> &BTreeSet<SyscallName>;
241
242 fn msg_ctx(&self) -> &MessageContext;
244}
245
246#[derive(
248 Debug,
249 Encode,
250 EncodeAsType,
251 Decode,
252 DecodeAsType,
253 Clone,
254 PartialEq,
255 Eq,
256 PartialOrd,
257 Ord,
258 TypeInfo,
259)]
260pub enum MessageWaitedType {
261 Wait,
263 WaitFor,
265 WaitUpTo,
268 WaitUpToFull,
271}
272
273pub trait WasmEntryPoint: Sized {
275 fn as_entry(&self) -> &str;
277
278 fn try_from_entry(entry: &str) -> Option<Self>;
280
281 fn try_into_kind(&self) -> Option<DispatchKind> {
283 <DispatchKind as WasmEntryPoint>::try_from_entry(self.as_entry())
284 }
285}
286
287impl WasmEntryPoint for String {
288 fn as_entry(&self) -> &str {
289 self
290 }
291
292 fn try_from_entry(entry: &str) -> Option<Self> {
293 Some(entry.into())
294 }
295}
296
297impl WasmEntryPoint for DispatchKind {
298 fn as_entry(&self) -> &str {
299 match self {
300 Self::Init => "init",
301 Self::Handle => "handle",
302 Self::Reply => "handle_reply",
303 Self::Signal => "handle_signal",
304 }
305 }
306
307 fn try_from_entry(entry: &str) -> Option<Self> {
308 let kind = match entry {
309 "init" => Self::Init,
310 "handle" => Self::Handle,
311 "handle_reply" => Self::Reply,
312 "handle_signal" => Self::Signal,
313 _ => return None,
314 };
315
316 Some(kind)
317 }
318}