From 5bed6b2f7de8308015ee45d09178039c7b7a6bc5 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Tue, 8 Aug 2023 16:10:25 +0300 Subject: [PATCH] Fix #9393 (#9395) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We made a single letter mistake and passed values larger than `i32::MAX` to a function that did only supports `0..=i32::MAX`. This fix corrects the problem, introduces the necessary protocol versioning, a regression test and an additional assert to validate the inputs in the aforementioned function. I ended up using the parameters for the behaviour flag in anticipation that I wouldn’t need to do this later as part of https://github.com/near/nearcore/pull/9364. --- .../jsonrpc-tests/res/genesis_config.json | 2 +- core/primitives-core/src/config.rs | 5 + core/primitives-core/src/parameter.rs | 3 + core/primitives/res/runtime_configs/62.yaml | 3 + core/primitives/res/runtime_configs/63.yaml | 1 + .../res/runtime_configs/parameters.snap | 1 + .../res/runtime_configs/parameters.yaml | 2 + .../runtime_configs/parameters_testnet.yaml | 2 + core/primitives/src/runtime/config_store.rs | 1 + .../primitives/src/runtime/parameter_table.rs | 19 ++ ..._runtime__config_store__tests__0.json.snap | 1 + ...runtime__config_store__tests__42.json.snap | 1 + ...runtime__config_store__tests__48.json.snap | 1 + ...runtime__config_store__tests__49.json.snap | 1 + ...runtime__config_store__tests__50.json.snap | 1 + ...runtime__config_store__tests__52.json.snap | 1 + ...runtime__config_store__tests__53.json.snap | 1 + ...runtime__config_store__tests__57.json.snap | 1 + ...runtime__config_store__tests__59.json.snap | 1 + ...runtime__config_store__tests__61.json.snap | 1 + ...runtime__config_store__tests__62.json.snap | 1 + ...runtime__config_store__tests__63.json.snap | 209 ++++++++++++++++++ ...__config_store__tests__testnet_0.json.snap | 1 + ..._config_store__tests__testnet_42.json.snap | 1 + ..._config_store__tests__testnet_48.json.snap | 1 + ..._config_store__tests__testnet_49.json.snap | 1 + ..._config_store__tests__testnet_50.json.snap | 1 + ..._config_store__tests__testnet_52.json.snap | 1 + ..._config_store__tests__testnet_53.json.snap | 1 + ..._config_store__tests__testnet_57.json.snap | 1 + ..._config_store__tests__testnet_59.json.snap | 1 + ..._config_store__tests__testnet_61.json.snap | 1 + ..._config_store__tests__testnet_62.json.snap | 1 + ..._config_store__tests__testnet_63.json.snap | 209 ++++++++++++++++++ ...es__views__tests__runtime_config_view.snap | 1 + core/primitives/src/views.rs | 4 + runtime/near-test-contracts/src/lib.rs | 29 +++ runtime/near-vm-runner/src/near_vm_runner.rs | 3 +- .../src/tests/runtime_errors.rs | 27 +++ .../near-vm-runner/src/tests/test_builder.rs | 13 +- .../compiler-singlepass/src/codegen_x64.rs | 37 +++- .../near-vm/compiler-singlepass/src/config.rs | 6 + .../src/costs_to_runtime_config.rs | 1 + 43 files changed, 587 insertions(+), 13 deletions(-) create mode 100644 core/primitives/res/runtime_configs/63.yaml create mode 100644 core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__63.json.snap create mode 100644 core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_63.json.snap diff --git a/chain/jsonrpc/jsonrpc-tests/res/genesis_config.json b/chain/jsonrpc/jsonrpc-tests/res/genesis_config.json index 730d113d766..e9c7e32d6cd 100644 --- a/chain/jsonrpc/jsonrpc-tests/res/genesis_config.json +++ b/chain/jsonrpc/jsonrpc-tests/res/genesis_config.json @@ -69,4 +69,4 @@ ], "use_production_config": false, "records": [] -} +} \ No newline at end of file diff --git a/core/primitives-core/src/config.rs b/core/primitives-core/src/config.rs index 8ff2f819d43..376915326de 100644 --- a/core/primitives-core/src/config.rs +++ b/core/primitives-core/src/config.rs @@ -22,6 +22,9 @@ pub struct VMConfig { /// Gas cost of a regular operation. pub regular_op_cost: u32, + /// Disable the fix for the #9393 issue in near-vm-runner. + pub disable_9393_fix: bool, + /// Describes limits for VM and Runtime. pub limit_config: VMLimitConfig, } @@ -179,6 +182,7 @@ impl VMConfig { ext_costs: ExtCostsConfig::test(), grow_mem_cost: 1, regular_op_cost: (SAFETY_MULTIPLIER as u32) * 1285457, + disable_9393_fix: false, limit_config: VMLimitConfig::test(), } } @@ -196,6 +200,7 @@ impl VMConfig { ext_costs: ExtCostsConfig::free(), grow_mem_cost: 0, regular_op_cost: 0, + disable_9393_fix: false, // We shouldn't have any costs in the limit config. limit_config: VMLimitConfig { max_gas_burnt: u64::MAX, ..VMLimitConfig::test() }, } diff --git a/core/primitives-core/src/parameter.rs b/core/primitives-core/src/parameter.rs index 258bc1349cc..e1824d26ee8 100644 --- a/core/primitives-core/src/parameter.rs +++ b/core/primitives-core/src/parameter.rs @@ -145,6 +145,9 @@ pub enum Parameter { Wasmer2StackLimit, MaxLocalsPerContract, AccountIdValidityRulesVersion, + + #[strum(serialize = "disable_9393_fix")] + Disable9393Fix, } #[derive( diff --git a/core/primitives/res/runtime_configs/62.yaml b/core/primitives/res/runtime_configs/62.yaml index 4171df5219a..3a19480c3de 100644 --- a/core/primitives/res/runtime_configs/62.yaml +++ b/core/primitives/res/runtime_configs/62.yaml @@ -3,3 +3,6 @@ # correct. max_stack_height: { old: 16384, new: 262144 } contract_prepare_version: { old: 1, new: 2 } + +# There was a bug for a short period of time that we need to reproduce... +disable_9393_fix: { old: false, new: true } diff --git a/core/primitives/res/runtime_configs/63.yaml b/core/primitives/res/runtime_configs/63.yaml new file mode 100644 index 00000000000..18dc4c1b745 --- /dev/null +++ b/core/primitives/res/runtime_configs/63.yaml @@ -0,0 +1 @@ +disable_9393_fix: { old: true, new: false } diff --git a/core/primitives/res/runtime_configs/parameters.snap b/core/primitives/res/runtime_configs/parameters.snap index 097cc69b462..992e18c4ad7 100644 --- a/core/primitives/res/runtime_configs/parameters.snap +++ b/core/primitives/res/runtime_configs/parameters.snap @@ -163,4 +163,5 @@ max_functions_number_per_contract 10_000 wasmer2_stack_limit 204_800 max_locals_per_contract 1_000_000 account_id_validity_rules_version 1 +disable_9393_fix false diff --git a/core/primitives/res/runtime_configs/parameters.yaml b/core/primitives/res/runtime_configs/parameters.yaml index 785da2f5181..c2977b97a65 100644 --- a/core/primitives/res/runtime_configs/parameters.yaml +++ b/core/primitives/res/runtime_configs/parameters.yaml @@ -196,3 +196,5 @@ max_length_storage_value: 4_194_304 max_promises_per_function_call_action: 1_024 max_number_input_data_dependencies: 128 account_id_validity_rules_version: 0 + +disable_9393_fix: false diff --git a/core/primitives/res/runtime_configs/parameters_testnet.yaml b/core/primitives/res/runtime_configs/parameters_testnet.yaml index a5a3fe7ea52..dbfde6c7195 100644 --- a/core/primitives/res/runtime_configs/parameters_testnet.yaml +++ b/core/primitives/res/runtime_configs/parameters_testnet.yaml @@ -192,3 +192,5 @@ max_length_storage_key: 4_194_304 max_length_storage_value: 4_194_304 max_promises_per_function_call_action: 1_024 max_number_input_data_dependencies: 128 + +disable_9393_fix: false diff --git a/core/primitives/src/runtime/config_store.rs b/core/primitives/src/runtime/config_store.rs index d3ac43396ea..f15ae58e2d1 100644 --- a/core/primitives/src/runtime/config_store.rs +++ b/core/primitives/src/runtime/config_store.rs @@ -32,6 +32,7 @@ static CONFIG_DIFFS: &[(ProtocolVersion, &str)] = &[ (59, include_config!("59.yaml")), (61, include_config!("61.yaml")), (62, include_config!("62.yaml")), + (63, include_config!("63.yaml")), ]; /// Testnet parameters for versions <= 29, which (incorrectly) differed from mainnet parameters diff --git a/core/primitives/src/runtime/parameter_table.rs b/core/primitives/src/runtime/parameter_table.rs index 3cb95aeba44..44ebd909d79 100644 --- a/core/primitives/src/runtime/parameter_table.rs +++ b/core/primitives/src/runtime/parameter_table.rs @@ -19,6 +19,7 @@ pub(crate) enum ParameterValue { // for u128, but this is currently impossible to express in YAML (see // `canonicalize_yaml_string`). String(String), + Flag(bool), } #[derive(thiserror::Error, Debug)] @@ -74,6 +75,22 @@ impl TryFrom<&ParameterValue> for u128 { } } +impl TryFrom<&ParameterValue> for bool { + type Error = ValueConversionError; + + fn try_from(value: &ParameterValue) -> Result { + match value { + ParameterValue::Flag(b) => Ok(*b), + ParameterValue::String(s) => match &**s { + "true" => Ok(true), + "false" => Ok(false), + _ => Err(ValueConversionError::ParseType("bool", value.clone())), + }, + _ => Err(ValueConversionError::ParseType("bool", value.clone())), + } + } +} + impl TryFrom<&ParameterValue> for Rational32 { type Error = ValueConversionError; @@ -177,6 +194,7 @@ impl core::fmt::Display for ParameterValue { ) } ParameterValue::String(v) => write!(f, "{v}"), + ParameterValue::Flag(b) => write!(f, "{b:?}"), } } } @@ -270,6 +288,7 @@ impl TryFrom<&ParameterTable> for RuntimeConfig { }, grow_mem_cost: params.get(Parameter::WasmGrowMemCost)?, regular_op_cost: params.get(Parameter::WasmRegularOpCost)?, + disable_9393_fix: params.get(Parameter::Disable9393Fix)?, limit_config: serde_yaml::from_value(params.yaml_map(Parameter::vm_limits())) .map_err(InvalidConfigError::InvalidYaml)?, }, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__0.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__0.json.snap index a1af3e3e846..8d3a9487167 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__0.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__0.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 3856371, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 200000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__42.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__42.json.snap index 521666a572a..da92d2b6351 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__42.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__42.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 3856371, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 200000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__48.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__48.json.snap index 54ba7733198..e9996d6cf48 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__48.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__48.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 2207874, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 200000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__49.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__49.json.snap index 5845165e3da..81a98cf3f6b 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__49.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__49.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 200000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__50.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__50.json.snap index 779a7a28ef8..fa98182d6f2 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__50.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__50.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 200000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__52.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__52.json.snap index d0f47addd07..40a4e9072bf 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__52.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__52.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 300000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__53.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__53.json.snap index 48bd59de1c8..944ebbc71be 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__53.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__53.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 300000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__57.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__57.json.snap index cc042ce7d63..df74cd295eb 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__57.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__57.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 300000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__59.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__59.json.snap index ef2462605a3..a806026f968 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__59.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__59.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 300000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__61.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__61.json.snap index ef2462605a3..a806026f968 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__61.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__61.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 300000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__62.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__62.json.snap index 60a5bcddd39..cf7a6a3cb42 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__62.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__62.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": true, "limit_config": { "max_gas_burnt": 300000000000000, "max_stack_height": 262144, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__63.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__63.json.snap new file mode 100644 index 00000000000..94b3a526bb6 --- /dev/null +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__63.json.snap @@ -0,0 +1,209 @@ +--- +source: core/primitives/src/runtime/config_store.rs +expression: config_view +--- +{ + "storage_amount_per_byte": "10000000000000000000", + "transaction_costs": { + "action_receipt_creation_config": { + "send_sir": 108059500000, + "send_not_sir": 108059500000, + "execution": 108059500000 + }, + "data_receipt_creation_config": { + "base_cost": { + "send_sir": 36486732312, + "send_not_sir": 36486732312, + "execution": 36486732312 + }, + "cost_per_byte": { + "send_sir": 17212011, + "send_not_sir": 17212011, + "execution": 17212011 + } + }, + "action_creation_config": { + "create_account_cost": { + "send_sir": 3850000000000, + "send_not_sir": 3850000000000, + "execution": 3850000000000 + }, + "deploy_contract_cost": { + "send_sir": 184765750000, + "send_not_sir": 184765750000, + "execution": 184765750000 + }, + "deploy_contract_cost_per_byte": { + "send_sir": 6812999, + "send_not_sir": 6812999, + "execution": 64572944 + }, + "function_call_cost": { + "send_sir": 2319861500000, + "send_not_sir": 2319861500000, + "execution": 2319861500000 + }, + "function_call_cost_per_byte": { + "send_sir": 2235934, + "send_not_sir": 2235934, + "execution": 2235934 + }, + "transfer_cost": { + "send_sir": 115123062500, + "send_not_sir": 115123062500, + "execution": 115123062500 + }, + "stake_cost": { + "send_sir": 141715687500, + "send_not_sir": 141715687500, + "execution": 102217625000 + }, + "add_key_cost": { + "full_access_cost": { + "send_sir": 101765125000, + "send_not_sir": 101765125000, + "execution": 101765125000 + }, + "function_call_cost": { + "send_sir": 102217625000, + "send_not_sir": 102217625000, + "execution": 102217625000 + }, + "function_call_cost_per_byte": { + "send_sir": 1925331, + "send_not_sir": 1925331, + "execution": 1925331 + } + }, + "delete_key_cost": { + "send_sir": 94946625000, + "send_not_sir": 94946625000, + "execution": 94946625000 + }, + "delete_account_cost": { + "send_sir": 147489000000, + "send_not_sir": 147489000000, + "execution": 147489000000 + }, + "delegate_cost": { + "send_sir": 200000000000, + "send_not_sir": 200000000000, + "execution": 200000000000 + } + }, + "storage_usage_config": { + "num_bytes_account": 100, + "num_extra_bytes_record": 40 + }, + "burnt_gas_reward": [ + 3, + 10 + ], + "pessimistic_gas_price_inflation_ratio": [ + 103, + 100 + ] + }, + "wasm_config": { + "ext_costs": { + "base": 264768111, + "contract_loading_base": 35445963, + "contract_loading_bytes": 216750, + "read_memory_base": 2609863200, + "read_memory_byte": 3801333, + "write_memory_base": 2803794861, + "write_memory_byte": 2723772, + "read_register_base": 2517165186, + "read_register_byte": 98562, + "write_register_base": 2865522486, + "write_register_byte": 3801564, + "utf8_decoding_base": 3111779061, + "utf8_decoding_byte": 291580479, + "utf16_decoding_base": 3543313050, + "utf16_decoding_byte": 163577493, + "sha256_base": 4540970250, + "sha256_byte": 24117351, + "keccak256_base": 5879491275, + "keccak256_byte": 21471105, + "keccak512_base": 5811388236, + "keccak512_byte": 36649701, + "ripemd160_base": 853675086, + "ripemd160_block": 680107584, + "ed25519_verify_base": 210000000000, + "ed25519_verify_byte": 9000000, + "ecrecover_base": 278821988457, + "log_base": 3543313050, + "log_byte": 13198791, + "storage_write_base": 64196736000, + "storage_write_key_byte": 70482867, + "storage_write_value_byte": 31018539, + "storage_write_evicted_byte": 32117307, + "storage_read_base": 56356845750, + "storage_read_key_byte": 30952533, + "storage_read_value_byte": 5611005, + "storage_remove_base": 53473030500, + "storage_remove_key_byte": 38220384, + "storage_remove_ret_value_byte": 11531556, + "storage_has_key_base": 54039896625, + "storage_has_key_byte": 30790845, + "storage_iter_create_prefix_base": 0, + "storage_iter_create_prefix_byte": 0, + "storage_iter_create_range_base": 0, + "storage_iter_create_from_byte": 0, + "storage_iter_create_to_byte": 0, + "storage_iter_next_base": 0, + "storage_iter_next_key_byte": 0, + "storage_iter_next_value_byte": 0, + "touching_trie_node": 16101955926, + "read_cached_trie_node": 2280000000, + "promise_and_base": 1465013400, + "promise_and_per_promise": 5452176, + "promise_return": 560152386, + "validator_stake_base": 911834726400, + "validator_total_stake_base": 911834726400, + "contract_compile_base": 0, + "contract_compile_bytes": 0, + "alt_bn128_g1_multiexp_base": 713000000000, + "alt_bn128_g1_multiexp_element": 320000000000, + "alt_bn128_g1_sum_base": 3000000000, + "alt_bn128_g1_sum_element": 5000000000, + "alt_bn128_pairing_check_base": 9686000000000, + "alt_bn128_pairing_check_element": 5102000000000 + }, + "grow_mem_cost": 1, + "regular_op_cost": 822756, + "disable_9393_fix": false, + "limit_config": { + "max_gas_burnt": 300000000000000, + "max_stack_height": 262144, + "contract_prepare_version": 2, + "initial_memory_pages": 1024, + "max_memory_pages": 2048, + "registers_memory_limit": 1073741824, + "max_register_size": 104857600, + "max_number_registers": 100, + "max_number_logs": 100, + "max_total_log_length": 16384, + "max_total_prepaid_gas": 300000000000000, + "max_actions_per_receipt": 100, + "max_number_bytes_method_names": 2000, + "max_length_method_name": 256, + "max_arguments_length": 4194304, + "max_length_returned_data": 4194304, + "max_contract_size": 4194304, + "max_transaction_size": 4194304, + "max_length_storage_key": 2048, + "max_length_storage_value": 4194304, + "max_promises_per_function_call_action": 1024, + "max_number_input_data_dependencies": 128, + "max_functions_number_per_contract": 10000, + "wasmer2_stack_limit": 204800, + "max_locals_per_contract": 1000000, + "account_id_validity_rules_version": 1 + } + }, + "account_creation_config": { + "min_allowed_top_level_account_length": 32, + "registrar_account_id": "registrar" + } +} diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_0.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_0.json.snap index a1af3e3e846..8d3a9487167 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_0.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_0.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 3856371, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 200000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_42.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_42.json.snap index 521666a572a..da92d2b6351 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_42.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_42.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 3856371, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 200000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_48.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_48.json.snap index 54ba7733198..e9996d6cf48 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_48.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_48.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 2207874, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 200000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_49.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_49.json.snap index 5845165e3da..81a98cf3f6b 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_49.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_49.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 200000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_50.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_50.json.snap index 779a7a28ef8..fa98182d6f2 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_50.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_50.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 200000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_52.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_52.json.snap index d0f47addd07..40a4e9072bf 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_52.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_52.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 300000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_53.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_53.json.snap index 48bd59de1c8..944ebbc71be 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_53.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_53.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 300000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_57.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_57.json.snap index cc042ce7d63..df74cd295eb 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_57.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_57.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 300000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_59.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_59.json.snap index ef2462605a3..a806026f968 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_59.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_59.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 300000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_61.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_61.json.snap index ef2462605a3..a806026f968 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_61.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_61.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 300000000000000, "max_stack_height": 16384, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_62.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_62.json.snap index 60a5bcddd39..cf7a6a3cb42 100644 --- a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_62.json.snap +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_62.json.snap @@ -172,6 +172,7 @@ expression: config_view }, "grow_mem_cost": 1, "regular_op_cost": 822756, + "disable_9393_fix": true, "limit_config": { "max_gas_burnt": 300000000000000, "max_stack_height": 262144, diff --git a/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_63.json.snap b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_63.json.snap new file mode 100644 index 00000000000..94b3a526bb6 --- /dev/null +++ b/core/primitives/src/runtime/snapshots/near_primitives__runtime__config_store__tests__testnet_63.json.snap @@ -0,0 +1,209 @@ +--- +source: core/primitives/src/runtime/config_store.rs +expression: config_view +--- +{ + "storage_amount_per_byte": "10000000000000000000", + "transaction_costs": { + "action_receipt_creation_config": { + "send_sir": 108059500000, + "send_not_sir": 108059500000, + "execution": 108059500000 + }, + "data_receipt_creation_config": { + "base_cost": { + "send_sir": 36486732312, + "send_not_sir": 36486732312, + "execution": 36486732312 + }, + "cost_per_byte": { + "send_sir": 17212011, + "send_not_sir": 17212011, + "execution": 17212011 + } + }, + "action_creation_config": { + "create_account_cost": { + "send_sir": 3850000000000, + "send_not_sir": 3850000000000, + "execution": 3850000000000 + }, + "deploy_contract_cost": { + "send_sir": 184765750000, + "send_not_sir": 184765750000, + "execution": 184765750000 + }, + "deploy_contract_cost_per_byte": { + "send_sir": 6812999, + "send_not_sir": 6812999, + "execution": 64572944 + }, + "function_call_cost": { + "send_sir": 2319861500000, + "send_not_sir": 2319861500000, + "execution": 2319861500000 + }, + "function_call_cost_per_byte": { + "send_sir": 2235934, + "send_not_sir": 2235934, + "execution": 2235934 + }, + "transfer_cost": { + "send_sir": 115123062500, + "send_not_sir": 115123062500, + "execution": 115123062500 + }, + "stake_cost": { + "send_sir": 141715687500, + "send_not_sir": 141715687500, + "execution": 102217625000 + }, + "add_key_cost": { + "full_access_cost": { + "send_sir": 101765125000, + "send_not_sir": 101765125000, + "execution": 101765125000 + }, + "function_call_cost": { + "send_sir": 102217625000, + "send_not_sir": 102217625000, + "execution": 102217625000 + }, + "function_call_cost_per_byte": { + "send_sir": 1925331, + "send_not_sir": 1925331, + "execution": 1925331 + } + }, + "delete_key_cost": { + "send_sir": 94946625000, + "send_not_sir": 94946625000, + "execution": 94946625000 + }, + "delete_account_cost": { + "send_sir": 147489000000, + "send_not_sir": 147489000000, + "execution": 147489000000 + }, + "delegate_cost": { + "send_sir": 200000000000, + "send_not_sir": 200000000000, + "execution": 200000000000 + } + }, + "storage_usage_config": { + "num_bytes_account": 100, + "num_extra_bytes_record": 40 + }, + "burnt_gas_reward": [ + 3, + 10 + ], + "pessimistic_gas_price_inflation_ratio": [ + 103, + 100 + ] + }, + "wasm_config": { + "ext_costs": { + "base": 264768111, + "contract_loading_base": 35445963, + "contract_loading_bytes": 216750, + "read_memory_base": 2609863200, + "read_memory_byte": 3801333, + "write_memory_base": 2803794861, + "write_memory_byte": 2723772, + "read_register_base": 2517165186, + "read_register_byte": 98562, + "write_register_base": 2865522486, + "write_register_byte": 3801564, + "utf8_decoding_base": 3111779061, + "utf8_decoding_byte": 291580479, + "utf16_decoding_base": 3543313050, + "utf16_decoding_byte": 163577493, + "sha256_base": 4540970250, + "sha256_byte": 24117351, + "keccak256_base": 5879491275, + "keccak256_byte": 21471105, + "keccak512_base": 5811388236, + "keccak512_byte": 36649701, + "ripemd160_base": 853675086, + "ripemd160_block": 680107584, + "ed25519_verify_base": 210000000000, + "ed25519_verify_byte": 9000000, + "ecrecover_base": 278821988457, + "log_base": 3543313050, + "log_byte": 13198791, + "storage_write_base": 64196736000, + "storage_write_key_byte": 70482867, + "storage_write_value_byte": 31018539, + "storage_write_evicted_byte": 32117307, + "storage_read_base": 56356845750, + "storage_read_key_byte": 30952533, + "storage_read_value_byte": 5611005, + "storage_remove_base": 53473030500, + "storage_remove_key_byte": 38220384, + "storage_remove_ret_value_byte": 11531556, + "storage_has_key_base": 54039896625, + "storage_has_key_byte": 30790845, + "storage_iter_create_prefix_base": 0, + "storage_iter_create_prefix_byte": 0, + "storage_iter_create_range_base": 0, + "storage_iter_create_from_byte": 0, + "storage_iter_create_to_byte": 0, + "storage_iter_next_base": 0, + "storage_iter_next_key_byte": 0, + "storage_iter_next_value_byte": 0, + "touching_trie_node": 16101955926, + "read_cached_trie_node": 2280000000, + "promise_and_base": 1465013400, + "promise_and_per_promise": 5452176, + "promise_return": 560152386, + "validator_stake_base": 911834726400, + "validator_total_stake_base": 911834726400, + "contract_compile_base": 0, + "contract_compile_bytes": 0, + "alt_bn128_g1_multiexp_base": 713000000000, + "alt_bn128_g1_multiexp_element": 320000000000, + "alt_bn128_g1_sum_base": 3000000000, + "alt_bn128_g1_sum_element": 5000000000, + "alt_bn128_pairing_check_base": 9686000000000, + "alt_bn128_pairing_check_element": 5102000000000 + }, + "grow_mem_cost": 1, + "regular_op_cost": 822756, + "disable_9393_fix": false, + "limit_config": { + "max_gas_burnt": 300000000000000, + "max_stack_height": 262144, + "contract_prepare_version": 2, + "initial_memory_pages": 1024, + "max_memory_pages": 2048, + "registers_memory_limit": 1073741824, + "max_register_size": 104857600, + "max_number_registers": 100, + "max_number_logs": 100, + "max_total_log_length": 16384, + "max_total_prepaid_gas": 300000000000000, + "max_actions_per_receipt": 100, + "max_number_bytes_method_names": 2000, + "max_length_method_name": 256, + "max_arguments_length": 4194304, + "max_length_returned_data": 4194304, + "max_contract_size": 4194304, + "max_transaction_size": 4194304, + "max_length_storage_key": 2048, + "max_length_storage_value": 4194304, + "max_promises_per_function_call_action": 1024, + "max_number_input_data_dependencies": 128, + "max_functions_number_per_contract": 10000, + "wasmer2_stack_limit": 204800, + "max_locals_per_contract": 1000000, + "account_id_validity_rules_version": 1 + } + }, + "account_creation_config": { + "min_allowed_top_level_account_length": 32, + "registrar_account_id": "registrar" + } +} diff --git a/core/primitives/src/snapshots/near_primitives__views__tests__runtime_config_view.snap b/core/primitives/src/snapshots/near_primitives__views__tests__runtime_config_view.snap index 4b2bd548491..aa4df5f7cdd 100644 --- a/core/primitives/src/snapshots/near_primitives__views__tests__runtime_config_view.snap +++ b/core/primitives/src/snapshots/near_primitives__views__tests__runtime_config_view.snap @@ -172,6 +172,7 @@ expression: "&view" }, "grow_mem_cost": 1, "regular_op_cost": 3856371, + "disable_9393_fix": false, "limit_config": { "max_gas_burnt": 200000000000000, "max_stack_height": 262144, diff --git a/core/primitives/src/views.rs b/core/primitives/src/views.rs index e9c7547d296..14a34407777 100644 --- a/core/primitives/src/views.rs +++ b/core/primitives/src/views.rs @@ -2476,6 +2476,8 @@ pub struct VMConfigView { /// Gas cost of a regular operation. pub regular_op_cost: u32, + pub disable_9393_fix: bool, + /// Describes limits for VM and Runtime. /// /// TODO: Consider changing this to `VMLimitConfigView` to avoid dependency @@ -2489,6 +2491,7 @@ impl From for VMConfigView { ext_costs: ExtCostsConfigView::from(config.ext_costs), grow_mem_cost: config.grow_mem_cost, regular_op_cost: config.regular_op_cost, + disable_9393_fix: config.disable_9393_fix, limit_config: config.limit_config, } } @@ -2500,6 +2503,7 @@ impl From for VMConfig { ext_costs: near_primitives_core::config::ExtCostsConfig::from(view.ext_costs), grow_mem_cost: view.grow_mem_cost, regular_op_cost: view.regular_op_cost, + disable_9393_fix: view.disable_9393_fix, limit_config: view.limit_config, } } diff --git a/runtime/near-test-contracts/src/lib.rs b/runtime/near-test-contracts/src/lib.rs index 1d975e24787..5a1314ef42a 100644 --- a/runtime/near-test-contracts/src/lib.rs +++ b/runtime/near-test-contracts/src/lib.rs @@ -220,6 +220,35 @@ impl LargeContract { } } +/// Generate contracts with function bodies of large continuous sequences of `nop` instruction. +/// +/// This is particularly useful for testing how gas instrumentation works and its corner cases. +pub fn function_with_a_lot_of_nop(nops: u64) -> Vec { + use wasm_encoder::{ + CodeSection, ExportKind, ExportSection, Function, FunctionSection, Instruction, Module, + TypeSection, + }; + let mut module = Module::new(); + let mut type_section = TypeSection::new(); + type_section.function([], []); + module.section(&type_section); + let mut functions_section = FunctionSection::new(); + functions_section.function(0); + module.section(&functions_section); + let mut exports_section = ExportSection::new(); + exports_section.export("main", ExportKind::Func, 0); + module.section(&exports_section); + let mut code_section = CodeSection::new(); + let mut f = Function::new([]); + for _ in 0..nops { + f.instruction(&Instruction::Nop); + } + f.instruction(&Instruction::End); + code_section.function(&f); + module.section(&code_section); + module.finish() +} + /// Generate an arbitrary valid contract. pub fn arbitrary_contract(seed: u64) -> Vec { let mut rng = rand::rngs::SmallRng::seed_from_u64(seed); diff --git a/runtime/near-vm-runner/src/near_vm_runner.rs b/runtime/near-vm-runner/src/near_vm_runner.rs index 7db593f2d1b..aa6d459f3d8 100644 --- a/runtime/near-vm-runner/src/near_vm_runner.rs +++ b/runtime/near-vm-runner/src/near_vm_runner.rs @@ -238,7 +238,8 @@ impl NearVM { pub(crate) fn new_for_target(config: VMConfig, target: near_vm_compiler::Target) -> Self { // We only support singlepass compiler at the moment. assert_eq!(VM_CONFIG.compiler, NearVmCompiler::Singlepass); - let compiler = Singlepass::new(); + let mut compiler = Singlepass::new(); + compiler.set_9393_fix(!config.disable_9393_fix); // We only support universal engine at the moment. assert_eq!(VM_CONFIG.engine, NearVmEngine::Universal); diff --git a/runtime/near-vm-runner/src/tests/runtime_errors.rs b/runtime/near-vm-runner/src/tests/runtime_errors.rs index 66a2b4f1bd8..666301658a2 100644 --- a/runtime/near-vm-runner/src/tests/runtime_errors.rs +++ b/runtime/near-vm-runner/src/tests/runtime_errors.rs @@ -1059,3 +1059,30 @@ mod fix_contract_loading_cost_protocol_upgrade { ]); } } + +#[test] +fn test_regression_9393() { + let before_builder = test_builder().protocol_versions(vec![62]); + let after_builder = test_builder().protocol_versions(vec![63]); + let before_cost = before_builder.configs().next().unwrap().wasm_config.regular_op_cost; + let after_cost = after_builder.configs().next().unwrap().wasm_config.regular_op_cost; + assert_eq!( + before_cost, after_cost, + "this test is not set up to test with different insn costs" + ); + let cost = u64::from(before_cost); + + let nops = (i32::MAX as u64 + cost - 1) / cost; + let contract = near_test_contracts::function_with_a_lot_of_nop(nops); + before_builder.wasm(&contract).only_near_vm().expects(&[ + expect![[r#" + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 100000000000000 used gas 100000000000000 + Err: Exceeded the maximum amount of gas allowed to burn per contract. + "#]], + ]); + after_builder.wasm(&contract).expects(&[ + expect![[r#" + VMOutcome: balance 4 storage_usage 12 return data None burnt gas 2763981177 used gas 2763981177 + "#]], + ]); +} diff --git a/runtime/near-vm-runner/src/tests/test_builder.rs b/runtime/near-vm-runner/src/tests/test_builder.rs index 01d4530f5c8..2a6b0d89af6 100644 --- a/runtime/near-vm-runner/src/tests/test_builder.rs +++ b/runtime/near-vm-runner/src/tests/test_builder.rs @@ -1,11 +1,14 @@ use crate::internal::VMKind; use crate::logic::{mocks::mock_external::MockedExternal, ProtocolVersion, VMContext, VMOutcome}; -use near_primitives::runtime::{config_store::RuntimeConfigStore, fees::RuntimeFeesConfig}; +use near_primitives::runtime::{ + config::RuntimeConfig, config_store::RuntimeConfigStore, fees::RuntimeFeesConfig, +}; use near_primitives_core::{ contract::ContractCode, types::Gas, version::{ProtocolFeature, PROTOCOL_VERSION}, }; +use std::sync::Arc; use std::{collections::HashSet, fmt::Write}; pub(crate) fn test_builder() -> TestBuilder { @@ -164,6 +167,14 @@ impl TestBuilder { self.expects(&[want]) } + pub(crate) fn configs(&self) -> impl Iterator> { + let runtime_config_store = RuntimeConfigStore::new(None); + self.protocol_versions + .clone() + .into_iter() + .map(move |pv| Arc::clone(runtime_config_store.get_config(pv))) + } + #[track_caller] pub(crate) fn expects(self, wants: &[expect_test::Expect]) { let runtime_config_store = RuntimeConfigStore::new(None); diff --git a/runtime/near-vm/compiler-singlepass/src/codegen_x64.rs b/runtime/near-vm/compiler-singlepass/src/codegen_x64.rs index 37602fa3a97..335e050463b 100644 --- a/runtime/near-vm/compiler-singlepass/src/codegen_x64.rs +++ b/runtime/near-vm/compiler-singlepass/src/codegen_x64.rs @@ -349,14 +349,26 @@ impl<'a> FuncGen<'a> { } fn emit_gas_const(&mut self, cost: u64) { - if let Ok(cost) = u32::try_from(cost) { - self.emit_gas(Location::Imm32(cost)); + if self.config.disable_9393_fix { + // emit_gas only supports Imm32 with an argument up-to i32::MAX, but we made *this* + // single-letter oversight at some point & the bug made its way into mainnet. Now that + // we need to maintain backwards compatibility and replayability of the old + // transactions, we end up with this wonderful and slightly horrifying monument to our + // former selves :) + if let Ok(cost) = u32::try_from(cost) { + return self.emit_gas(Location::Imm32(cost)); + } } else { - let cost_reg = self.machine.acquire_temp_gpr().unwrap(); - self.assembler.emit_mov(Size::S64, Location::Imm64(cost), Location::GPR(cost_reg)); - self.emit_gas(Location::GPR(cost_reg)); - self.machine.release_temp_gpr(cost_reg); + if let Ok(cost) = i32::try_from(cost) { + // This as `u32` cast is valid, as fallible u64->i32 conversions can’t produce a + // negative integer. + return self.emit_gas(Location::Imm32(cost as u32)); + } } + let cost_reg = self.machine.acquire_temp_gpr().unwrap(); + self.assembler.emit_mov(Size::S64, Location::Imm64(cost), Location::GPR(cost_reg)); + self.emit_gas(Location::GPR(cost_reg)); + self.machine.release_temp_gpr(cost_reg); } /// Emit a gas charge operation. The gas amount is stored in `cost_location`, which must be either an imm32 or a GPR @@ -365,10 +377,15 @@ impl<'a> FuncGen<'a> { if cost_location == Location::Imm32(0) { return; // skip, which we must do because emit_add optimizes out the add 0 which leaves CF clobbered otherwise } - assert!( - matches!(cost_location, Location::Imm32(_) | Location::GPR(_)), - "emit_gas can take only an imm32 or a gpr argument" - ); + + match cost_location { + Location::Imm32(v) if self.config.disable_9393_fix || v <= (i32::MAX as u32) => {} + Location::Imm32(v) => { + panic!("emit_gas can take only an imm32 <= 0xFFF_FFFF, got 0x{v:X}") + } + Location::GPR(_) => {} + _ => panic!("emit_gas can take only an imm32 or a gpr argument"), + } let counter_offset = offset_of!(FastGasCounter, burnt_gas) as i32; let gas_limit_offset = offset_of!(FastGasCounter, gas_limit) as i32; diff --git a/runtime/near-vm/compiler-singlepass/src/config.rs b/runtime/near-vm/compiler-singlepass/src/config.rs index 41b6b6cd157..2bfff6be9f7 100644 --- a/runtime/near-vm/compiler-singlepass/src/config.rs +++ b/runtime/near-vm/compiler-singlepass/src/config.rs @@ -24,6 +24,7 @@ pub(crate) struct Intrinsic { pub struct Singlepass { pub(crate) enable_nan_canonicalization: bool, pub(crate) enable_stack_check: bool, + pub(crate) disable_9393_fix: bool, /// Compiler intrinsics. pub(crate) intrinsics: Vec, } @@ -35,6 +36,7 @@ impl Singlepass { Self { enable_nan_canonicalization: true, enable_stack_check: false, + disable_9393_fix: false, intrinsics: vec![Intrinsic { kind: IntrinsicKind::Gas, name: "gas".to_string(), @@ -59,6 +61,10 @@ impl Singlepass { self.enable_nan_canonicalization = true; } + pub fn set_9393_fix(&mut self, enable: bool) { + self.disable_9393_fix = !enable; + } + pub fn canonicalize_nans(&mut self, enable: bool) -> &mut Self { self.enable_nan_canonicalization = enable; self diff --git a/runtime/runtime-params-estimator/src/costs_to_runtime_config.rs b/runtime/runtime-params-estimator/src/costs_to_runtime_config.rs index f7f79460da3..330ca497c0d 100644 --- a/runtime/runtime-params-estimator/src/costs_to_runtime_config.rs +++ b/runtime/runtime-params-estimator/src/costs_to_runtime_config.rs @@ -34,6 +34,7 @@ pub fn costs_to_runtime_config(cost_table: &CostTable) -> anyhow::Result