1use crate::prelude::*;
8
9macro_rules! implement_system_api {
35 (
36 $(
37 $trait: ident: {
38 $(
39 $func_ident: ident: (
40 &mut self
41 $(, $input_ident: ident: $input_type: ty)* $(,)?
42 ) -> $outputs: ty
43 ),* $(,)?
44 }
45 ),* $(,)*
46 ) => {
47 $(
48 impl<D> $trait<RuntimeError> for TestEnvironment<D>
49 where
50 D: SubstateDatabase + CommittableSubstateDatabase + 'static
51 {
52 $(
53 #[inline]
54 fn $func_ident(&mut self, $($input_ident: $input_type),*) -> $outputs {
55 let logs_before = self.0.with_kernel_mut(|kernel| {
56 kernel
57 .kernel_get_system_state()
58 .system
59 .modules
60 .transaction_runtime()
61 .map(|runtime| runtime.logs.len())
62 .unwrap_or(0)
63 });
64
65 let rtn = self.0.with_kernel_mut(|kernel| {
66 SystemService::new(kernel).$func_ident( $($input_ident),* )
67 });
68
69 self.0.with_kernel_mut(|kernel| {
70 let logs_after = kernel
71 .kernel_get_system_state()
72 .system
73 .modules
74 .transaction_runtime()
75 .map(|runtime| runtime.logs.len())
76 .unwrap_or(0);
77
78 if logs_before != logs_after {
79 for (level, message) in kernel
80 .kernel_get_system_state()
81 .system
82 .modules
83 .transaction_runtime()
84 .map(|module| module.logs.iter())
85 .unwrap_or_default()
86 .into_iter()
87 .skip(logs_before)
88 {
89 println!("[{}]: {}", level, message)
90 }
91 }
92 });
93
94 rtn
95 }
96 )*
97 }
98 )*
99 };
100}
101implement_system_api! {
102 SystemApi: {},
103 SystemActorApi: {
104 actor_get_blueprint_id: (&mut self) -> Result<BlueprintId, RuntimeError>,
105 actor_open_field: (
106 &mut self,
107 object_handle: ActorStateHandle,
108 field: FieldIndex,
109 flags: LockFlags,
110 ) -> Result<FieldHandle, RuntimeError>,
111 actor_is_feature_enabled: (
112 &mut self,
113 object_handle: ActorStateHandle,
114 feature: &str,
115 ) -> Result<bool, RuntimeError>,
116 actor_get_node_id: (&mut self, ref_handle: ActorRefHandle) -> Result<NodeId, RuntimeError>,
117 actor_emit_event: (
118 &mut self,
119 event_name: String,
120 event_data: Vec<u8>,
121 event_flags: EventFlags,
122 ) -> Result<(), RuntimeError>
123 },
124 SystemActorIndexApi: {
125 actor_index_insert: (
126 &mut self,
127 object_handle: ActorStateHandle,
128 collection_index: CollectionIndex,
129 key: Vec<u8>,
130 buffer: Vec<u8>,
131 ) -> Result<(), RuntimeError>,
132 actor_index_remove: (
133 &mut self,
134 object_handle: ActorStateHandle,
135 collection_index: CollectionIndex,
136 key: Vec<u8>,
137 ) -> Result<Option<Vec<u8>>, RuntimeError>,
138 actor_index_scan_keys: (
139 &mut self,
140 object_handle: ActorStateHandle,
141 collection_index: CollectionIndex,
142 limit: u32,
143 ) -> Result<Vec<Vec<u8>>, RuntimeError>,
144 actor_index_drain: (
145 &mut self,
146 object_handle: ActorStateHandle,
147 collection_index: CollectionIndex,
148 limit: u32,
149 ) -> Result<Vec<(Vec<u8>, Vec<u8>)>, RuntimeError>,
150 },
151 SystemActorKeyValueEntryApi: {
152 actor_open_key_value_entry: (
153 &mut self,
154 object_handle: ActorStateHandle,
155 collection_index: CollectionIndex,
156 key: &Vec<u8>,
157 flags: LockFlags,
158 ) -> Result<KeyValueEntryHandle, RuntimeError>,
159 actor_remove_key_value_entry: (
160 &mut self,
161 object_handle: ActorStateHandle,
162 collection_index: CollectionIndex,
163 key: &Vec<u8>,
164 ) -> Result<Vec<u8>, RuntimeError>,
165 },
166 SystemActorSortedIndexApi: {
167 actor_sorted_index_insert: (
168 &mut self,
169 object_handle: ActorStateHandle,
170 collection_index: CollectionIndex,
171 sorted_key: SortedKey,
172 buffer: Vec<u8>,
173 ) -> Result<(), RuntimeError>,
174 actor_sorted_index_remove: (
175 &mut self,
176 object_handle: ActorStateHandle,
177 collection_index: CollectionIndex,
178 sorted_key: &SortedKey,
179 ) -> Result<Option<Vec<u8>>, RuntimeError>,
180 actor_sorted_index_scan: (
181 &mut self,
182 object_handle: ActorStateHandle,
183 collection_index: CollectionIndex,
184 count: u32,
185 ) -> Result<Vec<(SortedKey, Vec<u8>)>, RuntimeError>,
186 },
187 SystemBlueprintApi: {
188 call_function: (
189 &mut self,
190 package_address: PackageAddress,
191 blueprint_name: &str,
192 function_name: &str,
193 args: Vec<u8>,
194 ) -> Result<Vec<u8>, RuntimeError>,
195 resolve_blueprint_type: (
196 &mut self,
197 blueprint_type_id: &BlueprintTypeIdentifier,
198 ) -> Result<(Rc<VersionedScryptoSchema>, ScopedTypeId), RuntimeError>
199 },
200 SystemFieldApi: {
201 field_read: (&mut self, handle: field_api::FieldHandle) -> Result<Vec<u8>, RuntimeError>,
202 field_write: (&mut self, handle: FieldHandle, buffer: Vec<u8>) -> Result<(), RuntimeError>,
203 field_lock: (&mut self, handle: FieldHandle) -> Result<(), RuntimeError>,
204 field_close: (&mut self, handle: FieldHandle) -> Result<(), RuntimeError>
205 },
206 SystemKeyValueEntryApi: {
207 key_value_entry_get: (&mut self, handle: KeyValueEntryHandle) -> Result<Vec<u8>, RuntimeError>,
208 key_value_entry_set: (
209 &mut self,
210 handle: KeyValueEntryHandle,
211 buffer: Vec<u8>,
212 ) -> Result<(), RuntimeError>,
213 key_value_entry_remove: (&mut self, handle: KeyValueEntryHandle) -> Result<Vec<u8>, RuntimeError>,
214 key_value_entry_lock: (&mut self, handle: KeyValueEntryHandle) -> Result<(), RuntimeError>,
215 key_value_entry_close: (&mut self, handle: KeyValueEntryHandle) -> Result<(), RuntimeError>,
216 },
217 SystemKeyValueStoreApi: {
218 key_value_store_new: (&mut self, data_schema: KeyValueStoreDataSchema) -> Result<NodeId, RuntimeError>,
219 key_value_store_open_entry: (
220 &mut self,
221 node_id: &NodeId,
222 key: &Vec<u8>,
223 flags: LockFlags,
224 ) -> Result<KeyValueEntryHandle, RuntimeError>,
225 key_value_store_remove_entry: (
226 &mut self,
227 node_id: &NodeId,
228 key: &Vec<u8>,
229 ) -> Result<Vec<u8>, RuntimeError>,
230 },
231 SystemObjectApi: {
232 new_object: (
233 &mut self,
234 blueprint_ident: &str,
235 features: Vec<&str>,
236 generic_args: GenericArgs,
237 fields: IndexMap<FieldIndex, FieldValue>,
238 kv_entries: IndexMap<u8, IndexMap<Vec<u8>, KVEntry>>,
239 ) -> Result<NodeId, RuntimeError>,
240 drop_object: (&mut self, node_id: &NodeId) -> Result<Vec<Vec<u8>>, RuntimeError>,
241 get_blueprint_id: (&mut self, node_id: &NodeId) -> Result<BlueprintId, RuntimeError>,
242 get_outer_object: (&mut self, node_id: &NodeId) -> Result<GlobalAddress, RuntimeError>,
243 allocate_global_address: (
244 &mut self,
245 blueprint_id: BlueprintId,
246 ) -> Result<(GlobalAddressReservation, GlobalAddress), RuntimeError>,
247 allocate_virtual_global_address: (
248 &mut self,
249 blueprint_id: BlueprintId,
250 global_address: GlobalAddress,
251 ) -> Result<GlobalAddressReservation, RuntimeError>,
252 get_reservation_address: (&mut self, node_id: &NodeId) -> Result<GlobalAddress, RuntimeError>,
253 globalize: (
254 &mut self,
255 node_id: NodeId,
256 modules: IndexMap<AttachedModuleId, NodeId>,
257 address_reservation: Option<GlobalAddressReservation>,
258 ) -> Result<GlobalAddress, RuntimeError>,
259 globalize_with_address_and_create_inner_object_and_emit_event: (
260 &mut self,
261 node_id: NodeId,
262 modules: IndexMap<AttachedModuleId, NodeId>,
263 address_reservation: GlobalAddressReservation,
264 inner_object_blueprint: &str,
265 inner_object_fields: IndexMap<u8, FieldValue>,
266 event_name: &str,
267 event_data: Vec<u8>,
268 ) -> Result<(GlobalAddress, NodeId), RuntimeError>,
269 call_method: (
270 &mut self,
271 receiver: &NodeId,
272 method_name: &str,
273 args: Vec<u8>,
274 ) -> Result<Vec<u8>, RuntimeError>,
275 call_direct_access_method: (
276 &mut self,
277 receiver: &NodeId,
278 method_name: &str,
279 args: Vec<u8>,
280 ) -> Result<Vec<u8>, RuntimeError>,
281 call_module_method: (
282 &mut self,
283 receiver: &NodeId,
284 module_id: AttachedModuleId,
285 method_name: &str,
286 args: Vec<u8>,
287 ) -> Result<Vec<u8>, RuntimeError>,
288 },
289 SystemExecutionTraceApi: {
290 update_instruction_index: (&mut self, new_index: usize) -> Result<(), RuntimeError>,
291 },
292 SystemTransactionRuntimeApi: {
293 bech32_encode_address: (&mut self, address: GlobalAddress) -> Result<String, RuntimeError>,
294 get_transaction_hash: (&mut self) -> Result<Hash, RuntimeError>,
295 generate_ruid: (&mut self) -> Result<[u8; 32], RuntimeError>,
296 emit_log: (&mut self, level: Level, message: String) -> Result<(), RuntimeError>,
297 panic: (&mut self, message: String) -> Result<(), RuntimeError>,
298 },
299 SystemCostingApi: {
300 start_lock_fee: (&mut self, amount: Decimal, contingent: bool) -> Result<bool, RuntimeError>,
301 lock_fee: (
302 &mut self,
303 locked_fee: LiquidFungibleResource,
304 contingent: bool,
305 ) -> (),
306 consume_cost_units: (&mut self, costing_entry: ClientCostingEntry) -> Result<(), RuntimeError>,
307 execution_cost_unit_limit: (&mut self) -> Result<u32, RuntimeError>,
308 execution_cost_unit_price: (&mut self) -> Result<Decimal, RuntimeError>,
309 finalization_cost_unit_limit: (&mut self) -> Result<u32, RuntimeError>,
310 finalization_cost_unit_price: (&mut self) -> Result<Decimal, RuntimeError>,
311 usd_price: (&mut self) -> Result<Decimal, RuntimeError>,
312 max_per_function_royalty_in_xrd: (&mut self) -> Result<Decimal, RuntimeError>,
313 tip_percentage_truncated: (&mut self) -> Result<u32, RuntimeError>,
314 fee_balance: (&mut self) -> Result<Decimal, RuntimeError>,
315 }
316}