Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 54 additions & 18 deletions core/bin/block_reverter/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ use zksync_block_reverter::{
use zksync_config::{
configs::{
chain::NetworkConfig, wallets::Wallets, BasicWitnessInputProducerConfig, DatabaseSecrets,
GeneralConfig, L1Secrets, ObservabilityConfig, ProtectiveReadsWriterConfig,
GatewayChainConfig, GeneralConfig, L1Secrets, ObservabilityConfig,
ProtectiveReadsWriterConfig,
},
ContractsConfig, DBConfig, EthConfig, GenesisConfig, PostgresConfig,
};
use zksync_core_leftovers::temp_config_store::read_yaml_repr;
use zksync_dal::{ConnectionPool, Core};
use zksync_env_config::{object_store::SnapshotsObjectStoreConfig, FromEnv};
use zksync_object_store::ObjectStoreFactory;
use zksync_protobuf_config::proto;
use zksync_types::{Address, L1BatchNumber};

#[derive(Debug, Parser)]
Expand All @@ -46,6 +48,10 @@ struct Cli {
/// Path to yaml genesis config. If set, it will be used instead of env vars
#[arg(long, global = true)]
genesis_path: Option<PathBuf>,
/// Path to yaml config of the chain on top of gateway.
/// It should be skipped in case a chain is not settling on top of Gateway.
#[arg(long, global = true)]
gateway_chain_path: Option<PathBuf>,
}

#[derive(Debug, Subcommand)]
Expand Down Expand Up @@ -182,23 +188,22 @@ async fn main() -> anyhow::Result<()> {
.context("BasicWitnessInputProducerConfig::from_env()")?,
};
let contracts = match opts.contracts_config_path {
Some(path) => read_yaml_repr::<zksync_protobuf_config::proto::contracts::Contracts>(&path)
Some(path) => read_yaml_repr::<proto::contracts::Contracts>(&path)
.context("failed decoding contracts YAML config")?,
None => ContractsConfig::from_env().context("ContractsConfig::from_env()")?,
};
let secrets_config = if let Some(path) = opts.secrets_path {
Some(
read_yaml_repr::<zksync_protobuf_config::proto::secrets::Secrets>(&path)
read_yaml_repr::<proto::secrets::Secrets>(&path)
.context("failed decoding secrets YAML config")?,
)
} else {
None
};

let default_priority_fee_per_gas = eth_sender
.gas_adjuster
.context("gas_adjuster")?
.default_priority_fee_per_gas;
let gas_adjuster = eth_sender.gas_adjuster.context("gas_adjuster")?;
let default_priority_fee_per_gas = gas_adjuster.default_priority_fee_per_gas;
let settlement_mode = gas_adjuster.settlement_mode;

let database_secrets = match &secrets_config {
Some(secrets_config) => secrets_config
Expand Down Expand Up @@ -230,7 +235,40 @@ async fn main() -> anyhow::Result<()> {
}
};

let config = BlockReverterEthConfig::new(&eth_sender, &contracts, zksync_network_id)?;
let (sl_rpc_url, sl_diamond_proxy, sl_validator_timelock) = if settlement_mode.is_gateway() {
// Gateway config is required to be provided by file for now.
let gateway_chain_config: GatewayChainConfig =
read_yaml_repr::<proto::gateway::GatewayChainConfig>(
&opts
.gateway_chain_path
.context("Genesis config path not provided")?,
)
.context("failed decoding genesis YAML config")?;

let gateway_url = l1_secrets
.gateway_rpc_url
.context("Gateway URL not found")?;

(
gateway_url,
gateway_chain_config.diamond_proxy_addr,
gateway_chain_config.validator_timelock_addr,
)
} else {
(
l1_secrets.l1_rpc_url,
contracts.diamond_proxy_addr,
contracts.validator_timelock_addr,
)
};

let config = BlockReverterEthConfig::new(
&eth_sender,
sl_diamond_proxy,
sl_validator_timelock,
zksync_network_id,
settlement_mode,
)?;

let connection_pool = ConnectionPool::<Core>::builder(
database_secrets.master_url()?,
Expand All @@ -246,12 +284,12 @@ async fn main() -> anyhow::Result<()> {
json,
operator_address,
} => {
let eth_client = Client::<L1>::http(l1_secrets.l1_rpc_url.clone())
let sl_client = Client::<L1>::http(sl_rpc_url)
.context("Ethereum client")?
.build();

let suggested_values = block_reverter
.suggested_values(&eth_client, &config, operator_address)
.suggested_values(&sl_client, &config, operator_address)
.await?;
if json {
println!("{}", serde_json::to_string(&suggested_values)?);
Expand All @@ -264,9 +302,7 @@ async fn main() -> anyhow::Result<()> {
priority_fee_per_gas,
nonce,
} => {
let eth_client = Client::http(l1_secrets.l1_rpc_url.clone())
.context("Ethereum client")?
.build();
let sl_client = Client::http(sl_rpc_url).context("Ethereum client")?.build();
let reverter_private_key = if let Some(wallets_config) = wallets_config {
wallets_config
.eth_sender
Expand All @@ -285,21 +321,21 @@ async fn main() -> anyhow::Result<()> {
};

let priority_fee_per_gas = priority_fee_per_gas.unwrap_or(default_priority_fee_per_gas);
let l1_chain_id = eth_client
let l1_chain_id = sl_client
.fetch_chain_id()
.await
.context("cannot fetch Ethereum chain ID")?;
let eth_client = PKSigningClient::new_raw(
let sl_client = PKSigningClient::new_raw(
reverter_private_key,
contracts.diamond_proxy_addr,
sl_diamond_proxy,
priority_fee_per_gas,
l1_chain_id,
Box::new(eth_client),
Box::new(sl_client),
);

block_reverter
.send_ethereum_revert_transaction(
&eth_client,
&sl_client,
&config,
L1BatchNumber(l1_batch_number),
nonce,
Expand Down
28 changes: 15 additions & 13 deletions core/bin/external_node/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ impl ConfigurationSource for Environment {
/// This part of the external node config is fetched directly from the main node.
#[derive(Debug, Deserialize)]
pub(crate) struct RemoteENConfig {
pub l1_bytecodes_supplier_addr: Option<Address>,
#[serde(alias = "bridgehub_proxy_addr")]
pub l1_bridgehub_proxy_addr: Option<Address>,
#[serde(alias = "state_transition_proxy_addr")]
Expand Down Expand Up @@ -191,6 +192,9 @@ impl RemoteENConfig {
l1_transparent_proxy_admin_addr: ecosystem_contracts
.as_ref()
.map(|a| a.transparent_proxy_admin_addr),
l1_bytecodes_supplier_addr: ecosystem_contracts
.as_ref()
.and_then(|a| a.l1_bytecodes_supplier_addr),
l1_diamond_proxy_addr,
l2_testnet_paymaster_addr,
l1_erc20_bridge_proxy_addr: bridges.l1_erc20_default_bridge,
Expand All @@ -216,6 +220,7 @@ impl RemoteENConfig {
#[cfg(test)]
fn mock() -> Self {
Self {
l1_bytecodes_supplier_addr: None,
l1_bridgehub_proxy_addr: None,
l1_state_transition_proxy_addr: None,
l1_transparent_proxy_admin_addr: None,
Expand Down Expand Up @@ -983,11 +988,11 @@ impl OptionalENConfig {
/// This part of the external node config is required for its operation.
#[derive(Debug, Deserialize)]
pub(crate) struct RequiredENConfig {
/// The chain ID of the L1 network (e.g., 1 for Ethereum mainnet). In the future, it may be different from the settlement layer.
/// The chain ID of the L1 network (e.g., 1 for Ethereum mainnet).
pub l1_chain_id: L1ChainId,
/// The chain ID of the settlement layer (e.g., 1 for Ethereum mainnet). This ID will be checked against the `eth_client_url` RPC provider on initialization
/// to ensure that there's no mismatch between the expected and actual settlement layer network.
pub sl_chain_id: Option<SLChainId>,
/// The chain ID of the gateway. This ID will be checked against the `gateway_rpc_url` RPC provider on initialization
/// to ensure that there's no mismatch between the expected and actual gateway network.
pub gateway_chain_id: Option<SLChainId>,
/// L2 chain ID (e.g., 270 for ZKsync Era mainnet). This ID will be checked against the `main_node_url` RPC provider on initialization
/// to ensure that there's no mismatch between the expected and actual L2 network.
pub l2_chain_id: L2ChainId,
Expand All @@ -1009,10 +1014,6 @@ pub(crate) struct RequiredENConfig {
}

impl RequiredENConfig {
pub fn settlement_layer_id(&self) -> SLChainId {
self.sl_chain_id.unwrap_or(self.l1_chain_id.into())
}

fn from_env() -> anyhow::Result<Self> {
envy::prefixed("EN_")
.from_env()
Expand All @@ -1034,7 +1035,7 @@ impl RequiredENConfig {
.context("Database config is required")?;
Ok(RequiredENConfig {
l1_chain_id: en_config.l1_chain_id,
sl_chain_id: None,
gateway_chain_id: en_config.gateway_chain_id,
l2_chain_id: en_config.l2_chain_id,
http_port: api_config.web3_json_rpc.http_port,
ws_port: api_config.web3_json_rpc.ws_port,
Expand All @@ -1055,7 +1056,7 @@ impl RequiredENConfig {
fn mock(temp_dir: &tempfile::TempDir) -> Self {
Self {
l1_chain_id: L1ChainId(9),
sl_chain_id: None,
gateway_chain_id: None,
l2_chain_id: L2ChainId::default(),
http_port: 0,
ws_port: 0,
Expand Down Expand Up @@ -1401,12 +1402,12 @@ impl ExternalNodeConfig<()> {
if let Some(local_diamond_proxy_addr) = self.optional.contracts_diamond_proxy_addr {
anyhow::ensure!(
local_diamond_proxy_addr == remote_diamond_proxy_addr,
"Diamond proxy address {local_diamond_proxy_addr:?} specified in config doesn't match one returned \
"L1 diamond proxy address {local_diamond_proxy_addr:?} specified in config doesn't match one returned \
by main node ({remote_diamond_proxy_addr:?})"
);
} else {
tracing::info!(
"Diamond proxy address is not specified in config; will use address \
"L1 diamond proxy address is not specified in config; will use address \
returned by main node: {remote_diamond_proxy_addr:?}"
);
}
Expand Down Expand Up @@ -1475,10 +1476,11 @@ impl From<&ExternalNodeConfig> for InternalApiConfig {
l1_weth_bridge: config.remote.l1_weth_bridge_addr,
l2_weth_bridge: config.remote.l2_weth_bridge_addr,
},
l1_bytecodes_supplier_addr: config.remote.l1_bytecodes_supplier_addr,
l1_bridgehub_proxy_addr: config.remote.l1_bridgehub_proxy_addr,
l1_state_transition_proxy_addr: config.remote.l1_state_transition_proxy_addr,
l1_transparent_proxy_admin_addr: config.remote.l1_transparent_proxy_admin_addr,
l1_diamond_proxy_addr: config.remote.l1_diamond_proxy_addr,
l1_diamond_proxy_addr: config.l1_diamond_proxy_address(),
l2_testnet_paymaster_addr: config.remote.l2_testnet_paymaster_addr,
req_entities_limit: config.optional.req_entities_limit,
fee_history_limit: config.optional.fee_history_limit,
Expand Down
12 changes: 9 additions & 3 deletions core/bin/external_node/src/node_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,11 @@ impl ExternalNodeBuilder {
fn add_external_node_metrics_layer(mut self) -> anyhow::Result<Self> {
self.node.add_layer(ExternalNodeMetricsLayer {
l1_chain_id: self.config.required.l1_chain_id,
sl_chain_id: self.config.required.settlement_layer_id(),
sl_chain_id: self
.config
.required
.gateway_chain_id
.unwrap_or(self.config.required.l1_chain_id.into()),
l2_chain_id: self.config.required.l2_chain_id,
postgres_pool_size: self.config.postgres.max_connections,
});
Expand Down Expand Up @@ -179,8 +183,9 @@ impl ExternalNodeBuilder {

fn add_query_eth_client_layer(mut self) -> anyhow::Result<Self> {
let query_eth_client_layer = QueryEthClientLayer::new(
self.config.required.settlement_layer_id(),
self.config.required.l1_chain_id,
self.config.required.eth_client_url.clone(),
self.config.required.gateway_chain_id,
self.config.optional.gateway_url.clone(),
);
self.node.add_layer(query_eth_client_layer);
Expand Down Expand Up @@ -285,8 +290,9 @@ impl ExternalNodeBuilder {

fn add_validate_chain_ids_layer(mut self) -> anyhow::Result<Self> {
let layer = ValidateChainIdsLayer::new(
self.config.required.settlement_layer_id(),
self.config.required.l1_chain_id,
self.config.required.l2_chain_id,
self.config.required.gateway_chain_id,
);
self.node.add_layer(layer);
Ok(self)
Expand Down
8 changes: 4 additions & 4 deletions core/bin/external_node/src/tests/framework.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use zksync_node_framework::{
task::TaskKind,
FromContext, IntoContext, StopReceiver, Task, TaskId, WiringError, WiringLayer,
};
use zksync_types::{L2ChainId, SLChainId};
use zksync_types::{L1ChainId, L2ChainId};
use zksync_web3_decl::client::{MockClient, L1, L2};

use super::ExternalNodeBuilder;
Expand Down Expand Up @@ -127,11 +127,11 @@ impl WiringLayer for MockL1ClientLayer {

fn layer_name(&self) -> &'static str {
// We don't care about values, we just want to hijack the layer name.
// TODO(EVM-676): configure the `settlement_mode` here
QueryEthClientLayer::new(
SLChainId(1),
L1ChainId(1),
"https://example.com".parse().unwrap(),
Default::default(),
None,
None,
)
.layer_name()
}
Expand Down
8 changes: 5 additions & 3 deletions core/bin/system-constants-generator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use std::fs;
use codegen::{Block, Scope};
use serde::{Deserialize, Serialize};
use zksync_multivm::{
utils::{get_bootloader_encoding_space, get_bootloader_max_txs_in_batch},
utils::{
get_bootloader_encoding_space, get_bootloader_max_txs_in_batch, get_max_new_factory_deps,
},
vm_latest::constants::MAX_VM_PUBDATA_PER_BATCH,
zk_evm_latest::zkevm_opcode_defs::{
circuit_prices::{
Expand All @@ -15,7 +17,7 @@ use zksync_multivm::{
};
use zksync_types::{
IntrinsicSystemGasConstants, ProtocolVersionId, GUARANTEED_PUBDATA_IN_TX,
L1_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS, REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE,
L1_GAS_PER_PUBDATA_BYTE, REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE,
};
use zksync_utils::env::Workspace;

Expand Down Expand Up @@ -73,7 +75,7 @@ pub fn generate_l1_contracts_system_config(gas_constants: &IntrinsicSystemGasCon
l1_tx_delta_544_encoding_bytes: gas_constants.l1_tx_delta_544_encoding_bytes,
l1_tx_delta_factory_deps_l2_gas: gas_constants.l1_tx_delta_factory_dep_gas,
l1_tx_delta_factory_deps_pubdata: gas_constants.l1_tx_delta_factory_dep_pubdata,
max_new_factory_deps: MAX_NEW_FACTORY_DEPS as u32,
max_new_factory_deps: get_max_new_factory_deps(ProtocolVersionId::latest().into()) as u32,
required_l2_gas_price_per_pubdata: REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE,
};

Expand Down
Loading
Loading