Repository: aptos-labs/aptos-core
File: aptos-move/aptos-gas-meter/src/algebra.rs (Rust)

Code before:
            .checked_sub(self.balance)
            .ok_or_else(|| {
                PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR).with_message(
                    format!(
                        "Current balance ({}) exceedes the initial balance ({}) -- how is this ever possible?",
                        self.balance,
                        self.initial_balance
                    ),
                )
            })?;

        let total_calculated =
            self.execution_gas_used + self.io_gas_used + self.storage_fee_in_internal_units;
        if total != total_calculated {
            return Err(
                PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR).with_message(
                    format!(
                        "The per-category costs do not add up. {} (total) != {} = {} (exec) + {} (io) + {} (storage)",
                        total,
                        total_calculated,
                        self.execution_gas_used,
                        self.io_gas_used,
                        self.storage_fee_in_internal_units,
                    ),
                ),
            );
        }

        Ok(())
    }

    #[inline(always)]
    fn charge_execution(
        &mut self,
        abstract_amount: impl GasExpression<VMGasParameters, Unit = InternalGasUnit> + Debug,
    ) -> PartialVMResult<()> {
        self.counter_for_kill_switch += 1;
        if self.counter_for_kill_switch & 3 == 0
            && self.block_synchronization_kill_switch.interrupt_requested()
        {
            return Err(
                PartialVMError::new(StatusCode::SPECULATIVE_EXECUTION_ABORT_ERROR)
                    .with_message("Interrupted from block synchronization view".to_string()),
            );
        }

        let amount = abstract_amount.evaluate(self.feature_version, &self.vm_gas_params);

        match self.balance.checked_sub(amount) {
            Some(new_balance) => {
                self.balance = new_balance;

Review comment (bug):
Might be helpful leaving a comment here documenting that we are expanding the helper function (`fn charge`) here so to move the feature version check into the failure case.

Code after:
                    ),
                ),
            );
        }

        Ok(())
    }

    #[inline(always)]
    fn charge_execution(
        &mut self,
        abstract_amount: impl GasExpression<VMGasParameters, Unit = InternalGasUnit> + Debug,
    ) -> PartialVMResult<()> {
        self.counter_for_kill_switch += 1;
        if self.counter_for_kill_switch & 3 == 0
            && self.block_synchronization_kill_switch.interrupt_requested()
        {
            return Err(
                PartialVMError::new(StatusCode::SPECULATIVE_EXECUTION_ABORT_ERROR)
                    .with_message("Interrupted from block synchronization view".to_string()),
            );
        }

        let amount = abstract_amount.evaluate(self.feature_version, &self.vm_gas_params);

        match self.balance.checked_sub(amount) {
            Some(new_balance) => {
                self.balance = new_balance;
                self.execution_gas_used += amount;
            },
            None => {
                let old_balance = self.balance;
                self.balance = 0.into();
                if self.feature_version >= 12 {
                    self.execution_gas_used += old_balance;
                }
                return Err(PartialVMError::new(StatusCode::OUT_OF_GAS));
            },
        };

        if self.feature_version >= 7 && self.execution_gas_used > self.max_execution_gas {
            Err(PartialVMError::new(StatusCode::EXECUTION_LIMIT_REACHED))
        } else {
            Ok(())
        }
    }

    fn charge_io(
        &mut self,
        abstract_amount: impl GasExpression<VMGasParameters, Unit = InternalGasUnit>,
    ) -> PartialVMResult<()> {