referrerpolicy=no-referrer-when-downgrade

pallet_contracts_uapi/
lib.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.
14
15//! External C API to communicate with substrate contracts runtime module.
16//!
17//! Refer to substrate FRAME contract module for more documentation.
18
19#![no_std]
20
21mod flags;
22pub use flags::*;
23
24#[cfg(target_arch = "wasm32")]
25mod host;
26
27#[cfg(target_arch = "wasm32")]
28pub use host::*;
29
30macro_rules! define_error_codes {
31    (
32        $(
33            $( #[$attr:meta] )*
34            $name:ident = $discr:literal,
35        )*
36    ) => {
37        /// Every error that can be returned to a contract when it calls any of the host functions.
38        #[derive(Debug, PartialEq, Eq)]
39        #[repr(u8)]
40        pub enum ReturnErrorCode {
41            /// API call successful.
42            Success = 0,
43            $(
44                $( #[$attr] )*
45                $name = $discr,
46            )*
47            /// Returns if an unknown error was received from the host module.
48            Unknown,
49        }
50
51        impl From<ReturnCode> for Result {
52            fn from(return_code: ReturnCode) -> Self {
53                match return_code.0 {
54                    0 => Ok(()),
55                    $(
56                        $discr => Err(ReturnErrorCode::$name),
57                    )*
58                    _ => Err(ReturnErrorCode::Unknown),
59                }
60            }
61        }
62    };
63}
64
65impl From<ReturnErrorCode> for u32 {
66	fn from(code: ReturnErrorCode) -> u32 {
67		code as u32
68	}
69}
70
71define_error_codes! {
72	/// The called function trapped and has its state changes reverted.
73	/// In this case no output buffer is returned.
74	/// Can only be returned from `call` and `instantiate`.
75	CalleeTrapped = 1,
76	/// The called function ran to completion but decided to revert its state.
77	/// An output buffer is returned when one was supplied.
78	/// Can only be returned from `call` and `instantiate`.
79	CalleeReverted = 2,
80	/// The passed key does not exist in storage.
81	KeyNotFound = 3,
82	/// Deprecated and no longer returned: There is only the minimum balance.
83	_BelowSubsistenceThreshold = 4,
84	/// Transfer failed for other not further specified reason. Most probably
85	/// reserved or locked balance of the sender that was preventing the transfer.
86	TransferFailed = 5,
87	/// Deprecated and no longer returned: Endowment is no longer required.
88	_EndowmentTooLow = 6,
89	/// No code could be found at the supplied code hash.
90	CodeNotFound = 7,
91	/// The account that was called is no contract.
92	NotCallable = 8,
93	/// The call to `debug_message` had no effect because debug message
94	/// recording was disabled.
95	LoggingDisabled = 9,
96	/// The call dispatched by `call_runtime` was executed but returned an error.
97	CallRuntimeFailed = 10,
98	/// ECDSA public key recovery failed. Most probably wrong recovery id or signature.
99	EcdsaRecoveryFailed = 11,
100	/// sr25519 signature verification failed.
101	Sr25519VerifyFailed = 12,
102	/// The `xcm_execute` call failed.
103	XcmExecutionFailed = 13,
104	/// The `xcm_send` call failed.
105	XcmSendFailed = 14,
106}
107
108/// The raw return code returned by the host side.
109#[repr(transparent)]
110pub struct ReturnCode(u32);
111
112/// Used as a sentinel value when reading and writing contract memory.
113///
114/// We use this value to signal `None` to a contract when only a primitive is
115/// allowed and we don't want to go through encoding a full Rust type.
116/// Using `u32::Max` is a safe sentinel because contracts are never
117/// allowed to use such a large amount of resources. So this value doesn't
118/// make sense for a memory location or length.
119const SENTINEL: u32 = u32::MAX;
120
121impl From<ReturnCode> for Option<u32> {
122	fn from(code: ReturnCode) -> Self {
123		(code.0 < SENTINEL).then_some(code.0)
124	}
125}
126
127impl ReturnCode {
128	/// Returns the raw underlying `u32` representation.
129	pub fn into_u32(self) -> u32 {
130		self.0
131	}
132	/// Returns the underlying `u32` converted into `bool`.
133	pub fn into_bool(self) -> bool {
134		self.0.ne(&0)
135	}
136}
137
138type Result = core::result::Result<(), ReturnErrorCode>;