Skip to content

Commit

Permalink
feat: update gas costs, to better reflect the costs post-memtrie
Browse files Browse the repository at this point in the history
  • Loading branch information
Ekleog committed Sep 9, 2024
1 parent 3718df6 commit 3bb82d8
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 18 deletions.
13 changes: 7 additions & 6 deletions core/parameters/res/runtime_configs/61.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Compute costs to allow for flat storage read-only MVP.
# See https://github.com/near/nearcore/issues/8006
wasm_touching_trie_node: { old: 16_101_955_926, new: { gas: 16_101_955_926, compute: 110_000_000_000 } }
wasm_storage_write_base: { old: 64_196_736_000, new: { gas: 64_196_736_000, compute: 200_000_000_000 } }
wasm_storage_remove_base: { old: 53_473_030_500, new: { gas: 53_473_030_500, compute: 200_000_000_000 } }
wasm_storage_read_base: { old: 56_356_845_750, new: { gas: 56_356_845_750, compute: 200_000_000_000 } }
wasm_storage_has_key_base: { old: 54_039_896_625, new: { gas: 54_039_896_625, compute: 200_000_000_000 } }
flat_storage_reads: { old: false, new: true }
wasm_touching_trie_node: { old: 16_101_955_926, new: { gas: 16_101_955_926, compute: 110_000_000_000 } }
wasm_storage_write_base: { old: 64_196_736_000, new: { gas: 64_196_736_000, compute: 200_000_000_000 } }
wasm_storage_remove_base: { old: 53_473_030_500, new: { gas: 53_473_030_500, compute: 200_000_000_000 } }
wasm_storage_read_base: { old: 56_356_845_750, new: { gas: 56_356_845_750, compute: 200_000_000_000 } }
wasm_storage_small_read_base: { old: 56_356_845_750, new: { gas: 56_356_845_750, compute: 200_000_000_000 } }
wasm_storage_has_key_base: { old: 54_039_896_625, new: { gas: 54_039_896_625, compute: 200_000_000_000 } }
flat_storage_reads: { old: false, new: true }
9 changes: 8 additions & 1 deletion core/parameters/res/runtime_configs/72.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
main_storage_proof_size_soft_limit: {old: 3_000_000, new: 4_000_000}
main_storage_proof_size_soft_limit: {old: 3_000_000, new: 4_000_000}
wasm_storage_has_key_base: { old: { gas: 54_039_896_625, compute: 200_000_000_000 }, new: { gas: 54_039_896_625, compute: 8_000_000_000 } }
wasm_storage_has_key_byte: { old: 30_790_845, new: { gas: 30_790_845, compute: 9_000_000 } }
wasm_storage_small_read_base: { old: { gas: 56_356_845_750, compute: 200_000_000_000 }, new: { gas: 56_356_845_750, compute: 9_000_000_000 } }
wasm_storage_small_read_key_byte: { old: 30_952_533, new: { gas: 30_952_533, compute: 10_000_000 } }
wasm_storage_small_read_value_byte: { old: 5_611_005, new: { gas: 5_611_005, compute: 2_500_000 } }
wasm_touching_trie_node: { old: { gas: 16_101_955_926, compute: 110_000_000_000 }, new: { gas: 16_101_955_926, compute: 20_000_000_000 } }
wasm_read_cached_trie_node: { old: 2_280_000_000, new: { gas: 2_280_000_000, compute: 1_400_000_000 } }
3 changes: 3 additions & 0 deletions core/parameters/res/runtime_configs/parameters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ wasm_storage_write_evicted_byte: 32_117_307
wasm_storage_read_base: 56_356_845_750
wasm_storage_read_key_byte: 30_952_533
wasm_storage_read_value_byte: 5_611_005
wasm_storage_small_read_base: 56_356_845_750
wasm_storage_small_read_key_byte: 30_952_533
wasm_storage_small_read_value_byte: 5_611_005
wasm_storage_remove_base: 53_473_030_500
wasm_storage_remove_key_byte: 38_220_384
wasm_storage_remove_ret_value_byte: 11_531_556
Expand Down
3 changes: 3 additions & 0 deletions core/parameters/res/runtime_configs/parameters_testnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ wasm_storage_write_evicted_byte: 32_117_307
wasm_storage_read_base: 56_356_845_750
wasm_storage_read_key_byte: 30_952_533
wasm_storage_read_value_byte: 5_611_005
wasm_storage_small_read_base: 56_356_845_750
wasm_storage_small_read_key_byte: 30_952_533
wasm_storage_small_read_value_byte: 5_611_005
wasm_storage_remove_base: 53_473_030_500
wasm_storage_remove_key_byte: 38_220_384
wasm_storage_remove_ret_value_byte: 11_531_556
Expand Down
9 changes: 9 additions & 0 deletions core/parameters/src/cost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ impl ExtCostsConfig {
ExtCosts::storage_read_base => SAFETY_MULTIPLIER * 18785615250,
ExtCosts::storage_read_key_byte => SAFETY_MULTIPLIER * 10317511,
ExtCosts::storage_read_value_byte => SAFETY_MULTIPLIER * 1870335,
ExtCosts::storage_small_read_base => SAFETY_MULTIPLIER * 18785615250,
ExtCosts::storage_small_read_key_byte => SAFETY_MULTIPLIER * 10317511,
ExtCosts::storage_small_read_value_byte => SAFETY_MULTIPLIER * 1870335,
ExtCosts::storage_remove_base => SAFETY_MULTIPLIER * 17824343500,
ExtCosts::storage_remove_key_byte => SAFETY_MULTIPLIER * 12740128,
ExtCosts::storage_remove_ret_value_byte => SAFETY_MULTIPLIER * 3843852,
Expand Down Expand Up @@ -268,6 +271,9 @@ pub enum ExtCosts {
bls12381_p1_decompress_element = 80,
bls12381_p2_decompress_base = 81,
bls12381_p2_decompress_element = 82,
storage_small_read_base = 83,
storage_small_read_key_byte = 84,
storage_small_read_value_byte = 85,
}

// Type of an action, used in fees logic.
Expand Down Expand Up @@ -351,6 +357,9 @@ impl ExtCosts {
ExtCosts::storage_read_base => Parameter::WasmStorageReadBase,
ExtCosts::storage_read_key_byte => Parameter::WasmStorageReadKeyByte,
ExtCosts::storage_read_value_byte => Parameter::WasmStorageReadValueByte,
ExtCosts::storage_small_read_base => Parameter::WasmStorageSmallReadBase,
ExtCosts::storage_small_read_key_byte => Parameter::WasmStorageSmallReadKeyByte,
ExtCosts::storage_small_read_value_byte => Parameter::WasmStorageSmallReadValueByte,
ExtCosts::storage_remove_base => Parameter::WasmStorageRemoveBase,
ExtCosts::storage_remove_key_byte => Parameter::WasmStorageRemoveKeyByte,
ExtCosts::storage_remove_ret_value_byte => Parameter::WasmStorageRemoveRetValueByte,
Expand Down
3 changes: 3 additions & 0 deletions core/parameters/src/parameter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ pub enum Parameter {
WasmStorageReadBase,
WasmStorageReadKeyByte,
WasmStorageReadValueByte,
WasmStorageSmallReadBase,
WasmStorageSmallReadKeyByte,
WasmStorageSmallReadValueByte,
WasmStorageRemoveBase,
WasmStorageRemoveKeyByte,
WasmStorageRemoveRetValueByte,
Expand Down
13 changes: 13 additions & 0 deletions core/parameters/src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,13 @@ pub struct ExtCostsConfigView {
/// Storage trie read value cost per byte cost
pub storage_read_value_byte: Gas,

/// Storage trie read key base cost, when doing small reads
pub storage_small_read_base: Gas,
/// Storage trie read key per byte cost, when doing small reads
pub storage_small_read_key_byte: Gas,
/// Storage trie read value cost per byte cost, when doing small reads
pub storage_small_read_value_byte: Gas,

/// Remove key from trie base cost
pub storage_remove_base: Gas,
/// Remove key from trie per byte cost
Expand Down Expand Up @@ -522,6 +529,9 @@ impl From<crate::ExtCostsConfig> for ExtCostsConfigView {
storage_read_base: config.gas_cost(ExtCosts::storage_read_base),
storage_read_key_byte: config.gas_cost(ExtCosts::storage_read_key_byte),
storage_read_value_byte: config.gas_cost(ExtCosts::storage_read_value_byte),
storage_small_read_base: config.gas_cost(ExtCosts::storage_small_read_base),
storage_small_read_key_byte: config.gas_cost(ExtCosts::storage_small_read_key_byte),
storage_small_read_value_byte: config.gas_cost(ExtCosts::storage_small_read_value_byte),
storage_remove_base: config.gas_cost(ExtCosts::storage_remove_base),
storage_remove_key_byte: config.gas_cost(ExtCosts::storage_remove_key_byte),
storage_remove_ret_value_byte: config.gas_cost(ExtCosts::storage_remove_ret_value_byte),
Expand Down Expand Up @@ -622,6 +632,9 @@ impl From<ExtCostsConfigView> for crate::ExtCostsConfig {
ExtCosts::storage_read_base => view.storage_read_base,
ExtCosts::storage_read_key_byte => view.storage_read_key_byte,
ExtCosts::storage_read_value_byte => view.storage_read_value_byte,
ExtCosts::storage_small_read_base => view.storage_small_read_base,
ExtCosts::storage_small_read_key_byte => view.storage_small_read_key_byte,
ExtCosts::storage_small_read_value_byte => view.storage_small_read_value_byte,
ExtCosts::storage_remove_base => view.storage_remove_base,
ExtCosts::storage_remove_key_byte => view.storage_remove_key_byte,
ExtCosts::storage_remove_ret_value_byte => view.storage_remove_ret_value_byte,
Expand Down
25 changes: 18 additions & 7 deletions runtime/near-vm-runner/src/logic/gas_counter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,18 @@ impl GasCounter {
}
}

/// Simpler version of `deduct_gas()` for when no promises are involved.
/// Checks whether the current contract execution is allowed to burn this much new gas.
///
/// Return an error if there are arithmetic overflows.
pub(crate) fn burn_gas(&mut self, gas_burnt: Gas) -> Result<()> {
let new_burnt_gas =
self.fast_counter.burnt_gas.checked_add(gas_burnt).ok_or(HostError::IntegerOverflow)?;
/// If yes, returns the total amount of gas that would have been burnt if this amount of gas
/// were burnt.
pub(crate) fn can_burn_gas(&mut self, gas_to_be_burnt: Gas) -> Result<Gas> {
let new_burnt_gas = self
.fast_counter
.burnt_gas
.checked_add(gas_to_be_burnt)
.ok_or(HostError::IntegerOverflow)?;
if new_burnt_gas <= self.fast_counter.gas_limit {
self.fast_counter.burnt_gas = new_burnt_gas;
Ok(())
Ok(new_burnt_gas)
} else {
// In the past `new_used_gas` would be computed using an implicit wrapping addition,
// which would then give an opportunity for the `assert` (now `debug_assert`) in the
Expand All @@ -138,6 +141,14 @@ impl GasCounter {
}
}

/// Simpler version of `deduct_gas()` for when no promises are involved.
///
/// Return an error if there are arithmetic overflows.
pub(crate) fn burn_gas(&mut self, gas_burnt: Gas) -> Result<()> {
self.fast_counter.burnt_gas = self.can_burn_gas(gas_burnt)?;
Ok(())
}

pub(crate) fn process_gas_limit(&mut self, new_burnt_gas: Gas, new_used_gas: Gas) -> HostError {
use std::cmp::min;
// Never burn more gas than what was paid for.
Expand Down
44 changes: 40 additions & 4 deletions runtime/near-vm-runner/src/logic/logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3157,7 +3157,17 @@ bls12381_p2_decompress_base + bls12381_p2_decompress_element * num_elements`
/// cost to read key from register + cost to write value into register`.
pub fn storage_read(&mut self, key_len: u64, key_ptr: u64, register_id: u64) -> Result<u64> {
self.result_state.gas_counter.pay_base(base)?;
self.result_state.gas_counter.pay_base(storage_read_base)?;
// Note: this host function charges the costs only after performing the work. In order to
// not be vulnerable to the various issues that could arise from that, this function does
// check that there is at least enough gas available for the "small" reads before performing
// the reads. And if there is enough gas for small reads but not large reads, the read
// should be interrupted before going down to disk, so there would not be undercharging.
//
// Make sure that we do have enough gas for the "small" reads at least, at the same place
// as we originally did. We will charge the actual gas at the end when we know to which
// cost type we should charge it.
let gas_to_be_burnt = storage_small_read_base.gas(&self.result_state.config.ext_costs);
self.result_state.gas_counter.can_burn_gas(gas_to_be_burnt)?;
let key = get_memory_or_register!(self, key_ptr, key_len)?;
if key.len() as u64 > self.config.limit_config.max_length_storage_key {
return Err(HostError::KeyLengthExceeded {
Expand All @@ -3166,7 +3176,12 @@ bls12381_p2_decompress_base + bls12381_p2_decompress_element * num_elements`
}
.into());
}
self.result_state.gas_counter.pay_per(storage_read_key_byte, key.len() as u64)?;
let gas_to_be_burnt = storage_small_read_key_byte
.gas(&self.result_state.config.ext_costs)
.checked_mul(key.len() as u64)
.and_then(|g| g.checked_add(gas_to_be_burnt))
.ok_or(HostError::IntegerOverflow)?;
self.result_state.gas_counter.can_burn_gas(gas_to_be_burnt)?;
let nodes_before = self.ext.get_trie_nodes_count();
let read = self.ext.storage_get(&key, self.config.storage_get_mode);
let nodes_delta = self
Expand All @@ -3175,8 +3190,29 @@ bls12381_p2_decompress_base + bls12381_p2_decompress_element * num_elements`
.checked_sub(&nodes_before)
.ok_or(InconsistentStateError::IntegerOverflow)?;
self.result_state.gas_counter.add_trie_fees(&nodes_delta)?;
let read =
Self::deref_value(&mut self.result_state.gas_counter, storage_read_value_byte, read?)?;
let read = match read? {
Some(read) => {
let read_len = read.len() as u64;
// TODO BEFORE UNDRAFTING: REPLACE WITH THE RIGHT CONSTANT USAGE
if read_len < 4096 {
self.result_state.gas_counter.pay_base(storage_small_read_base)?;
self.result_state
.gas_counter
.pay_per(storage_small_read_key_byte, key.len() as u64)?;
self.result_state
.gas_counter
.pay_per(storage_small_read_value_byte, read_len)?;
} else {
self.result_state.gas_counter.pay_base(storage_read_base)?;
self.result_state
.gas_counter
.pay_per(storage_read_key_byte, key.len() as u64)?;
self.result_state.gas_counter.pay_per(storage_read_value_byte, read_len)?;
}
Some(read.deref()?)
}
None => None,
};

#[cfg(feature = "io_trace")]
tracing::trace!(
Expand Down

0 comments on commit 3bb82d8

Please sign in to comment.