aptos-core icon indicating copy to clipboard operation
aptos-core copied to clipboard

feat: allow to use custom gas-meter at unit test

Open beer-1 opened this issue 6 months ago • 1 comments

Description

This update would allow the caller of unit test can use it's own gas meter .

Here is example use case.

pub struct InitiaUnitTestFactory {
    pub gas_params: InitiaGasParameters,
    pub balance: u64,
}

impl InitiaUnitTestFactory {
    pub fn new(gas_params: InitiaGasParameters, balance: u64) -> Self {
        Self {
            gas_params,
            balance,
        }
    }

    fn charge_write_set_gas(
        gas_meter: &mut InitiaGasMeter,
        changes: &ChangeSet,
        table_context: NativeTableContext,
    ) -> VMResult<()> {
        let table_change_set = table_context
            .into_change_set()
            .map_err(|e| e.finish(Location::Undefined))?;
        let write_set = WriteSet::new(changes.clone(), table_change_set).map_err(|e| {
            PartialVMError::new(StatusCode::FAILED_TO_SERIALIZE_WRITE_SET_CHANGES)
                .with_message(e.to_string())
                .finish(Location::Undefined)
        })?;

        gas_meter.charge_write_set_gas(&write_set)?;

        Ok(())
    }
}

// gas meter required for testing gas metering
impl UnitTestFactory<InitiaGasMeter> for InitiaUnitTestFactory {
    fn new_gas_meter(&self) -> InitiaGasMeter {
        InitiaGasMeter::new(self.gas_params.clone(), self.balance)
    }

    fn finish_session(
        &self,
        session: Session,
        mut gas_meter: InitiaGasMeter,
        mut test_run_info: TestRunInfo,
    ) -> (VMResult<ChangeSet>, TestRunInfo) {
        let mut apply_gas_used = |gas_meter: InitiaGasMeter| {
            test_run_info.gas_used = gas_meter
                .gas_limit()
                .checked_sub(gas_meter.balance())
                .unwrap()
                .into();
        };

        match session.finish_with_extensions() {
            Ok((cs, mut exts)) => {
                let table_context: NativeTableContext = exts.remove::<NativeTableContext>();
                match Self::charge_write_set_gas(&mut gas_meter, &cs, table_context) {
                    Ok(()) => {
                        apply_gas_used(gas_meter);
                        (Ok(cs), test_run_info)
                    }
                    Err(err) => {
                        apply_gas_used(gas_meter);
                        return (Err(err), test_run_info)
                    },
                }
            }
            Err(err) => {
                apply_gas_used(gas_meter);
                (Err(err), test_run_info)
            }
        }
    }
}

Type of Change

  • [ ] New feature
  • [ ] Bug fix
  • [ ] Breaking change
  • [ ] Performance improvement
  • [ ] Refactoring
  • [ ] Dependency update
  • [ ] Documentation update
  • [ ] Tests

Which Components or Systems Does This Change Impact?

  • [ ] Validator Node
  • [ ] Full Node (API, Indexer, etc.)
  • [ ] Move/Aptos Virtual Machine
  • [ ] Aptos Framework
  • [ ] Aptos CLI/SDK
  • [ ] Developer Infrastructure
  • [ ] Other (specify)

How Has This Been Tested?

Key Areas to Review

Checklist

  • [ ] I have read and followed the CONTRIBUTING doc
  • [ ] I have performed a self-review of my own code
  • [ ] I have commented my code, particularly in hard-to-understand areas
  • [ ] I identified and added all stakeholders and component owners affected by this change as reviewers
  • [ ] I tested both happy and unhappy path of the functionality
  • [ ] I have made corresponding changes to the documentation

beer-1 avatar Aug 14 '24 07:08 beer-1