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

WIP: Recompute gas costs considering precompilation #4455

Closed
wants to merge 20 commits into from
Closed
5 changes: 3 additions & 2 deletions chain/client/tests/process_blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,12 @@ fn prepare_env_with_congestion(
gas_price_adjustment_rate: Option<Rational>,
number_of_transactions: u64,
) -> (TestEnv, Vec<CryptoHash>) {
init_test_logger();
// init_test_logger();
let epoch_length = 100;
let mut genesis = Genesis::test(vec!["test0", "test1"], 1);
genesis.config.protocol_version = protocol_version;
genesis.config.epoch_length = epoch_length;
genesis.config.gas_limit = 10_000_000_000_000;
genesis.config.gas_limit = 1_000_000_000_000;
if let Some(gas_price_adjustment_rate) = gas_price_adjustment_rate {
genesis.config.gas_price_adjustment_rate = gas_price_adjustment_rate;
}
Expand Down Expand Up @@ -2846,6 +2846,7 @@ fn test_congestion_receipt_execution() {
env.produce_block(0, height);
let prev_block = env.clients[0].chain.get_block_by_height(height).unwrap().clone();
let chunk_extra = env.clients[0].chain.get_chunk_extra(prev_block.hash(), 0).unwrap().clone();
eprintln!("{} {}", chunk_extra.gas_used(), chunk_extra.gas_limit());
assert!(chunk_extra.gas_used() >= chunk_extra.gas_limit());
let state_update =
env.clients[0].runtime_adapter.get_tries().new_trie_update(0, *chunk_extra.state_root());
Expand Down
1 change: 1 addition & 0 deletions core/primitives-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ lazy_static = "1.4"
default = []
protocol_feature_evm = []
protocol_feature_alt_bn128 = []
protocol_feature_precompile_contracts = []
4 changes: 2 additions & 2 deletions core/primitives-core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,8 @@ impl Default for ExtCostsConfig {
fn default() -> ExtCostsConfig {
ExtCostsConfig {
base: SAFETY_MULTIPLIER * 88256037,
contract_compile_base: SAFETY_MULTIPLIER * 11815321,
contract_compile_bytes: SAFETY_MULTIPLIER * 72250,
contract_compile_base: 0,
contract_compile_bytes: 0,
read_memory_base: SAFETY_MULTIPLIER * 869954400,
read_memory_byte: SAFETY_MULTIPLIER * 1267111,
write_memory_base: SAFETY_MULTIPLIER * 934598287,
Expand Down
24 changes: 12 additions & 12 deletions core/primitives-core/src/runtime/fees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,24 +262,24 @@ impl Default for RuntimeFeesConfig {
execution: 99607375000,
},
deploy_contract_cost: Fee {
send_sir: 184765750000,
send_not_sir: 184765750000,
execution: 184765750000,
send_sir: 53526562500,
send_not_sir: 53526562500,
execution: 2378554689376,
},
deploy_contract_cost_per_byte: Fee {
send_sir: 6812999,
send_not_sir: 6812999,
execution: 6812999,
send_sir: 8295895,
send_not_sir: 8295895,
execution: 458361934,
},
function_call_cost: Fee {
send_sir: 2319861500000,
send_not_sir: 2319861500000,
execution: 2319861500000,
send_sir: 275464562500,
send_not_sir: 275464562500,
execution: 275464562500,
},
function_call_cost_per_byte: Fee {
send_sir: 2235934,
send_not_sir: 2235934,
execution: 2235934,
send_sir: 28984,
send_not_sir: 28984,
execution: 28984,
},
transfer_cost: Fee {
send_sir: 115123062500,
Expand Down
3 changes: 2 additions & 1 deletion core/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ protocol_feature_evm = ["near-primitives-core/protocol_feature_evm"]
protocol_feature_block_header_v3 = []
protocol_feature_alt_bn128 = ["near-primitives-core/protocol_feature_alt_bn128", "near-vm-errors/protocol_feature_alt_bn128"]
protocol_feature_restore_receipts_after_fix = []
nightly_protocol_features = ["nightly_protocol", "protocol_feature_evm", "protocol_feature_block_header_v3", "protocol_feature_alt_bn128", "protocol_feature_restore_receipts_after_fix"]
protocol_feature_precompile_contracts = ["near-primitives-core/protocol_feature_precompile_contracts"]
nightly_protocol_features = ["nightly_protocol", "protocol_feature_evm", "protocol_feature_block_header_v3", "protocol_feature_alt_bn128", "protocol_feature_restore_receipts_after_fix", "protocol_feature_precompile_contracts"]
nightly_protocol = []

[dev-dependencies]
Expand Down
45 changes: 41 additions & 4 deletions core/primitives/src/runtime/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use serde::{Deserialize, Serialize};

use crate::checked_feature;
use crate::config::VMConfig;
use crate::config::{ExtCostsConfig, VMConfig};
use crate::runtime::fees::RuntimeFeesConfig;
use crate::serialize::u128_dec_format;
use crate::types::{AccountId, Balance, Gas};
Expand Down Expand Up @@ -62,6 +62,9 @@ pub struct ActualRuntimeConfig {

/// The runtime configuration with lower storage cost adjustment applied.
with_lower_storage_cost: Arc<RuntimeConfig>,

/// The runtime configuration with fees updated at the time of adding precompilation.
precompilation_protocol_config: Arc<RuntimeConfig>,
}

impl ActualRuntimeConfig {
Expand All @@ -78,9 +81,14 @@ impl ActualRuntimeConfig {

// Adjust as per LowerStorageCost protocol feature.
config.storage_amount_per_byte = 10u128.pow(19);
let with_lower_storage_cost = Arc::new(config);
let with_lower_storage_cost = Arc::new(config.clone());

// Adjust transaction costs at the time of adding precompilation.
config.wasm_config.ext_costs = ExtCostsConfig::default();
config.transaction_costs = RuntimeFeesConfig::default();
let precompilation_protocol_config = Arc::new(config);

Self { runtime_config, with_lower_storage_cost }
Self { runtime_config, with_lower_storage_cost, precompilation_protocol_config }
}

/// Returns a `RuntimeConfig` for the corresponding protocol version.
Expand All @@ -89,7 +97,13 @@ impl ActualRuntimeConfig {
/// still return configuration which differs from configuration found in
/// genesis file by the `max_gas_burnt_view` limit.
pub fn for_protocol_version(&self, protocol_version: ProtocolVersion) -> &Arc<RuntimeConfig> {
if checked_feature!("stable", LowerStorageCost, protocol_version) {
if checked_feature!(
"protocol_feature_precompile_contracts",
PrecompileContracts,
protocol_version
) {
&self.precompilation_protocol_config
} else if checked_feature!("stable", LowerStorageCost, protocol_version) {
&self.with_lower_storage_cost
} else {
&self.runtime_config
Expand Down Expand Up @@ -119,10 +133,12 @@ impl Default for AccountCreationConfig {
#[cfg(test)]
mod tests {
use super::*;
use crate::version::PROTOCOL_VERSION;

#[test]
fn test_max_prepaid_gas() {
let config = RuntimeConfig::default();
eprintln!("{} {}", config.wasm_config.limit_config.max_total_prepaid_gas, config.transaction_costs.min_receipt_with_function_call_gas());
assert!(
config.wasm_config.limit_config.max_total_prepaid_gas
/ config.transaction_costs.min_receipt_with_function_call_gas()
Expand All @@ -147,4 +163,25 @@ mod tests {
let config = ActualRuntimeConfig::new(RuntimeConfig::default(), Some(42));
assert_eq!(42, config.for_protocol_version(0).wasm_config.limit_config.max_gas_burnt_view);
}

#[test]
fn test_after_precompile_contract() {
let mut config = RuntimeConfig::default();
config.wasm_config.ext_costs.contract_compile_base = 100;
config.wasm_config.ext_costs.contract_compile_bytes = 10;
let config = ActualRuntimeConfig::new(config, None);

let new_cfg = config.for_protocol_version(PROTOCOL_VERSION);
if checked_feature!(
"protocol_feature_precompile_contracts",
PrecompileContracts,
PROTOCOL_VERSION
) {
assert_eq!(new_cfg.wasm_config.ext_costs.contract_compile_base, 0);
assert_eq!(new_cfg.wasm_config.ext_costs.contract_compile_bytes, 0);
} else {
assert_eq!(new_cfg.wasm_config.ext_costs.contract_compile_base, 100);
assert_eq!(new_cfg.wasm_config.ext_costs.contract_compile_bytes, 10);
}
}
}
6 changes: 5 additions & 1 deletion core/primitives/src/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ pub enum ProtocolFeature {
AltBn128,
#[cfg(feature = "protocol_feature_restore_receipts_after_fix")]
RestoreReceiptsAfterFix,
#[cfg(feature = "protocol_feature_precompile_contracts")]
PrecompileContracts,
}

/// Current latest stable version of the protocol.
Expand All @@ -117,7 +119,7 @@ pub const PROTOCOL_VERSION: ProtocolVersion = 46;

/// Current latest nightly version of the protocol.
#[cfg(feature = "nightly_protocol")]
pub const PROTOCOL_VERSION: ProtocolVersion = 114;
pub const PROTOCOL_VERSION: ProtocolVersion = 115;

impl ProtocolFeature {
pub const fn protocol_version(self) -> ProtocolVersion {
Expand Down Expand Up @@ -145,6 +147,8 @@ impl ProtocolFeature {
ProtocolFeature::BlockHeaderV3 => 109,
#[cfg(feature = "protocol_feature_restore_receipts_after_fix")]
ProtocolFeature::RestoreReceiptsAfterFix => 112,
#[cfg(feature = "protocol_feature_precompile_contracts")]
ProtocolFeature::PrecompileContracts => 115,
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ expensive_tests = []
adversarial = ["nearcore/adversarial"]
protocol_feature_evm = ["nearcore/protocol_feature_evm", "testlib/protocol_feature_evm"]
protocol_feature_alt_bn128 = ["nearcore/protocol_feature_alt_bn128"]
nightly_protocol_features = ["nearcore/nightly_protocol_features", "testlib/nightly_protocol_features", "protocol_feature_alt_bn128", "protocol_feature_restore_receipts_after_fix"]
nightly_protocol_features = ["nearcore/nightly_protocol_features", "testlib/nightly_protocol_features", "protocol_feature_evm", "protocol_feature_alt_bn128", "protocol_feature_restore_receipts_after_fix"]
nightly_protocol = ["nearcore/nightly_protocol", "testlib/nightly_protocol"]
protocol_feature_restore_receipts_after_fix = ["nearcore/protocol_feature_restore_receipts_after_fix"]
3 changes: 2 additions & 1 deletion nearcore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ json_rpc = ["near-jsonrpc"]
protocol_feature_evm = ["near-primitives/protocol_feature_evm", "node-runtime/protocol_feature_evm", "near-chain-configs/protocol_feature_evm", "near-chain/protocol_feature_evm", "near-client/protocol_feature_evm"]
protocol_feature_alt_bn128 = ["near-primitives/protocol_feature_alt_bn128", "node-runtime/protocol_feature_alt_bn128"]
protocol_feature_block_header_v3 = ["near-epoch-manager/protocol_feature_block_header_v3", "near-store/protocol_feature_block_header_v3", "near-primitives/protocol_feature_block_header_v3", "near-chain/protocol_feature_block_header_v3", "near-client/protocol_feature_block_header_v3"]
nightly_protocol_features = ["nightly_protocol", "near-primitives/nightly_protocol_features", "near-client/nightly_protocol_features", "near-epoch-manager/nightly_protocol_features", "near-store/nightly_protocol_features", "protocol_feature_evm", "protocol_feature_block_header_v3", "protocol_feature_alt_bn128", "protocol_feature_restore_receipts_after_fix"]
nightly_protocol_features = ["nightly_protocol", "near-primitives/nightly_protocol_features", "near-client/nightly_protocol_features", "near-epoch-manager/nightly_protocol_features", "near-store/nightly_protocol_features", "protocol_feature_evm", "protocol_feature_block_header_v3", "protocol_feature_alt_bn128", "protocol_feature_restore_receipts_after_fix", "protocol_feature_precompile_contracts"]
nightly_protocol = ["near-primitives/nightly_protocol", "near-jsonrpc/nightly_protocol"]
protocol_feature_restore_receipts_after_fix = ["near-primitives/protocol_feature_restore_receipts_after_fix", "near-chain/protocol_feature_restore_receipts_after_fix", "node-runtime/protocol_feature_restore_receipts_after_fix"]
protocol_feature_precompile_contracts = ["near-vm-runner/protocol_feature_precompile_contracts", "near-primitives/protocol_feature_precompile_contracts"]

# enable this to build neard with wasmer 1.0 runner
# now if none of wasmer0_default, wasmer1_default or wasmtime_default is enabled, wasmer0 would be default
Expand Down
28 changes: 14 additions & 14 deletions nearcore/res/genesis_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,24 +61,24 @@
"execution": 99607375000
},
"deploy_contract_cost": {
"send_sir": 184765750000,
"send_not_sir": 184765750000,
"execution": 184765750000
"send_sir": 53526562500,
"send_not_sir": 53526562500,
"execution": 2378554689376
},
"deploy_contract_cost_per_byte": {
"send_sir": 6812999,
"send_not_sir": 6812999,
"execution": 6812999
"send_sir": 8295895,
"send_not_sir": 8295895,
"execution": 458361934
},
"function_call_cost": {
"send_sir": 2319861500000,
"send_not_sir": 2319861500000,
"execution": 2319861500000
"send_sir": 275464562500,
"send_not_sir": 275464562500,
"execution": 275464562500
},
"function_call_cost_per_byte": {
"send_sir": 2235934,
"send_not_sir": 2235934,
"execution": 2235934
"send_sir": 28984,
"send_not_sir": 28984,
"execution": 28984
},
"transfer_cost": {
"send_sir": 115123062500,
Expand Down Expand Up @@ -134,8 +134,8 @@
"wasm_config": {
"ext_costs": {
"base": 264768111,
"contract_compile_base": 35445963,
"contract_compile_bytes": 216750,
"contract_compile_base": 0,
"contract_compile_bytes": 0,
"read_memory_base": 2609863200,
"read_memory_byte": 3801333,
"write_memory_base": 2803794861,
Expand Down
1 change: 1 addition & 0 deletions neard/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ protocol_feature_evm = ["nearcore/protocol_feature_evm"]
protocol_feature_alt_bn128 = ["nearcore/protocol_feature_alt_bn128"]
protocol_feature_block_header_v3 = ["nearcore/protocol_feature_block_header_v3"]
protocol_feature_restore_receipts_after_fix = ["nearcore/protocol_feature_restore_receipts_after_fix"]
protocol_feature_precompile_contracts = ["nearcore/protocol_feature_precompile_contracts"]
nightly_protocol_features = ["nearcore/nightly_protocol_features"]
nightly_protocol = ["nearcore/nightly_protocol"]

Expand Down
1 change: 1 addition & 0 deletions runtime/near-vm-logic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ serde_json = {version= "1", features= ["preserve_order"]}
default = []
protocol_feature_evm = ["near-primitives-core/protocol_feature_evm"]
protocol_feature_alt_bn128 = ["bn", "near-primitives-core/protocol_feature_alt_bn128", "near-vm-errors/protocol_feature_alt_bn128"]
protocol_feature_precompile_contracts = []

# Use this feature to enable counting of fees and costs applied.
costs_counting = []
Expand Down
1 change: 1 addition & 0 deletions runtime/near-vm-runner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ protocol_feature_alt_bn128 = [
"near-primitives/protocol_feature_alt_bn128",
"near-vm-errors/protocol_feature_alt_bn128"
]
protocol_feature_precompile_contracts = ["near-vm-logic/protocol_feature_precompile_contracts", "near-primitives/protocol_feature_precompile_contracts"]

[package.metadata.cargo-udeps.ignore]
# `no_cache` feature leads to an unused `cached` crate
Expand Down
1 change: 1 addition & 0 deletions runtime/near-vm-runner/src/wasmtime_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ pub mod wasmtime_runner {
))),
);
}

// Unfortunately, due to the Wasmtime implementation we have to do tricks with the
// lifetimes of the logic instance and pass raw pointers here.
let raw_logic = &mut logic as *mut _ as *mut c_void;
Expand Down
3 changes: 2 additions & 1 deletion runtime/runtime-params-estimator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ no_cache = ["node-runtime/no_cache", "near-store/no_cache"]
wasmtime = ["near-vm-runner/wasmtime_default"]
lightbeam = ["wasmtime", "near-vm-runner/lightbeam"]
nightly_protocol = ["near-primitives/nightly_protocol"]
nightly_protocol_features = ["protocol_feature_alt_bn128", "protocol_feature_evm"]
nightly_protocol_features = ["protocol_feature_alt_bn128", "protocol_feature_evm", "protocol_feature_precompile_contracts"]
protocol_feature_alt_bn128 = [
"near-vm-logic/protocol_feature_alt_bn128",
"near-vm-runner/protocol_feature_alt_bn128",
Expand All @@ -70,4 +70,5 @@ protocol_feature_evm = [
"near-primitives/protocol_feature_evm",
"testlib/protocol_feature_evm"
]
protocol_feature_precompile_contracts = []
sandbox = ["node-runtime/sandbox", "state-viewer/sandbox"]
26 changes: 12 additions & 14 deletions runtime/runtime-params-estimator/src/cases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -714,17 +714,15 @@ fn get_runtime_fees_config(measurement: &Measurements) -> RuntimeFeesConfig {
}
}

fn get_ext_costs_config(measurement: &Measurements, config: &Config) -> ExtCostsConfig {
fn get_ext_costs_config(measurement: &Measurements) -> ExtCostsConfig {
let mut generator = ExtCostsGenerator::new(measurement);
let measured = generator.compute();
let metric = measurement.gas_metric;
use ExtCosts::*;
let (contract_compile_base_, contract_compile_bytes_) =
compute_compile_cost_vm(config.metric, config.vm_kind, false);
ExtCostsConfig {
base: measured_to_gas(metric, &measured, base),
contract_compile_base: contract_compile_base_,
contract_compile_bytes: contract_compile_bytes_,
contract_compile_base: 0,
contract_compile_bytes: 0,
read_memory_base: measured_to_gas(metric, &measured, read_memory_base),
read_memory_byte: measured_to_gas(metric, &measured, read_memory_byte),
write_memory_base: measured_to_gas(metric, &measured, write_memory_base),
Expand Down Expand Up @@ -812,9 +810,9 @@ fn get_ext_costs_config(measurement: &Measurements, config: &Config) -> ExtCosts
}
}

fn get_vm_config(measurement: &Measurements, config: &Config) -> VMConfig {
fn get_vm_config(measurement: &Measurements) -> VMConfig {
VMConfig {
ext_costs: get_ext_costs_config(measurement, config),
ext_costs: get_ext_costs_config(measurement),
// TODO: Figure out whether we need this fee at all. If we do what should be the memory
// growth cost.
grow_mem_cost: 1,
Expand All @@ -828,7 +826,7 @@ fn get_vm_config(measurement: &Measurements, config: &Config) -> VMConfig {

fn get_runtime_config(measurement: &Measurements, config: &Config) -> RuntimeConfig {
let mut runtime_config = RuntimeConfig::default();
runtime_config.wasm_config = get_vm_config(measurement, config);
runtime_config.wasm_config = get_vm_config(measurement);

// Compiling small test contract that was used for `noop` function call estimation.
load_and_compile(
Expand All @@ -840,18 +838,18 @@ fn get_runtime_config(measurement: &Measurements, config: &Config) -> RuntimeCon

runtime_config.transaction_costs = get_runtime_fees_config(measurement);

// Shifting compilation costs from function call runtime to the deploy action cost at execution
// time. Contract used in deploy action testing is very small, so we have to use more complex
// Adding compilation costs to the deploy action cost.
// Contract used in deploy action testing is very small, so we have to use more complex
// technique to compute the actual coefficients.
let (contract_compile_base, contract_compile_bytes) =
compute_compile_cost_vm(config.metric, config.vm_kind, false);
runtime_config.transaction_costs.action_creation_config.deploy_contract_cost.execution +=
runtime_config.wasm_config.ext_costs.contract_compile_base;
contract_compile_base;
runtime_config
.transaction_costs
.action_creation_config
.deploy_contract_cost_per_byte
.execution += runtime_config.wasm_config.ext_costs.contract_compile_bytes;
runtime_config.wasm_config.ext_costs.contract_compile_base = 0;
runtime_config.wasm_config.ext_costs.contract_compile_bytes = 0;
.execution += contract_compile_bytes;

runtime_config
}