Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use flat vm fee #4607

Merged
merged 20 commits into from
Oct 12, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
use flat vm fee
  • Loading branch information
oxade committed Sep 14, 2022
commit 5083108ee119148b6e6f6e37e8d6d0bd654f030f
4 changes: 2 additions & 2 deletions crates/sui-adapter/src/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ fn execute_internal<
function,
type_args,
args,
gas_status.get_move_gas_status(),
&mut gas_status.create_move_gas_status(),
)
.and_then(|ret| Ok((ret, session.finish()?)))?;

Expand Down Expand Up @@ -390,7 +390,7 @@ pub fn verify_and_link<
AccountAddress::from(package_id),
// TODO: publish_module_bundle() currently doesn't charge gas.
// Do we want to charge there?
gas_status.get_move_gas_status(),
&mut gas_status.create_move_gas_status(),
)?;

// run the Sui verifier
Expand Down
5 changes: 2 additions & 3 deletions crates/sui-core/src/execution_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,8 @@ fn execute_transaction<S: BackingPackageStore + ParentSync>(
// once across single tx, we should be able to run them in parallel.
for single_tx in transaction_data.kind.into_single_transactions() {
if single_tx.uses_vm() {
// Reserve gas for this VM execution
// Reserving only done once for the whole batch
if let Err(e) = gas_status.reserve_vm_gas() {
// Charge gas for this VM execution
if let Err(e) = gas_status.charge_vm_gas() {
result = Err(e);
break;
}
Expand Down
2 changes: 1 addition & 1 deletion crates/sui-core/src/unit_tests/gas_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ async fn test_publish_gas() -> anyhow::Result<()> {
// Mimic the gas charge behavior and cross check the result with above.
let mut gas_status = SuiGasStatus::new_with_budget(*MAX_GAS_BUDGET, 1.into(), 1.into());
gas_status.charge_min_tx_gas()?;
gas_status.reserve_vm_gas()?;
gas_status.charge_vm_gas()?;
gas_status.charge_storage_read(
genesis_objects
.iter()
Expand Down
61 changes: 3 additions & 58 deletions crates/sui-cost-tables/src/bytecode_tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ static ZERO_COST_SCHEDULE: Lazy<CostTable> = Lazy::new(zero_cost_schedule);
pub struct GasStatus<'a> {
cost_table: &'a CostTable,
gas_left: InternalGas,
vm_gas_left: InternalGas,
/// This is used for batches where we want to ensure we don't reserve multiple times
reserved: bool,
charge: bool,
}

Expand All @@ -65,9 +62,7 @@ impl<'a> GasStatus<'a> {
Self {
gas_left: gas_left.to_unit(),
cost_table,
reserved: false,
charge: true,
vm_gas_left: Gas::new(0).to_unit(),
}
}

Expand All @@ -79,8 +74,6 @@ impl<'a> GasStatus<'a> {
Self {
gas_left: InternalGas::new(0),
cost_table: &ZERO_COST_SCHEDULE,
reserved: false,
vm_gas_left: Gas::new(0).to_unit(),
charge: false,
}
}
Expand Down Expand Up @@ -113,56 +106,8 @@ impl<'a> GasStatus<'a> {
}
}

/// This takes gas from the general gas pool into the VM pool
/// This must be called before the VM is invoked
pub fn reserve_vm_gas(&mut self) -> PartialVMResult<()> {
if !self.charge {
return Ok(());
}

if self.reserved {
// Nothing to do since we already reserved gas
return Ok(());
}

let amount = VM_FLAT_FEE.to_unit();

match self.gas_left.checked_sub(amount) {
Some(gas_left) => {
self.gas_left = gas_left;
self.vm_gas_left = amount;
self.reserved = true;
Ok(())
}
None => {
self.gas_left = InternalGas::new(0);
self.vm_gas_left = InternalGas::new(0);

Err(PartialVMError::new(StatusCode::OUT_OF_GAS))
}
}
}

/// Charge a given amount of gas for VM execution and fail if not enough gas units are left.
pub fn deduct_vm_gas(&mut self, amount: InternalGas) -> PartialVMResult<()> {
if !self.charge {
return Ok(());
}

match self.vm_gas_left.checked_sub(amount) {
Some(gas_left) => {
self.vm_gas_left = gas_left;
Ok(())
}
None => {
self.vm_gas_left = InternalGas::new(0);
Err(PartialVMError::new(StatusCode::OUT_OF_GAS))
}
}
}

fn charge_instr(&mut self, opcode: Opcodes) -> PartialVMResult<()> {
self.deduct_vm_gas(
self.deduct_gas(
self.cost_table
.instruction_cost(opcode as u8)
.total()
Expand All @@ -179,7 +124,7 @@ impl<'a> GasStatus<'a> {
// Make sure that the size is always non-zero
let size = std::cmp::max(1.into(), size);
debug_assert!(size > 0.into());
self.deduct_vm_gas(
self.deduct_gas(
InternalGasPerAbstractMemoryUnit::new(
self.cost_table.instruction_cost(opcode as u8).total(),
)
Expand Down Expand Up @@ -255,7 +200,7 @@ impl<'b> GasMeter for GasStatus<'b> {
}

fn charge_native_function(&mut self, amount: InternalGas) -> PartialVMResult<()> {
self.deduct_vm_gas(amount)
self.deduct_gas(amount)
}

fn charge_call(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,32 @@ expression: common_costs
---
{
"MergeCoin": {
"computation_cost": 465,
"computation_cost": 1456,
"storage_cost": 32,
"storage_rebate": 0
},
"Publish": {
"computation_cost": 523,
"computation_cost": 1491,
"storage_cost": 83,
"storage_rebate": 0
},
"SharedCounterAssertValue": {
"computation_cost": 198,
"computation_cost": 1197,
"storage_cost": 31,
"storage_rebate": 15
},
"SharedCounterCreate": {
"computation_cost": 109,
"computation_cost": 1088,
"storage_cost": 31,
"storage_rebate": 0
},
"SharedCounterIncrement": {
"computation_cost": 197,
"computation_cost": 1197,
"storage_cost": 31,
"storage_rebate": 15
},
"SplitCoin": {
"computation_cost": 576,
"computation_cost": 1466,
"storage_cost": 80,
"storage_rebate": 0
},
Expand Down
2 changes: 1 addition & 1 deletion crates/sui-gateway/src/unit_tests/rpc_server_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ async fn test_move_call() -> Result<(), anyhow::Error> {
vec![GAS::type_tag().into()],
json_args,
Some(gas.object_id),
1000,
10_000,
)
.await?;

Expand Down
27 changes: 14 additions & 13 deletions crates/sui-types/src/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use std::{
ops::{Add, Deref, Mul},
};
use sui_cost_tables::{
bytecode_tables::{GasStatus, INITIAL_COST_SCHEDULE},
bytecode_tables::{GasStatus, INITIAL_COST_SCHEDULE, VM_FLAT_FEE},
non_execution_tables::{
BASE_TX_COST_FIXED, CONSENSUS_COST, MAXIMUM_TX_GAS, OBJ_ACCESS_COST_MUTATE_PER_BYTE,
OBJ_ACCESS_COST_READ_PER_BYTE, OBJ_DATA_COST_REFUNDABLE, PACKAGE_PUBLISH_COST_PER_BYTE,
Expand Down Expand Up @@ -84,7 +84,7 @@ impl Deref for FixedCost {
/// to ensure a value of this type is used specifically for computation cost.
/// Anything that does not change the amount of bytes stored in the authority data store
/// will charge ComputationCostPerByte.
struct ComputationCostPerByte(InternalGasPerByte);
pub struct ComputationCostPerByte(InternalGasPerByte);

impl ComputationCostPerByte {
pub fn new(x: u64) -> Self {
Expand All @@ -104,7 +104,7 @@ impl Deref for ComputationCostPerByte {
/// to ensure a value of this type is used specifically for storage cost.
/// Anything that changes the amount of bytes stored in the authority data store
/// will charge StorageCostPerByte.
struct StorageCostPerByte(InternalGasPerByte);
pub struct StorageCostPerByte(InternalGasPerByte);

impl Deref for StorageCostPerByte {
type Target = InternalGasPerByte;
Expand All @@ -121,7 +121,7 @@ impl StorageCostPerByte {
}

/// A list of constant costs of various operations in Sui.
struct SuiCostTable {
pub struct SuiCostTable {
/// A flat fee charged for every transaction. This is also the mimmum amount of
/// gas charged for a transaction.
pub min_transaction_cost: FixedCost,
Expand All @@ -148,7 +148,7 @@ struct SuiCostTable {
}

// TODO: The following numbers are arbitrary at this point.
static INIT_SUI_COST_TABLE: Lazy<SuiCostTable> = Lazy::new(|| SuiCostTable {
pub static INIT_SUI_COST_TABLE: Lazy<SuiCostTable> = Lazy::new(|| SuiCostTable {
min_transaction_cost: FixedCost::new(BASE_TX_COST_FIXED),
package_publish_per_byte_cost: ComputationCostPerByte::new(PACKAGE_PUBLISH_COST_PER_BYTE),
object_read_per_byte_cost: ComputationCostPerByte::new(OBJ_ACCESS_COST_READ_PER_BYTE),
Expand Down Expand Up @@ -210,15 +210,16 @@ impl<'a> SuiGasStatus<'a> {
!self.charge
}

pub fn get_move_gas_status(&mut self) -> &mut GasStatus<'a> {
&mut self.gas_status
pub fn create_move_gas_status(&mut self) -> GasStatus<'a> {
if self.charge {
GasStatus::new(&INITIAL_COST_SCHEDULE, VM_FLAT_FEE)
} else {
GasStatus::new_unmetered()
}
}

pub fn reserve_vm_gas(&mut self) -> Result<(), ExecutionError> {
self.gas_status.reserve_vm_gas().map_err(|e| {
debug_assert_eq!(e.major_status(), StatusCode::OUT_OF_GAS);
ExecutionErrorKind::InsufficientGas.into()
})
pub fn charge_vm_gas(&mut self) -> Result<(), ExecutionError> {
self.deduct_computation_cost(&VM_FLAT_FEE.to_unit())
}

pub fn charge_min_tx_gas(&mut self) -> Result<(), ExecutionError> {
Expand Down Expand Up @@ -270,7 +271,7 @@ impl<'a> SuiGasStatus<'a> {
/// Move VM charging gas.
pub fn charge_vm_exec_test_only(&mut self, cost: u64) -> Result<(), ExecutionError> {
self.gas_status
.deduct_vm_gas(InternalGas::new(cost))
.deduct_gas(InternalGas::new(cost))
.map_err(|e| {
debug_assert_eq!(e.major_status(), StatusCode::OUT_OF_GAS);
ExecutionErrorKind::InsufficientGas.into()
Expand Down