Skip to content

Commit 3b5a9df

Browse files
authored
feat(eth_sender): Set fusaka upgrade timestamp (#4571)
## What ❔ Use upgrade timestamp as well as block for switching to fusaka blobs ## Why ❔ Unfortunately ETH foundation doesn't provide the exact block for fusaka, but they have the exact timestamp. So it was decided to use this timestamp and half an hour before and after this as a safety margin https://blog.ethereum.org/2025/11/06/fusaka-mainnet-announcement#fusaka-activation ## Is this a breaking change? - [ ] Yes - [ ] No ## Operational changes <!-- Any config changes? Any new flags? Any changes to any scripts? --> <!-- Please add anything that non-Matter Labs entities running their own ZK Chain may need to know --> ## Checklist <!-- Check your PR fulfills the following items. --> <!-- For draft PRs check the boxes as you complete them. --> - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] Tests for the changes have been added / updated. - [ ] Documentation comments have been added / updated. - [ ] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. Signed-off-by: Danil <[email protected]>
1 parent 465b8ff commit 3b5a9df

File tree

3 files changed

+64
-11
lines changed

3 files changed

+64
-11
lines changed

core/lib/config/src/configs/eth_sender.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ impl EthConfig {
5656
force_use_validator_timelock: false,
5757
fusaka_upgrade_block: Some(0),
5858
fusaka_upgrade_safety_margin: 0,
59+
fusaka_upgrade_timestamp: Some(1),
5960
},
6061
gas_adjuster: GasAdjusterConfig {
6162
default_priority_fee_per_gas: 1000000000,
@@ -181,8 +182,13 @@ pub struct SenderConfig {
181182
pub force_use_validator_timelock: bool,
182183
/// Use fusaka blob tx format if the block has passed.
183184
pub fusaka_upgrade_block: Option<u64>,
184-
#[config(default_t = 100)]
185+
/// Half an hour safety margin
186+
#[config(default_t = 1800)]
185187
pub fusaka_upgrade_safety_margin: u64,
188+
/// Use fusaka blob tx format if the timestamp has passed. Default is mainnet upgrade.
189+
/// Use this value if block is not set
190+
#[config(default_t = Some(1764798551))]
191+
pub fusaka_upgrade_timestamp: Option<u64>,
186192
}
187193

188194
/// We send precommit if l2_blocks_to_aggregate OR deadline_sec passed since last precommit or beginning of batch.
@@ -309,6 +315,7 @@ mod tests {
309315
force_use_validator_timelock: false,
310316
fusaka_upgrade_safety_margin: 100,
311317
fusaka_upgrade_block: Some(33582142),
318+
fusaka_upgrade_timestamp: Some(1),
312319
},
313320
gas_adjuster: GasAdjusterConfig {
314321
default_priority_fee_per_gas: 20000000000,
@@ -376,6 +383,7 @@ mod tests {
376383
ETH_SENDER_SENDER_USE_FUSAKA_BLOB_FORMAT="true"
377384
ETH_SENDER_SENDER_USE_FUSAKA_BLOB_FORMAT="true"
378385
ETH_SENDER_SENDER_FUSAKA_UPGRADE_BLOCK="33582142"
386+
ETH_SENDER_SENDER_FUSAKA_UPGRADE_TIMESTAMP="1"
379387
ETH_SENDER_SENDER_FUSAKA_UPGRADE_SAFETY_MARGIN="100"
380388
381389
"#;
@@ -416,6 +424,7 @@ mod tests {
416424
force_use_validator_timelock: false
417425
fusaka_upgrade_safety_margin: 100
418426
fusaka_upgrade_block: 33582142
427+
fusaka_upgrade_timestamp: 1
419428
precommit_params:
420429
l2_blocks_to_aggregate: 1
421430
deadline: 1 sec
@@ -475,6 +484,7 @@ mod tests {
475484
force_use_validator_timelock: false
476485
fusaka_upgrade_safety_margin: 100
477486
fusaka_upgrade_block: 33582142
487+
fusaka_upgrade_timestamp: 1
478488
precommit_params:
479489
l2_blocks_to_aggregate: 1
480490
deadline: 1 sec

core/lib/eth_client/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,4 +334,8 @@ impl dyn BoundEthInterface {
334334
pub async fn block_number(&self) -> EnrichedClientResult<U64> {
335335
self.as_ref().block_number().await
336336
}
337+
338+
pub async fn block(&self, block_id: BlockId) -> EnrichedClientResult<Option<Block<H256>>> {
339+
self.as_ref().block(block_id).await
340+
}
337341
}

core/node/eth_sender/src/eth_tx_aggregator.rs

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use zksync_types::{
3333
pubdata_da::PubdataSendingMode,
3434
server_notification::GatewayMigrationState,
3535
settlement::SettlementLayer,
36-
web3::{contract::Error as Web3ContractError, CallRequest},
36+
web3::{contract::Error as Web3ContractError, BlockId, BlockNumber, CallRequest},
3737
Address, L1BatchNumber, L2ChainId, ProtocolVersionId, SLChainId, H256, U256,
3838
};
3939

@@ -204,17 +204,56 @@ impl EthTxAggregator {
204204
if self.config.fusaka_upgrade_block == Some(0) {
205205
return Ok(EthereumUpgradeState::Finished);
206206
}
207-
let Some(fusaka_upgrade_block) = self.config.fusaka_upgrade_block else {
207+
208+
if self.config.fusaka_upgrade_timestamp.is_none()
209+
&& self.config.fusaka_upgrade_block.is_none()
210+
{
208211
return Ok(EthereumUpgradeState::NotStarted);
209-
};
212+
}
210213

211-
let current_block = self.eth_client.block_number().await?.as_u64();
212-
if current_block - self.config.fusaka_upgrade_safety_margin < fusaka_upgrade_block {
213-
Ok(EthereumUpgradeState::NotStarted)
214-
} else if current_block < fusaka_upgrade_block {
215-
Ok(EthereumUpgradeState::Pending)
216-
} else {
217-
Ok(EthereumUpgradeState::Finished)
214+
let current_block = self
215+
.eth_client
216+
.block(BlockId::Number(BlockNumber::Latest))
217+
.await?
218+
.expect("Latest block not found");
219+
220+
// Prioritize using the block number for the upgrade if both are set
221+
// Timestamp is set with default, so block number takes precedence
222+
match (
223+
self.config.fusaka_upgrade_block,
224+
self.config.fusaka_upgrade_timestamp,
225+
) {
226+
(Some(fusaka_upgrade_block), _) => {
227+
if current_block.number.unwrap().as_u64() - self.config.fusaka_upgrade_safety_margin
228+
< fusaka_upgrade_block
229+
{
230+
Ok(EthereumUpgradeState::NotStarted)
231+
} else if current_block.number.unwrap().as_u64()
232+
+ self.config.fusaka_upgrade_safety_margin
233+
>= fusaka_upgrade_block
234+
{
235+
Ok(EthereumUpgradeState::Finished)
236+
} else {
237+
Ok(EthereumUpgradeState::Pending)
238+
}
239+
}
240+
(_, Some(fusaka_upgrade_timestamp)) => {
241+
let current_timestamp = current_block.timestamp.as_u64();
242+
if current_timestamp
243+
< fusaka_upgrade_timestamp - self.config.fusaka_upgrade_safety_margin
244+
{
245+
Ok(EthereumUpgradeState::NotStarted)
246+
} else if current_timestamp + self.config.fusaka_upgrade_safety_margin
247+
>= fusaka_upgrade_timestamp
248+
{
249+
Ok(EthereumUpgradeState::Finished)
250+
} else {
251+
Ok(EthereumUpgradeState::Pending)
252+
}
253+
}
254+
// All the values has already been checked this case is rather unreachable.
255+
// But for safety reasons, it's better to not panic if it's not necessary
256+
(_, _) => Ok(EthereumUpgradeState::NotStarted),
218257
}
219258
}
220259

0 commit comments

Comments
 (0)