1use super::*;
2use super::{FeeReserveError, FeeTable, SystemLoanFeeReserve};
3use crate::blueprints::package::PackageRoyaltyNativeBlueprint;
4use crate::internal_prelude::*;
5use crate::kernel::kernel_api::*;
6use crate::kernel::kernel_callback_api::*;
7use crate::object_modules::royalty::ComponentRoyaltyBlueprint;
8use crate::system::actor::{Actor, FunctionActor, MethodActor, MethodType};
9use crate::system::module::*;
10use crate::system::system_callback::*;
11use crate::{
12 errors::{CanBeAbortion, RuntimeError, SystemModuleError},
13 transaction::AbortReason,
14};
15use radix_engine_interface::api::AttachedModuleId;
16use radix_engine_interface::blueprints::package::BlueprintVersionKey;
17use radix_engine_interface::blueprints::resource::LiquidFungibleResource;
18use radix_engine_interface::types::NodeId;
19
20#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
21pub enum CostingError {
22 FeeReserveError(FeeReserveError),
23}
24
25impl CanBeAbortion for CostingError {
26 fn abortion(&self) -> Option<&AbortReason> {
27 match self {
28 Self::FeeReserveError(err) => err.abortion(),
29 }
30 }
31}
32
33#[derive(Debug, Clone, Default)]
34pub enum OnApplyCost {
35 #[default]
36 Normal,
37 ForceFailOnCount {
38 fail_after: Rc<RefCell<u64>>,
39 },
40}
41
42impl OnApplyCost {
43 pub fn on_call(&mut self) -> Result<(), CostingError> {
44 match self {
45 OnApplyCost::Normal => {}
46 OnApplyCost::ForceFailOnCount { fail_after } => {
47 if *fail_after.borrow() == 0 {
48 return Ok(());
49 }
50
51 *fail_after.borrow_mut() -= 1;
52 if *fail_after.borrow() == 0 {
53 return Err(CostingError::FeeReserveError(
54 FeeReserveError::InsufficientBalance {
55 required: Decimal::MAX,
56 remaining: Decimal::ONE,
57 },
58 ));
59 }
60 }
61 }
62
63 Ok(())
64 }
65}
66
67#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
68pub struct CostingModuleConfig {
69 pub max_per_function_royalty_in_xrd: Decimal,
71 pub apply_execution_cost_2: bool,
73 pub apply_boot_ref_check_costing: bool,
75}
76
77impl CostingModuleConfig {
78 pub fn babylon_genesis() -> Self {
79 Self {
80 max_per_function_royalty_in_xrd: Decimal::try_from(MAX_PER_FUNCTION_ROYALTY_IN_XRD)
81 .unwrap(),
82 apply_execution_cost_2: false,
83 apply_boot_ref_check_costing: false,
84 }
85 }
86
87 pub fn bottlenose() -> Self {
88 Self {
89 max_per_function_royalty_in_xrd: Decimal::try_from(MAX_PER_FUNCTION_ROYALTY_IN_XRD)
90 .unwrap(),
91 apply_execution_cost_2: true,
92 apply_boot_ref_check_costing: true,
93 }
94 }
95}
96
97#[derive(Debug, Clone, ScryptoSbor, PartialEq, Eq)]
98pub struct DetailedExecutionCostBreakdownEntry {
99 pub depth: usize,
100 pub item: ExecutionCostBreakdownItem,
101}
102
103#[derive(Debug, Clone, ScryptoSbor, PartialEq, Eq)]
104pub enum ExecutionCostBreakdownItem {
105 Invocation {
106 actor: Actor,
107 args: (ScryptoValue,),
108 },
109 InvocationComplete,
110 Execution {
111 simple_name: String,
112 item: owned::ExecutionCostingEntryOwned,
113 cost_units: u32,
114 },
115}
116
117#[derive(Debug, Clone, Default)]
118pub struct CostBreakdown {
119 pub execution_cost_breakdown: IndexMap<String, u32>,
120 pub finalization_cost_breakdown: IndexMap<String, u32>,
121 pub storage_cost_breakdown: IndexMap<StorageType, usize>,
122}
123
124#[derive(Debug, Clone, Default)]
125pub struct DetailedCostBreakdown {
126 pub detailed_execution_cost_breakdown: Vec<DetailedExecutionCostBreakdownEntry>,
128}
129
130#[derive(Debug, Clone)]
131pub struct CostingModule {
132 pub config: CostingModuleConfig,
133 pub fee_reserve: SystemLoanFeeReserve,
134 pub fee_table: FeeTable,
135 pub on_apply_cost: OnApplyCost,
136
137 pub tx_payload_len: usize,
138 pub tx_num_of_signature_validations: usize,
139 pub cost_breakdown: Option<CostBreakdown>,
140 pub detailed_cost_breakdown: Option<DetailedCostBreakdown>,
141
142 pub current_depth: usize,
144}
145
146impl CostingModule {
147 pub fn apply_execution_cost(
148 &mut self,
149 costing_entry: ExecutionCostingEntry,
150 ) -> Result<(), CostingError> {
151 self.on_apply_cost.on_call()?;
152
153 let cost_units = costing_entry.to_execution_cost_units(&self.fee_table);
154
155 self.fee_reserve
156 .consume_execution(cost_units)
157 .map_err(CostingError::FeeReserveError)?;
158
159 if let Some(cost_breakdown) = &mut self.cost_breakdown {
160 let key = costing_entry.to_trace_key();
161 cost_breakdown
162 .execution_cost_breakdown
163 .entry(key)
164 .or_default()
165 .add_assign(cost_units);
166 }
167 if let Some(detailed_cost_breakdown) = &mut self.detailed_cost_breakdown {
168 detailed_cost_breakdown
170 .detailed_execution_cost_breakdown
171 .push(DetailedExecutionCostBreakdownEntry {
172 depth: self.current_depth,
173 item: ExecutionCostBreakdownItem::Execution {
174 simple_name: costing_entry.to_trace_key(),
175 item: owned::ExecutionCostingEntryOwned::from(costing_entry),
176 cost_units,
177 },
178 });
179 }
180
181 Ok(())
182 }
183
184 pub fn apply_execution_cost_2(
185 &mut self,
186 costing_entry: ExecutionCostingEntry,
187 ) -> Result<(), CostingError> {
188 if self.config.apply_execution_cost_2 {
189 self.apply_execution_cost(costing_entry)
190 } else {
191 Ok(())
192 }
193 }
194
195 pub fn apply_deferred_execution_cost(
196 &mut self,
197 costing_entry: ExecutionCostingEntry,
198 ) -> Result<(), CostingError> {
199 if let ExecutionCostingEntry::CheckReference { .. } = &costing_entry {
200 if !self.config.apply_boot_ref_check_costing {
201 return Ok(());
202 }
203 }
204
205 self.on_apply_cost.on_call()?;
206
207 let cost_units = costing_entry.to_execution_cost_units(&self.fee_table);
208
209 self.fee_reserve
210 .consume_deferred_execution(cost_units)
211 .map_err(CostingError::FeeReserveError)?;
212
213 if let Some(cost_breakdown) = &mut self.cost_breakdown {
214 let key = costing_entry.to_trace_key();
215 cost_breakdown
216 .execution_cost_breakdown
217 .entry(key)
218 .or_default()
219 .add_assign(cost_units);
220 }
221
222 if let Some(detailed_cost_breakdown) = &mut self.detailed_cost_breakdown {
223 detailed_cost_breakdown
225 .detailed_execution_cost_breakdown
226 .push(DetailedExecutionCostBreakdownEntry {
227 depth: 0,
228 item: ExecutionCostBreakdownItem::Execution {
229 simple_name: costing_entry.to_trace_key(),
230 item: owned::ExecutionCostingEntryOwned::from(costing_entry),
231 cost_units,
232 },
233 });
234 }
235
236 Ok(())
237 }
238
239 pub fn apply_deferred_finalization_cost(
240 &mut self,
241 costing_entry: FinalizationCostingEntry,
242 ) -> Result<(), CostingError> {
243 self.on_apply_cost.on_call()?;
244
245 let cost_units = costing_entry.to_finalization_cost_units(&self.fee_table);
246
247 self.fee_reserve
248 .consume_deferred_finalization(cost_units)
249 .map_err(CostingError::FeeReserveError)?;
250
251 if let Some(cost_breakdown) = &mut self.cost_breakdown {
252 let key = costing_entry.to_trace_key();
253 cost_breakdown
254 .finalization_cost_breakdown
255 .entry(key)
256 .or_default()
257 .add_assign(cost_units);
258 }
259
260 Ok(())
261 }
262
263 pub fn apply_deferred_storage_cost(
264 &mut self,
265 storage_type: StorageType,
266 size_increase: usize,
267 ) -> Result<(), CostingError> {
268 self.on_apply_cost.on_call()?;
269
270 self.fee_reserve
271 .consume_deferred_storage(storage_type, size_increase)
272 .map_err(CostingError::FeeReserveError)?;
273
274 if let Some(cost_breakdown) = &mut self.cost_breakdown {
275 cost_breakdown
276 .storage_cost_breakdown
277 .entry(storage_type)
278 .or_default()
279 .add_assign(size_increase);
280 }
281
282 Ok(())
283 }
284
285 pub fn apply_finalization_cost(
286 &mut self,
287 costing_entry: FinalizationCostingEntry,
288 ) -> Result<(), CostingError> {
289 self.on_apply_cost.on_call()?;
290
291 let cost_units = costing_entry.to_finalization_cost_units(&self.fee_table);
292
293 self.fee_reserve
294 .consume_finalization(cost_units)
295 .map_err(CostingError::FeeReserveError)?;
296
297 if let Some(cost_breakdown) = &mut self.cost_breakdown {
298 let key = costing_entry.to_trace_key();
299 cost_breakdown
300 .finalization_cost_breakdown
301 .entry(key)
302 .or_default()
303 .add_assign(cost_units);
304 }
305
306 Ok(())
307 }
308
309 pub fn apply_storage_cost(
310 &mut self,
311 storage_type: StorageType,
312 size_increase: usize,
313 ) -> Result<(), CostingError> {
314 self.on_apply_cost.on_call()?;
315
316 self.fee_reserve
317 .consume_storage(storage_type, size_increase)
318 .map_err(CostingError::FeeReserveError)?;
319
320 if let Some(cost_breakdown) = &mut self.cost_breakdown {
321 cost_breakdown
322 .storage_cost_breakdown
323 .entry(storage_type)
324 .or_default()
325 .add_assign(size_increase);
326 }
327
328 Ok(())
329 }
330
331 pub fn lock_fee(
332 &mut self,
333 vault_id: NodeId,
334 locked_fee: LiquidFungibleResource,
335 contingent: bool,
336 ) {
337 self.fee_reserve.lock_fee(vault_id, locked_fee, contingent);
338 }
339
340 pub fn unpack_for_receipt(
341 self,
342 ) -> (
343 SystemLoanFeeReserve,
344 Option<CostBreakdown>,
345 Option<DetailedCostBreakdown>,
346 ) {
347 (
348 self.fee_reserve,
349 self.cost_breakdown,
350 self.detailed_cost_breakdown,
351 )
352 }
353}
354
355pub fn apply_royalty_cost(
356 api: &mut impl SystemModuleApiFor<CostingModule>,
357 royalty_amount: RoyaltyAmount,
358 recipient: RoyaltyRecipient,
359) -> Result<(), RuntimeError> {
360 api.module()
361 .on_apply_cost
362 .on_call()
363 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
364
365 api.module()
366 .fee_reserve
367 .consume_royalty(royalty_amount, recipient)
368 .map_err(|e| {
369 RuntimeError::SystemModuleError(SystemModuleError::CostingError(
370 CostingError::FeeReserveError(e),
371 ))
372 })
373}
374
375impl InitSystemModule for CostingModule {
376 fn init(&mut self) -> Result<(), BootloadingError> {
377 self.apply_deferred_execution_cost(ExecutionCostingEntry::ValidateTxPayload {
378 size: self.tx_payload_len,
379 })
380 .map_err(BootloadingError::FailedToApplyDeferredCosts)?;
381
382 self.apply_deferred_execution_cost(ExecutionCostingEntry::VerifyTxSignatures {
383 num_signatures: self.tx_num_of_signature_validations,
384 })
385 .map_err(BootloadingError::FailedToApplyDeferredCosts)?;
386
387 self.apply_deferred_storage_cost(StorageType::Archive, self.tx_payload_len)
388 .map_err(BootloadingError::FailedToApplyDeferredCosts)?;
389
390 Ok(())
391 }
392}
393
394impl ResolvableSystemModule for CostingModule {
395 #[inline]
396 fn resolve_from_system(system: &mut impl HasModules) -> &mut Self {
397 &mut system.modules_mut().costing
398 }
399}
400
401impl PrivilegedSystemModule for CostingModule {
402 fn privileged_before_invoke(
405 api: &mut impl SystemBasedKernelApi,
406 invocation: &KernelInvocation<Actor>,
407 ) -> Result<(), RuntimeError> {
408 if api.kernel_get_system_state().current_call_frame.is_root() {
412 return Ok(());
413 }
414
415 let (optional_blueprint_id, ident, maybe_object_royalties) = {
417 let (maybe_component, ident) = match &invocation.call_frame_data {
418 Actor::Method(MethodActor {
419 method_type,
420 node_id,
421 ident,
422 object_info,
423 ..
424 }) => {
425 match method_type {
427 MethodType::Main | MethodType::Direct => {}
428 MethodType::Module(..) => return Ok(()),
429 }
430
431 match &object_info.object_type {
432 ObjectType::Global { modules }
433 if modules.contains_key(&AttachedModuleId::Royalty) =>
434 {
435 (Some(*node_id), ident)
436 }
437 _ => (None, ident),
438 }
439 }
440 Actor::Function(FunctionActor { ident, .. }) => (None, ident),
441 Actor::BlueprintHook(..) | Actor::Root => {
442 return Ok(());
443 }
444 };
445
446 (
447 invocation.call_frame_data.blueprint_id(),
448 ident,
449 maybe_component,
450 )
451 };
452
453 if let Some(blueprint_id) = optional_blueprint_id {
457 let bp_version_key =
458 BlueprintVersionKey::new_default(blueprint_id.blueprint_name.as_str());
459 PackageRoyaltyNativeBlueprint::charge_package_royalty(
460 blueprint_id.package_address.as_node_id(),
461 &bp_version_key,
462 ident,
463 api,
464 )?;
465 }
466
467 if let Some(node_id) = maybe_object_royalties {
471 ComponentRoyaltyBlueprint::charge_component_royalty(&node_id, ident, api)?;
472 }
473
474 Ok(())
475 }
476}
477
478impl<ModuleApi: SystemModuleApiFor<Self>> SystemModule<ModuleApi> for CostingModule {
479 fn before_invoke(
480 api: &mut ModuleApi,
481 invocation: &KernelInvocation<Actor>,
482 ) -> Result<(), RuntimeError> {
483 let depth = api.current_stack_depth_uncosted();
484 let is_root = api.system_state().current_call_frame.is_root();
485 let costing_module = api.module();
486
487 if let Some(ref mut detailed_cost_breakdown) = costing_module.detailed_cost_breakdown {
489 detailed_cost_breakdown
490 .detailed_execution_cost_breakdown
491 .push(DetailedExecutionCostBreakdownEntry {
492 depth,
493 item: ExecutionCostBreakdownItem::Invocation {
494 actor: invocation.call_frame_data.clone(),
495 args: (invocation.args.as_scrypto_value().to_owned(),),
496 },
497 });
498 }
499
500 if is_root {
504 return Ok(());
505 }
506
507 costing_module.current_depth = depth;
508 costing_module
509 .apply_execution_cost(ExecutionCostingEntry::BeforeInvoke {
510 actor: &invocation.call_frame_data,
511 input_size: invocation.len(),
512 })
513 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
514
515 Ok(())
518 }
519
520 #[inline(always)]
521 fn after_invoke(api: &mut ModuleApi, output: &IndexedScryptoValue) -> Result<(), RuntimeError> {
522 let depth = api.current_stack_depth_uncosted();
523
524 if let Some(ref mut detailed_cost_breakdown) = api.module().detailed_cost_breakdown {
526 detailed_cost_breakdown
527 .detailed_execution_cost_breakdown
528 .push(DetailedExecutionCostBreakdownEntry {
529 depth,
530 item: ExecutionCostBreakdownItem::InvocationComplete,
531 });
532 }
533
534 if api.system_state().current_call_frame.is_root() {
538 return Ok(());
539 }
540
541 api.module().current_depth = depth;
542 api.module()
543 .apply_execution_cost(ExecutionCostingEntry::AfterInvoke {
544 output_size: output.len(),
545 })
546 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
547
548 Ok(())
549 }
550
551 fn on_create_node(api: &mut ModuleApi, event: &CreateNodeEvent) -> Result<(), RuntimeError> {
552 api.module().current_depth = api.current_stack_depth_uncosted();
553 api.module()
554 .apply_execution_cost(ExecutionCostingEntry::CreateNode { event })
555 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
556
557 Ok(())
558 }
559
560 fn on_pin_node(api: &mut ModuleApi, node_id: &NodeId) -> Result<(), RuntimeError> {
561 api.module()
562 .apply_execution_cost(ExecutionCostingEntry::PinNode { node_id })
563 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
564
565 Ok(())
566 }
567
568 fn on_drop_node(api: &mut ModuleApi, event: &DropNodeEvent) -> Result<(), RuntimeError> {
569 api.module().current_depth = api.current_stack_depth_uncosted();
570 api.module()
571 .apply_execution_cost(ExecutionCostingEntry::DropNode { event })
572 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
573
574 Ok(())
575 }
576
577 fn on_move_module(api: &mut ModuleApi, event: &MoveModuleEvent) -> Result<(), RuntimeError> {
578 api.module().current_depth = api.current_stack_depth_uncosted();
579 api.module()
580 .apply_execution_cost(ExecutionCostingEntry::MoveModule { event })
581 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
582
583 Ok(())
584 }
585
586 fn on_open_substate(
587 api: &mut ModuleApi,
588 event: &OpenSubstateEvent,
589 ) -> Result<(), RuntimeError> {
590 api.module().current_depth = api.current_stack_depth_uncosted();
591 api.module()
592 .apply_execution_cost(ExecutionCostingEntry::OpenSubstate { event })
593 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
594
595 Ok(())
596 }
597
598 fn on_mark_substate_as_transient(
599 api: &mut ModuleApi,
600 node_id: &NodeId,
601 partition_number: &PartitionNumber,
602 substate_key: &SubstateKey,
603 ) -> Result<(), RuntimeError> {
604 api.module()
605 .apply_execution_cost(ExecutionCostingEntry::MarkSubstateAsTransient {
606 node_id,
607 partition_number,
608 substate_key,
609 })
610 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
611
612 Ok(())
613 }
614
615 fn on_read_substate(
616 api: &mut ModuleApi,
617 event: &ReadSubstateEvent,
618 ) -> Result<(), RuntimeError> {
619 api.module().current_depth = api.current_stack_depth_uncosted();
620 api.module()
621 .apply_execution_cost(ExecutionCostingEntry::ReadSubstate { event })
622 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
623
624 Ok(())
625 }
626
627 fn on_write_substate(
628 api: &mut ModuleApi,
629 event: &WriteSubstateEvent,
630 ) -> Result<(), RuntimeError> {
631 api.module().current_depth = api.current_stack_depth_uncosted();
632 api.module()
633 .apply_execution_cost(ExecutionCostingEntry::WriteSubstate { event })
634 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
635
636 Ok(())
637 }
638
639 fn on_close_substate(
640 api: &mut ModuleApi,
641 event: &CloseSubstateEvent,
642 ) -> Result<(), RuntimeError> {
643 api.module().current_depth = api.current_stack_depth_uncosted();
644 api.module()
645 .apply_execution_cost(ExecutionCostingEntry::CloseSubstate { event })
646 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
647
648 Ok(())
649 }
650
651 fn on_set_substate(api: &mut ModuleApi, event: &SetSubstateEvent) -> Result<(), RuntimeError> {
652 api.module()
653 .apply_execution_cost(ExecutionCostingEntry::SetSubstate { event })
654 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
655
656 Ok(())
657 }
658
659 fn on_remove_substate(
660 api: &mut ModuleApi,
661 event: &RemoveSubstateEvent,
662 ) -> Result<(), RuntimeError> {
663 api.module()
664 .apply_execution_cost(ExecutionCostingEntry::RemoveSubstate { event })
665 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
666
667 Ok(())
668 }
669
670 fn on_scan_keys(api: &mut ModuleApi, event: &ScanKeysEvent) -> Result<(), RuntimeError> {
671 api.module()
672 .apply_execution_cost(ExecutionCostingEntry::ScanKeys { event })
673 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
674
675 Ok(())
676 }
677
678 fn on_drain_substates(
679 api: &mut ModuleApi,
680 event: &DrainSubstatesEvent,
681 ) -> Result<(), RuntimeError> {
682 api.module()
683 .apply_execution_cost(ExecutionCostingEntry::DrainSubstates { event })
684 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
685
686 Ok(())
687 }
688
689 fn on_scan_sorted_substates(
690 api: &mut ModuleApi,
691 event: &ScanSortedSubstatesEvent,
692 ) -> Result<(), RuntimeError> {
693 api.module()
694 .apply_execution_cost(ExecutionCostingEntry::ScanSortedSubstates { event })
695 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
696
697 Ok(())
698 }
699
700 fn on_allocate_node_id(
701 api: &mut ModuleApi,
702 _entity_type: EntityType,
703 ) -> Result<(), RuntimeError> {
704 api.module().current_depth = api.current_stack_depth_uncosted();
705 api.module()
706 .apply_execution_cost(ExecutionCostingEntry::AllocateNodeId)
707 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
708
709 Ok(())
710 }
711
712 fn on_get_stack_id(api: &mut ModuleApi) -> Result<(), RuntimeError> {
713 api.module()
714 .apply_execution_cost(ExecutionCostingEntry::GetStackId)
715 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
716
717 Ok(())
718 }
719
720 fn on_switch_stack(api: &mut ModuleApi) -> Result<(), RuntimeError> {
721 api.module()
722 .apply_execution_cost(ExecutionCostingEntry::SwitchStack)
723 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
724
725 Ok(())
726 }
727
728 fn on_send_to_stack(api: &mut ModuleApi, data_len: usize) -> Result<(), RuntimeError> {
729 api.module()
730 .apply_execution_cost(ExecutionCostingEntry::SendToStack { data_len })
731 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
732
733 Ok(())
734 }
735
736 fn on_set_call_frame_data(api: &mut ModuleApi, data_len: usize) -> Result<(), RuntimeError> {
737 api.module()
738 .apply_execution_cost(ExecutionCostingEntry::SetCallFrameData { data_len })
739 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
740
741 Ok(())
742 }
743
744 fn on_get_owned_nodes(api: &mut ModuleApi) -> Result<(), RuntimeError> {
745 api.module()
746 .apply_execution_cost(ExecutionCostingEntry::GetOwnedNodes)
747 .map_err(|e| RuntimeError::SystemModuleError(SystemModuleError::CostingError(e)))?;
748
749 Ok(())
750 }
751}