1#![no_std]
7
8extern crate alloc;
9
10#[cfg(any(feature = "bls12-381", feature = "bls12-381-std"))]
12pub mod bls12_381;
13
14#[cfg(any(feature = "eth-bridge", feature = "eth-bridge-std"))]
16pub mod eth_bridge;
17
18use gear_core::{
19 gas::{GasAllowanceCounter, GasAmount, GasCounter},
20 limited::LimitedStr,
21};
22use parity_scale_codec::{Decode, Encode};
23
24#[derive(Debug)]
26pub struct BuiltinContext {
27 pub(crate) gas_counter: GasCounter,
28 pub(crate) gas_allowance_counter: GasAllowanceCounter,
29}
30
31impl BuiltinContext {
32 pub fn new(counter_initial: u64, allowance_initial: u64) -> Self {
34 Self {
35 gas_counter: GasCounter::new(counter_initial),
36 gas_allowance_counter: GasAllowanceCounter::new(allowance_initial),
37 }
38 }
39
40 pub fn try_charge_gas(&mut self, amount: u64) -> Result<(), BuiltinActorError> {
42 if self.gas_counter.charge_if_enough(amount).is_not_enough() {
43 return Err(BuiltinActorError::InsufficientGas);
44 }
45
46 if self
47 .gas_allowance_counter
48 .charge_if_enough(amount)
49 .is_not_enough()
50 {
51 return Err(BuiltinActorError::GasAllowanceExceeded);
52 }
53
54 Ok(())
55 }
56
57 pub fn can_charge_gas(&self, amount: u64) -> Result<(), BuiltinActorError> {
59 if self.gas_counter.left() < amount {
60 return Err(BuiltinActorError::InsufficientGas);
61 }
62
63 if self.gas_allowance_counter.left() < amount {
64 return Err(BuiltinActorError::GasAllowanceExceeded);
65 }
66
67 Ok(())
68 }
69
70 pub fn to_gas_amount(&self) -> GasAmount {
72 self.gas_counter.to_amount()
73 }
74}
75
76#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, derive_more::Display)]
78pub enum BuiltinActorError {
79 #[display("Not enough gas supplied")]
81 InsufficientGas,
82 #[display("Not enough value supplied")]
84 InsufficientValue,
85 #[display("Failure to decode message")]
87 DecodingError,
88 #[display("Builtin execution resulted in error: {_0}")]
90 Custom(LimitedStr<'static>),
91 #[display("Block gas allowance exceeded")]
93 GasAllowanceExceeded,
94 #[display("Empty G1 points list")]
96 EmptyG1PointsList,
97 #[display("Failed to create `MapToCurveBasedHasher`")]
100 MapperCreationError,
101 #[display("Failed to map a message to a G2-point")]
103 MessageMappingError,
104}
105
106impl BuiltinActorError {
107 pub fn as_u32(&self) -> u32 {
113 match self {
114 BuiltinActorError::InsufficientGas => 0,
115 BuiltinActorError::InsufficientValue => 1,
116 BuiltinActorError::DecodingError => 2,
117 BuiltinActorError::Custom(_) => 3,
118 BuiltinActorError::GasAllowanceExceeded => 4,
119 BuiltinActorError::EmptyG1PointsList => 5,
120 BuiltinActorError::MapperCreationError => 6,
121 BuiltinActorError::MessageMappingError => 7,
122 }
123 }
124
125 pub fn from_u32(code: u32, custom_err_message: Option<&'static str>) -> Self {
129 match code {
130 0 => BuiltinActorError::InsufficientGas,
131 1 => BuiltinActorError::InsufficientValue,
132 2 => BuiltinActorError::DecodingError,
133 3 => BuiltinActorError::Custom(LimitedStr::from_small_str(
134 custom_err_message.unwrap_or("Unrecognized builtin actor error from RI call"),
135 )),
136 4 => BuiltinActorError::GasAllowanceExceeded,
137 5 => BuiltinActorError::EmptyG1PointsList,
138 6 => BuiltinActorError::MapperCreationError,
139 7 => BuiltinActorError::MessageMappingError,
140 _ => panic!("Invalid builtin-actor error code"),
141 }
142 }
143}