From db22a7683955ff6419d8115623819f3152477ec1 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Tue, 1 Oct 2024 14:24:56 +0300 Subject: [PATCH] Allow configuring binary search kind --- core/bin/external_node/src/config/mod.rs | 10 ++++++++++ core/lib/config/src/configs/api.rs | 5 +++++ core/lib/config/src/testonly.rs | 1 + core/lib/env_config/src/api.rs | 1 + core/lib/protobuf_config/src/api.rs | 2 ++ core/lib/protobuf_config/src/proto/config/api.proto | 2 ++ core/node/api_server/src/tx_sender/gas_estimation.rs | 11 ++++++++++- core/node/api_server/src/web3/namespaces/eth.rs | 3 ++- core/node/api_server/src/web3/namespaces/zks.rs | 3 ++- core/node/api_server/src/web3/state.rs | 4 +++- 10 files changed, 38 insertions(+), 4 deletions(-) diff --git a/core/bin/external_node/src/config/mod.rs b/core/bin/external_node/src/config/mod.rs index f8241deae26c..bbb39759c6a0 100644 --- a/core/bin/external_node/src/config/mod.rs +++ b/core/bin/external_node/src/config/mod.rs @@ -327,6 +327,10 @@ pub(crate) struct OptionalENConfig { /// The max possible number of gas that `eth_estimateGas` is allowed to overestimate. #[serde(default = "OptionalENConfig::default_estimate_gas_acceptable_overestimation")] pub estimate_gas_acceptable_overestimation: u32, + /// Enables optimizations for the binary search of the gas limit in `eth_estimateGas`. These optimizations are currently + /// considered experimental. + #[serde(default)] + pub estimate_gas_optimize_search: bool, /// The multiplier to use when suggesting gas price. Should be higher than one, /// otherwise if the L1 prices soar, the suggested gas price won't be sufficient to be included in block. #[serde(default = "OptionalENConfig::default_gas_price_scale_factor")] @@ -558,6 +562,11 @@ impl OptionalENConfig { web3_json_rpc.estimate_gas_acceptable_overestimation, default_estimate_gas_acceptable_overestimation ), + estimate_gas_optimize_search: general_config + .api_config + .as_ref() + .map(|a| a.web3_json_rpc.estimate_gas_optimize_search) + .unwrap_or_default(), gas_price_scale_factor: load_config_or_default!( general_config.api_config, web3_json_rpc.gas_price_scale_factor, @@ -1382,6 +1391,7 @@ impl From<&ExternalNodeConfig> for InternalApiConfig { estimate_gas_acceptable_overestimation: config .optional .estimate_gas_acceptable_overestimation, + estimate_gas_optimize_search: config.optional.estimate_gas_optimize_search, bridge_addresses: BridgeAddresses { l1_erc20_default_bridge: config.remote.l1_erc20_bridge_proxy_addr, l2_erc20_default_bridge: config.remote.l2_erc20_bridge_addr, diff --git a/core/lib/config/src/configs/api.rs b/core/lib/config/src/configs/api.rs index ca42cd5e5f8a..86c9ebd074d8 100644 --- a/core/lib/config/src/configs/api.rs +++ b/core/lib/config/src/configs/api.rs @@ -169,6 +169,10 @@ pub struct Web3JsonRpcConfig { pub estimate_gas_scale_factor: f64, /// The max possible number of gas that `eth_estimateGas` is allowed to overestimate. pub estimate_gas_acceptable_overestimation: u32, + /// Enables optimizations for the binary search of the gas limit in `eth_estimateGas`. These optimizations are currently + /// considered experimental. + #[serde(default)] + pub estimate_gas_optimize_search: bool, /// Max possible size of an ABI encoded tx (in bytes). pub max_tx_size: usize, /// Max number of cache misses during one VM execution. If the number of cache misses exceeds this value, the API server panics. @@ -237,6 +241,7 @@ impl Web3JsonRpcConfig { gas_price_scale_factor: 1.2, estimate_gas_scale_factor: 1.2, estimate_gas_acceptable_overestimation: 1000, + estimate_gas_optimize_search: false, max_tx_size: 1000000, vm_execution_cache_misses_limit: Default::default(), vm_concurrency_limit: Default::default(), diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs index 5a5a54304425..f873a2ad2248 100644 --- a/core/lib/config/src/testonly.rs +++ b/core/lib/config/src/testonly.rs @@ -77,6 +77,7 @@ impl Distribution for EncodeDist { gas_price_scale_factor: self.sample(rng), estimate_gas_scale_factor: self.sample(rng), estimate_gas_acceptable_overestimation: self.sample(rng), + estimate_gas_optimize_search: self.sample(rng), max_tx_size: self.sample(rng), vm_execution_cache_misses_limit: self.sample(rng), vm_concurrency_limit: self.sample(rng), diff --git a/core/lib/env_config/src/api.rs b/core/lib/env_config/src/api.rs index c6485d54d6b0..53efea9a7848 100644 --- a/core/lib/env_config/src/api.rs +++ b/core/lib/env_config/src/api.rs @@ -69,6 +69,7 @@ mod tests { estimate_gas_scale_factor: 1.0f64, gas_price_scale_factor: 1.2, estimate_gas_acceptable_overestimation: 1000, + estimate_gas_optimize_search: false, max_tx_size: 1000000, vm_execution_cache_misses_limit: None, vm_concurrency_limit: Some(512), diff --git a/core/lib/protobuf_config/src/api.rs b/core/lib/protobuf_config/src/api.rs index f4718c9f7960..a0c3825228af 100644 --- a/core/lib/protobuf_config/src/api.rs +++ b/core/lib/protobuf_config/src/api.rs @@ -84,6 +84,7 @@ impl ProtoRepr for proto::Web3JsonRpc { &self.estimate_gas_acceptable_overestimation, ) .context("acceptable_overestimation")?, + estimate_gas_optimize_search: self.estimate_gas_optimize_search.unwrap_or(false), max_tx_size: required(&self.max_tx_size) .and_then(|x| Ok((*x).try_into()?)) .context("max_tx_size")?, @@ -167,6 +168,7 @@ impl ProtoRepr for proto::Web3JsonRpc { estimate_gas_acceptable_overestimation: Some( this.estimate_gas_acceptable_overestimation, ), + estimate_gas_optimize_search: Some(this.estimate_gas_optimize_search), max_tx_size: Some(this.max_tx_size.try_into().unwrap()), vm_execution_cache_misses_limit: this .vm_execution_cache_misses_limit diff --git a/core/lib/protobuf_config/src/proto/config/api.proto b/core/lib/protobuf_config/src/proto/config/api.proto index e08677adc445..68475e442fd6 100644 --- a/core/lib/protobuf_config/src/proto/config/api.proto +++ b/core/lib/protobuf_config/src/proto/config/api.proto @@ -40,6 +40,8 @@ message Web3JsonRpc { repeated MaxResponseSizeOverride max_response_body_size_overrides = 31; repeated string api_namespaces = 32; // Optional, if empty all namespaces are available optional bool extended_api_tracing = 33; // optional, default false + optional bool estimate_gas_optimize_search = 34; // optional, default false + reserved 15; reserved "l1_to_l2_transactions_compatibility_mode"; reserved 11; reserved "request_timeout"; reserved 12; reserved "account_pks"; diff --git a/core/node/api_server/src/tx_sender/gas_estimation.rs b/core/node/api_server/src/tx_sender/gas_estimation.rs index 5b83f40aab1a..5d571408039a 100644 --- a/core/node/api_server/src/tx_sender/gas_estimation.rs +++ b/core/node/api_server/src/tx_sender/gas_estimation.rs @@ -23,10 +23,19 @@ pub(crate) enum BinarySearchKind { /// Full binary search. Full, /// Binary search with an optimized initial pivot. - #[allow(dead_code)] // FIXME Optimized, } +impl BinarySearchKind { + pub(crate) fn new(optimize: bool) -> Self { + if optimize { + Self::Optimized + } else { + Self::Full + } + } +} + impl TxSender { #[tracing::instrument(level = "debug", skip_all, fields( initiator = ?tx.initiator_account(), diff --git a/core/node/api_server/src/web3/namespaces/eth.rs b/core/node/api_server/src/web3/namespaces/eth.rs index 266e39015527..1d60d839e4ee 100644 --- a/core/node/api_server/src/web3/namespaces/eth.rs +++ b/core/node/api_server/src/web3/namespaces/eth.rs @@ -130,6 +130,7 @@ impl EthNamespace { let scale_factor = self.state.api_config.estimate_gas_scale_factor; let acceptable_overestimation = self.state.api_config.estimate_gas_acceptable_overestimation; + let search_kind = BinarySearchKind::new(self.state.api_config.estimate_gas_optimize_search); let fee = self .state @@ -139,7 +140,7 @@ impl EthNamespace { scale_factor, acceptable_overestimation as u64, state_override, - BinarySearchKind::Full, + search_kind, ) .await?; Ok(fee.gas_limit) diff --git a/core/node/api_server/src/web3/namespaces/zks.rs b/core/node/api_server/src/web3/namespaces/zks.rs index b27f553a2620..61456095d67c 100644 --- a/core/node/api_server/src/web3/namespaces/zks.rs +++ b/core/node/api_server/src/web3/namespaces/zks.rs @@ -105,6 +105,7 @@ impl ZksNamespace { let scale_factor = self.state.api_config.estimate_gas_scale_factor; let acceptable_overestimation = self.state.api_config.estimate_gas_acceptable_overestimation; + let search_kind = BinarySearchKind::new(self.state.api_config.estimate_gas_optimize_search); Ok(self .state @@ -114,7 +115,7 @@ impl ZksNamespace { scale_factor, acceptable_overestimation as u64, state_override, - BinarySearchKind::Full, + search_kind, ) .await?) } diff --git a/core/node/api_server/src/web3/state.rs b/core/node/api_server/src/web3/state.rs index 5c8b47dabeb0..8cbb75103cd9 100644 --- a/core/node/api_server/src/web3/state.rs +++ b/core/node/api_server/src/web3/state.rs @@ -90,7 +90,7 @@ impl BlockStartInfo { } /// Configuration values for the API. -/// This structure is detached from `ZkSyncConfig`, since different node types (main, external, etc) +/// This structure is detached from `ZkSyncConfig`, since different node types (main, external, etc.) /// may require different configuration layouts. /// The intention is to only keep the actually used information here. #[derive(Debug, Clone)] @@ -101,6 +101,7 @@ pub struct InternalApiConfig { pub max_tx_size: usize, pub estimate_gas_scale_factor: f64, pub estimate_gas_acceptable_overestimation: u32, + pub estimate_gas_optimize_search: bool, pub bridge_addresses: api::BridgeAddresses, pub bridgehub_proxy_addr: Option
, pub state_transition_proxy_addr: Option
, @@ -128,6 +129,7 @@ impl InternalApiConfig { estimate_gas_scale_factor: web3_config.estimate_gas_scale_factor, estimate_gas_acceptable_overestimation: web3_config .estimate_gas_acceptable_overestimation, + estimate_gas_optimize_search: web3_config.estimate_gas_optimize_search, bridge_addresses: api::BridgeAddresses { l1_erc20_default_bridge: contracts_config.l1_erc20_bridge_proxy_addr, l2_erc20_default_bridge: contracts_config.l2_erc20_bridge_addr,