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 13, 2023
1 parent 3c0ca5c commit 0d506a1
Show file tree
Hide file tree
Showing 19 changed files with 370 additions and 75 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
61 changes: 52 additions & 9 deletions aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,16 @@ crate::gas_schedule::macros::define_gas_parameters!(
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" },

Check warning on line 128 in aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs

View check run for this annotation

Codecov / codecov/patch

aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs#L127-L128

Added lines #L127 - L128 were not covered by tests
1024, // 1KB free event bytes per transaction
],
[
ephemeral_storage_fee_discount_per_transaction: Fee,
{ 12.. => "ephemeral_storage_fee_discount_per_transaction" },
// roughly 1KB worth of ephemeral bytes per txn
5_000,
],

Check warning on line 136 in aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs

View check run for this annotation

Codecov / codecov/patch

aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs#L131-L136

Added lines #L131 - L136 were not covered by tests
[
max_bytes_per_write_op: NumBytes,
{ 5.. => "max_bytes_per_write_op" },
Expand All @@ -154,24 +160,61 @@ 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" },

Check warning on line 164 in aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs

View check run for this annotation

Codecov / codecov/patch

aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs#L163-L164

Added lines #L163 - L164 were not covered by tests
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" },
// 1 million APT for 2 billion state slots
50_000,
],
[
legacy_storage_fee_per_excess_state_byte: FeePerByte,
{ 7..=11 => "storage_fee_per_excess_state_byte", 12 => "legacy_storage_fee_per_excess_state_byte" },

Check warning on line 175 in aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs

View check run for this annotation

Codecov / codecov/patch

aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs#L168-L175

Added lines #L168 - L175 were not covered by tests
50,
],
[
storage_fee_per_state_byte_refundable: FeePerByte,
{ 12.. => "storage_fee_per_state_byte_refundable" },
// 1 million APT for 4 TB state bytes
25,
],
[
storage_fee_per_write_op: FeePerSlot,
{ 12.. => "storage_fee_per_write_op" },
// The cost of writing down the upper level new JMT nodes are shared between transactions
// because we write down the JMT in batches, however the bottom levels will be specific
// to each transactions assuming they don't touch exactly the same leaves. It's fair to
// target roughly 1-2 full internal JMT nodes (about 0.5-1 KB in total) worth of writes
// for each write op.
5_000,
],
[
storage_fee_per_write_set_byte: FeePerByte,
{ 12.. => "storage_fee_per_write_set_byte" },
5,
],
[
legacy_storage_fee_per_event_byte: FeePerByte,
{ 7..=11 => "storage_fee_per_event_byte", 12 => "legacy_storage_fee_per_event_byte" },
20,
],

Check warning on line 203 in aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs

View check run for this annotation

Codecov / codecov/patch

aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs#L178-L203

Added lines #L178 - L203 were not covered by tests
[
storage_fee_per_event_byte: FeePerByte,
{ 7.. => "storage_fee_per_event_byte" },
{ 12 => "storage_fee_per_event_byte" },
5,
],
[
legacy_storage_fee_per_transaction_byte: FeePerByte,
{ 7..=11 => "storage_fee_per_transaction_byte", 12 => "legacy_storage_fee_per_transaction_byte" },

Check warning on line 211 in aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs

View check run for this annotation

Codecov / codecov/patch

aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs#L206-L211

Added lines #L206 - L211 were not covered by tests
20,
],
[
storage_fee_per_transaction_byte: FeePerByte,
{ 7.. => "storage_fee_per_transaction_byte" },
20,
{ 12 => "storage_fee_per_transaction_byte" },
5,

Check warning on line 217 in aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs

View check run for this annotation

Codecov / codecov/patch

aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs#L216-L217

Added lines #L216 - L217 were not covered by tests
],
[
max_execution_gas: InternalGas,
Expand Down
2 changes: 2 additions & 0 deletions aptos-move/aptos-gas-schedule/src/ver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
/// - V12
/// - Making resource group charge on first read independent of BTreeMap serialization.
/// - Added BN254 operations.
/// - IO gas change: 1. read bytes charged at 4KB intervals; 2. ignore free_write_bytes_quota
/// - 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 @@ -94,6 +94,7 @@ pub enum FeatureFlag {
ResourceGroupsChargeAsSizeSum,
CommissionChangeDelegationPool,
BN254Structures,
EphemeralStorageFee,
}

fn generate_features_blob(writer: &CodeWriter, data: &[u64]) {
Expand Down Expand Up @@ -246,6 +247,7 @@ impl From<FeatureFlag> for AptosFeatureFlag {
AptosFeatureFlag::COMMISSION_CHANGE_DELEGATION_POOL
},
FeatureFlag::BN254Structures => AptosFeatureFlag::BN254_STRUCTURES,
FeatureFlag::EphemeralStorageFee => AptosFeatureFlag::EPHEMERAL_STORAGE_FEE,
}
}
}
Expand Down Expand Up @@ -321,6 +323,7 @@ impl From<AptosFeatureFlag> for FeatureFlag {
FeatureFlag::CommissionChangeDelegationPool
},
AptosFeatureFlag::BN254_STRUCTURES => FeatureFlag::BN254Structures,
AptosFeatureFlag::EPHEMERAL_STORAGE_FEE => FeatureFlag::EphemeralStorageFee,
}
}
}
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,

Check warning on line 47 in aptos-move/aptos-vm-types/src/storage/mod.rs

View check run for this annotation

Codecov / codecov/patch

aptos-move/aptos-vm-types/src/storage/mod.rs#L47

Added line #L47 was not covered by tests
}),
space_pricing: DiskSpacePricing::v1(),
space_pricing: DiskSpacePricing::latest(),

Check warning on line 49 in aptos-move/aptos-vm-types/src/storage/mod.rs

View check run for this annotation

Codecov / codecov/patch

aptos-move/aptos-vm-types/src/storage/mod.rs#L49

Added line #L49 was not covered by tests
change_set_configs: ChangeSetConfigs::unlimited_at_gas_feature_version(
LATEST_GAS_FEATURE_VERSION,
),
Expand Down
Loading

0 comments on commit 0d506a1

Please sign in to comment.