1use crate::{
7 buffer::PayloadSlice,
8 env_vars::EnvVars,
9 ids::{ActorId, MessageId, ReservationId},
10 memory::Memory,
11 message::{DispatchKind, HandlePacket, InitPacket, MessageContext, ReplyPacket},
12 pages::WasmPage,
13};
14use alloc::{collections::BTreeSet, string::String};
15use core::fmt::Display;
16use gear_core_errors::{ReplyCode, SignalCode};
17use gear_wasm_instrument::syscalls::SyscallName;
18use parity_scale_codec::{Decode, Encode};
19use scale_decode::DecodeAsType;
20use scale_encode::EncodeAsType;
21use scale_info::TypeInfo;
22
23pub trait Externalities {
27 type UnrecoverableError;
29
30 type FallibleError;
32
33 type AllocError: Display;
35
36 fn alloc<Context>(
40 &mut self,
41 ctx: &mut Context,
42 mem: &mut impl Memory<Context>,
43 pages_num: u32,
44 ) -> Result<WasmPage, Self::AllocError>;
45
46 fn free(&mut self, page: WasmPage) -> Result<(), Self::AllocError>;
48
49 fn free_range(&mut self, start: WasmPage, end: WasmPage) -> Result<(), Self::AllocError>;
51
52 fn env_vars(&self, version: u32) -> Result<EnvVars, Self::UnrecoverableError>;
55
56 fn block_height(&self) -> Result<u32, Self::UnrecoverableError>;
58
59 fn block_timestamp(&self) -> Result<u64, Self::UnrecoverableError>;
61
62 fn send_init(&mut self) -> Result<u32, Self::FallibleError>;
64
65 fn send_push(&mut self, handle: u32, buffer: &[u8]) -> Result<(), Self::FallibleError>;
67
68 fn send_commit(
70 &mut self,
71 handle: u32,
72 msg: HandlePacket,
73 delay: u32,
74 ) -> Result<MessageId, Self::FallibleError>;
75
76 fn send(&mut self, msg: HandlePacket, delay: u32) -> Result<MessageId, Self::FallibleError> {
78 let handle = self.send_init()?;
79 self.send_commit(handle, msg, delay)
80 }
81
82 fn send_push_input(
84 &mut self,
85 handle: u32,
86 offset: u32,
87 len: u32,
88 ) -> Result<(), Self::FallibleError>;
89
90 fn reservation_send_commit(
92 &mut self,
93 id: ReservationId,
94 handle: u32,
95 msg: HandlePacket,
96 delay: u32,
97 ) -> Result<MessageId, Self::FallibleError>;
98
99 fn reservation_send(
101 &mut self,
102 id: ReservationId,
103 msg: HandlePacket,
104 delay: u32,
105 ) -> Result<MessageId, Self::FallibleError> {
106 let handle = self.send_init()?;
107 self.reservation_send_commit(id, handle, msg, delay)
108 }
109
110 fn reply_push(&mut self, buffer: &[u8]) -> Result<(), Self::FallibleError>;
112
113 fn reply_commit(&mut self, msg: ReplyPacket) -> Result<MessageId, Self::FallibleError>;
115
116 fn reservation_reply_commit(
118 &mut self,
119 id: ReservationId,
120 msg: ReplyPacket,
121 ) -> Result<MessageId, Self::FallibleError>;
122
123 fn reply(&mut self, msg: ReplyPacket) -> Result<MessageId, Self::FallibleError> {
125 self.reply_commit(msg)
126 }
127
128 fn reservation_reply(
130 &mut self,
131 id: ReservationId,
132 msg: ReplyPacket,
133 ) -> Result<MessageId, Self::FallibleError> {
134 self.reservation_reply_commit(id, msg)
135 }
136
137 fn reply_to(&self) -> Result<MessageId, Self::FallibleError>;
139
140 fn signal_from(&self) -> Result<MessageId, Self::FallibleError>;
142
143 fn reply_push_input(&mut self, offset: u32, len: u32) -> Result<(), Self::FallibleError>;
145
146 fn source(&self) -> Result<ActorId, Self::UnrecoverableError>;
148
149 fn reply_code(&self) -> Result<ReplyCode, Self::FallibleError>;
151
152 fn signal_code(&self) -> Result<SignalCode, Self::FallibleError>;
154
155 fn message_id(&self) -> Result<MessageId, Self::UnrecoverableError>;
157
158 fn program_id(&self) -> Result<ActorId, Self::UnrecoverableError>;
160
161 fn debug(&self, data: &str) -> Result<(), Self::UnrecoverableError>;
165
166 fn payload_slice(&mut self, at: u32, len: u32) -> Result<PayloadSlice, Self::FallibleError>;
168
169 fn size(&self) -> Result<usize, Self::UnrecoverableError>;
171
172 fn random(&self) -> Result<(&[u8], u32), Self::UnrecoverableError>;
174
175 fn reserve_gas(
177 &mut self,
178 amount: u64,
179 duration: u32,
180 ) -> Result<ReservationId, Self::FallibleError>;
181
182 fn unreserve_gas(&mut self, id: ReservationId) -> Result<u64, Self::FallibleError>;
184
185 fn system_reserve_gas(&mut self, amount: u64) -> Result<(), Self::FallibleError>;
187
188 fn gas_available(&self) -> Result<u64, Self::UnrecoverableError>;
190
191 fn value(&self) -> Result<u128, Self::UnrecoverableError>;
193
194 fn value_available(&self) -> Result<u128, Self::UnrecoverableError>;
196
197 fn wait(&mut self) -> Result<(), Self::UnrecoverableError>;
199
200 fn wait_for(&mut self, duration: u32) -> Result<(), Self::UnrecoverableError>;
202
203 fn wait_up_to(&mut self, duration: u32) -> Result<bool, Self::UnrecoverableError>;
206
207 fn wake(&mut self, waker_id: MessageId, delay: u32) -> Result<(), Self::FallibleError>;
209
210 fn create_program(
212 &mut self,
213 packet: InitPacket,
214 delay: u32,
215 ) -> Result<(MessageId, ActorId), Self::FallibleError>;
216
217 fn reply_deposit(
219 &mut self,
220 message_id: MessageId,
221 amount: u64,
222 ) -> Result<(), Self::FallibleError>;
223
224 fn forbidden_funcs(&self) -> &BTreeSet<SyscallName>;
226
227 fn msg_ctx(&self) -> &MessageContext;
229}
230
231#[derive(
233 Debug,
234 Encode,
235 EncodeAsType,
236 Decode,
237 DecodeAsType,
238 Clone,
239 PartialEq,
240 Eq,
241 PartialOrd,
242 Ord,
243 TypeInfo,
244)]
245pub enum MessageWaitedType {
246 Wait,
248 WaitFor,
250 WaitUpTo,
253 WaitUpToFull,
256}
257
258pub trait WasmEntryPoint: Sized {
260 fn as_entry(&self) -> &str;
262
263 fn try_from_entry(entry: &str) -> Option<Self>;
265
266 fn try_into_kind(&self) -> Option<DispatchKind> {
268 <DispatchKind as WasmEntryPoint>::try_from_entry(self.as_entry())
269 }
270}
271
272impl WasmEntryPoint for String {
273 fn as_entry(&self) -> &str {
274 self
275 }
276
277 fn try_from_entry(entry: &str) -> Option<Self> {
278 Some(entry.into())
279 }
280}
281
282impl WasmEntryPoint for DispatchKind {
283 fn as_entry(&self) -> &str {
284 match self {
285 Self::Init => "init",
286 Self::Handle => "handle",
287 Self::Reply => "handle_reply",
288 Self::Signal => "handle_signal",
289 }
290 }
291
292 fn try_from_entry(entry: &str) -> Option<Self> {
293 let kind = match entry {
294 "init" => Self::Init,
295 "handle" => Self::Handle,
296 "handle_reply" => Self::Reply,
297 "handle_signal" => Self::Signal,
298 _ => return None,
299 };
300
301 Some(kind)
302 }
303}