pallet_evm_polkavm_uapi/host.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 crate::ReturnFlags;
15
16#[cfg(target_arch = "riscv64")]
17mod riscv64;
18
19/// Implements [`HostFn`] when compiled on supported architectures (RISC-V).
20pub enum HostFnImpl {}
21
22/// Defines all the host apis available to contracts.
23pub trait HostFn: private::Sealed {
24 /// Stores the address of the current contract into the supplied buffer.
25 ///
26 /// # Parameters
27 ///
28 /// - `output`: A reference to the output data buffer to write the address.
29 fn address(output: &mut [u8; 20]);
30
31 /// Stores the U256 value at given `offset` from the input passed by the caller
32 /// into the supplied buffer.
33 ///
34 /// # Note
35 /// - If `offset` is out of bounds, a value of zero will be returned.
36 /// - If `offset` is in bounds but there is not enough call data, the available data
37 /// is right-padded in order to fill a whole U256 value.
38 /// - The data written to `output` is a little endian U256 integer value.
39 ///
40 /// # Parameters
41 ///
42 /// - `output`: A reference to the fixed output data buffer to write the value.
43 /// - `offset`: The offset (index) into the call data.
44 fn call_data_load(output: &mut [u8; 32], offset: u32);
45
46 /// Returns the call data size.
47 fn call_data_size() -> u64;
48
49 /// Stores the input data passed by the caller into the supplied `output` buffer,
50 /// starting from the given input data `offset`.
51 ///
52 /// The `output` buffer is guaranteed to always be fully populated:
53 /// - If the call data (starting from the given `offset`) is larger than the `output` buffer,
54 /// only what fits into the `output` buffer is written.
55 /// - If the `output` buffer size exceeds the call data size (starting from `offset`), remaining
56 /// bytes in the `output` buffer are zeroed out.
57 /// - If the provided call data `offset` is out-of-bounds, the whole `output` buffer is zeroed
58 /// out.
59 ///
60 /// # Note
61 ///
62 /// This function traps if:
63 /// - the input was previously forwarded by a [`call()`][`Self::call()`].
64 /// - the `output` buffer is located in an PolkaVM invalid memory range.
65 ///
66 /// # Parameters
67 ///
68 /// - `output`: A reference to the output data buffer to write the call data.
69 /// - `offset`: The offset index into the call data from where to start copying.
70 fn call_data_copy(output: &mut [u8], offset: u32);
71
72 /// Stores the address of the caller into the supplied buffer.
73 ///
74 /// If this is a top-level call (i.e. initiated by an extrinsic) the origin address of the
75 /// extrinsic will be returned. Otherwise, if this call is initiated by another contract then
76 /// the address of the contract will be returned.
77 ///
78 /// If there is no address associated with the caller (e.g. because the caller is root) then
79 /// it traps with `BadOrigin`.
80 ///
81 /// # Parameters
82 ///
83 /// - `output`: A reference to the output data buffer to write the caller address.
84 fn caller(output: &mut [u8; 20]);
85
86 /// Stores the origin address (initator of the call stack) into the supplied buffer.
87 ///
88 /// If there is no address associated with the origin (e.g. because the origin is root) then
89 /// it traps with `BadOrigin`. This can only happen through on-chain governance actions or
90 /// customized runtimes.
91 ///
92 /// # Parameters
93 ///
94 /// - `output`: A reference to the output data buffer to write the origin's address.
95 fn origin(output: &mut [u8; 20]);
96
97 /// Deposit a contract event with the data buffer and optional list of topics. There is a limit
98 /// on the maximum number of topics specified by `event_topics`.
99 ///
100 /// There should not be any duplicates in `topics`.
101 ///
102 /// # Parameters
103 ///
104 /// - `topics`: The topics list. It can't contain duplicates.
105 fn deposit_event(topics: &[[u8; 32]], data: &[u8]);
106
107 /// Cease contract execution and save a data buffer as a result of the execution.
108 ///
109 /// This function never returns as it stops execution of the caller.
110 /// This is the only way to return a data buffer to the caller. Returning from
111 /// execution without calling this function is equivalent to calling:
112 /// ```nocompile
113 /// return_value(ReturnFlags::empty(), &[])
114 /// ```
115 ///
116 /// Using an unnamed non empty `ReturnFlags` triggers a trap.
117 ///
118 /// # Parameters
119 ///
120 /// - `flags`: Flag used to signal special return conditions to the supervisor. See
121 /// [`ReturnFlags`] for a documentation of the supported flags.
122 /// - `return_value`: The return value buffer.
123 fn return_value(flags: ReturnFlags, return_value: &[u8]) -> !;
124}
125
126mod private {
127 pub trait Sealed {}
128 impl Sealed for super::HostFnImpl {}
129}