ink_revive_types/
primitives.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18#![cfg_attr(not(feature = "std"), allow(unused_imports))]
19
20use alloc::vec::Vec;
21use ink_primitives::{
22    H160,
23    H256,
24    Weight,
25};
26use pallet_revive_uapi::ReturnFlags;
27use scale::{
28    Decode,
29    Encode,
30    MaxEncodedLen,
31};
32use scale_info::TypeInfo;
33use sp_runtime::{
34    DispatchError,
35    RuntimeDebug,
36    traits::{
37        Saturating,
38        Zero,
39    },
40};
41
42/// The amount of balance that was either charged or refunded in order to pay for storage.
43#[derive(
44    Clone,
45    Eq,
46    PartialEq,
47    Ord,
48    PartialOrd,
49    Encode,
50    Decode,
51    MaxEncodedLen,
52    RuntimeDebug,
53    TypeInfo,
54)]
55pub enum StorageDeposit<Balance> {
56    /// The transaction reduced storage consumption.
57    ///
58    /// This means that the specified amount of balance was transferred from the involved
59    /// deposit accounts to the origin.
60    Refund(Balance),
61    /// The transaction increased storage consumption.
62    ///
63    /// This means that the specified amount of balance was transferred from the origin
64    /// to the involved deposit accounts.
65    Charge(Balance),
66}
67
68impl<Balance: Zero> Default for StorageDeposit<Balance> {
69    fn default() -> Self {
70        Self::Charge(Zero::zero())
71    }
72}
73
74impl<Balance: Zero + Copy> StorageDeposit<Balance> {
75    /// Returns how much balance is charged or `0` in case of a refund.
76    pub fn charge_or_zero(&self) -> Balance {
77        match self {
78            Self::Charge(amount) => *amount,
79            Self::Refund(_) => Zero::zero(),
80        }
81    }
82
83    pub fn is_zero(&self) -> bool {
84        match self {
85            Self::Charge(amount) => amount.is_zero(),
86            Self::Refund(amount) => amount.is_zero(),
87        }
88    }
89}
90
91impl<Balance> StorageDeposit<Balance>
92where
93    Balance: Saturating + Ord + Copy,
94{
95    /// This is essentially a saturating signed add.
96    pub fn saturating_add(&self, rhs: &Self) -> Self {
97        use StorageDeposit::*;
98        match (self, rhs) {
99            (Charge(lhs), Charge(rhs)) => Charge(lhs.saturating_add(*rhs)),
100            (Refund(lhs), Refund(rhs)) => Refund(lhs.saturating_add(*rhs)),
101            (Charge(lhs), Refund(rhs)) => {
102                if lhs >= rhs {
103                    Charge(lhs.saturating_sub(*rhs))
104                } else {
105                    Refund(rhs.saturating_sub(*lhs))
106                }
107            }
108            (Refund(lhs), Charge(rhs)) => {
109                if lhs > rhs {
110                    Refund(lhs.saturating_sub(*rhs))
111                } else {
112                    Charge(rhs.saturating_sub(*lhs))
113                }
114            }
115        }
116    }
117
118    /// This is essentially a saturating signed sub.
119    pub fn saturating_sub(&self, rhs: &Self) -> Self {
120        use StorageDeposit::*;
121        match (self, rhs) {
122            (Charge(lhs), Refund(rhs)) => Charge(lhs.saturating_add(*rhs)),
123            (Refund(lhs), Charge(rhs)) => Refund(lhs.saturating_add(*rhs)),
124            (Charge(lhs), Charge(rhs)) => {
125                if lhs >= rhs {
126                    Charge(lhs.saturating_sub(*rhs))
127                } else {
128                    Refund(rhs.saturating_sub(*lhs))
129                }
130            }
131            (Refund(lhs), Refund(rhs)) => {
132                if lhs > rhs {
133                    Refund(lhs.saturating_sub(*rhs))
134                } else {
135                    Charge(rhs.saturating_sub(*lhs))
136                }
137            }
138        }
139    }
140
141    /// If the amount of deposit (this type) is constrained by a `limit` this calculates
142    /// how much balance (if any) is still available from this limit.
143    ///
144    /// # Note
145    ///
146    /// In case of a refund the return value can be larger than `limit`.
147    pub fn available(&self, limit: &Balance) -> Balance {
148        use StorageDeposit::*;
149        match self {
150            Charge(amount) => limit.saturating_sub(*amount),
151            Refund(amount) => limit.saturating_add(*amount),
152        }
153    }
154}
155
156/// Result type of a `bare_call` or `bare_instantiate` call as well as
157/// `ContractsApi::call` and `ContractsApi::instantiate`.
158///
159/// It contains the execution result together with some auxiliary information.
160///
161/// #Note
162///
163/// It has been extended to include `events` at the end of the struct while not bumping
164/// the `ContractsApi` version. Therefore when SCALE decoding a `ContractResult` its
165/// trailing data should be ignored to avoid any potential compatibility issues.
166#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
167pub struct ContractResult<R, Balance> {
168    /// How much weight was consumed during execution.
169    pub gas_consumed: Weight,
170    /// How much weight is required as gas limit in order to execute this call.
171    ///
172    /// This value should be used to determine the weight limit for on-chain execution.
173    ///
174    /// # Note
175    ///
176    /// This can only be different from [`Self::gas_consumed`] when weight pre charging
177    /// is used. Currently, only `seal_call_runtime` makes use of pre charging.
178    /// Additionally, any `seal_call` or `seal_instantiate` makes use of pre-charging
179    /// when a non-zero `gas_limit` argument is supplied.
180    pub gas_required: Weight,
181    /// How much balance was paid by the origin into the contract's deposit account in
182    /// order to pay for storage.
183    ///
184    /// The storage deposit is never actually charged from the origin in case of
185    /// [`Self::result`] is `Err`. This is because on error all storage changes are
186    /// rolled back including the payment of the deposit.
187    pub storage_deposit: StorageDeposit<Balance>,
188    /// The execution result of the vm binary code.
189    pub result: Result<R, DispatchError>,
190}
191
192/// Output of a contract call or instantiation which ran to completion.
193#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Default)]
194pub struct ExecReturnValue {
195    /// Flags passed along by `seal_return`. Empty when `seal_return` was never called.
196    pub flags: ReturnFlags,
197    /// Buffer passed along by `seal_return`. Empty when `seal_return` was never called.
198    pub data: Vec<u8>,
199}
200
201impl ExecReturnValue {
202    /// The contract did revert all storage changes.
203    pub fn did_revert(&self) -> bool {
204        self.flags.contains(ReturnFlags::REVERT)
205    }
206}
207
208/// The result of a successful contract instantiation.
209#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)]
210pub struct InstantiateReturnValue {
211    /// The output of the called constructor.
212    pub result: ExecReturnValue,
213    /// The address of the new contract.
214    pub addr: H160,
215}
216
217/// The result of successfully uploading a contract.
218#[derive(Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen, RuntimeDebug, TypeInfo)]
219pub struct CodeUploadReturnValue<Balance> {
220    /// The key under which the new code is stored.
221    pub code_hash: H256,
222    /// The deposit that was reserved at the caller. Is zero when the code already
223    /// existed.
224    pub deposit: Balance,
225}
226
227/// Result type of a `bare_code_upload` call.
228pub type CodeUploadResult<Balance> =
229    Result<CodeUploadReturnValue<Balance>, DispatchError>;