ab_contracts_common/
env.rs1use crate::method::{ExternalArgs, MethodFingerprint};
2use crate::{Address, ContractError, ShardIndex};
3use ab_contracts_io_type::trivial_type::TrivialType;
4use core::ffi::c_void;
5use core::marker::PhantomData;
6use core::ptr::NonNull;
7
8pub type Blake3Hash = [u8; 32];
10
11#[derive(Debug, Copy, Clone, Eq, PartialEq, TrivialType)]
22#[repr(u8)]
23pub enum MethodContext {
24 Keep,
26 Reset,
28 Replace,
30}
31
32#[derive(Debug)]
34#[repr(C)]
35#[must_use]
36pub struct PreparedMethod<'a> {
37 pub contract: Address,
39 pub fingerprint: MethodFingerprint,
41 pub external_args: NonNull<NonNull<c_void>>,
44 pub method_context: MethodContext,
46 pub phantom: PhantomData<&'a ()>,
48}
49
50#[derive(Debug, Copy, Clone, TrivialType)]
52#[repr(C)]
53pub struct EnvState {
54 pub shard_index: ShardIndex,
56 pub padding_0: [u8; 4],
58 pub own_address: Address,
60 pub context: Address,
62 pub caller: Address,
64}
65
66#[cfg(feature = "executor")]
68pub trait ExecutorContext: core::fmt::Debug {
69 fn call(
71 &self,
72 previous_env_state: &EnvState,
73 prepared_methods: &mut PreparedMethod<'_>,
74 ) -> Result<(), ContractError>;
75}
76
77#[cfg(all(feature = "executor", feature = "guest", not(any(doc, unix, windows))))]
78compile_error!(
79 "`executor` and `guest` features are mutually exclusive due to it affecting `Env` layout"
80);
81
82#[derive(Debug)]
87#[repr(C)]
88pub struct Env<'a> {
89 state: EnvState,
90 #[cfg(feature = "executor")]
91 executor_context: &'a mut dyn ExecutorContext,
92 phantom_data: PhantomData<&'a ()>,
93}
94
95impl<'a> Env<'a> {
99 #[cfg(feature = "executor")]
101 #[inline(always)]
102 #[cfg_attr(feature = "no-panic", no_panic::no_panic)]
103 pub fn with_executor_context(
104 state: EnvState,
105 executor_context: &'a mut dyn ExecutorContext,
106 ) -> Self {
107 Self {
108 state,
109 executor_context,
110 phantom_data: PhantomData,
111 }
112 }
113
114 #[cfg(feature = "executor")]
116 #[inline(always)]
117 #[cfg_attr(feature = "no-panic", no_panic::no_panic)]
118 pub fn get_mut_executor_context(&mut self) -> &mut dyn ExecutorContext {
119 self.executor_context
120 }
121
122 #[inline(always)]
124 #[cfg_attr(feature = "no-panic", no_panic::no_panic)]
125 pub fn shard_index(&self) -> ShardIndex {
126 self.state.shard_index
127 }
128
129 #[inline(always)]
131 #[cfg_attr(feature = "no-panic", no_panic::no_panic)]
132 pub fn own_address(&self) -> Address {
133 self.state.own_address
134 }
135
136 #[inline(always)]
138 #[cfg_attr(feature = "no-panic", no_panic::no_panic)]
139 pub fn context<'b>(self: &'b &'b mut Self) -> Address {
140 self.state.context
141 }
142
143 #[inline(always)]
145 #[cfg_attr(feature = "no-panic", no_panic::no_panic)]
146 pub fn caller<'b>(self: &'b &'b mut Self) -> Address {
147 self.state.caller
148 }
149
150 #[inline(always)]
154 pub fn call<Args>(
155 &self,
156 contract: Address,
157 args: &mut Args,
158 method_context: MethodContext,
159 ) -> Result<(), ContractError>
160 where
161 Args: ExternalArgs,
162 {
163 let prepared_method = Self::prepare_method_call(contract, args, method_context);
164 self.call_prepared(prepared_method)
165 }
166
167 #[inline(always)]
171 #[cfg_attr(feature = "no-panic", no_panic::no_panic)]
172 pub fn prepare_method_call<Args>(
173 contract: Address,
174 args: &mut Args,
175 method_context: MethodContext,
176 ) -> PreparedMethod<'_>
177 where
178 Args: ExternalArgs,
179 {
180 PreparedMethod {
181 contract,
182 fingerprint: Args::FINGERPRINT,
183 external_args: NonNull::from_mut(args).cast::<NonNull<c_void>>(),
185 method_context,
186 phantom: PhantomData,
187 }
188 }
189
190 #[inline]
195 pub fn call_prepared(&self, method: PreparedMethod<'_>) -> Result<(), ContractError> {
196 #[cfg(feature = "executor")]
197 {
198 let mut method = method;
199 self.executor_context.call(&self.state, &mut method)
200 }
201 #[cfg(all(feature = "guest", not(feature = "executor")))]
202 {
203 let _ = method;
204 todo!()
205 }
206 #[cfg(not(any(feature = "executor", feature = "guest")))]
207 {
208 let _ = method;
209 Err(ContractError::InternalError)
210 }
211 }
212}