sails_rs/gstd/
syscalls.rs1use crate::prelude::*;
2
3pub struct Syscall;
19
20#[cfg(target_arch = "wasm32")]
21impl Syscall {
22 pub fn message_id() -> MessageId {
23 gstd::msg::id()
24 }
25
26 pub fn message_size() -> usize {
27 gstd::msg::size()
28 }
29
30 pub fn message_source() -> ActorId {
31 gstd::msg::source()
32 }
33
34 pub fn message_value() -> u128 {
35 gstd::msg::value()
36 }
37
38 pub fn reply_to() -> Result<MessageId, gcore::errors::Error> {
39 gstd::msg::reply_to()
40 }
41
42 pub fn reply_code() -> Result<ReplyCode, gcore::errors::Error> {
43 gstd::msg::reply_code()
44 }
45
46 #[cfg(not(feature = "ethexe"))]
47 pub fn signal_from() -> Result<MessageId, gcore::errors::Error> {
48 gstd::msg::signal_from()
49 }
50
51 #[cfg(not(feature = "ethexe"))]
52 pub fn signal_code() -> Result<Option<SignalCode>, gcore::errors::Error> {
53 gstd::msg::signal_code()
54 }
55
56 pub fn program_id() -> ActorId {
57 gstd::exec::program_id()
58 }
59
60 pub fn block_height() -> u32 {
61 gstd::exec::block_height()
62 }
63
64 pub fn block_timestamp() -> u64 {
65 gstd::exec::block_timestamp()
66 }
67
68 pub fn value_available() -> u128 {
69 gstd::exec::value_available()
70 }
71
72 pub fn env_vars() -> gstd::EnvVars {
73 gstd::exec::env_vars()
74 }
75
76 pub fn exit(inheritor_id: ActorId) -> ! {
77 gstd::exec::exit(inheritor_id)
78 }
79}
80
81#[cfg(not(target_arch = "wasm32"))]
82#[cfg(not(feature = "std"))]
83macro_rules! syscall_unimplemented {
84 ($($name:ident() -> $type:ty),* $(,)?) => {
85 impl Syscall {
86 $(
87 pub fn $name() -> $type {
88 unimplemented!("{ERROR}")
89 }
90 )*
91 }
92 };
93}
94
95#[cfg(not(target_arch = "wasm32"))]
96#[cfg(not(feature = "std"))]
97const ERROR: &str = "Syscall is implemented only for the wasm32 architecture and the std future";
98
99#[cfg(not(target_arch = "wasm32"))]
100#[cfg(not(feature = "std"))]
101syscall_unimplemented!(
102 message_id() -> MessageId,
103 message_size() -> usize,
104 message_source() -> ActorId,
105 message_value() -> u128,
106 reply_to() -> Result<MessageId, gcore::errors::Error>,
107 reply_code() -> Result<ReplyCode, gcore::errors::Error>,
108 signal_from() -> Result<MessageId, gcore::errors::Error>,
109 signal_code() -> Result<Option<SignalCode>, gcore::errors::Error>,
110 program_id() -> ActorId,
111 block_height() -> u32,
112 block_timestamp() -> u64,
113 value_available() -> u128,
114 env_vars() -> gstd::EnvVars,
115);
116
117#[cfg(not(target_arch = "wasm32"))]
118#[cfg(not(feature = "std"))]
119impl Syscall {
120 pub fn exit(_inheritor_id: ActorId) -> ! {
121 unimplemented!("{ERROR}")
122 }
123}
124
125#[cfg(not(target_arch = "wasm32"))]
126#[cfg(feature = "std")]
127const _: () = {
128 use core::cell::RefCell;
129 use paste::paste;
130 use std::thread_local;
131
132 macro_rules! syscall_struct_impl {
133 ($($name:ident() -> $type:ty),* $(,)?) => {
134 #[derive(Clone)]
135 struct SyscallState {
136 $(
137 $name: $type,
138 )*
139 }
140
141 thread_local! {
142 static SYSCALL_STATE: RefCell<SyscallState> = RefCell::new(SyscallState::default());
143 }
144
145 impl Syscall {
146 $(
147 pub fn $name() -> $type {
148 SYSCALL_STATE.with_borrow(|state| state.$name.clone())
149 }
150 )*
151 }
152
153 impl Syscall {
154 $(
155 paste! {
156 pub fn [<with_ $name>]($name: $type) {
157 SYSCALL_STATE.with_borrow_mut(|state| state.$name = $name);
158 }
159 }
160 )*
161 }
162 };
163 }
164
165 syscall_struct_impl!(
166 message_id() -> MessageId,
167 message_size() -> usize,
168 message_source() -> ActorId,
169 message_value() -> u128,
170 reply_to() -> Result<MessageId, gcore::errors::Error>,
171 reply_code() -> Result<ReplyCode, gcore::errors::Error>,
172 signal_from() -> Result<MessageId, gcore::errors::Error>,
173 signal_code() -> Result<Option<SignalCode>, gcore::errors::Error>,
174 program_id() -> ActorId,
175 block_height() -> u32,
176 block_timestamp() -> u64,
177 value_available() -> u128,
178 );
179
180 impl Default for SyscallState {
181 fn default() -> Self {
182 use gear_core_errors::{ExecutionError, ExtError};
183
184 Self {
185 message_id: MessageId::default(),
186 message_size: 0,
187 message_source: ActorId::default(),
188 message_value: 0,
189 reply_to: Err(ExtError::Execution(ExecutionError::NoReplyContext).into()),
190 reply_code: Err(ExtError::Execution(ExecutionError::NoReplyContext).into()),
191 signal_from: Err(ExtError::Execution(ExecutionError::NoSignalContext).into()),
192 signal_code: Err(ExtError::Execution(ExecutionError::NoSignalContext).into()),
193 program_id: ActorId::default(),
194 block_height: 0,
195 block_timestamp: 0,
196 value_available: 0,
197 }
198 }
199 }
200
201 impl Syscall {
202 pub fn env_vars() -> gstd::EnvVars {
203 gstd::EnvVars {
204 performance_multiplier: gstd::Percent::new(100),
205 existential_deposit: 1_000_000_000_000,
206 mailbox_threshold: 3000,
207 gas_multiplier: gstd::GasMultiplier::from_value_per_gas(100),
208 }
209 }
210
211 pub fn exit(inheritor_id: ActorId) -> ! {
212 panic!("Program exited with inheritor id: {}", inheritor_id);
213 }
214 }
215};