pallet_contracts_uapi/host/
wasm32.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14use super::{
15	extract_from_slice, ptr_len_or_sentinel, ptr_or_sentinel, CallFlags, HostFn, HostFnImpl, Result,
16};
17use crate::{ReturnCode, ReturnFlags};
18
19mod sys {
20	use super::ReturnCode;
21
22	#[link(wasm_import_module = "seal0")]
23	extern "C" {
24		pub fn account_reentrance_count(account_ptr: *const u8) -> u32;
25
26		pub fn lock_delegate_dependency(code_hash_ptr: *const u8);
27
28		pub fn address(output_ptr: *mut u8, output_len_ptr: *mut u32);
29
30		pub fn balance(output_ptr: *mut u8, output_len_ptr: *mut u32);
31
32		pub fn block_number(output_ptr: *mut u8, output_len_ptr: *mut u32);
33
34		pub fn call(
35			callee_ptr: *const u8,
36			callee_len: u32,
37			gas: u64,
38			value_ptr: *const u8,
39			value_len: u32,
40			input_data_ptr: *const u8,
41			input_data_len: u32,
42			output_ptr: *mut u8,
43			output_len_ptr: *mut u32,
44		) -> ReturnCode;
45
46		pub fn call_chain_extension(
47			func_id: u32,
48			input_ptr: *const u8,
49			input_len: u32,
50			output_ptr: *mut u8,
51			output_len_ptr: *mut u32,
52		) -> ReturnCode;
53
54		pub fn call_runtime(call_ptr: *const u8, call_len: u32) -> ReturnCode;
55
56		pub fn caller(output_ptr: *mut u8, output_len_ptr: *mut u32);
57
58		pub fn caller_is_origin() -> ReturnCode;
59
60		pub fn caller_is_root() -> ReturnCode;
61
62		pub fn clear_storage(key_ptr: *const u8);
63
64		pub fn clear_transient_storage(key_ptr: *const u8, key_len: u32) -> ReturnCode;
65
66		pub fn code_hash(
67			account_id_ptr: *const u8,
68			output_ptr: *mut u8,
69			output_len_ptr: *mut u32,
70		) -> ReturnCode;
71
72		pub fn contains_storage(key_ptr: *const u8) -> ReturnCode;
73
74		pub fn contains_transient_storage(key_ptr: *const u8, key_len: u32) -> ReturnCode;
75
76		pub fn debug_message(str_ptr: *const u8, str_len: u32) -> ReturnCode;
77
78		pub fn delegate_call(
79			flags: u32,
80			code_hash_ptr: *const u8,
81			input_data_ptr: *const u8,
82			input_data_len: u32,
83			output_ptr: *mut u8,
84			output_len_ptr: *mut u32,
85		) -> ReturnCode;
86
87		pub fn deposit_event(
88			topics_ptr: *const u8,
89			topics_len: u32,
90			data_ptr: *const u8,
91			data_len: u32,
92		);
93
94		pub fn ecdsa_recover(
95			signature_ptr: *const u8,
96			message_hash_ptr: *const u8,
97			output_ptr: *mut u8,
98		) -> ReturnCode;
99
100		pub fn ecdsa_to_eth_address(public_key_ptr: *const u8, output_ptr: *mut u8) -> ReturnCode;
101
102		pub fn gas_left(output_ptr: *mut u8, output_len_ptr: *mut u32);
103
104		pub fn get_storage(
105			key_ptr: *const u8,
106			out_ptr: *mut u8,
107			out_len_ptr: *mut u32,
108		) -> ReturnCode;
109
110		pub fn get_transient_storage(
111			key_ptr: *const u8,
112			key_len: u32,
113			out_ptr: *mut u8,
114			out_len_ptr: *mut u32,
115		) -> ReturnCode;
116
117		pub fn hash_blake2_128(input_ptr: *const u8, input_len: u32, output_ptr: *mut u8);
118
119		pub fn hash_blake2_256(input_ptr: *const u8, input_len: u32, output_ptr: *mut u8);
120
121		pub fn hash_keccak_256(input_ptr: *const u8, input_len: u32, output_ptr: *mut u8);
122
123		pub fn hash_sha2_256(input_ptr: *const u8, input_len: u32, output_ptr: *mut u8);
124
125		pub fn input(buf_ptr: *mut u8, buf_len_ptr: *mut u32);
126
127		pub fn instantiation_nonce() -> u64;
128
129		pub fn is_contract(account_id_ptr: *const u8) -> ReturnCode;
130
131		pub fn minimum_balance(output_ptr: *mut u8, output_len_ptr: *mut u32);
132
133		pub fn now(output_ptr: *mut u8, output_len_ptr: *mut u32);
134
135		pub fn own_code_hash(output_ptr: *mut u8, output_len_ptr: *mut u32);
136
137		pub fn reentrance_count() -> u32;
138
139		pub fn unlock_delegate_dependency(code_hash_ptr: *const u8);
140
141		pub fn seal_return(flags: u32, data_ptr: *const u8, data_len: u32) -> !;
142
143		pub fn set_code_hash(code_hash_ptr: *const u8) -> ReturnCode;
144
145		pub fn set_storage(key_ptr: *const u8, value_ptr: *const u8, value_len: u32);
146
147		pub fn set_transient_storage(
148			key_ptr: *const u8,
149			key_len: u32,
150			value_ptr: *const u8,
151			value_len: u32,
152		) -> ReturnCode;
153
154		pub fn sr25519_verify(
155			signature_ptr: *const u8,
156			public_key_ptr: *const u8,
157			message_len: u32,
158			message_ptr: *const u8,
159		) -> ReturnCode;
160
161		pub fn take_storage(
162			key_ptr: *const u8,
163			key_len: u32,
164			out_ptr: *mut u8,
165			out_len_ptr: *mut u32,
166		) -> ReturnCode;
167
168		pub fn take_transient_storage(
169			key_ptr: *const u8,
170			key_len: u32,
171			out_ptr: *mut u8,
172			out_len_ptr: *mut u32,
173		) -> ReturnCode;
174
175		pub fn terminate(beneficiary_ptr: *const u8) -> !;
176
177		pub fn transfer(
178			account_id_ptr: *const u8,
179			account_id_len: u32,
180			transferred_value_ptr: *const u8,
181			transferred_value_len: u32,
182		) -> ReturnCode;
183
184		pub fn value_transferred(output_ptr: *mut u8, output_len_ptr: *mut u32);
185
186		pub fn weight_to_fee(gas: u64, output_ptr: *mut u8, output_len_ptr: *mut u32);
187
188		pub fn xcm_execute(msg_ptr: *const u8, msg_len: u32) -> ReturnCode;
189
190		pub fn xcm_send(
191			dest_ptr: *const u8,
192			msg_ptr: *const u8,
193			msg_len: u32,
194			output_ptr: *mut u8,
195		) -> ReturnCode;
196	}
197
198	pub mod v1 {
199		use crate::ReturnCode;
200
201		#[link(wasm_import_module = "seal1")]
202		extern "C" {
203			pub fn call(
204				flags: u32,
205				callee_ptr: *const u8,
206				gas: u64,
207				transferred_value_ptr: *const u8,
208				input_data_ptr: *const u8,
209				input_data_len: u32,
210				output_ptr: *mut u8,
211				output_len_ptr: *mut u32,
212			) -> ReturnCode;
213
214			pub fn clear_storage(key_ptr: *const u8, key_len: u32) -> ReturnCode;
215
216			pub fn contains_storage(key_ptr: *const u8, key_len: u32) -> ReturnCode;
217
218			pub fn gas_left(output_ptr: *mut u8, output_len_ptr: *mut u32);
219
220			pub fn get_storage(
221				key_ptr: *const u8,
222				key_len: u32,
223				out_ptr: *mut u8,
224				out_len_ptr: *mut u32,
225			) -> ReturnCode;
226
227			pub fn instantiate(
228				code_hash_ptr: *const u8,
229				gas: u64,
230				value_ptr: *const u8,
231				input_ptr: *const u8,
232				input_len: u32,
233				address_ptr: *mut u8,
234				address_len_ptr: *mut u32,
235				output_ptr: *mut u8,
236				output_len_ptr: *mut u32,
237				salt_ptr: *const u8,
238				salt_len: u32,
239			) -> ReturnCode;
240
241			pub fn set_storage(
242				key_ptr: *const u8,
243				value_ptr: *const u8,
244				value_len: u32,
245			) -> ReturnCode;
246
247			pub fn terminate(beneficiary_ptr: *const u8) -> !;
248
249			pub fn weight_to_fee(
250				ref_time_limit: u64,
251				proof_size_limit: u64,
252				output_ptr: *mut u8,
253				output_len_ptr: *mut u32,
254			);
255		}
256	}
257
258	pub mod v2 {
259		use crate::ReturnCode;
260
261		#[link(wasm_import_module = "seal2")]
262		extern "C" {
263			pub fn call(
264				flags: u32,
265				callee_ptr: *const u8,
266				ref_time_limit: u64,
267				proof_size_limit: u64,
268				deposit_ptr: *const u8,
269				transferred_value_ptr: *const u8,
270				input_data_ptr: *const u8,
271				input_data_len: u32,
272				output_ptr: *mut u8,
273				output_len_ptr: *mut u32,
274			) -> ReturnCode;
275
276			pub fn instantiate(
277				code_hash_ptr: *const u8,
278				ref_time_limit: u64,
279				proof_size_limit: u64,
280				deposit_ptr: *const u8,
281				value_ptr: *const u8,
282				input_ptr: *const u8,
283				input_len: u32,
284				address_ptr: *mut u8,
285				address_len_ptr: *mut u32,
286				output_ptr: *mut u8,
287				output_len_ptr: *mut u32,
288				salt_ptr: *const u8,
289				salt_len: u32,
290			) -> ReturnCode;
291
292			pub fn set_storage(
293				key_ptr: *const u8,
294				key_len: u32,
295				value_ptr: *const u8,
296				value_len: u32,
297			) -> ReturnCode;
298		}
299	}
300}
301
302/// A macro to implement all Host functions with a signature of `fn(&mut &mut [u8])`.
303///
304/// Example:
305/// ```nocompile
306// impl_wrapper_for! {
307//     () => [gas_left],
308//     (v1) => [gas_left],
309// }
310// ```
311// 
312// Expands to:
313// ```nocompile
314// fn gas_left(output: &mut &mut [u8]) {
315//     unsafe { sys::gas_left(...); }
316// }
317// fn gas_left_v1(output: &mut &mut [u8]) {
318//     unsafe { sys::v1::gas_left(...); }
319// }
320// ```
321macro_rules! impl_wrapper_for {
322	(@impl_fn $( $mod:ident )::*, $suffix_sep: literal, $suffix:tt, $name:ident) => {
323		paste::paste! {
324			fn [<$name $suffix_sep $suffix>](output: &mut &mut [u8]) {
325				let mut output_len = output.len() as u32;
326				unsafe {
327					$( $mod )::*::$name(output.as_mut_ptr(), &mut output_len);
328				}
329				extract_from_slice(output, output_len as usize)
330			}
331		}
332	};
333
334	() => {};
335
336	(($mod:ident) => [$( $name:ident),*], $($tail:tt)*) => {
337		$(impl_wrapper_for!(@impl_fn sys::$mod, "_", $mod, $name);)*
338		impl_wrapper_for!($($tail)*);
339	};
340
341	(() =>	[$( $name:ident),*], $($tail:tt)*) => {
342		$(impl_wrapper_for!(@impl_fn sys, "", "", $name);)*
343		impl_wrapper_for!($($tail)*);
344	};
345}
346
347/// A macro to implement all the hash functions Apis.
348macro_rules! impl_hash_fn {
349	( $name:ident, $bytes_result:literal ) => {
350		paste::item! {
351			fn [<hash_ $name>](input: &[u8], output: &mut [u8; $bytes_result]) {
352				unsafe {
353					sys::[<hash_ $name>](
354						input.as_ptr(),
355						input.len() as u32,
356						output.as_mut_ptr(),
357					)
358				}
359			}
360		}
361	};
362}
363
364impl HostFn for HostFnImpl {
365	#[inline(always)]
366	fn instantiate_v1(
367		code_hash: &[u8],
368		gas: u64,
369		value: &[u8],
370		input: &[u8],
371		mut address: Option<&mut &mut [u8]>,
372		mut output: Option<&mut &mut [u8]>,
373		salt: &[u8],
374	) -> Result {
375		let (address_ptr, mut address_len) = ptr_len_or_sentinel(&mut address);
376		let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
377		let ret_code = unsafe {
378			sys::v1::instantiate(
379				code_hash.as_ptr(),
380				gas,
381				value.as_ptr(),
382				input.as_ptr(),
383				input.len() as u32,
384				address_ptr,
385				&mut address_len,
386				output_ptr,
387				&mut output_len,
388				salt.as_ptr(),
389				salt.len() as u32,
390			)
391		};
392
393		if let Some(ref mut address) = address {
394			extract_from_slice(address, address_len as usize);
395		}
396		if let Some(ref mut output) = output {
397			extract_from_slice(output, output_len as usize);
398		}
399		ret_code.into()
400	}
401
402	fn instantiate_v2(
403		code_hash: &[u8],
404		ref_time_limit: u64,
405		proof_size_limit: u64,
406		deposit: Option<&[u8]>,
407		value: &[u8],
408		input: &[u8],
409		mut address: Option<&mut &mut [u8]>,
410		mut output: Option<&mut &mut [u8]>,
411		salt: &[u8],
412	) -> Result {
413		let (address_ptr, mut address_len) = ptr_len_or_sentinel(&mut address);
414		let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
415		let deposit_ptr = ptr_or_sentinel(&deposit);
416
417		let ret_code = {
418			unsafe {
419				sys::v2::instantiate(
420					code_hash.as_ptr(),
421					ref_time_limit,
422					proof_size_limit,
423					deposit_ptr,
424					value.as_ptr(),
425					input.as_ptr(),
426					input.len() as u32,
427					address_ptr,
428					&mut address_len,
429					output_ptr,
430					&mut output_len,
431					salt.as_ptr(),
432					salt.len() as u32,
433				)
434			}
435		};
436
437		if let Some(ref mut address) = address {
438			extract_from_slice(address, address_len as usize);
439		}
440
441		if let Some(ref mut output) = output {
442			extract_from_slice(output, output_len as usize);
443		}
444
445		ret_code.into()
446	}
447
448	#[inline(always)]
449	fn call(
450		callee: &[u8],
451		gas: u64,
452		value: &[u8],
453		input_data: &[u8],
454		mut output: Option<&mut &mut [u8]>,
455	) -> Result {
456		let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
457		let ret_code = {
458			unsafe {
459				sys::call(
460					callee.as_ptr(),
461					callee.len() as u32,
462					gas,
463					value.as_ptr(),
464					value.len() as u32,
465					input_data.as_ptr(),
466					input_data.len() as u32,
467					output_ptr,
468					&mut output_len,
469				)
470			}
471		};
472
473		if let Some(ref mut output) = output {
474			extract_from_slice(output, output_len as usize);
475		}
476
477		ret_code.into()
478	}
479
480	#[inline(always)]
481	fn call_v1(
482		flags: CallFlags,
483		callee: &[u8],
484		gas: u64,
485		value: &[u8],
486		input_data: &[u8],
487		mut output: Option<&mut &mut [u8]>,
488	) -> Result {
489		let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
490		let ret_code = {
491			unsafe {
492				sys::v1::call(
493					flags.bits(),
494					callee.as_ptr(),
495					gas,
496					value.as_ptr(),
497					input_data.as_ptr(),
498					input_data.len() as u32,
499					output_ptr,
500					&mut output_len,
501				)
502			}
503		};
504
505		if let Some(ref mut output) = output {
506			extract_from_slice(output, output_len as usize);
507		}
508
509		ret_code.into()
510	}
511
512	fn call_v2(
513		flags: CallFlags,
514		callee: &[u8],
515		ref_time_limit: u64,
516		proof_size_limit: u64,
517		deposit: Option<&[u8]>,
518		value: &[u8],
519		input_data: &[u8],
520		mut output: Option<&mut &mut [u8]>,
521	) -> Result {
522		let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
523		let deposit_ptr = ptr_or_sentinel(&deposit);
524		let ret_code = {
525			unsafe {
526				sys::v2::call(
527					flags.bits(),
528					callee.as_ptr(),
529					ref_time_limit,
530					proof_size_limit,
531					deposit_ptr,
532					value.as_ptr(),
533					input_data.as_ptr(),
534					input_data.len() as u32,
535					output_ptr,
536					&mut output_len,
537				)
538			}
539		};
540
541		if let Some(ref mut output) = output {
542			extract_from_slice(output, output_len as usize);
543		}
544
545		ret_code.into()
546	}
547
548	fn caller_is_root() -> u32 {
549		unsafe { sys::caller_is_root() }.into_u32()
550	}
551
552	#[inline(always)]
553	fn delegate_call(
554		flags: CallFlags,
555		code_hash: &[u8],
556		input: &[u8],
557		mut output: Option<&mut &mut [u8]>,
558	) -> Result {
559		let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
560		let ret_code = {
561			unsafe {
562				sys::delegate_call(
563					flags.bits(),
564					code_hash.as_ptr(),
565					input.as_ptr(),
566					input.len() as u32,
567					output_ptr,
568					&mut output_len,
569				)
570			}
571		};
572
573		if let Some(ref mut output) = output {
574			extract_from_slice(output, output_len as usize);
575		}
576
577		ret_code.into()
578	}
579
580	fn transfer(account_id: &[u8], value: &[u8]) -> Result {
581		let ret_code = unsafe {
582			sys::transfer(
583				account_id.as_ptr(),
584				account_id.len() as u32,
585				value.as_ptr(),
586				value.len() as u32,
587			)
588		};
589		ret_code.into()
590	}
591
592	fn deposit_event(topics: &[u8], data: &[u8]) {
593		unsafe {
594			sys::deposit_event(
595				topics.as_ptr(),
596				topics.len() as u32,
597				data.as_ptr(),
598				data.len() as u32,
599			)
600		}
601	}
602
603	fn set_storage(key: &[u8], value: &[u8]) {
604		unsafe { sys::set_storage(key.as_ptr(), value.as_ptr(), value.len() as u32) };
605	}
606
607	fn set_storage_v1(key: &[u8], encoded_value: &[u8]) -> Option<u32> {
608		let ret_code = unsafe {
609			sys::v1::set_storage(key.as_ptr(), encoded_value.as_ptr(), encoded_value.len() as u32)
610		};
611		ret_code.into()
612	}
613
614	fn set_storage_v2(key: &[u8], encoded_value: &[u8]) -> Option<u32> {
615		let ret_code = unsafe {
616			sys::v2::set_storage(
617				key.as_ptr(),
618				key.len() as u32,
619				encoded_value.as_ptr(),
620				encoded_value.len() as u32,
621			)
622		};
623		ret_code.into()
624	}
625
626	fn set_transient_storage(key: &[u8], encoded_value: &[u8]) -> Option<u32> {
627		let ret_code = unsafe {
628			sys::set_transient_storage(
629				key.as_ptr(),
630				key.len() as u32,
631				encoded_value.as_ptr(),
632				encoded_value.len() as u32,
633			)
634		};
635		ret_code.into()
636	}
637
638	fn clear_storage(key: &[u8]) {
639		unsafe { sys::clear_storage(key.as_ptr()) };
640	}
641
642	fn clear_storage_v1(key: &[u8]) -> Option<u32> {
643		let ret_code = unsafe { sys::v1::clear_storage(key.as_ptr(), key.len() as u32) };
644		ret_code.into()
645	}
646
647	fn clear_transient_storage(key: &[u8]) -> Option<u32> {
648		let ret_code = unsafe { sys::clear_transient_storage(key.as_ptr(), key.len() as u32) };
649		ret_code.into()
650	}
651
652	#[inline(always)]
653	fn get_storage(key: &[u8], output: &mut &mut [u8]) -> Result {
654		let mut output_len = output.len() as u32;
655		let ret_code =
656			{ unsafe { sys::get_storage(key.as_ptr(), output.as_mut_ptr(), &mut output_len) } };
657		extract_from_slice(output, output_len as usize);
658		ret_code.into()
659	}
660
661	#[inline(always)]
662	fn get_storage_v1(key: &[u8], output: &mut &mut [u8]) -> Result {
663		let mut output_len = output.len() as u32;
664		let ret_code = {
665			unsafe {
666				sys::v1::get_storage(
667					key.as_ptr(),
668					key.len() as u32,
669					output.as_mut_ptr(),
670					&mut output_len,
671				)
672			}
673		};
674		extract_from_slice(output, output_len as usize);
675		ret_code.into()
676	}
677
678	#[inline(always)]
679	fn get_transient_storage(key: &[u8], output: &mut &mut [u8]) -> Result {
680		let mut output_len = output.len() as u32;
681		let ret_code = {
682			unsafe {
683				sys::get_transient_storage(
684					key.as_ptr(),
685					key.len() as u32,
686					output.as_mut_ptr(),
687					&mut output_len,
688				)
689			}
690		};
691		extract_from_slice(output, output_len as usize);
692		ret_code.into()
693	}
694
695	#[inline(always)]
696	fn take_storage(key: &[u8], output: &mut &mut [u8]) -> Result {
697		let mut output_len = output.len() as u32;
698		let ret_code = {
699			unsafe {
700				sys::take_storage(
701					key.as_ptr(),
702					key.len() as u32,
703					output.as_mut_ptr(),
704					&mut output_len,
705				)
706			}
707		};
708		extract_from_slice(output, output_len as usize);
709		ret_code.into()
710	}
711
712	#[inline(always)]
713	fn take_transient_storage(key: &[u8], output: &mut &mut [u8]) -> Result {
714		let mut output_len = output.len() as u32;
715		let ret_code = {
716			unsafe {
717				sys::take_transient_storage(
718					key.as_ptr(),
719					key.len() as u32,
720					output.as_mut_ptr(),
721					&mut output_len,
722				)
723			}
724		};
725		extract_from_slice(output, output_len as usize);
726		ret_code.into()
727	}
728
729	fn debug_message(str: &[u8]) -> Result {
730		let ret_code = unsafe { sys::debug_message(str.as_ptr(), str.len() as u32) };
731		ret_code.into()
732	}
733
734	fn contains_storage(key: &[u8]) -> Option<u32> {
735		let ret_code = unsafe { sys::contains_storage(key.as_ptr()) };
736		ret_code.into()
737	}
738
739	fn contains_storage_v1(key: &[u8]) -> Option<u32> {
740		let ret_code = unsafe { sys::v1::contains_storage(key.as_ptr(), key.len() as u32) };
741		ret_code.into()
742	}
743
744	fn contains_transient_storage(key: &[u8]) -> Option<u32> {
745		let ret_code = unsafe { sys::contains_transient_storage(key.as_ptr(), key.len() as u32) };
746		ret_code.into()
747	}
748
749	fn terminate(beneficiary: &[u8]) -> ! {
750		unsafe { sys::terminate(beneficiary.as_ptr()) }
751	}
752
753	fn terminate_v1(beneficiary: &[u8]) -> ! {
754		unsafe { sys::v1::terminate(beneficiary.as_ptr()) }
755	}
756
757	fn call_chain_extension(func_id: u32, input: &[u8], mut output: Option<&mut &mut [u8]>) -> u32 {
758		let (output_ptr, mut output_len) = ptr_len_or_sentinel(&mut output);
759		let ret_code = {
760			unsafe {
761				sys::call_chain_extension(
762					func_id,
763					input.as_ptr(),
764					input.len() as u32,
765					output_ptr,
766					&mut output_len,
767				)
768			}
769		};
770
771		if let Some(ref mut output) = output {
772			extract_from_slice(output, output_len as usize);
773		}
774		ret_code.into_u32()
775	}
776
777	#[inline(always)]
778	fn input(output: &mut &mut [u8]) {
779		let mut output_len = output.len() as u32;
780		{
781			unsafe { sys::input(output.as_mut_ptr(), &mut output_len) };
782		}
783		extract_from_slice(output, output_len as usize);
784	}
785
786	fn return_value(flags: ReturnFlags, return_value: &[u8]) -> ! {
787		unsafe { sys::seal_return(flags.bits(), return_value.as_ptr(), return_value.len() as u32) }
788	}
789
790	fn call_runtime(call: &[u8]) -> Result {
791		let ret_code = unsafe { sys::call_runtime(call.as_ptr(), call.len() as u32) };
792		ret_code.into()
793	}
794
795	impl_wrapper_for! {
796		() => [caller, block_number, address, balance, gas_left, value_transferred, now, minimum_balance],
797		(v1) => [gas_left],
798	}
799
800	#[inline(always)]
801	fn weight_to_fee(gas: u64, output: &mut &mut [u8]) {
802		let mut output_len = output.len() as u32;
803		{
804			unsafe { sys::weight_to_fee(gas, output.as_mut_ptr(), &mut output_len) };
805		}
806		extract_from_slice(output, output_len as usize);
807	}
808
809	fn weight_to_fee_v1(ref_time_limit: u64, proof_size_limit: u64, output: &mut &mut [u8]) {
810		let mut output_len = output.len() as u32;
811		{
812			unsafe {
813				sys::v1::weight_to_fee(
814					ref_time_limit,
815					proof_size_limit,
816					output.as_mut_ptr(),
817					&mut output_len,
818				)
819			};
820		}
821		extract_from_slice(output, output_len as usize);
822	}
823
824	impl_hash_fn!(sha2_256, 32);
825	impl_hash_fn!(keccak_256, 32);
826	impl_hash_fn!(blake2_256, 32);
827	impl_hash_fn!(blake2_128, 16);
828
829	fn ecdsa_recover(
830		signature: &[u8; 65],
831		message_hash: &[u8; 32],
832		output: &mut [u8; 33],
833	) -> Result {
834		let ret_code = unsafe {
835			sys::ecdsa_recover(signature.as_ptr(), message_hash.as_ptr(), output.as_mut_ptr())
836		};
837		ret_code.into()
838	}
839
840	fn ecdsa_to_eth_address(pubkey: &[u8; 33], output: &mut [u8; 20]) -> Result {
841		let ret_code = unsafe { sys::ecdsa_to_eth_address(pubkey.as_ptr(), output.as_mut_ptr()) };
842		ret_code.into()
843	}
844
845	fn sr25519_verify(signature: &[u8; 64], message: &[u8], pub_key: &[u8; 32]) -> Result {
846		let ret_code = unsafe {
847			sys::sr25519_verify(
848				signature.as_ptr(),
849				pub_key.as_ptr(),
850				message.len() as u32,
851				message.as_ptr(),
852			)
853		};
854		ret_code.into()
855	}
856
857	fn is_contract(account_id: &[u8]) -> bool {
858		let ret_val = unsafe { sys::is_contract(account_id.as_ptr()) };
859		ret_val.into_bool()
860	}
861
862	fn caller_is_origin() -> bool {
863		let ret_val = unsafe { sys::caller_is_origin() };
864		ret_val.into_bool()
865	}
866
867	fn set_code_hash(code_hash: &[u8]) -> Result {
868		let ret_val = unsafe { sys::set_code_hash(code_hash.as_ptr()) };
869		ret_val.into()
870	}
871
872	fn code_hash(account_id: &[u8], output: &mut [u8]) -> Result {
873		let mut output_len = output.len() as u32;
874		let ret_val =
875			unsafe { sys::code_hash(account_id.as_ptr(), output.as_mut_ptr(), &mut output_len) };
876		ret_val.into()
877	}
878
879	fn own_code_hash(output: &mut [u8]) {
880		let mut output_len = output.len() as u32;
881		unsafe { sys::own_code_hash(output.as_mut_ptr(), &mut output_len) }
882	}
883
884	fn account_reentrance_count(account: &[u8]) -> u32 {
885		unsafe { sys::account_reentrance_count(account.as_ptr()) }
886	}
887
888	fn lock_delegate_dependency(code_hash: &[u8]) {
889		unsafe { sys::lock_delegate_dependency(code_hash.as_ptr()) }
890	}
891
892	fn unlock_delegate_dependency(code_hash: &[u8]) {
893		unsafe { sys::unlock_delegate_dependency(code_hash.as_ptr()) }
894	}
895
896	fn instantiation_nonce() -> u64 {
897		unsafe { sys::instantiation_nonce() }
898	}
899
900	fn reentrance_count() -> u32 {
901		unsafe { sys::reentrance_count() }
902	}
903
904	fn xcm_execute(msg: &[u8]) -> Result {
905		let ret_code = unsafe { sys::xcm_execute(msg.as_ptr(), msg.len() as _) };
906		ret_code.into()
907	}
908
909	fn xcm_send(dest: &[u8], msg: &[u8], output: &mut [u8; 32]) -> Result {
910		let ret_code = unsafe {
911			sys::xcm_send(dest.as_ptr(), msg.as_ptr(), msg.len() as _, output.as_mut_ptr())
912		};
913		ret_code.into()
914	}
915}