From 91dfe9299973792c66ddc2e4a26c7a676f7348a9 Mon Sep 17 00:00:00 2001 From: tomg10 Date: Fri, 4 Oct 2024 12:43:08 +0200 Subject: [PATCH 01/15] add time_in_mempool_cap config --- core/lib/config/src/configs/eth_sender.rs | 22 +++++++++++++++++++ core/lib/config/src/testonly.rs | 1 + core/lib/protobuf_config/src/eth.rs | 8 +++++-- .../src/proto/config/eth_sender.proto | 1 + core/node/eth_sender/src/eth_fees_oracle.rs | 3 ++- core/node/eth_sender/src/eth_tx_manager.rs | 1 + 6 files changed, 33 insertions(+), 3 deletions(-) diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index 7e6ef2244cbf..31d925e75272 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -42,6 +42,7 @@ impl EthConfig { pubdata_sending_mode: PubdataSendingMode::Calldata, tx_aggregation_paused: false, tx_aggregation_only_prove_and_execute: false, + time_in_mempool_cap: 1800, }), gas_adjuster: Some(GasAdjusterConfig { default_priority_fee_per_gas: 1000000000, @@ -127,6 +128,10 @@ pub struct SenderConfig { /// special mode specifically for gateway migration to decrease number of non-executed batches #[serde(default = "SenderConfig::default_tx_aggregation_only_prove_and_execute")] pub tx_aggregation_only_prove_and_execute: bool, + + /// Cap of time in mempool for price calculations + #[serde(default = "SenderConfig::default_time_in_mempool_cap")] + pub time_in_mempool_cap: u32, } impl SenderConfig { @@ -168,6 +173,13 @@ impl SenderConfig { const fn default_tx_aggregation_only_prove_and_execute() -> bool { false } + + pub const fn default_time_in_mempool_cap() -> u32 { + let blocks_per_hour = 3600 / 12; + // cap it at 6h to not allow nearly infinite values when a tx is stuck for a long time + // 1,001 ^ 1800 ~= 6, so by default we cap exponential price formula at roughly median * 6 + blocks_per_hour * 6 + } } #[derive(Debug, Deserialize, Copy, Clone, PartialEq, Default)] @@ -177,8 +189,10 @@ pub struct GasAdjusterConfig { /// Number of blocks collected by GasAdjuster from which base_fee median is taken pub max_base_fee_samples: usize, /// Parameter of the transaction base_fee_per_gas pricing formula + #[serde(default = "GasAdjusterConfig::default_pricing_formula_parameter_a")] pub pricing_formula_parameter_a: f64, /// Parameter of the transaction base_fee_per_gas pricing formula + #[serde(default = "GasAdjusterConfig::default_pricing_formula_parameter_b")] pub pricing_formula_parameter_b: f64, /// Parameter by which the base fee will be multiplied for internal purposes pub internal_l1_pricing_multiplier: f64, @@ -225,4 +239,12 @@ impl GasAdjusterConfig { pub const fn default_internal_pubdata_pricing_multiplier() -> f64 { 1.0 } + + pub const fn default_pricing_formula_parameter_a() -> f64 { + 1.1 + } + + pub const fn default_pricing_formula_parameter_b() -> f64 { + 1.001 + } } diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs index 6fbbad9d8ff2..b1a6bf72dac9 100644 --- a/core/lib/config/src/testonly.rs +++ b/core/lib/config/src/testonly.rs @@ -419,6 +419,7 @@ impl Distribution for EncodeDist { pubdata_sending_mode: PubdataSendingMode::Calldata, tx_aggregation_paused: false, tx_aggregation_only_prove_and_execute: false, + time_in_mempool_cap: self.sample(rng), } } } diff --git a/core/lib/protobuf_config/src/eth.rs b/core/lib/protobuf_config/src/eth.rs index 273b7f4e3445..077443305c4a 100644 --- a/core/lib/protobuf_config/src/eth.rs +++ b/core/lib/protobuf_config/src/eth.rs @@ -115,6 +115,9 @@ impl ProtoRepr for proto::Sender { .parse(), tx_aggregation_only_prove_and_execute: self.tx_aggregation_paused.unwrap_or(false), tx_aggregation_paused: self.tx_aggregation_only_prove_and_execute.unwrap_or(false), + time_in_mempool_cap: self + .time_in_mempool_cap + .unwrap_or(Self::Type::default_time_in_mempool_cap()), }) } @@ -147,6 +150,7 @@ impl ProtoRepr for proto::Sender { ), tx_aggregation_only_prove_and_execute: Some(this.tx_aggregation_only_prove_and_execute), tx_aggregation_paused: Some(this.tx_aggregation_paused), + time_in_mempool_cap: Some(this.time_in_mempool_cap), } } } @@ -161,9 +165,9 @@ impl ProtoRepr for proto::GasAdjuster { .and_then(|x| Ok((*x).try_into()?)) .context("max_base_fee_samples")?, pricing_formula_parameter_a: *required(&self.pricing_formula_parameter_a) - .context("pricing_formula_parameter_a")?, + .unwrap_or(&Self::Type::default_pricing_formula_parameter_a()), pricing_formula_parameter_b: *required(&self.pricing_formula_parameter_b) - .context("pricing_formula_parameter_b")?, + .unwrap_or(&Self::Type::default_pricing_formula_parameter_b()), internal_l1_pricing_multiplier: *required(&self.internal_l1_pricing_multiplier) .context("internal_l1_pricing_multiplier")?, internal_enforced_l1_gas_price: self.internal_enforced_l1_gas_price, diff --git a/core/lib/protobuf_config/src/proto/config/eth_sender.proto b/core/lib/protobuf_config/src/proto/config/eth_sender.proto index b102a08be04c..f15897241a16 100644 --- a/core/lib/protobuf_config/src/proto/config/eth_sender.proto +++ b/core/lib/protobuf_config/src/proto/config/eth_sender.proto @@ -48,6 +48,7 @@ message Sender { reserved 19; reserved "proof_loading_mode"; optional bool tx_aggregation_paused = 20; // required optional bool tx_aggregation_only_prove_and_execute = 21; // required + optional uint32 time_in_mempool_cap = 22; // optional } message GasAdjuster { diff --git a/core/node/eth_sender/src/eth_fees_oracle.rs b/core/node/eth_sender/src/eth_fees_oracle.rs index 2c87848dcc3e..d2dd293387a1 100644 --- a/core/node/eth_sender/src/eth_fees_oracle.rs +++ b/core/node/eth_sender/src/eth_fees_oracle.rs @@ -32,6 +32,7 @@ pub(crate) trait EthFeesOracle: 'static + Sync + Send + fmt::Debug { pub(crate) struct GasAdjusterFeesOracle { pub gas_adjuster: Arc, pub max_acceptable_priority_fee_in_gwei: u64, + pub time_in_mempool_cap: u32, } impl GasAdjusterFeesOracle { @@ -83,7 +84,7 @@ impl GasAdjusterFeesOracle { time_in_mempool: u32, ) -> Result { // cap it at 6h to not allow nearly infinite values when a tx is stuck for a long time - let capped_time_in_mempool = min(time_in_mempool, 1800); + let capped_time_in_mempool = min(time_in_mempool, self.time_in_mempool_cap); let mut base_fee_per_gas = self.gas_adjuster.get_base_fee(capped_time_in_mempool); self.assert_fee_is_not_zero(base_fee_per_gas, "base"); if let Some(previous_sent_tx) = previous_sent_tx { diff --git a/core/node/eth_sender/src/eth_tx_manager.rs b/core/node/eth_sender/src/eth_tx_manager.rs index 0d78ab71c62d..c5ba95d9f655 100644 --- a/core/node/eth_sender/src/eth_tx_manager.rs +++ b/core/node/eth_sender/src/eth_tx_manager.rs @@ -48,6 +48,7 @@ impl EthTxManager { let fees_oracle = GasAdjusterFeesOracle { gas_adjuster, max_acceptable_priority_fee_in_gwei: config.max_acceptable_priority_fee_in_gwei, + time_in_mempool_cap: config.time_in_mempool_cap, }; let l1_interface = Box::new(RealL1Interface { ethereum_gateway, From 2a5a7270f8051007a62ff7fa54e00c5f30fbfaaf Mon Sep 17 00:00:00 2001 From: tomg10 Date: Fri, 4 Oct 2024 14:11:53 +0200 Subject: [PATCH 02/15] fix --- core/lib/env_config/src/eth_sender.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/lib/env_config/src/eth_sender.rs b/core/lib/env_config/src/eth_sender.rs index 64e0a89d5a42..2f3f70895a8a 100644 --- a/core/lib/env_config/src/eth_sender.rs +++ b/core/lib/env_config/src/eth_sender.rs @@ -72,6 +72,7 @@ mod tests { pubdata_sending_mode: PubdataSendingMode::Calldata, tx_aggregation_only_prove_and_execute: false, tx_aggregation_paused: false, + time_in_mempool_cap: 2000, }), gas_adjuster: Some(GasAdjusterConfig { default_priority_fee_per_gas: 20000000000, @@ -131,6 +132,7 @@ mod tests { ETH_SENDER_SENDER_TIMESTAMP_CRITERIA_MAX_ALLOWED_LAG="30" ETH_SENDER_SENDER_MAX_AGGREGATED_TX_GAS="4000000" ETH_SENDER_SENDER_MAX_ETH_TX_DATA_SIZE="120000" + ETH_SENDER_SENDER_TIME_IN_MEMPOOL_CAP="2000" ETH_SENDER_SENDER_L1_BATCH_MIN_AGE_BEFORE_EXECUTE_SECONDS="1000" ETH_SENDER_SENDER_MAX_ACCEPTABLE_PRIORITY_FEE_IN_GWEI="100000000000" ETH_SENDER_SENDER_PUBDATA_SENDING_MODE="Calldata" From d967d5862dbd87b8fe150b2eaa7b5ab0f7982938 Mon Sep 17 00:00:00 2001 From: tomg10 Date: Fri, 4 Oct 2024 14:12:16 +0200 Subject: [PATCH 03/15] fix --- .githooks/pre-push | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.githooks/pre-push b/.githooks/pre-push index 73168e08ec42..e702f1708933 100755 --- a/.githooks/pre-push +++ b/.githooks/pre-push @@ -6,6 +6,8 @@ RED='\033[0;31m' NC='\033[0m' # No Color +source ~/.bashrc + # Check that prettier formatting rules are not violated. if which zk_supervisor >/dev/null; then if ! zk_supervisor fmt --check; then From e5c4e7915b15bf7715482e42d1187ae8320e08b0 Mon Sep 17 00:00:00 2001 From: tomg10 Date: Fri, 4 Oct 2024 14:12:32 +0200 Subject: [PATCH 04/15] fix --- .githooks/pre-push | 2 -- 1 file changed, 2 deletions(-) diff --git a/.githooks/pre-push b/.githooks/pre-push index e702f1708933..73168e08ec42 100755 --- a/.githooks/pre-push +++ b/.githooks/pre-push @@ -6,8 +6,6 @@ RED='\033[0;31m' NC='\033[0m' # No Color -source ~/.bashrc - # Check that prettier formatting rules are not violated. if which zk_supervisor >/dev/null; then if ! zk_supervisor fmt --check; then From 3339111e614bca560bb6e437a4006bfd556ef2d1 Mon Sep 17 00:00:00 2001 From: tomg10 Date: Fri, 4 Oct 2024 14:14:49 +0200 Subject: [PATCH 05/15] fix --- core/lib/config/src/configs/eth_sender.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index 31d925e75272..a61e09e0e08c 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -175,6 +175,7 @@ impl SenderConfig { } pub const fn default_time_in_mempool_cap() -> u32 { + // ethereum produces blocks every 12s let blocks_per_hour = 3600 / 12; // cap it at 6h to not allow nearly infinite values when a tx is stuck for a long time // 1,001 ^ 1800 ~= 6, so by default we cap exponential price formula at roughly median * 6 From f87b6e5b78a060916032a7d2468d9464ec42a8a0 Mon Sep 17 00:00:00 2001 From: tomg10 Date: Fri, 4 Oct 2024 14:16:33 +0200 Subject: [PATCH 06/15] fix --- core/lib/config/src/configs/eth_sender.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index a61e09e0e08c..31d925e75272 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -175,7 +175,6 @@ impl SenderConfig { } pub const fn default_time_in_mempool_cap() -> u32 { - // ethereum produces blocks every 12s let blocks_per_hour = 3600 / 12; // cap it at 6h to not allow nearly infinite values when a tx is stuck for a long time // 1,001 ^ 1800 ~= 6, so by default we cap exponential price formula at roughly median * 6 From 9525e9781e923eddca006389f83adc6d5101e98a Mon Sep 17 00:00:00 2001 From: tomg10 Date: Fri, 4 Oct 2024 14:17:25 +0200 Subject: [PATCH 07/15] fix --- core/lib/config/src/configs/eth_sender.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index 31d925e75272..3016f8aeb7bf 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -175,6 +175,7 @@ impl SenderConfig { } pub const fn default_time_in_mempool_cap() -> u32 { + // ethereum produces blocks every 12 seconds let blocks_per_hour = 3600 / 12; // cap it at 6h to not allow nearly infinite values when a tx is stuck for a long time // 1,001 ^ 1800 ~= 6, so by default we cap exponential price formula at roughly median * 6 From 9869330d5d13bb16d5688606441b3cf0bac2dfaa Mon Sep 17 00:00:00 2001 From: tomg10 Date: Fri, 4 Oct 2024 14:18:14 +0200 Subject: [PATCH 08/15] fix --- core/lib/config/src/configs/eth_sender.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index 3016f8aeb7bf..31d925e75272 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -175,7 +175,6 @@ impl SenderConfig { } pub const fn default_time_in_mempool_cap() -> u32 { - // ethereum produces blocks every 12 seconds let blocks_per_hour = 3600 / 12; // cap it at 6h to not allow nearly infinite values when a tx is stuck for a long time // 1,001 ^ 1800 ~= 6, so by default we cap exponential price formula at roughly median * 6 From 2926f0677a5e24f777cf3090b5db2f6b9b7921e7 Mon Sep 17 00:00:00 2001 From: tomg10 Date: Fri, 4 Oct 2024 14:20:57 +0200 Subject: [PATCH 09/15] fix --- core/lib/config/src/configs/eth_sender.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index 31d925e75272..3016f8aeb7bf 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -175,6 +175,7 @@ impl SenderConfig { } pub const fn default_time_in_mempool_cap() -> u32 { + // ethereum produces blocks every 12 seconds let blocks_per_hour = 3600 / 12; // cap it at 6h to not allow nearly infinite values when a tx is stuck for a long time // 1,001 ^ 1800 ~= 6, so by default we cap exponential price formula at roughly median * 6 From 8128c4cdbb11b2c2d7cf30e82b03d3708c95d3a3 Mon Sep 17 00:00:00 2001 From: tomg10 Date: Fri, 4 Oct 2024 14:22:04 +0200 Subject: [PATCH 10/15] fix --- core/lib/config/src/configs/eth_sender.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index 3016f8aeb7bf..31d925e75272 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -175,7 +175,6 @@ impl SenderConfig { } pub const fn default_time_in_mempool_cap() -> u32 { - // ethereum produces blocks every 12 seconds let blocks_per_hour = 3600 / 12; // cap it at 6h to not allow nearly infinite values when a tx is stuck for a long time // 1,001 ^ 1800 ~= 6, so by default we cap exponential price formula at roughly median * 6 From a40bbebb69a17825ec792acce9a65f29a203a3b0 Mon Sep 17 00:00:00 2001 From: tomg10 Date: Fri, 4 Oct 2024 14:25:48 +0200 Subject: [PATCH 11/15] fix --- core/lib/config/src/configs/eth_sender.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index 31d925e75272..3016f8aeb7bf 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -175,6 +175,7 @@ impl SenderConfig { } pub const fn default_time_in_mempool_cap() -> u32 { + // ethereum produces blocks every 12 seconds let blocks_per_hour = 3600 / 12; // cap it at 6h to not allow nearly infinite values when a tx is stuck for a long time // 1,001 ^ 1800 ~= 6, so by default we cap exponential price formula at roughly median * 6 From 5c6fcfc704e381e2f46db2407d1049a445a79829 Mon Sep 17 00:00:00 2001 From: tomg10 Date: Fri, 4 Oct 2024 14:29:01 +0200 Subject: [PATCH 12/15] fix --- core/lib/config/src/configs/eth_sender.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index 3016f8aeb7bf..31d925e75272 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -175,7 +175,6 @@ impl SenderConfig { } pub const fn default_time_in_mempool_cap() -> u32 { - // ethereum produces blocks every 12 seconds let blocks_per_hour = 3600 / 12; // cap it at 6h to not allow nearly infinite values when a tx is stuck for a long time // 1,001 ^ 1800 ~= 6, so by default we cap exponential price formula at roughly median * 6 From cd0cd7cb14e355956260586df5f7d24d80d7ec56 Mon Sep 17 00:00:00 2001 From: tomg10 Date: Fri, 4 Oct 2024 14:31:04 +0200 Subject: [PATCH 13/15] fix --- core/lib/config/src/configs/eth_sender.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index 31d925e75272..3016f8aeb7bf 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -175,6 +175,7 @@ impl SenderConfig { } pub const fn default_time_in_mempool_cap() -> u32 { + // ethereum produces blocks every 12 seconds let blocks_per_hour = 3600 / 12; // cap it at 6h to not allow nearly infinite values when a tx is stuck for a long time // 1,001 ^ 1800 ~= 6, so by default we cap exponential price formula at roughly median * 6 From 08d3c8eba018714c3db7fec291df515b8b883401 Mon Sep 17 00:00:00 2001 From: tomg10 Date: Fri, 4 Oct 2024 14:40:09 +0200 Subject: [PATCH 14/15] fix --- core/lib/config/src/configs/eth_sender.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index 3016f8aeb7bf..31d925e75272 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -175,7 +175,6 @@ impl SenderConfig { } pub const fn default_time_in_mempool_cap() -> u32 { - // ethereum produces blocks every 12 seconds let blocks_per_hour = 3600 / 12; // cap it at 6h to not allow nearly infinite values when a tx is stuck for a long time // 1,001 ^ 1800 ~= 6, so by default we cap exponential price formula at roughly median * 6 From fd506c29e84dcb72705e0a775caca5b82cccc1e5 Mon Sep 17 00:00:00 2001 From: tomg10 Date: Mon, 7 Oct 2024 13:48:56 +0200 Subject: [PATCH 15/15] PR feedback --- core/lib/config/src/configs/eth_sender.rs | 10 ++++----- core/lib/config/src/testonly.rs | 2 +- core/lib/env_config/src/eth_sender.rs | 4 ++-- core/lib/protobuf_config/src/eth.rs | 8 +++---- .../src/proto/config/eth_sender.proto | 2 +- core/node/eth_sender/src/eth_fees_oracle.rs | 21 ++++++++++++------- core/node/eth_sender/src/eth_tx_manager.rs | 15 ++++++++----- .../src/l1_gas_price/gas_adjuster/mod.rs | 6 +++--- core/node/fee_model/src/l1_gas_price/mod.rs | 2 +- etc/env/base/eth_sender.toml | 4 ++-- 10 files changed, 42 insertions(+), 32 deletions(-) diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index 31d925e75272..3a1a0505728c 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -42,7 +42,7 @@ impl EthConfig { pubdata_sending_mode: PubdataSendingMode::Calldata, tx_aggregation_paused: false, tx_aggregation_only_prove_and_execute: false, - time_in_mempool_cap: 1800, + time_in_mempool_in_l1_blocks_cap: 1800, }), gas_adjuster: Some(GasAdjusterConfig { default_priority_fee_per_gas: 1000000000, @@ -130,8 +130,8 @@ pub struct SenderConfig { pub tx_aggregation_only_prove_and_execute: bool, /// Cap of time in mempool for price calculations - #[serde(default = "SenderConfig::default_time_in_mempool_cap")] - pub time_in_mempool_cap: u32, + #[serde(default = "SenderConfig::default_time_in_mempool_in_l1_blocks_cap")] + pub time_in_mempool_in_l1_blocks_cap: u32, } impl SenderConfig { @@ -174,9 +174,9 @@ impl SenderConfig { false } - pub const fn default_time_in_mempool_cap() -> u32 { + pub const fn default_time_in_mempool_in_l1_blocks_cap() -> u32 { let blocks_per_hour = 3600 / 12; - // cap it at 6h to not allow nearly infinite values when a tx is stuck for a long time + // we cap it at 6h to not allow nearly infinite values when a tx is stuck for a long time // 1,001 ^ 1800 ~= 6, so by default we cap exponential price formula at roughly median * 6 blocks_per_hour * 6 } diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs index b1a6bf72dac9..4170f9e2d05f 100644 --- a/core/lib/config/src/testonly.rs +++ b/core/lib/config/src/testonly.rs @@ -419,7 +419,7 @@ impl Distribution for EncodeDist { pubdata_sending_mode: PubdataSendingMode::Calldata, tx_aggregation_paused: false, tx_aggregation_only_prove_and_execute: false, - time_in_mempool_cap: self.sample(rng), + time_in_mempool_in_l1_blocks_cap: self.sample(rng), } } } diff --git a/core/lib/env_config/src/eth_sender.rs b/core/lib/env_config/src/eth_sender.rs index 2f3f70895a8a..e5132eb7d91f 100644 --- a/core/lib/env_config/src/eth_sender.rs +++ b/core/lib/env_config/src/eth_sender.rs @@ -72,7 +72,7 @@ mod tests { pubdata_sending_mode: PubdataSendingMode::Calldata, tx_aggregation_only_prove_and_execute: false, tx_aggregation_paused: false, - time_in_mempool_cap: 2000, + time_in_mempool_in_l1_blocks_cap: 2000, }), gas_adjuster: Some(GasAdjusterConfig { default_priority_fee_per_gas: 20000000000, @@ -132,7 +132,7 @@ mod tests { ETH_SENDER_SENDER_TIMESTAMP_CRITERIA_MAX_ALLOWED_LAG="30" ETH_SENDER_SENDER_MAX_AGGREGATED_TX_GAS="4000000" ETH_SENDER_SENDER_MAX_ETH_TX_DATA_SIZE="120000" - ETH_SENDER_SENDER_TIME_IN_MEMPOOL_CAP="2000" + ETH_SENDER_SENDER_TIME_IN_MEMPOOL_IN_L1_BLOCKS_CAP="2000" ETH_SENDER_SENDER_L1_BATCH_MIN_AGE_BEFORE_EXECUTE_SECONDS="1000" ETH_SENDER_SENDER_MAX_ACCEPTABLE_PRIORITY_FEE_IN_GWEI="100000000000" ETH_SENDER_SENDER_PUBDATA_SENDING_MODE="Calldata" diff --git a/core/lib/protobuf_config/src/eth.rs b/core/lib/protobuf_config/src/eth.rs index 077443305c4a..c1d95bd30d2b 100644 --- a/core/lib/protobuf_config/src/eth.rs +++ b/core/lib/protobuf_config/src/eth.rs @@ -115,9 +115,9 @@ impl ProtoRepr for proto::Sender { .parse(), tx_aggregation_only_prove_and_execute: self.tx_aggregation_paused.unwrap_or(false), tx_aggregation_paused: self.tx_aggregation_only_prove_and_execute.unwrap_or(false), - time_in_mempool_cap: self - .time_in_mempool_cap - .unwrap_or(Self::Type::default_time_in_mempool_cap()), + time_in_mempool_in_l1_blocks_cap: self + .time_in_mempool_in_l1_blocks_cap + .unwrap_or(Self::Type::default_time_in_mempool_in_l1_blocks_cap()), }) } @@ -150,7 +150,7 @@ impl ProtoRepr for proto::Sender { ), tx_aggregation_only_prove_and_execute: Some(this.tx_aggregation_only_prove_and_execute), tx_aggregation_paused: Some(this.tx_aggregation_paused), - time_in_mempool_cap: Some(this.time_in_mempool_cap), + time_in_mempool_in_l1_blocks_cap: Some(this.time_in_mempool_in_l1_blocks_cap), } } } diff --git a/core/lib/protobuf_config/src/proto/config/eth_sender.proto b/core/lib/protobuf_config/src/proto/config/eth_sender.proto index f15897241a16..6438573e08df 100644 --- a/core/lib/protobuf_config/src/proto/config/eth_sender.proto +++ b/core/lib/protobuf_config/src/proto/config/eth_sender.proto @@ -48,7 +48,7 @@ message Sender { reserved 19; reserved "proof_loading_mode"; optional bool tx_aggregation_paused = 20; // required optional bool tx_aggregation_only_prove_and_execute = 21; // required - optional uint32 time_in_mempool_cap = 22; // optional + optional uint32 time_in_mempool_in_l1_blocks_cap = 22; // optional } message GasAdjuster { diff --git a/core/node/eth_sender/src/eth_fees_oracle.rs b/core/node/eth_sender/src/eth_fees_oracle.rs index d2dd293387a1..ebd1568edb66 100644 --- a/core/node/eth_sender/src/eth_fees_oracle.rs +++ b/core/node/eth_sender/src/eth_fees_oracle.rs @@ -23,7 +23,7 @@ pub(crate) trait EthFeesOracle: 'static + Sync + Send + fmt::Debug { fn calculate_fees( &self, previous_sent_tx: &Option, - time_in_mempool: u32, + time_in_mempool_in_l1_blocks: u32, operator_type: OperatorType, ) -> Result; } @@ -32,7 +32,7 @@ pub(crate) trait EthFeesOracle: 'static + Sync + Send + fmt::Debug { pub(crate) struct GasAdjusterFeesOracle { pub gas_adjuster: Arc, pub max_acceptable_priority_fee_in_gwei: u64, - pub time_in_mempool_cap: u32, + pub time_in_mempool_in_l1_blocks_cap: u32, } impl GasAdjusterFeesOracle { @@ -81,11 +81,16 @@ impl GasAdjusterFeesOracle { fn calculate_fees_no_blob_sidecar( &self, previous_sent_tx: &Option, - time_in_mempool: u32, + time_in_mempool_in_l1_blocks: u32, ) -> Result { - // cap it at 6h to not allow nearly infinite values when a tx is stuck for a long time - let capped_time_in_mempool = min(time_in_mempool, self.time_in_mempool_cap); - let mut base_fee_per_gas = self.gas_adjuster.get_base_fee(capped_time_in_mempool); + // we cap it to not allow nearly infinite values when a tx is stuck for a long time + let capped_time_in_mempool_in_l1_blocks = min( + time_in_mempool_in_l1_blocks, + self.time_in_mempool_in_l1_blocks_cap, + ); + let mut base_fee_per_gas = self + .gas_adjuster + .get_base_fee(capped_time_in_mempool_in_l1_blocks); self.assert_fee_is_not_zero(base_fee_per_gas, "base"); if let Some(previous_sent_tx) = previous_sent_tx { self.verify_base_fee_not_too_low_on_resend( @@ -163,14 +168,14 @@ impl EthFeesOracle for GasAdjusterFeesOracle { fn calculate_fees( &self, previous_sent_tx: &Option, - time_in_mempool: u32, + time_in_mempool_in_l1_blocks: u32, operator_type: OperatorType, ) -> Result { let has_blob_sidecar = operator_type == OperatorType::Blob; if has_blob_sidecar { self.calculate_fees_with_blob_sidecar(previous_sent_tx) } else { - self.calculate_fees_no_blob_sidecar(previous_sent_tx, time_in_mempool) + self.calculate_fees_no_blob_sidecar(previous_sent_tx, time_in_mempool_in_l1_blocks) } } } diff --git a/core/node/eth_sender/src/eth_tx_manager.rs b/core/node/eth_sender/src/eth_tx_manager.rs index c5ba95d9f655..7de91a3b7736 100644 --- a/core/node/eth_sender/src/eth_tx_manager.rs +++ b/core/node/eth_sender/src/eth_tx_manager.rs @@ -48,7 +48,7 @@ impl EthTxManager { let fees_oracle = GasAdjusterFeesOracle { gas_adjuster, max_acceptable_priority_fee_in_gwei: config.max_acceptable_priority_fee_in_gwei, - time_in_mempool_cap: config.time_in_mempool_cap, + time_in_mempool_in_l1_blocks_cap: config.time_in_mempool_in_l1_blocks_cap, }; let l1_interface = Box::new(RealL1Interface { ethereum_gateway, @@ -112,7 +112,7 @@ impl EthTxManager { &mut self, storage: &mut Connection<'_, Core>, tx: &EthTx, - time_in_mempool: u32, + time_in_mempool_in_l1_blocks: u32, current_block: L1BlockNumber, ) -> Result { let previous_sent_tx = storage @@ -128,7 +128,7 @@ impl EthTxManager { pubdata_price: _, } = self.fees_oracle.calculate_fees( &previous_sent_tx, - time_in_mempool, + time_in_mempool_in_l1_blocks, self.operator_type(tx), )?; @@ -602,13 +602,18 @@ impl EthTxManager { .await? { // New gas price depends on the time this tx spent in mempool. - let time_in_mempool = l1_block_numbers.latest.0 - sent_at_block; + let time_in_mempool_in_l1_blocks = l1_block_numbers.latest.0 - sent_at_block; // We don't want to return early in case resend does not succeed - // the error is logged anyway, but early returns will prevent // sending new operations. let _ = self - .send_eth_tx(storage, &tx, time_in_mempool, l1_block_numbers.latest) + .send_eth_tx( + storage, + &tx, + time_in_mempool_in_l1_blocks, + l1_block_numbers.latest, + ) .await?; } Ok(()) diff --git a/core/node/fee_model/src/l1_gas_price/gas_adjuster/mod.rs b/core/node/fee_model/src/l1_gas_price/gas_adjuster/mod.rs index e6842b92fdba..27cdc7f5d5e0 100644 --- a/core/node/fee_model/src/l1_gas_price/gas_adjuster/mod.rs +++ b/core/node/fee_model/src/l1_gas_price/gas_adjuster/mod.rs @@ -317,14 +317,14 @@ impl TxParamsProvider for GasAdjuster { // smooth out base_fee increases in general. // In other words, in order to pay less fees, we are ready to wait longer. // But the longer we wait, the more we are ready to pay. - fn get_base_fee(&self, time_in_mempool: u32) -> u64 { + fn get_base_fee(&self, time_in_mempool_in_l1_blocks: u32) -> u64 { let a = self.config.pricing_formula_parameter_a; let b = self.config.pricing_formula_parameter_b; // Currently we use an exponential formula. // The alternative is a linear one: - // `let scale_factor = a + b * time_in_mempool as f64;` - let scale_factor = a * b.powf(time_in_mempool as f64); + // `let scale_factor = a + b * time_in_mempool_in_l1_blocks as f64;` + let scale_factor = a * b.powf(time_in_mempool_in_l1_blocks as f64); let median = self.base_fee_statistics.median(); METRICS.median_base_fee_per_gas.set(median); let new_fee = median as f64 * scale_factor; diff --git a/core/node/fee_model/src/l1_gas_price/mod.rs b/core/node/fee_model/src/l1_gas_price/mod.rs index 2a5d63089ca1..e23bccf27ee1 100644 --- a/core/node/fee_model/src/l1_gas_price/mod.rs +++ b/core/node/fee_model/src/l1_gas_price/mod.rs @@ -16,7 +16,7 @@ mod main_node_fetcher; /// This trait, as a bound, should only be used in components that actually sign and send transactions. pub trait TxParamsProvider: fmt::Debug + 'static + Send + Sync { /// Returns the recommended `max_fee_per_gas` value (EIP1559). - fn get_base_fee(&self, time_in_mempool: u32) -> u64; + fn get_base_fee(&self, time_in_mempool_in_l1_blocks: u32) -> u64; /// Returns the recommended `max_priority_fee_per_gas` value (EIP1559). fn get_priority_fee(&self) -> u64; diff --git a/etc/env/base/eth_sender.toml b/etc/env/base/eth_sender.toml index 31fe626c87f2..ad5709551c45 100644 --- a/etc/env/base/eth_sender.toml +++ b/etc/env/base/eth_sender.toml @@ -55,8 +55,8 @@ default_priority_fee_per_gas = 1_000_000_000 max_base_fee_samples = 10_000 # These two are parameters of the base_fee_per_gas formula in GasAdjuster. # The possible formulas are: -# 1. base_fee_median * (A + B * time_in_mempool) -# 2. base_fee_median * A * B ^ time_in_mempool +# 1. base_fee_median * (A + B * time_in_mempool_in_l1_blocks) +# 2. base_fee_median * A * B ^ time_in_mempool_in_l1_blocks # Currently the second is used. # To confirm, see core/bin/zksync_core/src/eth_sender/gas_adjuster/mod.rs pricing_formula_parameter_a = 1.5