diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index 89f8d459a1d9..7e6ef2244cbf 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -40,6 +40,8 @@ impl EthConfig { l1_batch_min_age_before_execute_seconds: None, max_acceptable_priority_fee_in_gwei: 100000000000, pubdata_sending_mode: PubdataSendingMode::Calldata, + tx_aggregation_paused: false, + tx_aggregation_only_prove_and_execute: false, }), gas_adjuster: Some(GasAdjusterConfig { default_priority_fee_per_gas: 1000000000, @@ -119,6 +121,12 @@ pub struct SenderConfig { /// The mode in which we send pubdata: Calldata, Blobs or Custom (DA layers, Object Store, etc.) pub pubdata_sending_mode: PubdataSendingMode, + /// special mode specifically for gateway migration to allow all inflight txs to be processed + #[serde(default = "SenderConfig::default_tx_aggregation_paused")] + pub tx_aggregation_paused: bool, + /// 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, } impl SenderConfig { @@ -153,6 +161,13 @@ impl SenderConfig { .ok() .map(|pk| pk.parse().unwrap()) } + + const fn default_tx_aggregation_paused() -> bool { + false + } + const fn default_tx_aggregation_only_prove_and_execute() -> bool { + false + } } #[derive(Debug, Deserialize, Copy, Clone, PartialEq, Default)] diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs index 3f548ac1c80c..162f1d1617d8 100644 --- a/core/lib/config/src/testonly.rs +++ b/core/lib/config/src/testonly.rs @@ -407,6 +407,8 @@ impl Distribution for EncodeDist { l1_batch_min_age_before_execute_seconds: self.sample(rng), max_acceptable_priority_fee_in_gwei: self.sample(rng), pubdata_sending_mode: PubdataSendingMode::Calldata, + tx_aggregation_paused: false, + tx_aggregation_only_prove_and_execute: false, } } } diff --git a/core/lib/env_config/src/eth_sender.rs b/core/lib/env_config/src/eth_sender.rs index 18a661099b61..30a6ebf4f008 100644 --- a/core/lib/env_config/src/eth_sender.rs +++ b/core/lib/env_config/src/eth_sender.rs @@ -70,6 +70,8 @@ mod tests { l1_batch_min_age_before_execute_seconds: Some(1000), max_acceptable_priority_fee_in_gwei: 100_000_000_000, pubdata_sending_mode: PubdataSendingMode::Calldata, + tx_aggregation_only_prove_and_execute: false, + tx_aggregation_paused: false, }), gas_adjuster: Some(GasAdjusterConfig { default_priority_fee_per_gas: 20000000000, diff --git a/core/lib/protobuf_config/src/eth.rs b/core/lib/protobuf_config/src/eth.rs index c605e6d2cccb..273b7f4e3445 100644 --- a/core/lib/protobuf_config/src/eth.rs +++ b/core/lib/protobuf_config/src/eth.rs @@ -113,6 +113,8 @@ impl ProtoRepr for proto::Sender { .and_then(|x| Ok(proto::PubdataSendingMode::try_from(*x)?)) .context("pubdata_sending_mode")? .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), }) } @@ -143,6 +145,8 @@ impl ProtoRepr for proto::Sender { pubdata_sending_mode: Some( proto::PubdataSendingMode::new(&this.pubdata_sending_mode).into(), ), + tx_aggregation_only_prove_and_execute: Some(this.tx_aggregation_only_prove_and_execute), + tx_aggregation_paused: Some(this.tx_aggregation_paused), } } } 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 536ac216863e..b102a08be04c 100644 --- a/core/lib/protobuf_config/src/proto/config/eth_sender.proto +++ b/core/lib/protobuf_config/src/proto/config/eth_sender.proto @@ -46,6 +46,8 @@ message Sender { optional uint64 max_acceptable_priority_fee_in_gwei = 16; // required; gwei optional PubdataSendingMode pubdata_sending_mode = 18; // required reserved 19; reserved "proof_loading_mode"; + optional bool tx_aggregation_paused = 20; // required + optional bool tx_aggregation_only_prove_and_execute = 21; // required } message GasAdjuster { diff --git a/core/node/eth_sender/src/aggregated_operations.rs b/core/node/eth_sender/src/aggregated_operations.rs index 657624e3a7c5..2dfaf5942659 100644 --- a/core/node/eth_sender/src/aggregated_operations.rs +++ b/core/node/eth_sender/src/aggregated_operations.rs @@ -53,4 +53,9 @@ impl AggregatedOperation { Self::Execute(op) => op.l1_batches[0].header.protocol_version.unwrap(), } } + + pub fn is_prove_or_execute(&self) -> bool { + self.get_action_type() == AggregatedActionType::PublishProofOnchain + || self.get_action_type() == AggregatedActionType::Execute + } } diff --git a/core/node/eth_sender/src/eth_tx_aggregator.rs b/core/node/eth_sender/src/eth_tx_aggregator.rs index 312e9d31e9ff..856b79eb5c93 100644 --- a/core/node/eth_sender/src/eth_tx_aggregator.rs +++ b/core/node/eth_sender/src/eth_tx_aggregator.rs @@ -355,6 +355,25 @@ impl EthTxAggregator { ) .await { + if self.config.tx_aggregation_paused { + tracing::info!( + "Skipping sending operation of type {} for batches {}-{} \ + as tx_aggregation_paused=true", + agg_op.get_action_type(), + agg_op.l1_batch_range().start(), + agg_op.l1_batch_range().end() + ); + return Ok(()); + } + if self.config.tx_aggregation_only_prove_and_execute && !agg_op.is_prove_or_execute() { + tracing::info!( + "Skipping sending commit operation for batches {}-{} \ + as tx_aggregation_only_prove_and_execute=true", + agg_op.l1_batch_range().start(), + agg_op.l1_batch_range().end() + ); + return Ok(()); + } let tx = self .save_eth_tx(storage, &agg_op, contracts_are_pre_shared_bridge, false) .await?;