1use std::{any::Any, collections::HashMap, marker::PhantomData};
5
6use linera_base::{
7 data_types::{
8 Amount, ApplicationDescription, ApplicationPermissions, BlockHeight, Bytecode,
9 SendMessageRequest, Timestamp,
10 },
11 http,
12 identifiers::{Account, AccountOwner, ApplicationId, ChainId, StreamName},
13 ownership::{ChainOwnership, ManageChainError},
14 vm::VmRuntime,
15};
16use linera_views::batch::{Batch, WriteOperation};
17use linera_witty::{wit_export, Instance, RuntimeError};
18use tracing::log;
19
20use super::WasmExecutionError;
21use crate::{BaseRuntime, ContractRuntime, DataBlobHash, ExecutionError, ModuleId, ServiceRuntime};
22
23pub struct RuntimeApiData<Runtime> {
25 runtime: Runtime,
26 active_promises: HashMap<u32, Box<dyn Any + Send + Sync>>,
27 promise_counter: u32,
28}
29
30impl<Runtime> RuntimeApiData<Runtime> {
31 pub fn new(runtime: Runtime) -> Self {
33 RuntimeApiData {
34 runtime,
35 active_promises: HashMap::new(),
36 promise_counter: 0,
37 }
38 }
39
40 pub fn runtime_mut(&mut self) -> &mut Runtime {
42 &mut self.runtime
43 }
44
45 fn register_promise<Promise>(&mut self, promise: Promise) -> u32
48 where
49 Promise: Send + Sync + 'static,
50 {
51 let id = self.promise_counter;
52
53 self.active_promises.insert(id, Box::new(promise));
54 self.promise_counter += 1;
55
56 id
57 }
58
59 fn take_promise<Promise>(&mut self, promise_id: u32) -> Result<Promise, RuntimeError>
61 where
62 Promise: Send + Sync + 'static,
63 {
64 let type_erased_promise = self
65 .active_promises
66 .remove(&promise_id)
67 .ok_or_else(|| RuntimeError::Custom(WasmExecutionError::UnknownPromise.into()))?;
68
69 type_erased_promise
70 .downcast()
71 .map(|boxed_promise| *boxed_promise)
72 .map_err(|_| RuntimeError::Custom(WasmExecutionError::IncorrectPromise.into()))
73 }
74}
75
76#[derive(Default)]
79pub struct BaseRuntimeApi<Caller>(PhantomData<Caller>);
80
81#[wit_export(package = "linera:app")]
82impl<Caller, Runtime> BaseRuntimeApi<Caller>
83where
84 Caller: Instance<UserData = RuntimeApiData<Runtime>>,
85 Runtime: BaseRuntime + 'static,
86{
87 fn get_chain_id(caller: &mut Caller) -> Result<ChainId, RuntimeError> {
89 caller
90 .user_data_mut()
91 .runtime
92 .chain_id()
93 .map_err(|error| RuntimeError::Custom(error.into()))
94 }
95
96 fn get_block_height(caller: &mut Caller) -> Result<BlockHeight, RuntimeError> {
98 caller
99 .user_data_mut()
100 .runtime
101 .block_height()
102 .map_err(|error| RuntimeError::Custom(error.into()))
103 }
104
105 fn get_application_id(caller: &mut Caller) -> Result<ApplicationId, RuntimeError> {
107 caller
108 .user_data_mut()
109 .runtime
110 .application_id()
111 .map_err(|error| RuntimeError::Custom(error.into()))
112 }
113
114 fn get_application_creator_chain_id(caller: &mut Caller) -> Result<ChainId, RuntimeError> {
116 caller
117 .user_data_mut()
118 .runtime
119 .application_creator_chain_id()
120 .map_err(|error| RuntimeError::Custom(error.into()))
121 }
122
123 fn read_application_description(
125 caller: &mut Caller,
126 application_id: ApplicationId,
127 ) -> Result<ApplicationDescription, RuntimeError> {
128 caller
129 .user_data_mut()
130 .runtime
131 .read_application_description(application_id)
132 .map_err(|error| RuntimeError::Custom(error.into()))
133 }
134
135 fn application_parameters(caller: &mut Caller) -> Result<Vec<u8>, RuntimeError> {
137 caller
138 .user_data_mut()
139 .runtime
140 .application_parameters()
141 .map_err(|error| RuntimeError::Custom(error.into()))
142 }
143
144 fn get_chain_ownership(caller: &mut Caller) -> Result<ChainOwnership, RuntimeError> {
146 caller
147 .user_data_mut()
148 .runtime
149 .chain_ownership()
150 .map_err(|error| RuntimeError::Custom(error.into()))
151 }
152
153 fn get_application_permissions(
155 caller: &mut Caller,
156 ) -> Result<ApplicationPermissions, RuntimeError> {
157 caller
158 .user_data_mut()
159 .runtime
160 .application_permissions()
161 .map_err(|error| RuntimeError::Custom(error.into()))
162 }
163
164 fn read_system_timestamp(caller: &mut Caller) -> Result<Timestamp, RuntimeError> {
166 caller
167 .user_data_mut()
168 .runtime
169 .read_system_timestamp()
170 .map_err(|error| RuntimeError::Custom(error.into()))
171 }
172
173 fn read_chain_balance(caller: &mut Caller) -> Result<Amount, RuntimeError> {
175 caller
176 .user_data_mut()
177 .runtime
178 .read_chain_balance()
179 .map_err(|error| RuntimeError::Custom(error.into()))
180 }
181
182 fn read_owner_balance(
184 caller: &mut Caller,
185 owner: AccountOwner,
186 ) -> Result<Amount, RuntimeError> {
187 caller
188 .user_data_mut()
189 .runtime
190 .read_owner_balance(owner)
191 .map_err(|error| RuntimeError::Custom(error.into()))
192 }
193
194 fn read_owner_balances(
196 caller: &mut Caller,
197 ) -> Result<Vec<(AccountOwner, Amount)>, RuntimeError> {
198 caller
199 .user_data_mut()
200 .runtime
201 .read_owner_balances()
202 .map_err(|error| RuntimeError::Custom(error.into()))
203 }
204
205 fn read_balance_owners(caller: &mut Caller) -> Result<Vec<AccountOwner>, RuntimeError> {
207 caller
208 .user_data_mut()
209 .runtime
210 .read_balance_owners()
211 .map_err(|error| RuntimeError::Custom(error.into()))
212 }
213
214 fn read_allowance(
216 caller: &mut Caller,
217 owner: AccountOwner,
218 spender: AccountOwner,
219 ) -> Result<Amount, RuntimeError> {
220 caller
221 .user_data_mut()
222 .runtime
223 .read_allowance(owner, spender)
224 .map_err(|error| RuntimeError::Custom(error.into()))
225 }
226
227 fn read_allowances(
229 caller: &mut Caller,
230 ) -> Result<Vec<(AccountOwner, AccountOwner, Amount)>, RuntimeError> {
231 caller
232 .user_data_mut()
233 .runtime
234 .read_allowances()
235 .map_err(|error| RuntimeError::Custom(error.into()))
236 }
237
238 fn perform_http_request(
240 caller: &mut Caller,
241 request: http::Request,
242 ) -> Result<http::Response, RuntimeError> {
243 caller
244 .user_data_mut()
245 .runtime
246 .perform_http_request(request)
247 .map_err(|error| RuntimeError::Custom(error.into()))
248 }
249
250 fn assert_before(caller: &mut Caller, timestamp: Timestamp) -> Result<(), RuntimeError> {
254 caller
255 .user_data_mut()
256 .runtime
257 .assert_before(timestamp)
258 .map_err(|error| RuntimeError::Custom(error.into()))
259 }
260
261 fn read_data_blob(caller: &mut Caller, hash: DataBlobHash) -> Result<Vec<u8>, RuntimeError> {
263 caller
264 .user_data_mut()
265 .runtime
266 .read_data_blob(hash)
267 .map_err(|error| RuntimeError::Custom(error.into()))
268 }
269
270 fn assert_data_blob_exists(
272 caller: &mut Caller,
273 hash: DataBlobHash,
274 ) -> Result<(), RuntimeError> {
275 caller
276 .user_data_mut()
277 .runtime
278 .assert_data_blob_exists(hash)
279 .map_err(|error| RuntimeError::Custom(error.into()))
280 }
281
282 fn log(caller: &mut Caller, message: String, level: log::Level) -> Result<(), RuntimeError> {
284 let allowed = caller
285 .user_data_mut()
286 .runtime
287 .allow_application_logs()
288 .map_err(|error| RuntimeError::Custom(error.into()))?;
289
290 if !allowed {
291 return Ok(());
292 }
293
294 #[cfg(web)]
295 {
296 caller
298 .user_data_mut()
299 .runtime
300 .send_log(message.clone(), level);
301 }
302
303 match level {
305 log::Level::Trace => tracing::trace!("{message}"),
306 log::Level::Debug => tracing::debug!("{message}"),
307 log::Level::Info => tracing::info!("{message}"),
308 log::Level::Warn => tracing::warn!("{message}"),
309 log::Level::Error => tracing::error!("{message}"),
310 }
311 Ok(())
312 }
313
314 fn contains_key_new(caller: &mut Caller, key: Vec<u8>) -> Result<u32, RuntimeError> {
316 let mut data = caller.user_data_mut();
317 let promise = data
318 .runtime
319 .contains_key_new(key)
320 .map_err(|error| RuntimeError::Custom(error.into()))?;
321
322 Ok(data.register_promise(promise))
323 }
324
325 fn contains_key_wait(caller: &mut Caller, promise_id: u32) -> Result<bool, RuntimeError> {
327 let mut data = caller.user_data_mut();
328 let promise = data.take_promise(promise_id)?;
329
330 data.runtime
331 .contains_key_wait(&promise)
332 .map_err(|error| RuntimeError::Custom(error.into()))
333 }
334
335 fn contains_keys_new(caller: &mut Caller, keys: Vec<Vec<u8>>) -> Result<u32, RuntimeError> {
337 let mut data = caller.user_data_mut();
338 let promise = data
339 .runtime
340 .contains_keys_new(keys)
341 .map_err(|error| RuntimeError::Custom(error.into()))?;
342
343 Ok(data.register_promise(promise))
344 }
345
346 fn contains_keys_wait(caller: &mut Caller, promise_id: u32) -> Result<Vec<bool>, RuntimeError> {
348 let mut data = caller.user_data_mut();
349 let promise = data.take_promise(promise_id)?;
350
351 data.runtime
352 .contains_keys_wait(&promise)
353 .map_err(|error| RuntimeError::Custom(error.into()))
354 }
355
356 fn read_multi_values_bytes_new(
358 caller: &mut Caller,
359 keys: Vec<Vec<u8>>,
360 ) -> Result<u32, RuntimeError> {
361 let mut data = caller.user_data_mut();
362 let promise = data
363 .runtime
364 .read_multi_values_bytes_new(keys)
365 .map_err(|error| RuntimeError::Custom(error.into()))?;
366
367 Ok(data.register_promise(promise))
368 }
369
370 fn read_multi_values_bytes_wait(
372 caller: &mut Caller,
373 promise_id: u32,
374 ) -> Result<Vec<Option<Vec<u8>>>, RuntimeError> {
375 let mut data = caller.user_data_mut();
376 let promise = data.take_promise(promise_id)?;
377
378 data.runtime
379 .read_multi_values_bytes_wait(&promise)
380 .map_err(|error| RuntimeError::Custom(error.into()))
381 }
382
383 fn read_value_bytes_new(caller: &mut Caller, key: Vec<u8>) -> Result<u32, RuntimeError> {
385 let mut data = caller.user_data_mut();
386 let promise = data
387 .runtime
388 .read_value_bytes_new(key)
389 .map_err(|error| RuntimeError::Custom(error.into()))?;
390
391 Ok(data.register_promise(promise))
392 }
393
394 fn read_value_bytes_wait(
396 caller: &mut Caller,
397 promise_id: u32,
398 ) -> Result<Option<Vec<u8>>, RuntimeError> {
399 let mut data = caller.user_data_mut();
400 let promise = data.take_promise(promise_id)?;
401
402 data.runtime
403 .read_value_bytes_wait(&promise)
404 .map_err(|error| RuntimeError::Custom(error.into()))
405 }
406
407 fn find_keys_new(caller: &mut Caller, key_prefix: Vec<u8>) -> Result<u32, RuntimeError> {
409 let mut data = caller.user_data_mut();
410 let promise = data
411 .runtime
412 .find_keys_by_prefix_new(key_prefix)
413 .map_err(|error| RuntimeError::Custom(error.into()))?;
414
415 Ok(data.register_promise(promise))
416 }
417
418 fn find_keys_wait(caller: &mut Caller, promise_id: u32) -> Result<Vec<Vec<u8>>, RuntimeError> {
420 let mut data = caller.user_data_mut();
421 let promise = data.take_promise(promise_id)?;
422
423 data.runtime
424 .find_keys_by_prefix_wait(&promise)
425 .map_err(|error| RuntimeError::Custom(error.into()))
426 }
427
428 fn find_key_values_new(caller: &mut Caller, key_prefix: Vec<u8>) -> Result<u32, RuntimeError> {
430 let mut data = caller.user_data_mut();
431 let promise = data
432 .runtime
433 .find_key_values_by_prefix_new(key_prefix)
434 .map_err(|error| RuntimeError::Custom(error.into()))?;
435
436 Ok(data.register_promise(promise))
437 }
438
439 #[expect(clippy::type_complexity)]
441 fn find_key_values_wait(
442 caller: &mut Caller,
443 promise_id: u32,
444 ) -> Result<Vec<(Vec<u8>, Vec<u8>)>, RuntimeError> {
445 let mut data = caller.user_data_mut();
446 let promise = data.take_promise(promise_id)?;
447
448 data.runtime
449 .find_key_values_by_prefix_wait(&promise)
450 .map_err(|error| RuntimeError::Custom(error.into()))
451 }
452}
453
454#[derive(Default)]
456pub struct ContractRuntimeApi<Caller>(PhantomData<Caller>);
457
458#[wit_export(package = "linera:app")]
459impl<Caller, Runtime> ContractRuntimeApi<Caller>
460where
461 Caller: Instance<UserData = RuntimeApiData<Runtime>>,
462 Runtime: ContractRuntime + 'static,
463{
464 fn authenticated_owner(caller: &mut Caller) -> Result<Option<AccountOwner>, RuntimeError> {
466 caller
467 .user_data_mut()
468 .runtime
469 .authenticated_owner()
470 .map_err(|error| RuntimeError::Custom(error.into()))
471 }
472
473 fn message_is_bouncing(caller: &mut Caller) -> Result<Option<bool>, RuntimeError> {
477 caller
478 .user_data_mut()
479 .runtime
480 .message_is_bouncing()
481 .map_err(|error| RuntimeError::Custom(error.into()))
482 }
483
484 fn message_origin_chain_id(caller: &mut Caller) -> Result<Option<ChainId>, RuntimeError> {
487 caller
488 .user_data_mut()
489 .runtime
490 .message_origin_chain_id()
491 .map_err(|error| RuntimeError::Custom(error.into()))
492 }
493
494 fn message_origin_timestamp(caller: &mut Caller) -> Result<Option<Timestamp>, RuntimeError> {
497 caller
498 .user_data_mut()
499 .runtime
500 .message_origin_timestamp()
501 .map_err(|error| RuntimeError::Custom(error.into()))
502 }
503
504 fn authenticated_caller_id(caller: &mut Caller) -> Result<Option<ApplicationId>, RuntimeError> {
506 caller
507 .user_data_mut()
508 .runtime
509 .authenticated_caller_id()
510 .map_err(|error| RuntimeError::Custom(error.into()))
511 }
512
513 fn send_message(
515 caller: &mut Caller,
516 message: SendMessageRequest<Vec<u8>>,
517 ) -> Result<(), RuntimeError> {
518 caller
519 .user_data_mut()
520 .runtime
521 .send_message(message)
522 .map_err(|error| RuntimeError::Custom(error.into()))
523 }
524
525 fn transfer(
528 caller: &mut Caller,
529 source: AccountOwner,
530 destination: Account,
531 amount: Amount,
532 ) -> Result<(), RuntimeError> {
533 caller
534 .user_data_mut()
535 .runtime
536 .transfer(source, destination, amount)
537 .map_err(|error| RuntimeError::Custom(error.into()))
538 }
539
540 fn claim(
542 caller: &mut Caller,
543 source: Account,
544 destination: Account,
545 amount: Amount,
546 ) -> Result<(), RuntimeError> {
547 caller
548 .user_data_mut()
549 .runtime
550 .claim(source, destination, amount)
551 .map_err(|error| RuntimeError::Custom(error.into()))
552 }
553
554 fn approve(
556 caller: &mut Caller,
557 owner: AccountOwner,
558 spender: AccountOwner,
559 amount: Amount,
560 ) -> Result<(), RuntimeError> {
561 caller
562 .user_data_mut()
563 .runtime
564 .approve(owner, spender, amount)
565 .map_err(|error| RuntimeError::Custom(error.into()))
566 }
567
568 fn transfer_from(
570 caller: &mut Caller,
571 owner: AccountOwner,
572 spender: AccountOwner,
573 destination: Account,
574 amount: Amount,
575 ) -> Result<(), RuntimeError> {
576 caller
577 .user_data_mut()
578 .runtime
579 .transfer_from(owner, spender, destination, amount)
580 .map_err(|error| RuntimeError::Custom(error.into()))
581 }
582
583 fn open_chain(
587 caller: &mut Caller,
588 chain_ownership: ChainOwnership,
589 application_permissions: ApplicationPermissions,
590 account: AccountOwner,
591 balance: Amount,
592 ) -> Result<ChainId, RuntimeError> {
593 caller
594 .user_data_mut()
595 .runtime
596 .open_chain(chain_ownership, application_permissions, account, balance)
597 .map_err(|error| RuntimeError::Custom(error.into()))
598 }
599
600 fn close_chain(caller: &mut Caller) -> Result<Result<(), ManageChainError>, RuntimeError> {
603 match caller.user_data_mut().runtime.close_chain() {
604 Ok(()) => Ok(Ok(())),
605 Err(ExecutionError::UnauthorizedApplication(_)) => {
606 Ok(Err(ManageChainError::NotPermitted))
607 }
608 Err(error) => Err(RuntimeError::Custom(error.into())),
609 }
610 }
611
612 fn change_ownership(
615 caller: &mut Caller,
616 ownership: ChainOwnership,
617 ) -> Result<Result<(), ManageChainError>, RuntimeError> {
618 match caller.user_data_mut().runtime.change_ownership(ownership) {
619 Ok(()) => Ok(Ok(())),
620 Err(ExecutionError::UnauthorizedApplication(_)) => {
621 Ok(Err(ManageChainError::NotPermitted))
622 }
623 Err(error) => Err(RuntimeError::Custom(error.into())),
624 }
625 }
626
627 fn change_application_permissions(
630 caller: &mut Caller,
631 application_permissions: ApplicationPermissions,
632 ) -> Result<Result<(), ManageChainError>, RuntimeError> {
633 match caller
634 .user_data_mut()
635 .runtime
636 .change_application_permissions(application_permissions)
637 {
638 Ok(()) => Ok(Ok(())),
639 Err(ExecutionError::UnauthorizedApplication(_)) => {
640 Ok(Err(ManageChainError::NotPermitted))
641 }
642 Err(error) => Err(RuntimeError::Custom(error.into())),
643 }
644 }
645
646 fn create_application(
649 caller: &mut Caller,
650 module_id: ModuleId,
651 parameters: Vec<u8>,
652 argument: Vec<u8>,
653 required_application_ids: Vec<ApplicationId>,
654 ) -> Result<ApplicationId, RuntimeError> {
655 caller
656 .user_data_mut()
657 .runtime
658 .create_application(module_id, parameters, argument, required_application_ids)
659 .map_err(|error| RuntimeError::Custom(error.into()))
660 }
661
662 fn create_data_blob(caller: &mut Caller, bytes: Vec<u8>) -> Result<DataBlobHash, RuntimeError> {
664 caller
665 .user_data_mut()
666 .runtime
667 .create_data_blob(bytes)
668 .map_err(|error| RuntimeError::Custom(error.into()))
669 }
670
671 fn publish_module(
674 caller: &mut Caller,
675 contract: Bytecode,
676 service: Bytecode,
677 vm_runtime: VmRuntime,
678 formats: Option<Vec<u8>>,
679 ) -> Result<ModuleId, RuntimeError> {
680 caller
681 .user_data_mut()
682 .runtime
683 .publish_module(contract, service, vm_runtime, formats)
684 .map_err(|error| RuntimeError::Custom(error.into()))
685 }
686
687 fn try_call_application(
689 caller: &mut Caller,
690 authenticated: bool,
691 callee_id: ApplicationId,
692 argument: Vec<u8>,
693 ) -> Result<Vec<u8>, RuntimeError> {
694 caller
695 .user_data_mut()
696 .runtime
697 .try_call_application(authenticated, callee_id, argument)
698 .map_err(|error| RuntimeError::Custom(error.into()))
699 }
700
701 fn emit(caller: &mut Caller, name: StreamName, value: Vec<u8>) -> Result<u32, RuntimeError> {
703 caller
704 .user_data_mut()
705 .runtime
706 .emit(name, value)
707 .map_err(|error| RuntimeError::Custom(error.into()))
708 }
709
710 fn read_event(
714 caller: &mut Caller,
715 chain_id: ChainId,
716 name: StreamName,
717 index: u32,
718 ) -> Result<Vec<u8>, RuntimeError> {
719 caller
720 .user_data_mut()
721 .runtime
722 .read_event(chain_id, name, index)
723 .map_err(|error| RuntimeError::Custom(error.into()))
724 }
725
726 fn subscribe_to_events(
728 caller: &mut Caller,
729 chain_id: ChainId,
730 application_id: ApplicationId,
731 name: StreamName,
732 ) -> Result<(), RuntimeError> {
733 caller
734 .user_data_mut()
735 .runtime
736 .subscribe_to_events(chain_id, application_id, name)
737 .map_err(|error| RuntimeError::Custom(error.into()))
738 }
739
740 fn unsubscribe_from_events(
742 caller: &mut Caller,
743 chain_id: ChainId,
744 application_id: ApplicationId,
745 name: StreamName,
746 ) -> Result<(), RuntimeError> {
747 caller
748 .user_data_mut()
749 .runtime
750 .unsubscribe_from_events(chain_id, application_id, name)
751 .map_err(|error| RuntimeError::Custom(error.into()))
752 }
753
754 fn query_service(
756 caller: &mut Caller,
757 application_id: ApplicationId,
758 query: Vec<u8>,
759 ) -> Result<Vec<u8>, RuntimeError> {
760 caller
761 .user_data_mut()
762 .runtime
763 .query_service(application_id, query)
764 .map_err(|error| RuntimeError::Custom(error.into()))
765 }
766
767 fn consume_fuel(caller: &mut Caller, fuel: u64) -> Result<(), RuntimeError> {
772 caller
773 .user_data_mut()
774 .runtime_mut()
775 .consume_fuel(fuel, VmRuntime::Wasm)
776 .map_err(|e| RuntimeError::Custom(e.into()))
777 }
778
779 fn remaining_fuel(caller: &mut Caller) -> Result<u64, RuntimeError> {
781 caller
782 .user_data_mut()
783 .runtime_mut()
784 .remaining_fuel(VmRuntime::Wasm)
785 .map_err(|error| RuntimeError::Custom(error.into()))
786 }
787
788 fn validation_round(caller: &mut Caller) -> Result<Option<u32>, RuntimeError> {
790 caller
791 .user_data_mut()
792 .runtime_mut()
793 .validation_round()
794 .map_err(|error| RuntimeError::Custom(error.into()))
795 }
796
797 fn write_batch(
799 caller: &mut Caller,
800 operations: Vec<WriteOperation>,
801 ) -> Result<(), RuntimeError> {
802 caller
803 .user_data_mut()
804 .runtime_mut()
805 .write_batch(Batch { operations })
806 .map_err(|error| RuntimeError::Custom(error.into()))
807 }
808
809 fn has_empty_storage(
811 caller: &mut Caller,
812 application: ApplicationId,
813 ) -> Result<bool, RuntimeError> {
814 caller
815 .user_data_mut()
816 .runtime_mut()
817 .has_empty_storage(application)
818 .map_err(|error| RuntimeError::Custom(error.into()))
819 }
820}
821
822#[derive(Default)]
824pub struct ServiceRuntimeApi<Caller>(PhantomData<Caller>);
825
826#[wit_export(package = "linera:app")]
827impl<Caller, Runtime> ServiceRuntimeApi<Caller>
828where
829 Caller: Instance<UserData = RuntimeApiData<Runtime>>,
830 Runtime: ServiceRuntime + 'static,
831{
832 fn schedule_operation(caller: &mut Caller, operation: Vec<u8>) -> Result<(), RuntimeError> {
834 caller
835 .user_data_mut()
836 .runtime
837 .schedule_operation(operation)
838 .map_err(|error| RuntimeError::Custom(error.into()))
839 }
840
841 fn try_query_application(
843 caller: &mut Caller,
844 application: ApplicationId,
845 argument: Vec<u8>,
846 ) -> Result<Vec<u8>, RuntimeError> {
847 caller
848 .user_data_mut()
849 .runtime
850 .try_query_application(application, argument)
851 .map_err(|error| RuntimeError::Custom(error.into()))
852 }
853
854 #[expect(unused_variables)]
859 fn check_execution_time(caller: &mut Caller, fuel_consumed: u64) -> Result<(), RuntimeError> {
860 caller
861 .user_data_mut()
862 .runtime_mut()
863 .check_execution_time()
864 .map_err(|error| RuntimeError::Custom(error.into()))
865 }
866}