Skip to content

Commit

Permalink
ephemeral storage fee
Browse files Browse the repository at this point in the history
  • Loading branch information
msmouse committed Dec 12, 2023
1 parent e2a17a7 commit d177cc6
Show file tree
Hide file tree
Showing 19 changed files with 362 additions and 78 deletions.
39 changes: 27 additions & 12 deletions aptos-move/aptos-gas-meter/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,34 +142,49 @@ pub trait AptosGasMeter: MoveGasMeter {
let pricing = self.disk_space_pricing();
let params = &self.vm_gas_params().txn;

// Calculate the storage fees.
let mut write_fee = Fee::new(0);
let mut total_refund = Fee::new(0);
// Write set
let mut writeset_charge_and_refund = ChargeAndRefund::zero();
for (key, op_size, metadata_opt) in change_set.write_set_iter_mut() {
let ChargeAndRefund { charge, refund } =
pricing.charge_refund_write_op(params, key, &op_size, metadata_opt);
total_refund += refund;

write_fee += charge;
writeset_charge_and_refund.combine(pricing.charge_refund_write_op(
params,
key,
&op_size,
metadata_opt,
));
}
let ChargeAndRefund {
non_discountable,
discountable,
refund,
} = writeset_charge_and_refund;

// Events
let event_fee = change_set
.events()
.iter()
.fold(Fee::new(0), |acc, (event, _)| {
acc + pricing.storage_fee_per_event(params, event)
});
let event_discount = pricing.storage_discount_for_events(params, event_fee);
let event_net_fee = event_fee
let net_event_fee = event_fee
.checked_sub(event_discount)
.expect("discount should always be less than or equal to total amount");
.expect("event discount should always be less than or equal to total amount");

// Txn
let txn_fee = pricing.storage_fee_for_transaction_storage(params, txn_size);
let fee = write_fee + event_net_fee + txn_fee;

// Ephemeral fee discount
let total_discountable = discountable + net_event_fee + txn_fee;
let discount = pricing.ephemeral_storage_fee_discount(params, total_discountable);
let net_ephemeral = total_discountable
.checked_sub(discount)
.expect("ephemeral fee discount should always be less than or equal to total amount");

let fee = non_discountable + net_ephemeral;
self.charge_storage_fee(fee, gas_unit_price)
.map_err(|err| err.finish(Location::Undefined))?;

Ok(total_refund)
Ok(refund)
}

// Below are getters reexported from the gas algebra.
Expand Down
42 changes: 25 additions & 17 deletions aptos-move/aptos-gas-profiling/src/profiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,23 +523,26 @@ where
let pricing = self.disk_space_pricing();
let params = &self.vm_gas_params().txn;

// Writes
let mut write_fee = Fee::new(0);
// Write set
let mut write_set_storage = vec![];
let mut total_refund = Fee::new(0);
let mut writeset_charge_and_refund = ChargeAndRefund::zero();
for (key, op_size, metadata_opt) in change_set.write_set_iter_mut() {
let ChargeAndRefund { charge, refund } =
let charge_and_refund =
pricing.charge_refund_write_op(params, key, &op_size, metadata_opt);
write_fee += charge;
total_refund += refund;

write_set_storage.push(WriteStorage {
key: key.clone(),
op_type: write_op_type(&op_size),
cost: charge,
refund,
cost: charge_and_refund.non_discountable + charge_and_refund.discountable,
refund: charge_and_refund.refund,
});
writeset_charge_and_refund.combine(charge_and_refund);
}
let ChargeAndRefund {
non_discountable,
discountable,
refund,
} = writeset_charge_and_refund;

// Events
let mut event_fee = Fee::new(0);
Expand All @@ -553,30 +556,35 @@ where
event_fee += fee;
}
let event_discount = pricing.storage_discount_for_events(params, event_fee);
let event_fee_with_discount = event_fee
let net_event_fee = event_fee
.checked_sub(event_discount)
.expect("discount should always be less than or equal to total amount");

// Txn
let txn_fee = pricing.storage_fee_for_transaction_storage(params, txn_size);

// Ephemeral fee discount
let total_discountable = discountable + net_event_fee + txn_fee;
let discount = pricing.ephemeral_storage_fee_discount(params, total_discountable);
let net_ephemeral = total_discountable
.checked_sub(discount)
.expect("ephemeral fee discount should always be less than or equal to total amount");
let fee = non_discountable + net_ephemeral;

self.storage_fees = Some(StorageFees {
total: write_fee + event_fee + txn_fee,
total_refund,
total: fee,
total_refund: refund,

write_set_storage,
events: event_fees,
event_discount,
txn_storage: txn_fee,
});

self.charge_storage_fee(
write_fee + event_fee_with_discount + txn_fee,
gas_unit_price,
)
.map_err(|err| err.finish(Location::Undefined))?;
self.charge_storage_fee(fee, gas_unit_price)
.map_err(|err| err.finish(Location::Undefined))?;

Ok(total_refund)
Ok(refund)
}

fn charge_intrinsic_gas_for_transaction(&mut self, txn_size: NumBytes) -> VMResult<()> {
Expand Down
59 changes: 47 additions & 12 deletions aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,21 +101,26 @@ crate::gas_schedule::macros::define_gas_parameters!(
5_000
],
[
write_data_per_byte_in_val: InternalGasPerByte,
"write_data.per_byte_in_val",
legacy_write_data_per_byte_in_val: InternalGasPerByte,
{ 0..=10 => "write_data.per_byte_in_val" },
10_000
],
[memory_quota: AbstractValueSize, { 1.. => "memory_quota" }, 10_000_000],
[
legacy_free_write_bytes_quota: NumBytes,
{ 5..=11 => "free_write_bytes_quota", 12 => "legacy_free_write_bytes_quota" },
{ 5..=11 => "free_write_bytes_quota" },
1024, // 1KB free per state write
],
[
free_event_bytes_quota: NumBytes,
{ 7.. => "free_event_bytes_quota" },
legacy_free_event_bytes_quota: NumBytes,
{ 7..=11 => "free_event_bytes_quota", 12.. => "legacy_free_event_bytes_quota" },
1024, // 1KB free event bytes per transaction
],
[
ephemeral_storage_fee_discount_per_transaction: Fee,
{ 12.. => "ephemeral_storage_fee_discount_per_transaction" },
50000, // FIXME(aldenhu): tune -- for example, 4k of ephemeral bytes, roughly 50k octas
],
[
max_bytes_per_write_op: NumBytes,
{ 5.. => "max_bytes_per_write_op" },
Expand All @@ -142,24 +147,54 @@ crate::gas_schedule::macros::define_gas_parameters!(
8192,
],
[
storage_fee_per_state_slot_create: FeePerSlot,
{ 7.. => "storage_fee_per_state_slot_create" },
legacy_storage_fee_per_state_slot_create: FeePerSlot,
{ 7..=11 => "storage_fee_per_state_slot_create", 12 => "legacy_storage_fee_per_state_slot_create" },
50000,
],
[
storage_fee_per_excess_state_byte: FeePerByte,
{ 7.. => "storage_fee_per_excess_state_byte" },
storage_fee_per_state_slot_refundable: FeePerSlot,
{ 12.. => "storage_fee_per_state_slot_refundable" },
50000, // FIXME(aldenhu): tune
],
[
legacy_storage_fee_per_excess_state_byte: FeePerByte,
{ 7..=11 => "storage_fee_per_excess_state_byte", 12 => "legacy_storage_fee_per_excess_state_byte" },
50,
],
[
storage_fee_per_state_byte_refundable: FeePerByte,
{ 12.. => "storage_fee_per_state_byte_refundable" },
50, // FIXME(aldenhu): tune
],
[
storage_fee_per_write_op: FeePerSlot,
{ 12.. => "storage_fee_per_write_op" },
10000, // FIMXME(aldenhu): tune -- calculate based on the mainnet tree height
],
[
storage_fee_per_write_set_byte: FeePerByte,
{ 12.. => "storage_fee_per_write_set_byte" },
10, // FIMXME(aldenhu): tune
],
[
legacy_storage_fee_per_event_byte: FeePerByte,
{ 7..=11 => "storage_fee_per_event_byte", 12 => "legacy_storage_fee_per_event_byte" },
20,
],
[
storage_fee_per_event_byte: FeePerByte,
{ 7.. => "storage_fee_per_event_byte" },
{ 12 => "storage_fee_per_event_byte" },
10, // FIXME(aldenhu): tune
],
[
legacy_storage_fee_per_transaction_byte: FeePerByte,
{ 7..=11 => "storage_fee_per_transaction_byte", 12 => "legacy_storage_fee_per_transaction_byte" },
20,
],
[
storage_fee_per_transaction_byte: FeePerByte,
{ 7.. => "storage_fee_per_transaction_byte" },
20,
{ 12 => "storage_fee_per_transaction_byte" },
10, // FIXME(aldenhu): tune
],
[
max_execution_gas: InternalGas,
Expand Down
1 change: 1 addition & 0 deletions aptos-move/aptos-gas-schedule/src/ver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
/// Change log:
/// - V12
/// - Making resource group charge on first read independent of BTreeMap serialization.
/// - Support "ephemeral" storage fee scheme, gated by FeatrueFlag::EPHEMERAL_STORAGE_FEE
/// - V11
/// - Ristretto255 natives (point cloning & double-scalar multiplication) and Bulletproofs natives
/// - Hard limit on the number of write ops per transaction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ pub enum FeatureFlag {
VMBinaryFormatV7,
ResourceGroupsChargeAsSizeSum,
CommissionChangeDelegationPool,
EphemeralStorageFee,
}

fn generate_features_blob(writer: &CodeWriter, data: &[u64]) {
Expand Down Expand Up @@ -244,6 +245,7 @@ impl From<FeatureFlag> for AptosFeatureFlag {
FeatureFlag::CommissionChangeDelegationPool => {
AptosFeatureFlag::COMMISSION_CHANGE_DELEGATION_POOL
},
FeatureFlag::EphemeralStorageFee => AptosFeatureFlag::EPHEMERAL_STORAGE_FEE,
}
}
}
Expand Down Expand Up @@ -318,6 +320,7 @@ impl From<AptosFeatureFlag> for FeatureFlag {
AptosFeatureFlag::COMMISSION_CHANGE_DELEGATION_POOL => {
FeatureFlag::CommissionChangeDelegationPool
},
AptosFeatureFlag::EPHEMERAL_STORAGE_FEE => FeatureFlag::EphemeralStorageFee,
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion aptos-move/aptos-vm-types/src/storage/io_pricing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl IoPricingV1 {
write_data_per_op: gas_params.vm.txn.storage_io_per_state_slot_write,
write_data_per_new_item: gas_params.vm.txn.write_data_per_new_item,
write_data_per_byte_in_key: gas_params.vm.txn.storage_io_per_state_byte_write,
write_data_per_byte_in_val: gas_params.vm.txn.write_data_per_byte_in_val,
write_data_per_byte_in_val: gas_params.vm.txn.legacy_write_data_per_byte_in_val,
load_data_base: gas_params.vm.txn.storage_io_per_state_slot_read * NumArgs::new(1),
load_data_per_byte: gas_params.vm.txn.storage_io_per_state_byte_read,
load_data_failure: gas_params.vm.txn.load_data_failure,
Expand Down
13 changes: 7 additions & 6 deletions aptos-move/aptos-vm-types/src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::storage::{
space_pricing::DiskSpacePricing,
};
use aptos_gas_schedule::{AptosGasParameters, LATEST_GAS_FEATURE_VERSION};
use aptos_types::on_chain_config::ConfigStorage;
use aptos_types::on_chain_config::{ConfigStorage, Features};
use move_core_types::gas_algebra::NumBytes;
use std::fmt::Debug;

Expand All @@ -24,13 +24,14 @@ pub struct StorageGasParameters {

impl StorageGasParameters {
pub fn new(
feature_version: u64,
gas_feature_version: u64,
features: &Features,
gas_params: &AptosGasParameters,
config_storage: &impl ConfigStorage,
) -> Self {
let io_pricing = IoPricing::new(feature_version, gas_params, config_storage);
let space_pricing = DiskSpacePricing::v1();
let change_set_configs = ChangeSetConfigs::new(feature_version, gas_params);
let io_pricing = IoPricing::new(gas_feature_version, gas_params, config_storage);
let space_pricing = DiskSpacePricing::new(gas_feature_version, features);
let change_set_configs = ChangeSetConfigs::new(gas_feature_version, gas_params);

Self {
io_pricing,
Expand All @@ -45,7 +46,7 @@ impl StorageGasParameters {
feature_version: LATEST_GAS_FEATURE_VERSION,
legacy_free_write_bytes_quota: free_write_bytes_quota,
}),
space_pricing: DiskSpacePricing::v1(),
space_pricing: DiskSpacePricing::latest(),
change_set_configs: ChangeSetConfigs::unlimited_at_gas_feature_version(
LATEST_GAS_FEATURE_VERSION,
),
Expand Down
Loading

0 comments on commit d177cc6

Please sign in to comment.