#![no_std]
extern crate alloc;
#[cfg(any(feature = "bls12-381", feature = "bls12-381-std"))]
pub mod bls12_381;
#[cfg(any(feature = "eth-bridge", feature = "eth-bridge-std"))]
pub mod eth_bridge;
use gear_core::{
gas::{GasAllowanceCounter, GasAmount, GasCounter},
limited::LimitedStr,
};
use parity_scale_codec::{Decode, Encode};
#[derive(Debug)]
pub struct BuiltinContext {
pub(crate) gas_counter: GasCounter,
pub(crate) gas_allowance_counter: GasAllowanceCounter,
}
impl BuiltinContext {
pub fn new(counter_initial: u64, allowance_initial: u64) -> Self {
Self {
gas_counter: GasCounter::new(counter_initial),
gas_allowance_counter: GasAllowanceCounter::new(allowance_initial),
}
}
pub fn try_charge_gas(&mut self, amount: u64) -> Result<(), BuiltinActorError> {
if self.gas_counter.charge_if_enough(amount).is_not_enough() {
return Err(BuiltinActorError::InsufficientGas);
}
if self
.gas_allowance_counter
.charge_if_enough(amount)
.is_not_enough()
{
return Err(BuiltinActorError::GasAllowanceExceeded);
}
Ok(())
}
pub fn can_charge_gas(&self, amount: u64) -> Result<(), BuiltinActorError> {
if self.gas_counter.left() < amount {
return Err(BuiltinActorError::InsufficientGas);
}
if self.gas_allowance_counter.left() < amount {
return Err(BuiltinActorError::GasAllowanceExceeded);
}
Ok(())
}
pub fn to_gas_amount(&self) -> GasAmount {
self.gas_counter.to_amount()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, derive_more::Display)]
pub enum BuiltinActorError {
#[display("Not enough gas supplied")]
InsufficientGas,
#[display("Not enough value supplied")]
InsufficientValue,
#[display("Failure to decode message")]
DecodingError,
#[display("Builtin execution resulted in error: {_0}")]
Custom(LimitedStr<'static>),
#[display("Block gas allowance exceeded")]
GasAllowanceExceeded,
#[display("Empty G1 points list")]
EmptyG1PointsList,
#[display("Failed to create `MapToCurveBasedHasher`")]
MapperCreationError,
#[display("Failed to map a message to a G2-point")]
MessageMappingError,
}
impl BuiltinActorError {
pub fn as_u32(&self) -> u32 {
match self {
BuiltinActorError::InsufficientGas => 0,
BuiltinActorError::InsufficientValue => 1,
BuiltinActorError::DecodingError => 2,
BuiltinActorError::Custom(_) => 3,
BuiltinActorError::GasAllowanceExceeded => 4,
BuiltinActorError::EmptyG1PointsList => 5,
BuiltinActorError::MapperCreationError => 6,
BuiltinActorError::MessageMappingError => 7,
}
}
pub fn from_u32(code: u32, custom_err_message: Option<&'static str>) -> Self {
match code {
0 => BuiltinActorError::InsufficientGas,
1 => BuiltinActorError::InsufficientValue,
2 => BuiltinActorError::DecodingError,
3 => BuiltinActorError::Custom(LimitedStr::from_small_str(
custom_err_message.unwrap_or("Unrecognized builtin actor error from RI call"),
)),
4 => BuiltinActorError::GasAllowanceExceeded,
5 => BuiltinActorError::EmptyG1PointsList,
6 => BuiltinActorError::MapperCreationError,
7 => BuiltinActorError::MessageMappingError,
_ => panic!("Invalid builtin-actor error code"),
}
}
}