1use crate::{BalanceOf, Config, H160, U256};
21use alloc::{string::String, vec::Vec};
22use codec::{Decode, Encode, MaxEncodedLen};
23use frame_support::weights::Weight;
24use pallet_revive_uapi::ReturnFlags;
25use scale_info::TypeInfo;
26use sp_arithmetic::traits::Bounded;
27use sp_core::Get;
28use sp_runtime::{
29 traits::{One, Saturating, Zero},
30 DispatchError, RuntimeDebug,
31};
32
33#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
34pub enum DepositLimit<Balance> {
35 UnsafeOnlyForDryRun,
37
38 Balance(Balance),
40}
41
42impl<T> DepositLimit<T> {
43 pub fn is_unchecked(&self) -> bool {
44 match self {
45 Self::UnsafeOnlyForDryRun => true,
46 _ => false,
47 }
48 }
49}
50
51impl<T> From<T> for DepositLimit<T> {
52 fn from(value: T) -> Self {
53 Self::Balance(value)
54 }
55}
56
57impl<T: Bounded + Copy> DepositLimit<T> {
58 pub fn limit(&self) -> T {
59 match self {
60 Self::UnsafeOnlyForDryRun => T::max_value(),
61 Self::Balance(limit) => *limit,
62 }
63 }
64}
65
66#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
77pub struct ContractResult<R, Balance> {
78 pub gas_consumed: Weight,
80 pub gas_required: Weight,
91 pub storage_deposit: StorageDeposit<Balance>,
98 pub result: Result<R, DispatchError>,
100}
101
102#[derive(Clone, Eq, PartialEq, Default, Encode, Decode, RuntimeDebug, TypeInfo)]
104pub struct EthTransactInfo<Balance> {
105 pub gas_required: Weight,
107 pub storage_deposit: Balance,
109 pub eth_gas: U256,
111 pub data: Vec<u8>,
113}
114
115#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
117pub enum EthTransactError {
118 Data(Vec<u8>),
119 Message(String),
120}
121
122#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
123pub enum BalanceConversionError {
125 Value,
127 Dust,
129}
130
131#[derive(Default, Clone, Copy, Eq, PartialEq, Debug)]
134pub struct BalanceWithDust<Balance> {
135 value: Balance,
137 dust: u32,
140}
141
142impl<Balance> From<Balance> for BalanceWithDust<Balance> {
143 fn from(value: Balance) -> Self {
144 Self { value, dust: 0 }
145 }
146}
147
148impl<Balance> BalanceWithDust<Balance> {
149 pub fn deconstruct(self) -> (Balance, u32) {
151 (self.value, self.dust)
152 }
153
154 pub fn new_unchecked<T: Config>(value: Balance, dust: u32) -> Self {
156 debug_assert!(dust < T::NativeToEthRatio::get());
157 Self { value, dust }
158 }
159
160 pub fn from_value<T: Config>(
162 value: U256,
163 ) -> Result<BalanceWithDust<BalanceOf<T>>, BalanceConversionError>
164 where
165 BalanceOf<T>: TryFrom<U256>,
166 {
167 if value.is_zero() {
168 return Ok(Default::default())
169 }
170
171 let (quotient, remainder) = value.div_mod(T::NativeToEthRatio::get().into());
172 let value = quotient.try_into().map_err(|_| BalanceConversionError::Value)?;
173 let dust = remainder.try_into().map_err(|_| BalanceConversionError::Dust)?;
174
175 Ok(BalanceWithDust { value, dust })
176 }
177}
178
179impl<Balance: Zero + One + Saturating> BalanceWithDust<Balance> {
180 pub fn is_zero(&self) -> bool {
182 self.value.is_zero() && self.dust == 0
183 }
184
185 pub fn into_rounded_balance(self) -> Balance {
187 if self.dust == 0 {
188 self.value
189 } else {
190 self.value.saturating_add(Balance::one())
191 }
192 }
193}
194
195pub type CodeUploadResult<Balance> = Result<CodeUploadReturnValue<Balance>, DispatchError>;
197
198pub type GetStorageResult = Result<Option<Vec<u8>>, ContractAccessError>;
200
201#[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, MaxEncodedLen, RuntimeDebug, TypeInfo)]
203pub enum ContractAccessError {
204 DoesntExist,
206 KeyDecodingFailed,
208}
209
210#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo, Default)]
212pub struct ExecReturnValue {
213 pub flags: ReturnFlags,
215 pub data: Vec<u8>,
217}
218
219impl ExecReturnValue {
220 pub fn did_revert(&self) -> bool {
222 self.flags.contains(ReturnFlags::REVERT)
223 }
224}
225
226#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)]
228pub struct InstantiateReturnValue {
229 pub result: ExecReturnValue,
231 pub addr: H160,
233}
234
235#[derive(Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen, RuntimeDebug, TypeInfo)]
237pub struct CodeUploadReturnValue<Balance> {
238 pub code_hash: sp_core::H256,
240 pub deposit: Balance,
242}
243
244#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
246pub enum Code {
247 Upload(Vec<u8>),
249 Existing(sp_core::H256),
251}
252
253#[derive(
255 Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, MaxEncodedLen, RuntimeDebug, TypeInfo,
256)]
257pub enum StorageDeposit<Balance> {
258 Refund(Balance),
263 Charge(Balance),
268}
269
270impl<Balance: Zero> Default for StorageDeposit<Balance> {
271 fn default() -> Self {
272 Self::Charge(Zero::zero())
273 }
274}
275
276impl<Balance: Zero + Copy> StorageDeposit<Balance> {
277 pub fn charge_or_zero(&self) -> Balance {
279 match self {
280 Self::Charge(amount) => *amount,
281 Self::Refund(_) => Zero::zero(),
282 }
283 }
284
285 pub fn is_zero(&self) -> bool {
286 match self {
287 Self::Charge(amount) => amount.is_zero(),
288 Self::Refund(amount) => amount.is_zero(),
289 }
290 }
291}
292
293impl<Balance> StorageDeposit<Balance>
294where
295 Balance: Saturating + Ord + Copy,
296{
297 pub fn saturating_add(&self, rhs: &Self) -> Self {
299 use StorageDeposit::*;
300 match (self, rhs) {
301 (Charge(lhs), Charge(rhs)) => Charge(lhs.saturating_add(*rhs)),
302 (Refund(lhs), Refund(rhs)) => Refund(lhs.saturating_add(*rhs)),
303 (Charge(lhs), Refund(rhs)) =>
304 if lhs >= rhs {
305 Charge(lhs.saturating_sub(*rhs))
306 } else {
307 Refund(rhs.saturating_sub(*lhs))
308 },
309 (Refund(lhs), Charge(rhs)) =>
310 if lhs > rhs {
311 Refund(lhs.saturating_sub(*rhs))
312 } else {
313 Charge(rhs.saturating_sub(*lhs))
314 },
315 }
316 }
317
318 pub fn saturating_sub(&self, rhs: &Self) -> Self {
320 use StorageDeposit::*;
321 match (self, rhs) {
322 (Charge(lhs), Refund(rhs)) => Charge(lhs.saturating_add(*rhs)),
323 (Refund(lhs), Charge(rhs)) => Refund(lhs.saturating_add(*rhs)),
324 (Charge(lhs), Charge(rhs)) =>
325 if lhs >= rhs {
326 Charge(lhs.saturating_sub(*rhs))
327 } else {
328 Refund(rhs.saturating_sub(*lhs))
329 },
330 (Refund(lhs), Refund(rhs)) =>
331 if lhs > rhs {
332 Refund(lhs.saturating_sub(*rhs))
333 } else {
334 Charge(rhs.saturating_sub(*lhs))
335 },
336 }
337 }
338
339 pub fn available(&self, limit: &Balance) -> Balance {
346 use StorageDeposit::*;
347 match self {
348 Charge(amount) => limit.saturating_sub(*amount),
349 Refund(amount) => limit.saturating_add(*amount),
350 }
351 }
352}
353
354pub enum BumpNonce {
366 No,
368 Yes,
370}
371
372#[must_use = "You must handle whether the code was removed or not."]
374pub enum CodeRemoved {
375 No,
377 Yes,
379}