1use radix_engine::init::InitializationParameters;
2
3use crate::prelude::*;
4
5#[derive(Clone)]
6pub struct InjectCostingErrorInit<I> {
7 pub system_input: I,
8 pub error_after_count: u64,
9}
10
11impl<I: InitializationParameters<For: KernelTransactionExecutor>> InitializationParameters
12 for InjectCostingErrorInit<I>
13{
14 type For = InjectCostingError<I::For>;
15}
16
17pub struct InjectCostingError<Y: KernelTransactionExecutor> {
18 fail_after: Rc<RefCell<u64>>,
19 wrapped: Y,
20}
21
22impl<Y: KernelTransactionExecutor> InjectCostingError<Y> {
23 fn maybe_err(&mut self) -> Result<(), RuntimeError> {
24 if *self.fail_after.borrow() == 0 {
25 return Ok(());
26 }
27
28 *self.fail_after.borrow_mut() -= 1;
29
30 if *self.fail_after.borrow() == 0 {
31 return Err(RuntimeError::SystemModuleError(
32 SystemModuleError::CostingError(CostingError::FeeReserveError(
33 FeeReserveError::InsufficientBalance {
34 required: Decimal::MAX,
35 remaining: Decimal::ONE,
36 },
37 )),
38 ));
39 }
40
41 Ok(())
42 }
43}
44
45macro_rules! wrapped_api {
46 ($api:ident) => {
47 WrappedKernelApi { api: $api }
48 };
49}
50
51macro_rules! wrapped_internal_api {
52 ($api:ident) => {
53 WrappedKernelInternalApi { api: $api }
54 };
55}
56
57impl<
58 E: KernelTransactionExecutor<
59 Executable = ExecutableTransaction,
60 ExecutionOutput = Vec<InstructionOutput>,
61 Receipt = TransactionReceipt,
62 > + HasModules,
63 > KernelTransactionExecutor for InjectCostingError<E>
64{
65 type Init = InjectCostingErrorInit<E::Init>;
66 type Executable = ExecutableTransaction;
67 type ExecutionOutput = Vec<InstructionOutput>;
68 type Receipt = TransactionReceipt;
69
70 fn init(
71 store: &mut impl CommitableSubstateStore,
72 executable: &ExecutableTransaction,
73 init_input: Self::Init,
74 always_visible_global_nodes: &'static IndexSet<NodeId>,
75 ) -> Result<(Self, Vec<CallFrameInit<Self::CallFrameData>>), Self::Receipt> {
76 let (mut system, call_frame_inits) = E::init(
77 store,
78 executable,
79 init_input.system_input,
80 always_visible_global_nodes,
81 )?;
82
83 let fail_after = Rc::new(RefCell::new(init_input.error_after_count));
84 system.modules_mut().costing_mut().unwrap().on_apply_cost = OnApplyCost::ForceFailOnCount {
85 fail_after: fail_after.clone(),
86 };
87
88 Ok((
89 Self {
90 fail_after,
91 wrapped: system,
92 },
93 call_frame_inits,
94 ))
95 }
96
97 fn execute<Y: KernelApi<CallbackObject = Self>>(
98 api: &mut Y,
99 executable: &ExecutableTransaction,
100 ) -> Result<Vec<InstructionOutput>, RuntimeError> {
101 let mut api = wrapped_api!(api);
102 E::execute(&mut api, executable)
103 }
104
105 fn finalize(
106 &mut self,
107 executable: &ExecutableTransaction,
108 store_commit_info: StoreCommitInfo,
109 ) -> Result<(), RuntimeError> {
110 self.maybe_err()?;
111 self.wrapped.finalize(executable, store_commit_info)
112 }
113
114 fn create_receipt<S: SubstateDatabase>(
115 self,
116 track: Track<S>,
117 result: Result<Vec<InstructionOutput>, TransactionExecutionError>,
118 ) -> TransactionReceipt {
119 self.wrapped.create_receipt(track, result)
120 }
121}
122
123impl<E: KernelTransactionExecutor> KernelCallbackObject for InjectCostingError<E> {
124 type LockData = E::LockData;
125 type CallFrameData = E::CallFrameData;
126
127 fn on_pin_node<Y: KernelInternalApi<System = Self>>(
128 node_id: &NodeId,
129 api: &mut Y,
130 ) -> Result<(), RuntimeError> {
131 api.kernel_get_system_state().system.maybe_err()?;
132 let mut api = wrapped_internal_api!(api);
133 E::on_pin_node(node_id, &mut api)
134 }
135
136 fn on_create_node<Y: KernelInternalApi<System = Self>>(
137 event: CreateNodeEvent,
138 api: &mut Y,
139 ) -> Result<(), RuntimeError> {
140 api.kernel_get_system_state().system.maybe_err()?;
141 let mut api = wrapped_internal_api!(api);
142 E::on_create_node(event, &mut api)
143 }
144
145 fn on_drop_node<Y: KernelInternalApi<System = Self>>(
146 event: DropNodeEvent,
147 api: &mut Y,
148 ) -> Result<(), RuntimeError> {
149 api.kernel_get_system_state().system.maybe_err()?;
150 let mut api = wrapped_internal_api!(api);
151 E::on_drop_node(event, &mut api)
152 }
153
154 fn on_move_module<Y: KernelInternalApi<System = Self>>(
155 event: MoveModuleEvent,
156 api: &mut Y,
157 ) -> Result<(), RuntimeError> {
158 api.kernel_get_system_state().system.maybe_err()?;
159 let mut api = wrapped_internal_api!(api);
160 E::on_move_module(event, &mut api)
161 }
162
163 fn on_open_substate<Y: KernelInternalApi<System = Self>>(
164 event: OpenSubstateEvent,
165 api: &mut Y,
166 ) -> Result<(), RuntimeError> {
167 api.kernel_get_system_state().system.maybe_err()?;
168 let mut api = wrapped_internal_api!(api);
169 E::on_open_substate(event, &mut api)
170 }
171
172 fn on_close_substate<Y: KernelInternalApi<System = Self>>(
173 event: CloseSubstateEvent,
174 api: &mut Y,
175 ) -> Result<(), RuntimeError> {
176 api.kernel_get_system_state().system.maybe_err()?;
177 let mut api = wrapped_internal_api!(api);
178 E::on_close_substate(event, &mut api)
179 }
180
181 fn on_read_substate<Y: KernelInternalApi<System = Self>>(
182 event: ReadSubstateEvent,
183 api: &mut Y,
184 ) -> Result<(), RuntimeError> {
185 api.kernel_get_system_state().system.maybe_err()?;
186 let mut api = wrapped_internal_api!(api);
187 E::on_read_substate(event, &mut api)
188 }
189
190 fn on_write_substate<Y: KernelInternalApi<System = Self>>(
191 event: WriteSubstateEvent,
192 api: &mut Y,
193 ) -> Result<(), RuntimeError> {
194 api.kernel_get_system_state().system.maybe_err()?;
195 let mut api = wrapped_internal_api!(api);
196 E::on_write_substate(event, &mut api)
197 }
198
199 fn on_set_substate<Y: KernelInternalApi<System = Self>>(
200 event: SetSubstateEvent,
201 api: &mut Y,
202 ) -> Result<(), RuntimeError> {
203 api.kernel_get_system_state().system.maybe_err()?;
204 let mut api = wrapped_internal_api!(api);
205 E::on_set_substate(event, &mut api)
206 }
207
208 fn on_remove_substate<Y: KernelInternalApi<System = Self>>(
209 event: RemoveSubstateEvent,
210 api: &mut Y,
211 ) -> Result<(), RuntimeError> {
212 api.kernel_get_system_state().system.maybe_err()?;
213 let mut api = wrapped_internal_api!(api);
214 E::on_remove_substate(event, &mut api)
215 }
216
217 fn on_scan_keys<Y: KernelInternalApi<System = Self>>(
218 event: ScanKeysEvent,
219 api: &mut Y,
220 ) -> Result<(), RuntimeError> {
221 api.kernel_get_system_state().system.maybe_err()?;
222 let mut api = wrapped_internal_api!(api);
223 E::on_scan_keys(event, &mut api)
224 }
225
226 fn on_drain_substates<Y: KernelInternalApi<System = Self>>(
227 event: DrainSubstatesEvent,
228 api: &mut Y,
229 ) -> Result<(), RuntimeError> {
230 api.kernel_get_system_state().system.maybe_err()?;
231 let mut api = wrapped_internal_api!(api);
232 E::on_drain_substates(event, &mut api)
233 }
234
235 fn on_scan_sorted_substates<Y: KernelInternalApi<System = Self>>(
236 event: ScanSortedSubstatesEvent,
237 api: &mut Y,
238 ) -> Result<(), RuntimeError> {
239 api.kernel_get_system_state().system.maybe_err()?;
240 let mut api = wrapped_internal_api!(api);
241 E::on_scan_sorted_substates(event, &mut api)
242 }
243
244 fn before_invoke<Y: KernelApi<CallbackObject = Self>>(
245 invocation: &KernelInvocation<Self::CallFrameData>,
246 api: &mut Y,
247 ) -> Result<(), RuntimeError> {
248 api.kernel_get_system_state().system.maybe_err()?;
249 let mut api = wrapped_api!(api);
250 E::before_invoke(invocation, &mut api)
251 }
252
253 fn on_execution_start<Y: KernelInternalApi<System = Self>>(
254 api: &mut Y,
255 ) -> Result<(), RuntimeError> {
256 api.kernel_get_system_state().system.maybe_err()?;
257 let mut api = wrapped_internal_api!(api);
258 E::on_execution_start(&mut api)
259 }
260
261 fn invoke_upstream<Y: KernelApi<CallbackObject = Self>>(
262 args: &IndexedScryptoValue,
263 api: &mut Y,
264 ) -> Result<IndexedScryptoValue, RuntimeError> {
265 api.kernel_get_system_state().system.maybe_err()?;
266 let mut api = wrapped_api!(api);
267 E::invoke_upstream(args, &mut api)
268 }
269
270 fn auto_drop<Y: KernelApi<CallbackObject = Self>>(
271 nodes: Vec<NodeId>,
272 api: &mut Y,
273 ) -> Result<(), RuntimeError> {
274 api.kernel_get_system_state().system.maybe_err()?;
275 let mut api = wrapped_api!(api);
276 E::auto_drop(nodes, &mut api)
277 }
278
279 fn on_execution_finish<Y: KernelInternalApi<System = Self>>(
280 message: &CallFrameMessage,
281 api: &mut Y,
282 ) -> Result<(), RuntimeError> {
283 api.kernel_get_system_state().system.maybe_err()?;
284 let mut api = wrapped_internal_api!(api);
285 E::on_execution_finish(message, &mut api)
286 }
287
288 fn after_invoke<Y: KernelApi<CallbackObject = Self>>(
289 output: &IndexedScryptoValue,
290 api: &mut Y,
291 ) -> Result<(), RuntimeError> {
292 api.kernel_get_system_state().system.maybe_err()?;
293 let mut api = wrapped_api!(api);
294 E::after_invoke(output, &mut api)
295 }
296
297 fn on_allocate_node_id<Y: KernelInternalApi<System = Self>>(
298 entity_type: EntityType,
299 api: &mut Y,
300 ) -> Result<(), RuntimeError> {
301 api.kernel_get_system_state().system.maybe_err()?;
302 let mut api = wrapped_internal_api!(api);
303 E::on_allocate_node_id(entity_type, &mut api)
304 }
305
306 fn on_mark_substate_as_transient<Y: KernelInternalApi<System = Self>>(
307 node_id: &NodeId,
308 partition_number: &PartitionNumber,
309 substate_key: &SubstateKey,
310 api: &mut Y,
311 ) -> Result<(), RuntimeError> {
312 api.kernel_get_system_state().system.maybe_err()?;
313 let mut api = wrapped_internal_api!(api);
314 E::on_mark_substate_as_transient(node_id, partition_number, substate_key, &mut api)
315 }
316
317 fn on_substate_lock_fault<Y: KernelApi<CallbackObject = Self>>(
318 node_id: NodeId,
319 partition_num: PartitionNumber,
320 offset: &SubstateKey,
321 api: &mut Y,
322 ) -> Result<bool, RuntimeError> {
323 api.kernel_get_system_state().system.maybe_err()?;
324 let mut api = wrapped_api!(api);
325 E::on_substate_lock_fault(node_id, partition_num, offset, &mut api)
326 }
327
328 fn on_drop_node_mut<Y: KernelApi<CallbackObject = Self>>(
329 node_id: &NodeId,
330 api: &mut Y,
331 ) -> Result<(), RuntimeError> {
332 api.kernel_get_system_state().system.maybe_err()?;
333 let mut api = wrapped_api!(api);
334 E::on_drop_node_mut(node_id, &mut api)
335 }
336
337 fn on_get_stack_id<Y: KernelInternalApi<System = Self>>(
338 api: &mut Y,
339 ) -> Result<(), RuntimeError> {
340 api.kernel_get_system_state().system.maybe_err()?;
341 let mut api = wrapped_internal_api!(api);
342 E::on_get_stack_id(&mut api)
343 }
344
345 fn on_switch_stack<Y: KernelInternalApi<System = Self>>(
346 api: &mut Y,
347 ) -> Result<(), RuntimeError> {
348 api.kernel_get_system_state().system.maybe_err()?;
349 let mut api = wrapped_internal_api!(api);
350 E::on_switch_stack(&mut api)
351 }
352
353 fn on_send_to_stack<Y: KernelInternalApi<System = Self>>(
354 value: &IndexedScryptoValue,
355 api: &mut Y,
356 ) -> Result<(), RuntimeError> {
357 api.kernel_get_system_state().system.maybe_err()?;
358 let mut api = wrapped_internal_api!(api);
359 E::on_send_to_stack(value, &mut api)
360 }
361
362 fn on_set_call_frame_data<Y: KernelInternalApi<System = Self>>(
363 data: &Self::CallFrameData,
364 api: &mut Y,
365 ) -> Result<(), RuntimeError> {
366 api.kernel_get_system_state().system.maybe_err()?;
367 let mut api = wrapped_internal_api!(api);
368 E::on_set_call_frame_data(data, &mut api)
369 }
370
371 fn on_get_owned_nodes<Y: KernelInternalApi<System = Self>>(
372 api: &mut Y,
373 ) -> Result<(), RuntimeError> {
374 api.kernel_get_system_state().system.maybe_err()?;
375 let mut api = wrapped_internal_api!(api);
376 E::on_get_owned_nodes(&mut api)
377 }
378}
379
380pub struct WrappedKernelApi<
381 'a,
382 E: KernelTransactionExecutor + 'a,
383 K: KernelApi<CallbackObject = InjectCostingError<E>>,
384> {
385 api: &'a mut K,
386}
387
388impl<
389 'a,
390 E: KernelTransactionExecutor + 'a,
391 K: KernelApi<CallbackObject = InjectCostingError<E>>,
392 > KernelNodeApi for WrappedKernelApi<'a, E, K>
393{
394 fn kernel_pin_node(&mut self, node_id: NodeId) -> Result<(), RuntimeError> {
395 self.api.kernel_pin_node(node_id)
396 }
397
398 fn kernel_allocate_node_id(&mut self, entity_type: EntityType) -> Result<NodeId, RuntimeError> {
399 self.api.kernel_allocate_node_id(entity_type)
400 }
401
402 fn kernel_create_node(
403 &mut self,
404 node_id: NodeId,
405 node_substates: NodeSubstates,
406 ) -> Result<(), RuntimeError> {
407 self.api.kernel_create_node(node_id, node_substates)
408 }
409
410 fn kernel_create_node_from(
411 &mut self,
412 node_id: NodeId,
413 partitions: BTreeMap<PartitionNumber, (NodeId, PartitionNumber)>,
414 ) -> Result<(), RuntimeError> {
415 self.api.kernel_create_node_from(node_id, partitions)
416 }
417
418 fn kernel_drop_node(&mut self, node_id: &NodeId) -> Result<DroppedNode, RuntimeError> {
419 self.api.kernel_drop_node(node_id)
420 }
421}
422
423impl<
424 'a,
425 E: KernelTransactionExecutor + 'a,
426 Y: KernelApi<CallbackObject = InjectCostingError<E>>,
427 > KernelSubstateApi<E::LockData> for WrappedKernelApi<'a, E, Y>
428{
429 fn kernel_mark_substate_as_transient(
430 &mut self,
431 node_id: NodeId,
432 partition_num: PartitionNumber,
433 key: SubstateKey,
434 ) -> Result<(), RuntimeError> {
435 self.api
436 .kernel_mark_substate_as_transient(node_id, partition_num, key)
437 }
438
439 fn kernel_open_substate_with_default<F: FnOnce() -> IndexedScryptoValue>(
440 &mut self,
441 node_id: &NodeId,
442 partition_num: PartitionNumber,
443 substate_key: &SubstateKey,
444 flags: LockFlags,
445 default: Option<F>,
446 lock_data: E::LockData,
447 ) -> Result<SubstateHandle, RuntimeError> {
448 self.api.kernel_open_substate_with_default(
449 node_id,
450 partition_num,
451 substate_key,
452 flags,
453 default,
454 lock_data,
455 )
456 }
457
458 fn kernel_get_lock_data(
459 &mut self,
460 lock_handle: SubstateHandle,
461 ) -> Result<E::LockData, RuntimeError> {
462 self.api.kernel_get_lock_data(lock_handle)
463 }
464
465 fn kernel_close_substate(&mut self, lock_handle: SubstateHandle) -> Result<(), RuntimeError> {
466 self.api.kernel_close_substate(lock_handle)
467 }
468
469 fn kernel_read_substate(
470 &mut self,
471 lock_handle: SubstateHandle,
472 ) -> Result<&IndexedScryptoValue, RuntimeError> {
473 self.api.kernel_read_substate(lock_handle)
474 }
475
476 fn kernel_write_substate(
477 &mut self,
478 lock_handle: SubstateHandle,
479 value: IndexedScryptoValue,
480 ) -> Result<(), RuntimeError> {
481 self.api.kernel_write_substate(lock_handle, value)
482 }
483
484 fn kernel_set_substate(
485 &mut self,
486 node_id: &NodeId,
487 partition_num: PartitionNumber,
488 substate_key: SubstateKey,
489 value: IndexedScryptoValue,
490 ) -> Result<(), RuntimeError> {
491 self.api
492 .kernel_set_substate(node_id, partition_num, substate_key, value)
493 }
494
495 fn kernel_remove_substate(
496 &mut self,
497 node_id: &NodeId,
498 partition_num: PartitionNumber,
499 substate_key: &SubstateKey,
500 ) -> Result<Option<IndexedScryptoValue>, RuntimeError> {
501 self.api
502 .kernel_remove_substate(node_id, partition_num, substate_key)
503 }
504
505 fn kernel_scan_sorted_substates(
506 &mut self,
507 node_id: &NodeId,
508 partition_num: PartitionNumber,
509 count: u32,
510 ) -> Result<Vec<(SortedKey, IndexedScryptoValue)>, RuntimeError> {
511 self.api
512 .kernel_scan_sorted_substates(node_id, partition_num, count)
513 }
514
515 fn kernel_scan_keys<K: SubstateKeyContent>(
516 &mut self,
517 node_id: &NodeId,
518 partition_num: PartitionNumber,
519 count: u32,
520 ) -> Result<Vec<SubstateKey>, RuntimeError> {
521 self.api
522 .kernel_scan_keys::<K>(node_id, partition_num, count)
523 }
524
525 fn kernel_drain_substates<K: SubstateKeyContent>(
526 &mut self,
527 node_id: &NodeId,
528 partition_num: PartitionNumber,
529 count: u32,
530 ) -> Result<Vec<(SubstateKey, IndexedScryptoValue)>, RuntimeError> {
531 self.api
532 .kernel_drain_substates::<K>(node_id, partition_num, count)
533 }
534}
535
536impl<
537 'a,
538 E: KernelTransactionExecutor + 'a,
539 K: KernelApi<CallbackObject = InjectCostingError<E>>,
540 > KernelInvokeApi<E::CallFrameData> for WrappedKernelApi<'a, E, K>
541{
542 fn kernel_invoke(
543 &mut self,
544 invocation: Box<KernelInvocation<E::CallFrameData>>,
545 ) -> Result<IndexedScryptoValue, RuntimeError> {
546 self.api.kernel_invoke(invocation)
547 }
548}
549
550impl<
551 'a,
552 E: KernelTransactionExecutor + 'a,
553 K: KernelApi<CallbackObject = InjectCostingError<E>>,
554 > KernelStackApi for WrappedKernelApi<'a, E, K>
555{
556 type CallFrameData = E::CallFrameData;
557
558 fn kernel_get_stack_id(&mut self) -> Result<usize, RuntimeError> {
559 self.api.kernel_get_stack_id()
560 }
561
562 fn kernel_switch_stack(&mut self, id: usize) -> Result<(), RuntimeError> {
563 self.api.kernel_switch_stack(id)
564 }
565
566 fn kernel_send_to_stack(
567 &mut self,
568 id: usize,
569 value: &IndexedScryptoValue,
570 ) -> Result<(), RuntimeError> {
571 self.api.kernel_send_to_stack(id, value)
572 }
573
574 fn kernel_set_call_frame_data(&mut self, data: E::CallFrameData) -> Result<(), RuntimeError> {
575 self.api.kernel_set_call_frame_data(data)
576 }
577
578 fn kernel_get_owned_nodes(&mut self) -> Result<Vec<NodeId>, RuntimeError> {
579 self.api.kernel_get_owned_nodes()
580 }
581}
582
583impl<
584 'a,
585 E: KernelTransactionExecutor + 'a,
586 K: KernelApi<CallbackObject = InjectCostingError<E>>,
587 > KernelInternalApi for WrappedKernelApi<'a, E, K>
588{
589 type System = E;
590
591 fn kernel_get_system_state(&mut self) -> SystemState<'_, E> {
592 let state = self.api.kernel_get_system_state();
593 SystemState {
594 system: &mut state.system.wrapped,
595 caller_call_frame: state.caller_call_frame,
596 current_call_frame: state.current_call_frame,
597 }
598 }
599
600 fn kernel_get_current_stack_depth_uncosted(&self) -> usize {
601 self.api.kernel_get_current_stack_depth_uncosted()
602 }
603
604 fn kernel_get_current_stack_id_uncosted(&self) -> usize {
605 self.api.kernel_get_current_stack_id_uncosted()
606 }
607
608 fn kernel_get_node_visibility_uncosted(&self, node_id: &NodeId) -> NodeVisibility {
609 self.api.kernel_get_node_visibility_uncosted(node_id)
610 }
611
612 fn kernel_read_substate_uncosted(
613 &self,
614 node_id: &NodeId,
615 partition_num: PartitionNumber,
616 substate_key: &SubstateKey,
617 ) -> Option<&IndexedScryptoValue> {
618 self.api
619 .kernel_read_substate_uncosted(node_id, partition_num, substate_key)
620 }
621}
622
623impl<
624 'a,
625 E: KernelTransactionExecutor + 'a,
626 K: KernelApi<CallbackObject = InjectCostingError<E>>,
627 > KernelApi for WrappedKernelApi<'a, E, K>
628{
629 type CallbackObject = E;
630}
631
632pub struct WrappedKernelInternalApi<
633 'a,
634 E: KernelTransactionExecutor + 'a,
635 K: KernelInternalApi<System = InjectCostingError<E>>,
636> {
637 api: &'a mut K,
638}
639
640impl<
641 'a,
642 E: KernelTransactionExecutor + 'a,
643 K: KernelInternalApi<System = InjectCostingError<E>>,
644 > KernelInternalApi for WrappedKernelInternalApi<'a, E, K>
645{
646 type System = E;
647
648 fn kernel_get_system_state(&mut self) -> SystemState<'_, E> {
649 let state = self.api.kernel_get_system_state();
650 SystemState {
651 system: &mut state.system.wrapped,
652 caller_call_frame: state.caller_call_frame,
653 current_call_frame: state.current_call_frame,
654 }
655 }
656
657 fn kernel_get_current_stack_depth_uncosted(&self) -> usize {
658 self.api.kernel_get_current_stack_depth_uncosted()
659 }
660
661 fn kernel_get_current_stack_id_uncosted(&self) -> usize {
662 self.api.kernel_get_current_stack_id_uncosted()
663 }
664
665 fn kernel_get_node_visibility_uncosted(&self, node_id: &NodeId) -> NodeVisibility {
666 self.api.kernel_get_node_visibility_uncosted(node_id)
667 }
668
669 fn kernel_read_substate_uncosted(
670 &self,
671 node_id: &NodeId,
672 partition_num: PartitionNumber,
673 substate_key: &SubstateKey,
674 ) -> Option<&IndexedScryptoValue> {
675 self.api
676 .kernel_read_substate_uncosted(node_id, partition_num, substate_key)
677 }
678}