1#![no_std]
22
23extern crate alloc;
24
25#[cfg(any(feature = "bls12-381", feature = "bls12-381-std"))]
27pub mod bls12_381;
28
29#[cfg(any(feature = "eth-bridge", feature = "eth-bridge-std"))]
31pub mod eth_bridge;
32
33use gear_core::{
34 gas::{ChargeResult, GasAllowanceCounter, GasAmount, GasCounter},
35 limited::LimitedStr,
36};
37use parity_scale_codec::{Decode, Encode};
38
39#[derive(Debug)]
41pub struct BuiltinContext {
42 pub(crate) gas_counter: GasCounter,
43 pub(crate) gas_allowance_counter: GasAllowanceCounter,
44}
45
46impl BuiltinContext {
47 pub fn new(counter_initial: u64, allowance_initial: u64) -> Self {
49 Self {
50 gas_counter: GasCounter::new(counter_initial),
51 gas_allowance_counter: GasAllowanceCounter::new(allowance_initial),
52 }
53 }
54
55 pub fn try_charge_gas(&mut self, amount: u64) -> Result<(), BuiltinActorError> {
57 if self.gas_counter.charge_if_enough(amount) == ChargeResult::NotEnough {
58 return Err(BuiltinActorError::InsufficientGas);
59 }
60
61 if self.gas_allowance_counter.charge_if_enough(amount) == ChargeResult::NotEnough {
62 return Err(BuiltinActorError::GasAllowanceExceeded);
63 }
64
65 Ok(())
66 }
67
68 pub fn can_charge_gas(&self, amount: u64) -> Result<(), BuiltinActorError> {
70 if self.gas_counter.left() < amount {
71 return Err(BuiltinActorError::InsufficientGas);
72 }
73
74 if self.gas_allowance_counter.left() < amount {
75 return Err(BuiltinActorError::GasAllowanceExceeded);
76 }
77
78 Ok(())
79 }
80
81 pub fn to_gas_amount(&self) -> GasAmount {
83 self.gas_counter.to_amount()
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, derive_more::Display)]
89pub enum BuiltinActorError {
90 #[display("Not enough gas supplied")]
92 InsufficientGas,
93 #[display("Not enough value supplied")]
95 InsufficientValue,
96 #[display("Failure to decode message")]
98 DecodingError,
99 #[display("Builtin execution resulted in error: {_0}")]
101 Custom(LimitedStr<'static>),
102 #[display("Block gas allowance exceeded")]
104 GasAllowanceExceeded,
105 #[display("Empty G1 points list")]
107 EmptyG1PointsList,
108 #[display("Failed to create `MapToCurveBasedHasher`")]
111 MapperCreationError,
112 #[display("Failed to map a message to a G2-point")]
114 MessageMappingError,
115}
116
117impl BuiltinActorError {
118 pub fn as_u32(&self) -> u32 {
124 match self {
125 BuiltinActorError::InsufficientGas => 0,
126 BuiltinActorError::InsufficientValue => 1,
127 BuiltinActorError::DecodingError => 2,
128 BuiltinActorError::Custom(_) => 3,
129 BuiltinActorError::GasAllowanceExceeded => 4,
130 BuiltinActorError::EmptyG1PointsList => 5,
131 BuiltinActorError::MapperCreationError => 6,
132 BuiltinActorError::MessageMappingError => 7,
133 }
134 }
135
136 pub fn from_u32(code: u32, custom_err_message: Option<&'static str>) -> Self {
140 match code {
141 0 => BuiltinActorError::InsufficientGas,
142 1 => BuiltinActorError::InsufficientValue,
143 2 => BuiltinActorError::DecodingError,
144 3 => BuiltinActorError::Custom(LimitedStr::from_small_str(
145 custom_err_message.unwrap_or("Unrecognized builtin actor error from RI call"),
146 )),
147 4 => BuiltinActorError::GasAllowanceExceeded,
148 5 => BuiltinActorError::EmptyG1PointsList,
149 6 => BuiltinActorError::MapperCreationError,
150 7 => BuiltinActorError::MessageMappingError,
151 _ => panic!("Invalid builtin-actor error code"),
152 }
153 }
154}