From 754add77f0a1affb7145b0ff0f4bdc99aa9caf6e Mon Sep 17 00:00:00 2001 From: aldenhu Date: Tue, 12 Dec 2023 03:51:32 +0000 Subject: [PATCH] Io Gas adjustments 1. read bytes charged in 4k steps 2. remove per write op free quota --- .../src/gas_schedule/transaction.rs | 8 ++--- .../aptos-vm-types/src/storage/io_pricing.rs | 33 +++++++++++++++---- aptos-move/aptos-vm-types/src/storage/mod.rs | 2 +- .../src/tests/per_category_gas_limits.rs | 8 ++--- .../src/tests/failed_transaction_tests.rs | 2 +- 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs index d835322f2af015..f296461b37628e 100644 --- a/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs +++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs @@ -84,7 +84,7 @@ crate::gas_schedule::macros::define_gas_parameters!( [ storage_io_per_state_byte_read: InternalGasPerByte, { 0..=9 => "load_data.per_byte", 10.. => "storage_io_per_state_byte_read"}, - 300, + 300, // FIXME(aldenhu): tune ], [load_data_failure: InternalGas, "load_data.failure", 0], // Gas parameters for writing data to storage. @@ -110,8 +110,8 @@ crate::gas_schedule::macros::define_gas_parameters!( ], [memory_quota: AbstractValueSize, { 1.. => "memory_quota" }, 10_000_000], [ - free_write_bytes_quota: NumBytes, - { 5.. => "free_write_bytes_quota" }, + legacy_free_write_bytes_quota: NumBytes, + { 5..=11 => "free_write_bytes_quota" }, 1024, // 1KB free per state write ], [ @@ -211,7 +211,7 @@ impl TransactionGasParameters { pub fn storage_fee_for_bytes(&self, key: &StateKey, op_size: &WriteOpSize) -> Fee { if let Some(value_size) = op_size.write_len() { let size = NumBytes::new(key.size() as u64) + NumBytes::new(value_size); - if let Some(excess) = size.checked_sub(self.free_write_bytes_quota) { + if let Some(excess) = size.checked_sub(self.legacy_free_write_bytes_quota) { return excess * self.storage_fee_per_excess_state_byte; } } diff --git a/aptos-move/aptos-vm-types/src/storage/io_pricing.rs b/aptos-move/aptos-vm-types/src/storage/io_pricing.rs index a208e5d32b5f2a..ed05627df37013 100644 --- a/aptos-move/aptos-vm-types/src/storage/io_pricing.rs +++ b/aptos-move/aptos-vm-types/src/storage/io_pricing.rs @@ -120,7 +120,7 @@ impl IoPricingV2 { 0 => unreachable!("PricingV2 not applicable for feature version 0"), 1..=2 => 0.into(), 3..=4 => 1024.into(), - 5.. => gas_params.vm.txn.free_write_bytes_quota, + 5.. => gas_params.vm.txn.legacy_free_write_bytes_quota, } } @@ -167,24 +167,43 @@ impl IoPricingV2 { #[derive(Debug, Clone)] pub struct IoPricingV3 { pub feature_version: u64, - pub free_write_bytes_quota: NumBytes, + pub legacy_free_write_bytes_quota: NumBytes, } impl IoPricingV3 { + fn read_size(&self, loaded: NumBytes) -> NumBytes { + if self.feature_version >= 12 { + // round up bytes to whole pages + + const PAGE_SIZE: u64 = 4096; + let loaded_u64: u64 = loaded.into(); + let r = loaded_u64 % PAGE_SIZE; + let rounded_up = loaded_u64 + if r == 0 { 0 } else { PAGE_SIZE - r }; + NumBytes::new(rounded_up) + } else { + loaded + } + } + fn calculate_read_gas( &self, loaded: NumBytes, ) -> impl GasExpression { - STORAGE_IO_PER_STATE_SLOT_READ * NumArgs::from(1) + STORAGE_IO_PER_STATE_BYTE_READ * loaded + STORAGE_IO_PER_STATE_SLOT_READ * NumArgs::from(1) + + STORAGE_IO_PER_STATE_BYTE_READ * self.read_size(loaded) } fn write_op_size(&self, key: &StateKey, value_size: u64) -> NumBytes { let key_size = NumBytes::new(key.size() as u64); let value_size = NumBytes::new(value_size); + let size = key_size + value_size; - (key_size + value_size) - .checked_sub(self.free_write_bytes_quota) - .unwrap_or(NumBytes::zero()) + if self.feature_version >= 12 { + size.checked_sub(self.legacy_free_write_bytes_quota) + .unwrap_or(NumBytes::zero()) + } else { + size + } } fn io_gas_per_write( @@ -232,7 +251,7 @@ impl IoPricing { }, 10.. => V3(IoPricingV3 { feature_version, - free_write_bytes_quota: gas_params.vm.txn.free_write_bytes_quota, + legacy_free_write_bytes_quota: gas_params.vm.txn.legacy_free_write_bytes_quota, }), } } diff --git a/aptos-move/aptos-vm-types/src/storage/mod.rs b/aptos-move/aptos-vm-types/src/storage/mod.rs index 12a8dfb5a8f2fa..68c4ced4a1e1c9 100644 --- a/aptos-move/aptos-vm-types/src/storage/mod.rs +++ b/aptos-move/aptos-vm-types/src/storage/mod.rs @@ -38,7 +38,7 @@ impl StorageGasParameters { Self { io_pricing: IoPricing::V3(IoPricingV3 { feature_version: LATEST_GAS_FEATURE_VERSION, - free_write_bytes_quota, + legacy_free_write_bytes_quota: free_write_bytes_quota, }), change_set_configs: ChangeSetConfigs::unlimited_at_gas_feature_version( LATEST_GAS_FEATURE_VERSION, diff --git a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs index 012538886f613b..56a5269bb05427 100644 --- a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs +++ b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs @@ -91,7 +91,7 @@ fn io_limit_reached_by_new_bytes() { // Allow 10 value bytes charged at most. gas_params.vm.txn.max_io_gas = 110_000_000.into(); // Make the key bytes free, only play around value sizes. - gas_params.vm.txn.free_write_bytes_quota = state_key_size(); + gas_params.vm.txn.legacy_free_write_bytes_quota = state_key_size(); }); test_create_multiple_items(&mut h, &acc, |status| { @@ -112,7 +112,7 @@ fn storage_limit_reached_by_new_bytes() { // Allow 10 value bytes charged at most. gas_params.vm.txn.max_storage_fee = 11_000_000.into(); // Make the key bytes free, only play around value sizes. - gas_params.vm.txn.free_write_bytes_quota = state_key_size(); + gas_params.vm.txn.legacy_free_write_bytes_quota = state_key_size(); }); test_create_multiple_items(&mut h, &acc, |status| { @@ -134,7 +134,7 @@ fn out_of_gas_while_charging_write_gas() { // Bump max gas allowed gas_params.vm.txn.maximum_number_of_gas_units = 1_000_000_000.into(); // Make the key bytes free, only play around value sizes. - gas_params.vm.txn.free_write_bytes_quota = state_key_size(); + gas_params.vm.txn.legacy_free_write_bytes_quota = state_key_size(); }); // Allow 10 value bytes charged at most. Notice this is in external units. h.set_max_gas_per_txn(110_000); @@ -156,7 +156,7 @@ fn out_of_gas_while_charging_storage_fee() { // Bump max gas allowed gas_params.vm.txn.maximum_number_of_gas_units = 1_000_000_000.into(); // Make the key bytes free, only play around value sizes. - gas_params.vm.txn.free_write_bytes_quota = state_key_size(); + gas_params.vm.txn.legacy_free_write_bytes_quota = state_key_size(); }); // Allow 10 value bytes charged at most. Notice this is in external units, // which is 1/100x octas or 1Mx internal units. diff --git a/aptos-move/e2e-testsuite/src/tests/failed_transaction_tests.rs b/aptos-move/e2e-testsuite/src/tests/failed_transaction_tests.rs index 30716ef97fbfd2..034bc2d68204ee 100644 --- a/aptos-move/e2e-testsuite/src/tests/failed_transaction_tests.rs +++ b/aptos-move/e2e-testsuite/src/tests/failed_transaction_tests.rs @@ -40,7 +40,7 @@ fn failed_transaction_cleanup_test() { let gas_params = AptosGasParameters::zeros(); let storage_gas_params = - StorageGasParameters::unlimited(gas_params.vm.txn.free_write_bytes_quota); + StorageGasParameters::unlimited(gas_params.vm.txn.legacy_free_write_bytes_quota); let change_set_configs = storage_gas_params.change_set_configs.clone();