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(
586 caller: &mut Caller,
587 chain_ownership: ChainOwnership,
588 application_permissions: ApplicationPermissions,
589 balance: Amount,
590 ) -> Result<ChainId, RuntimeError> {
591 caller
592 .user_data_mut()
593 .runtime
594 .open_chain(chain_ownership, application_permissions, balance)
595 .map_err(|error| RuntimeError::Custom(error.into()))
596 }
597
598 fn close_chain(caller: &mut Caller) -> Result<Result<(), ManageChainError>, RuntimeError> {
601 match caller.user_data_mut().runtime.close_chain() {
602 Ok(()) => Ok(Ok(())),
603 Err(ExecutionError::UnauthorizedApplication(_)) => {
604 Ok(Err(ManageChainError::NotPermitted))
605 }
606 Err(error) => Err(RuntimeError::Custom(error.into())),
607 }
608 }
609
610 fn change_ownership(
613 caller: &mut Caller,
614 ownership: ChainOwnership,
615 ) -> Result<Result<(), ManageChainError>, RuntimeError> {
616 match caller.user_data_mut().runtime.change_ownership(ownership) {
617 Ok(()) => Ok(Ok(())),
618 Err(ExecutionError::UnauthorizedApplication(_)) => {
619 Ok(Err(ManageChainError::NotPermitted))
620 }
621 Err(error) => Err(RuntimeError::Custom(error.into())),
622 }
623 }
624
625 fn change_application_permissions(
628 caller: &mut Caller,
629 application_permissions: ApplicationPermissions,
630 ) -> Result<Result<(), ManageChainError>, RuntimeError> {
631 match caller
632 .user_data_mut()
633 .runtime
634 .change_application_permissions(application_permissions)
635 {
636 Ok(()) => Ok(Ok(())),
637 Err(ExecutionError::UnauthorizedApplication(_)) => {
638 Ok(Err(ManageChainError::NotPermitted))
639 }
640 Err(error) => Err(RuntimeError::Custom(error.into())),
641 }
642 }
643
644 fn create_application(
647 caller: &mut Caller,
648 module_id: ModuleId,
649 parameters: Vec<u8>,
650 argument: Vec<u8>,
651 required_application_ids: Vec<ApplicationId>,
652 ) -> Result<ApplicationId, RuntimeError> {
653 caller
654 .user_data_mut()
655 .runtime
656 .create_application(module_id, parameters, argument, required_application_ids)
657 .map_err(|error| RuntimeError::Custom(error.into()))
658 }
659
660 fn create_data_blob(caller: &mut Caller, bytes: Vec<u8>) -> Result<DataBlobHash, RuntimeError> {
662 caller
663 .user_data_mut()
664 .runtime
665 .create_data_blob(bytes)
666 .map_err(|error| RuntimeError::Custom(error.into()))
667 }
668
669 fn publish_module(
672 caller: &mut Caller,
673 contract: Bytecode,
674 service: Bytecode,
675 vm_runtime: VmRuntime,
676 formats: Option<Vec<u8>>,
677 ) -> Result<ModuleId, RuntimeError> {
678 caller
679 .user_data_mut()
680 .runtime
681 .publish_module(contract, service, vm_runtime, formats)
682 .map_err(|error| RuntimeError::Custom(error.into()))
683 }
684
685 fn try_call_application(
687 caller: &mut Caller,
688 authenticated: bool,
689 callee_id: ApplicationId,
690 argument: Vec<u8>,
691 ) -> Result<Vec<u8>, RuntimeError> {
692 caller
693 .user_data_mut()
694 .runtime
695 .try_call_application(authenticated, callee_id, argument)
696 .map_err(|error| RuntimeError::Custom(error.into()))
697 }
698
699 fn emit(caller: &mut Caller, name: StreamName, value: Vec<u8>) -> Result<u32, RuntimeError> {
701 caller
702 .user_data_mut()
703 .runtime
704 .emit(name, value)
705 .map_err(|error| RuntimeError::Custom(error.into()))
706 }
707
708 fn read_event(
712 caller: &mut Caller,
713 chain_id: ChainId,
714 name: StreamName,
715 index: u32,
716 ) -> Result<Vec<u8>, RuntimeError> {
717 caller
718 .user_data_mut()
719 .runtime
720 .read_event(chain_id, name, index)
721 .map_err(|error| RuntimeError::Custom(error.into()))
722 }
723
724 fn subscribe_to_events(
726 caller: &mut Caller,
727 chain_id: ChainId,
728 application_id: ApplicationId,
729 name: StreamName,
730 ) -> Result<(), RuntimeError> {
731 caller
732 .user_data_mut()
733 .runtime
734 .subscribe_to_events(chain_id, application_id, name)
735 .map_err(|error| RuntimeError::Custom(error.into()))
736 }
737
738 fn unsubscribe_from_events(
740 caller: &mut Caller,
741 chain_id: ChainId,
742 application_id: ApplicationId,
743 name: StreamName,
744 ) -> Result<(), RuntimeError> {
745 caller
746 .user_data_mut()
747 .runtime
748 .unsubscribe_from_events(chain_id, application_id, name)
749 .map_err(|error| RuntimeError::Custom(error.into()))
750 }
751
752 fn query_service(
754 caller: &mut Caller,
755 application_id: ApplicationId,
756 query: Vec<u8>,
757 ) -> Result<Vec<u8>, RuntimeError> {
758 caller
759 .user_data_mut()
760 .runtime
761 .query_service(application_id, query)
762 .map_err(|error| RuntimeError::Custom(error.into()))
763 }
764
765 fn consume_fuel(caller: &mut Caller, fuel: u64) -> Result<(), RuntimeError> {
770 caller
771 .user_data_mut()
772 .runtime_mut()
773 .consume_fuel(fuel, VmRuntime::Wasm)
774 .map_err(|e| RuntimeError::Custom(e.into()))
775 }
776
777 fn remaining_fuel(caller: &mut Caller) -> Result<u64, RuntimeError> {
779 caller
780 .user_data_mut()
781 .runtime_mut()
782 .remaining_fuel(VmRuntime::Wasm)
783 .map_err(|error| RuntimeError::Custom(error.into()))
784 }
785
786 fn validation_round(caller: &mut Caller) -> Result<Option<u32>, RuntimeError> {
788 caller
789 .user_data_mut()
790 .runtime_mut()
791 .validation_round()
792 .map_err(|error| RuntimeError::Custom(error.into()))
793 }
794
795 fn write_batch(
797 caller: &mut Caller,
798 operations: Vec<WriteOperation>,
799 ) -> Result<(), RuntimeError> {
800 caller
801 .user_data_mut()
802 .runtime_mut()
803 .write_batch(Batch { operations })
804 .map_err(|error| RuntimeError::Custom(error.into()))
805 }
806
807 fn has_empty_storage(
809 caller: &mut Caller,
810 application: ApplicationId,
811 ) -> Result<bool, RuntimeError> {
812 caller
813 .user_data_mut()
814 .runtime_mut()
815 .has_empty_storage(application)
816 .map_err(|error| RuntimeError::Custom(error.into()))
817 }
818}
819
820#[derive(Default)]
822pub struct ServiceRuntimeApi<Caller>(PhantomData<Caller>);
823
824#[wit_export(package = "linera:app")]
825impl<Caller, Runtime> ServiceRuntimeApi<Caller>
826where
827 Caller: Instance<UserData = RuntimeApiData<Runtime>>,
828 Runtime: ServiceRuntime + 'static,
829{
830 fn schedule_operation(caller: &mut Caller, operation: Vec<u8>) -> Result<(), RuntimeError> {
832 caller
833 .user_data_mut()
834 .runtime
835 .schedule_operation(operation)
836 .map_err(|error| RuntimeError::Custom(error.into()))
837 }
838
839 fn try_query_application(
841 caller: &mut Caller,
842 application: ApplicationId,
843 argument: Vec<u8>,
844 ) -> Result<Vec<u8>, RuntimeError> {
845 caller
846 .user_data_mut()
847 .runtime
848 .try_query_application(application, argument)
849 .map_err(|error| RuntimeError::Custom(error.into()))
850 }
851
852 #[expect(unused_variables)]
857 fn check_execution_time(caller: &mut Caller, fuel_consumed: u64) -> Result<(), RuntimeError> {
858 caller
859 .user_data_mut()
860 .runtime_mut()
861 .check_execution_time()
862 .map_err(|error| RuntimeError::Custom(error.into()))
863 }
864}