use super::Interpreter;
use crate::{
constraints::reg_key::*,
error::SimpleResult,
};
use fuel_asm::{
PanicReason,
RegId,
};
use fuel_tx::DependentCost;
use fuel_types::Word;
#[cfg(test)]
mod tests;
impl<M, S, Tx, Ecal, V> Interpreter<M, S, Tx, Ecal, V> {
pub fn remaining_gas(&self) -> Word {
self.registers[RegId::GGAS]
}
pub(crate) fn set_gas(&mut self, gas: Word) {
self.registers[RegId::GGAS] = gas;
self.registers[RegId::CGAS] = gas;
}
pub(crate) fn dependent_gas_charge(
&mut self,
gas_cost: DependentCost,
arg: Word,
) -> SimpleResult<()> {
let SystemRegisters { ggas, cgas, .. } = split_registers(&mut self.registers).0;
dependent_gas_charge(cgas, ggas, gas_cost, arg)
}
pub(crate) fn dependent_gas_charge_without_base(
&mut self,
gas_cost: DependentCost,
arg: Word,
) -> SimpleResult<()> {
let SystemRegisters { ggas, cgas, .. } = split_registers(&mut self.registers).0;
dependent_gas_charge_without_base(cgas, ggas, gas_cost, arg)
}
pub fn gas_charge(&mut self, gas: Word) -> SimpleResult<()> {
let SystemRegisters { ggas, cgas, .. } = split_registers(&mut self.registers).0;
gas_charge(cgas, ggas, gas)
}
}
pub(crate) fn dependent_gas_charge_without_base(
mut cgas: RegMut<CGAS>,
ggas: RegMut<GGAS>,
gas_cost: DependentCost,
arg: Word,
) -> SimpleResult<()> {
let cost = gas_cost.resolve_without_base(arg);
gas_charge(cgas.as_mut(), ggas, cost)
}
pub(crate) fn dependent_gas_charge(
mut cgas: RegMut<CGAS>,
ggas: RegMut<GGAS>,
gas_cost: DependentCost,
arg: Word,
) -> SimpleResult<()> {
let cost = gas_cost.resolve(arg);
gas_charge(cgas.as_mut(), ggas, cost)
}
pub(crate) fn gas_charge(
mut reg_cgas: RegMut<CGAS>,
mut reg_ggas: RegMut<GGAS>,
gas_to_use: Word,
) -> SimpleResult<()> {
let cgas_before = *reg_cgas;
let ggas_before = *reg_ggas;
#[allow(clippy::arithmetic_side_effects)]
if gas_to_use > cgas_before {
*reg_ggas = ggas_before.saturating_sub(cgas_before);
*reg_cgas = 0;
Err(PanicReason::OutOfGas.into())
} else {
*reg_ggas = ggas_before - gas_to_use;
*reg_cgas = cgas_before - gas_to_use;
Ok(())
}
}