From cbc91e35f84d04f2e4c8e81028596db009e478d1 Mon Sep 17 00:00:00 2001
From: perekopskiy <53865202+perekopskiy@users.noreply.github.com>
Date: Wed, 27 Nov 2024 17:34:43 +0200
Subject: [PATCH] feat: integrate gateway changes for some components (#3274)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## What ❔
Generally moves some code from gateway integration branch into main.
High-level list of changes:
- `eth_watch`: refactors watcher's client so it can use L2-specific
features if gateway is queried. New event processor is added for chains
that settle on gateway, it calculates part of merkle proof for L2->L1
logs.
- `api`: new method is added to `unstable` namespace that is utilized by
the new event processor. This method encapsulates a few storage reads +
builds merkle tree. This is a temporary measure and method will likely
be removed (that's why it's in unstable namespace) pretty soon after a
contract getter that does exactly the same is merged into contracts,
replacing unstable_getChainLogProof invocation with a simple `eth_call`
- `consistency_checker`, `tree_data_fetcher`: adds support for reading
batch commitment from either L1 or GW depending on what the SL is for a
batch.
- adds support for new format of commitBatches, proveBatches,
executeBatches data encoding
- bug fixes: `L2_NATIVE_TOKEN_VAULT_ADDRESS` was used instead of
`L2_ASSET_ROUTER_ADDRESS` in
`core/bin/external_node/src/node_builder.rs`, mixed up if/else branches
in `core/node/commitment_generator/src/lib.rs`
- some clean up, renaming, refactoring: `resolve_l1_batch_to_l2_block` +
`get_block_details` are replaced with just `get_batch_details` in
`batch_status_updater`, some code for old protocol versions (pre-boojum
or pre-shared-bridge) removed, `l1_` prefix is added to some addresses
to avoid confusion
## Why ❔
Finalize and merge some gateway features
## Checklist
- [ ] 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`.
---
Cargo.lock | 6 +
core/bin/external_node/src/config/mod.rs | 66 +-
core/bin/external_node/src/node_builder.rs | 22 +-
core/bin/external_node/src/tests/mod.rs | 6 +-
core/bin/external_node/src/tests/utils.rs | 3 +
core/bin/zksync_server/src/node_builder.rs | 7 +-
core/lib/basic_types/src/lib.rs | 2 +-
core/lib/basic_types/src/web3/mod.rs | 8 +-
core/lib/config/src/configs/en_config.rs | 1 -
core/lib/config/src/configs/secrets.rs | 1 +
core/lib/config/src/testonly.rs | 3 +-
core/lib/constants/src/contracts.rs | 2 +
core/lib/constants/src/message_root.rs | 13 +-
core/lib/contracts/src/lib.rs | 462 +++++++++-
...90ded732839b9f5bf16042205a730fac07c3a.json | 3 +-
...53b2126b52d568196f333973a345f984ea7c4.json | 22 +
...44469e431e35c4419fd710050d51eeefd6b8b.json | 22 +
...f98ded0ad3e59e6de69c2b13d92d8ab1a07dd.json | 3 +-
...f99779da93fc8939dc724a49b286c5568129.json} | 7 +-
...5204831b7ede1a8e3b3c2d441d505c4ca58f.json} | 44 +-
...7928aa933616d2186c13a4e005297b0ad63a7.json | 15 +
...55a360f8ae12b6378f8168c000d668d6489d0.json | 22 +
...ce5a6cca1524adfe99b0cb35662746479dcc1.json | 3 +-
...5d1cd01521f82e2962c3feebac395caef36f.json} | 40 +-
...53e30af54675ce58273cbb29312e6e88cbdf5.json | 22 +
...09fb7e3baa5ae84bd5e010008f8972e1a7f98.json | 28 +
...011081834_batch_chain_merkle_path.down.sql | 2 +
...41011081834_batch_chain_merkle_path.up.sql | 5 +
core/lib/dal/src/blocks_dal.rs | 148 +++-
core/lib/dal/src/blocks_web3_dal.rs | 36 +
core/lib/dal/src/eth_sender_dal.rs | 36 +-
core/lib/dal/src/eth_watcher_dal.rs | 1 +
core/lib/dal/src/models/storage_block.rs | 14 +-
core/lib/env_config/src/eth_sender.rs | 5 +
core/lib/eth_client/src/clients/http/query.rs | 2 +-
core/lib/eth_client/src/clients/mock.rs | 20 +-
.../src/i_executor/methods/commit_batches.rs | 24 +-
.../src/i_executor/methods/execute_batches.rs | 51 +-
.../src/i_executor/methods/prove_batches.rs | 74 +-
.../structures/commit_batch_info.rs | 152 +++-
.../src/i_executor/structures/mod.rs | 10 +-
.../structures/stored_batch_info.rs | 24 +-
core/lib/mini_merkle_tree/src/lib.rs | 27 +-
core/lib/mini_merkle_tree/src/tests.rs | 16 +-
core/lib/multivm/src/versions/shadow/tests.rs | 19 +-
.../src/versions/testonly/default_aa.rs | 7 +-
.../src/versions/testonly/l1_messenger.rs | 178 ++++
core/lib/multivm/src/versions/testonly/mod.rs | 1 +
.../src/versions/testonly/tester/mod.rs | 12 +-
.../versions/vm_fast/tests/l1_messenger.rs | 7 +
.../multivm/src/versions/vm_fast/tests/mod.rs | 10 +-
.../versions/vm_latest/tests/l1_messenger.rs | 10 +
.../src/versions/vm_latest/tests/mod.rs | 7 +-
core/lib/protobuf_config/src/en.rs | 9 -
.../protobuf_config/src/proto/config/en.proto | 2 +-
.../src/proto/config/secrets.proto | 1 +
core/lib/protobuf_config/src/secrets.rs | 10 +
core/lib/snapshots_applier/src/tests/utils.rs | 3 +
core/lib/types/src/api/mod.rs | 51 +-
core/lib/types/src/commitment/mod.rs | 26 +
core/lib/types/src/l2_to_l1_log.rs | 30 +
core/lib/types/src/storage/mod.rs | 5 +
core/lib/vm_interface/src/pubdata/mod.rs | 4 +-
core/lib/web3_decl/src/namespaces/eth.rs | 2 +-
core/lib/web3_decl/src/namespaces/unstable.rs | 11 +-
core/lib/web3_decl/src/types.rs | 98 +--
core/node/api_server/Cargo.toml | 1 +
.../web3/backend_jsonrpsee/namespaces/eth.rs | 12 +-
.../backend_jsonrpsee/namespaces/unstable.rs | 14 +-
.../node/api_server/src/web3/namespaces/en.rs | 6 +-
.../src/web3/namespaces/unstable.rs | 65 --
.../src/web3/namespaces/unstable/mod.rs | 142 +++
.../src/web3/namespaces/unstable/utils.rs | 104 +++
.../api_server/src/web3/namespaces/zks.rs | 78 +-
core/node/api_server/src/web3/state.rs | 29 +-
core/node/api_server/src/web3/tests/mod.rs | 18 +-
core/node/commitment_generator/src/lib.rs | 4 +-
core/node/consistency_checker/src/lib.rs | 311 +++++--
.../node/consistency_checker/src/tests/mod.rs | 250 +++++-
core/node/db_pruner/src/tests.rs | 1 +
core/node/eth_sender/src/aggregator.rs | 5 +-
core/node/eth_sender/src/eth_tx_aggregator.rs | 81 +-
core/node/eth_sender/src/tester.rs | 2 +-
core/node/eth_sender/src/tests.rs | 2 +-
core/node/eth_sender/src/zksync_functions.rs | 42 +-
core/node/eth_watch/Cargo.toml | 5 +
core/node/eth_watch/src/client.rs | 237 ++++-
.../appended_chain_batch_root.rs | 238 +++++
.../decentralized_upgrades.rs | 15 +-
.../eth_watch/src/event_processors/mod.rs | 24 +-
.../src/event_processors/priority_ops.rs | 18 +-
core/node/eth_watch/src/lib.rs | 91 +-
core/node/eth_watch/src/tests.rs | 791 -----------------
core/node/eth_watch/src/tests/client.rs | 487 +++++++++++
core/node/eth_watch/src/tests/mod.rs | 827 ++++++++++++++++++
.../layers/consistency_checker.rs | 20 +-
.../src/implementations/layers/eth_watch.rs | 12 +-
.../layers/query_eth_client.rs | 28 +-
.../layers/tree_data_fetcher.rs | 30 +-
.../resources/eth_interface.rs | 9 +
.../node_sync/src/batch_status_updater/mod.rs | 115 ++-
.../src/batch_status_updater/tests.rs | 45 +-
core/node/node_sync/src/metrics.rs | 5 +-
.../node_sync/src/tree_data_fetcher/mod.rs | 22 +-
.../src/tree_data_fetcher/provider/mod.rs | 113 ++-
.../src/tree_data_fetcher/provider/tests.rs | 216 ++++-
etc/env/file_based/external_node.yaml | 2 -
.../commands/external_node/prepare_configs.rs | 2 +-
108 files changed, 4908 insertions(+), 1594 deletions(-)
create mode 100644 core/lib/dal/.sqlx/query-2d0a4e9281e53b0e410b9be0ebd53b2126b52d568196f333973a345f984ea7c4.json
create mode 100644 core/lib/dal/.sqlx/query-2e3107b0c5e8466598066ceca9844469e431e35c4419fd710050d51eeefd6b8b.json
rename core/lib/dal/.sqlx/{query-5503575d9377785894de6cf6139a8d4768c6a803a1a90889e5a1b8254c315231.json => query-5cc172812d228c5b60be8dd8b8eaf99779da93fc8939dc724a49b286c5568129.json} (57%)
rename core/lib/dal/.sqlx/{query-d3760406b7bf5d14a3fe6cbc9fb3926df634ebf0d8286181fa04884fb747cee8.json => query-9b011c7afa158edd17fe0dc56dad5204831b7ede1a8e3b3c2d441d505c4ca58f.json} (52%)
create mode 100644 core/lib/dal/.sqlx/query-c1f9ecf033d609457106189bc4d7928aa933616d2186c13a4e005297b0ad63a7.json
create mode 100644 core/lib/dal/.sqlx/query-c2c288d268d6b266acbfc1058bc55a360f8ae12b6378f8168c000d668d6489d0.json
rename core/lib/dal/.sqlx/{query-a88b113b5dc06ac990a66202b3c05e2c2f10d5cbdb03d02c3c541f7eaa1f58a6.json => query-cd6ab0aea6e1f72c58c189e098be5d1cd01521f82e2962c3feebac395caef36f.json} (51%)
create mode 100644 core/lib/dal/.sqlx/query-cf8aaa95e3e8c376b6083c7015753e30af54675ce58273cbb29312e6e88cbdf5.json
create mode 100644 core/lib/dal/.sqlx/query-f516657dd48332522a5580e26c509fb7e3baa5ae84bd5e010008f8972e1a7f98.json
create mode 100644 core/lib/dal/migrations/20241011081834_batch_chain_merkle_path.down.sql
create mode 100644 core/lib/dal/migrations/20241011081834_batch_chain_merkle_path.up.sql
create mode 100644 core/lib/multivm/src/versions/testonly/l1_messenger.rs
create mode 100644 core/lib/multivm/src/versions/vm_fast/tests/l1_messenger.rs
create mode 100644 core/lib/multivm/src/versions/vm_latest/tests/l1_messenger.rs
delete mode 100644 core/node/api_server/src/web3/namespaces/unstable.rs
create mode 100644 core/node/api_server/src/web3/namespaces/unstable/mod.rs
create mode 100644 core/node/api_server/src/web3/namespaces/unstable/utils.rs
create mode 100644 core/node/eth_watch/src/event_processors/appended_chain_batch_root.rs
delete mode 100644 core/node/eth_watch/src/tests.rs
create mode 100644 core/node/eth_watch/src/tests/client.rs
create mode 100644 core/node/eth_watch/src/tests/mod.rs
diff --git a/Cargo.lock b/Cargo.lock
index e8f33f35c13d..f5d23edcf3e1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -11784,6 +11784,9 @@ dependencies = [
"anyhow",
"async-recursion",
"async-trait",
+ "bincode",
+ "hex",
+ "itertools 0.10.5",
"test-log",
"thiserror",
"tokio",
@@ -11793,9 +11796,11 @@ dependencies = [
"zksync_contracts",
"zksync_dal",
"zksync_eth_client",
+ "zksync_mini_merkle_tree",
"zksync_shared_metrics",
"zksync_system_constants",
"zksync_types",
+ "zksync_web3_decl",
]
[[package]]
@@ -12149,6 +12154,7 @@ dependencies = [
"zksync_config",
"zksync_consensus_roles",
"zksync_contracts",
+ "zksync_crypto_primitives",
"zksync_dal",
"zksync_health_check",
"zksync_metadata_calculator",
diff --git a/core/bin/external_node/src/config/mod.rs b/core/bin/external_node/src/config/mod.rs
index 81604f83008a..49f37116de75 100644
--- a/core/bin/external_node/src/config/mod.rs
+++ b/core/bin/external_node/src/config/mod.rs
@@ -102,11 +102,15 @@ 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 bridgehub_proxy_addr: Option
,
- pub state_transition_proxy_addr: Option,
- pub transparent_proxy_admin_addr: Option,
- /// Should not be accessed directly. Use [`ExternalNodeConfig::diamond_proxy_address`] instead.
- diamond_proxy_addr: Address,
+ #[serde(alias = "bridgehub_proxy_addr")]
+ pub l1_bridgehub_proxy_addr: Option,
+ #[serde(alias = "state_transition_proxy_addr")]
+ pub l1_state_transition_proxy_addr: Option,
+ #[serde(alias = "transparent_proxy_admin_addr")]
+ pub l1_transparent_proxy_admin_addr: Option,
+ /// Should not be accessed directly. Use [`ExternalNodeConfig::l1_diamond_proxy_address`] instead.
+ #[serde(alias = "diamond_proxy_addr")]
+ l1_diamond_proxy_addr: Address,
// While on L1 shared bridge and legacy bridge are different contracts with different addresses,
// the `l2_erc20_bridge_addr` and `l2_shared_bridge_addr` are basically the same contract, but with
// a different name, with names adapted only for consistency.
@@ -144,7 +148,7 @@ impl RemoteENConfig {
.rpc_context("ecosystem_contracts")
.await
.ok();
- let diamond_proxy_addr = client
+ let l1_diamond_proxy_addr = client
.get_main_contract()
.rpc_context("get_main_contract")
.await?;
@@ -180,14 +184,14 @@ impl RemoteENConfig {
}
Ok(Self {
- bridgehub_proxy_addr: ecosystem_contracts.as_ref().map(|a| a.bridgehub_proxy_addr),
- state_transition_proxy_addr: ecosystem_contracts
+ l1_bridgehub_proxy_addr: ecosystem_contracts.as_ref().map(|a| a.bridgehub_proxy_addr),
+ l1_state_transition_proxy_addr: ecosystem_contracts
.as_ref()
.map(|a| a.state_transition_proxy_addr),
- transparent_proxy_admin_addr: ecosystem_contracts
+ l1_transparent_proxy_admin_addr: ecosystem_contracts
.as_ref()
.map(|a| a.transparent_proxy_admin_addr),
- diamond_proxy_addr,
+ l1_diamond_proxy_addr,
l2_testnet_paymaster_addr,
l1_erc20_bridge_proxy_addr: bridges.l1_erc20_default_bridge,
l2_erc20_bridge_addr: l2_erc20_default_bridge,
@@ -212,10 +216,10 @@ impl RemoteENConfig {
#[cfg(test)]
fn mock() -> Self {
Self {
- bridgehub_proxy_addr: None,
- state_transition_proxy_addr: None,
- transparent_proxy_admin_addr: None,
- diamond_proxy_addr: Address::repeat_byte(1),
+ l1_bridgehub_proxy_addr: None,
+ l1_state_transition_proxy_addr: None,
+ l1_transparent_proxy_admin_addr: None,
+ l1_diamond_proxy_addr: Address::repeat_byte(1),
l1_erc20_bridge_proxy_addr: Some(Address::repeat_byte(2)),
l2_erc20_bridge_addr: Some(Address::repeat_byte(3)),
l2_weth_bridge_addr: None,
@@ -479,7 +483,6 @@ pub(crate) struct OptionalENConfig {
#[serde(default = "OptionalENConfig::default_pruning_data_retention_sec")]
pruning_data_retention_sec: u64,
/// Gateway RPC URL, needed for operating during migration.
- #[allow(dead_code)]
pub gateway_url: Option,
/// Interval for bridge addresses refreshing in seconds.
bridge_addresses_refresh_interval_sec: Option,
@@ -489,7 +492,11 @@ pub(crate) struct OptionalENConfig {
}
impl OptionalENConfig {
- fn from_configs(general_config: &GeneralConfig, enconfig: &ENConfig) -> anyhow::Result {
+ fn from_configs(
+ general_config: &GeneralConfig,
+ enconfig: &ENConfig,
+ secrets: &Secrets,
+ ) -> anyhow::Result {
let api_namespaces = load_config!(general_config.api_config, web3_json_rpc.api_namespaces)
.map(|a: Vec| a.iter().map(|a| a.parse()).collect::>())
.transpose()?;
@@ -721,7 +728,10 @@ impl OptionalENConfig {
.unwrap_or_else(Self::default_main_node_rate_limit_rps),
api_namespaces,
contracts_diamond_proxy_addr: None,
- gateway_url: enconfig.gateway_url.clone(),
+ gateway_url: secrets
+ .l1
+ .as_ref()
+ .and_then(|l1| l1.gateway_rpc_url.clone()),
bridge_addresses_refresh_interval_sec: enconfig.bridge_addresses_refresh_interval_sec,
timestamp_asserter_min_time_till_end_sec: general_config
.timestamp_asserter_config
@@ -1340,7 +1350,11 @@ impl ExternalNodeConfig<()> {
&external_node_config,
&secrets_config,
)?;
- let optional = OptionalENConfig::from_configs(&general_config, &external_node_config)?;
+ let optional = OptionalENConfig::from_configs(
+ &general_config,
+ &external_node_config,
+ &secrets_config,
+ )?;
let postgres = PostgresConfig {
database_url: secrets_config
.database
@@ -1383,7 +1397,7 @@ impl ExternalNodeConfig<()> {
let remote = RemoteENConfig::fetch(main_node_client)
.await
.context("Unable to fetch required config values from the main node")?;
- let remote_diamond_proxy_addr = remote.diamond_proxy_addr;
+ let remote_diamond_proxy_addr = remote.l1_diamond_proxy_addr;
if let Some(local_diamond_proxy_addr) = self.optional.contracts_diamond_proxy_addr {
anyhow::ensure!(
local_diamond_proxy_addr == remote_diamond_proxy_addr,
@@ -1430,14 +1444,14 @@ impl ExternalNodeConfig {
}
}
- /// Returns a verified diamond proxy address.
+ /// Returns verified L1 diamond proxy address.
/// If local configuration contains the address, it will be checked against the one returned by the main node.
/// Otherwise, the remote value will be used. However, using remote value has trust implications for the main
/// node so relying on it solely is not recommended.
- pub fn diamond_proxy_address(&self) -> Address {
+ pub fn l1_diamond_proxy_address(&self) -> Address {
self.optional
.contracts_diamond_proxy_addr
- .unwrap_or(self.remote.diamond_proxy_addr)
+ .unwrap_or(self.remote.l1_diamond_proxy_addr)
}
}
@@ -1461,10 +1475,10 @@ impl From<&ExternalNodeConfig> for InternalApiConfig {
l1_weth_bridge: config.remote.l1_weth_bridge_addr,
l2_weth_bridge: config.remote.l2_weth_bridge_addr,
},
- bridgehub_proxy_addr: config.remote.bridgehub_proxy_addr,
- state_transition_proxy_addr: config.remote.state_transition_proxy_addr,
- transparent_proxy_admin_addr: config.remote.transparent_proxy_admin_addr,
- diamond_proxy_addr: config.remote.diamond_proxy_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,
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,
diff --git a/core/bin/external_node/src/node_builder.rs b/core/bin/external_node/src/node_builder.rs
index c5d9228e9930..5f9445d30fe8 100644
--- a/core/bin/external_node/src/node_builder.rs
+++ b/core/bin/external_node/src/node_builder.rs
@@ -57,7 +57,7 @@ use zksync_node_framework::{
service::{ZkStackService, ZkStackServiceBuilder},
};
use zksync_state::RocksdbStorageOptions;
-use zksync_types::L2_NATIVE_TOKEN_VAULT_ADDRESS;
+use zksync_types::L2_ASSET_ROUTER_ADDRESS;
use crate::{config::ExternalNodeConfig, metrics::framework::ExternalNodeMetricsLayer, Component};
@@ -181,8 +181,7 @@ impl ExternalNodeBuilder {
let query_eth_client_layer = QueryEthClientLayer::new(
self.config.required.settlement_layer_id(),
self.config.required.eth_client_url.clone(),
- // TODO(EVM-676): add this config for external node
- Default::default(),
+ self.config.optional.gateway_url.clone(),
);
self.node.add_layer(query_eth_client_layer);
Ok(self)
@@ -200,12 +199,11 @@ impl ExternalNodeBuilder {
.remote
.l2_shared_bridge_addr
.context("Missing `l2_shared_bridge_addr`")?;
- let l2_legacy_shared_bridge_addr = if l2_shared_bridge_addr == L2_NATIVE_TOKEN_VAULT_ADDRESS
- {
- // System has migrated to `L2_NATIVE_TOKEN_VAULT_ADDRESS`, use legacy shared bridge address from main node.
+ let l2_legacy_shared_bridge_addr = if l2_shared_bridge_addr == L2_ASSET_ROUTER_ADDRESS {
+ // System has migrated to `L2_ASSET_ROUTER_ADDRESS`, use legacy shared bridge address from main node.
self.config.remote.l2_legacy_shared_bridge_addr
} else {
- // System hasn't migrated on `L2_NATIVE_TOKEN_VAULT_ADDRESS`, we can safely use `l2_shared_bridge_addr`.
+ // System hasn't migrated on `L2_ASSET_ROUTER_ADDRESS`, we can safely use `l2_shared_bridge_addr`.
Some(l2_shared_bridge_addr)
};
@@ -278,7 +276,7 @@ impl ExternalNodeBuilder {
fn add_l1_batch_commitment_mode_validation_layer(mut self) -> anyhow::Result {
let layer = L1BatchCommitmentModeValidationLayer::new(
- self.config.diamond_proxy_address(),
+ self.config.l1_diamond_proxy_address(),
self.config.optional.l1_batch_commit_data_generator_mode,
);
self.node.add_layer(layer);
@@ -297,9 +295,10 @@ impl ExternalNodeBuilder {
fn add_consistency_checker_layer(mut self) -> anyhow::Result {
let max_batches_to_recheck = 10; // TODO (BFT-97): Make it a part of a proper EN config
let layer = ConsistencyCheckerLayer::new(
- self.config.diamond_proxy_address(),
+ self.config.l1_diamond_proxy_address(),
max_batches_to_recheck,
self.config.optional.l1_batch_commit_data_generator_mode,
+ self.config.required.l2_chain_id,
);
self.node.add_layer(layer);
Ok(self)
@@ -324,7 +323,10 @@ impl ExternalNodeBuilder {
}
fn add_tree_data_fetcher_layer(mut self) -> anyhow::Result {
- let layer = TreeDataFetcherLayer::new(self.config.diamond_proxy_address());
+ let layer = TreeDataFetcherLayer::new(
+ self.config.l1_diamond_proxy_address(),
+ self.config.required.l2_chain_id,
+ );
self.node.add_layer(layer);
Ok(self)
}
diff --git a/core/bin/external_node/src/tests/mod.rs b/core/bin/external_node/src/tests/mod.rs
index 59aceea819f1..fd616a467ee8 100644
--- a/core/bin/external_node/src/tests/mod.rs
+++ b/core/bin/external_node/src/tests/mod.rs
@@ -35,7 +35,7 @@ async fn external_node_basics(components_str: &'static str) {
}
let l2_client = utils::mock_l2_client(&env);
- let eth_client = utils::mock_eth_client(env.config.diamond_proxy_address());
+ let eth_client = utils::mock_eth_client(env.config.l1_diamond_proxy_address());
let node_handle = tokio::task::spawn_blocking(move || {
std::thread::spawn(move || {
@@ -104,7 +104,7 @@ async fn node_reacts_to_stop_signal_during_initial_reorg_detection() {
let (env, env_handles) = utils::TestEnvironment::with_genesis_block("core").await;
let l2_client = utils::mock_l2_client_hanging();
- let eth_client = utils::mock_eth_client(env.config.diamond_proxy_address());
+ let eth_client = utils::mock_eth_client(env.config.l1_diamond_proxy_address());
let mut node_handle = tokio::task::spawn_blocking(move || {
std::thread::spawn(move || {
@@ -140,7 +140,7 @@ async fn running_tree_without_core_is_not_allowed() {
let (env, _env_handles) = utils::TestEnvironment::with_genesis_block("tree").await;
let l2_client = utils::mock_l2_client(&env);
- let eth_client = utils::mock_eth_client(env.config.diamond_proxy_address());
+ let eth_client = utils::mock_eth_client(env.config.l1_diamond_proxy_address());
let node_handle = tokio::task::spawn_blocking(move || {
std::thread::spawn(move || {
diff --git a/core/bin/external_node/src/tests/utils.rs b/core/bin/external_node/src/tests/utils.rs
index b26fa80d1a95..58e2a88e5fb7 100644
--- a/core/bin/external_node/src/tests/utils.rs
+++ b/core/bin/external_node/src/tests/utils.rs
@@ -23,10 +23,13 @@ pub(super) fn block_details_base(hash: H256) -> api::BlockDetailsBase {
status: api::BlockStatus::Sealed,
commit_tx_hash: None,
committed_at: None,
+ commit_chain_id: None,
prove_tx_hash: None,
proven_at: None,
+ prove_chain_id: None,
execute_tx_hash: None,
executed_at: None,
+ execute_chain_id: None,
l1_gas_price: 0,
l2_fair_gas_price: 0,
fair_pubdata_price: None,
diff --git a/core/bin/zksync_server/src/node_builder.rs b/core/bin/zksync_server/src/node_builder.rs
index 7e7d219856ca..d74928e8fbc7 100644
--- a/core/bin/zksync_server/src/node_builder.rs
+++ b/core/bin/zksync_server/src/node_builder.rs
@@ -161,11 +161,7 @@ impl MainNodeBuilder {
let query_eth_client_layer = QueryEthClientLayer::new(
genesis.settlement_layer_id(),
eth_config.l1_rpc_url,
- self.configs
- .eth
- .as_ref()
- .and_then(|x| Some(x.gas_adjuster?.settlement_mode))
- .unwrap_or(SettlementMode::SettlesToL1),
+ eth_config.gateway_rpc_url,
);
self.node.add_layer(query_eth_client_layer);
Ok(self)
@@ -283,6 +279,7 @@ impl MainNodeBuilder {
self.node.add_layer(EthWatchLayer::new(
try_load_config!(eth_config.watcher),
self.contracts_config.clone(),
+ self.genesis_config.l2_chain_id,
));
Ok(self)
}
diff --git a/core/lib/basic_types/src/lib.rs b/core/lib/basic_types/src/lib.rs
index d79bc57cc5e1..8b8e24af4339 100644
--- a/core/lib/basic_types/src/lib.rs
+++ b/core/lib/basic_types/src/lib.rs
@@ -149,7 +149,7 @@ impl<'de> Deserialize<'de> for L2ChainId {
}
impl L2ChainId {
- fn new(number: u64) -> Result {
+ pub fn new(number: u64) -> Result {
if number > L2ChainId::max().0 {
return Err(format!(
"Cannot convert given value {} into L2ChainId. It's greater than MAX: {}",
diff --git a/core/lib/basic_types/src/web3/mod.rs b/core/lib/basic_types/src/web3/mod.rs
index e6d3cab37273..98625831c991 100644
--- a/core/lib/basic_types/src/web3/mod.rs
+++ b/core/lib/basic_types/src/web3/mod.rs
@@ -198,7 +198,7 @@ pub struct Filter {
}
#[derive(Default, Debug, PartialEq, Clone)]
-pub struct ValueOrArray(Vec);
+pub struct ValueOrArray(pub Vec);
impl ValueOrArray {
pub fn flatten(self) -> Vec {
@@ -206,6 +206,12 @@ impl ValueOrArray {
}
}
+impl From for ValueOrArray {
+ fn from(value: T) -> Self {
+ Self(vec![value])
+ }
+}
+
impl Serialize for ValueOrArray
where
T: Serialize,
diff --git a/core/lib/config/src/configs/en_config.rs b/core/lib/config/src/configs/en_config.rs
index 4cab47b0779e..13a0e1f2c99d 100644
--- a/core/lib/config/src/configs/en_config.rs
+++ b/core/lib/config/src/configs/en_config.rs
@@ -18,6 +18,5 @@ pub struct ENConfig {
pub main_node_url: SensitiveUrl,
pub main_node_rate_limit_rps: Option,
- pub gateway_url: Option,
pub bridge_addresses_refresh_interval_sec: Option,
}
diff --git a/core/lib/config/src/configs/secrets.rs b/core/lib/config/src/configs/secrets.rs
index 75ff067c2473..8285d81e4bd2 100644
--- a/core/lib/config/src/configs/secrets.rs
+++ b/core/lib/config/src/configs/secrets.rs
@@ -16,6 +16,7 @@ pub struct DatabaseSecrets {
#[derive(Debug, Clone, PartialEq)]
pub struct L1Secrets {
pub l1_rpc_url: SensitiveUrl,
+ pub gateway_rpc_url: Option,
}
#[derive(Debug, Clone, PartialEq)]
diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs
index 8a9e96c96a5e..d58867ea7418 100644
--- a/core/lib/config/src/testonly.rs
+++ b/core/lib/config/src/testonly.rs
@@ -852,6 +852,7 @@ impl Distribution for EncodeDist {
use configs::secrets::L1Secrets;
L1Secrets {
l1_rpc_url: format!("localhost:{}", rng.gen::()).parse().unwrap(),
+ gateway_rpc_url: Some(format!("localhost:{}", rng.gen::()).parse().unwrap()),
}
}
}
@@ -938,8 +939,6 @@ impl Distribution for EncodeDist {
_ => L1BatchCommitmentMode::Validium,
},
main_node_rate_limit_rps: self.sample_opt(|| rng.gen()),
- gateway_url: self
- .sample_opt(|| format!("localhost:{}", rng.gen::()).parse().unwrap()),
bridge_addresses_refresh_interval_sec: self.sample_opt(|| rng.gen()),
}
}
diff --git a/core/lib/constants/src/contracts.rs b/core/lib/constants/src/contracts.rs
index 4f0f362d9149..6e402c117bfe 100644
--- a/core/lib/constants/src/contracts.rs
+++ b/core/lib/constants/src/contracts.rs
@@ -135,6 +135,8 @@ pub const EVM_GAS_MANAGER_ADDRESS: Address = H160([
0x00, 0x00, 0x80, 0x13,
]);
+/// Note, that the `Create2Factory` and higher are explicitly deployed on a non-system-contract address
+/// as they don't require any kernel space features.
pub const CREATE2_FACTORY_ADDRESS: Address = H160([
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00,
diff --git a/core/lib/constants/src/message_root.rs b/core/lib/constants/src/message_root.rs
index a8f4a034fb99..9bb8764cd667 100644
--- a/core/lib/constants/src/message_root.rs
+++ b/core/lib/constants/src/message_root.rs
@@ -1,5 +1,14 @@
-// Position of `FullTree::_height` in `MessageRoot`'s storage layout.
+/// Position of `chainCount` in `MessageRoot`'s storage layout.
+pub const CHAIN_COUNT_KEY: usize = 0;
+
+/// Position of `chainIndexToId` in `MessageRoot`'s storage layout.
+pub const CHAIN_INDEX_TO_ID_KEY: usize = 2;
+
+/// Position of `FullTree::_height` in `MessageRoot`'s storage layout.
pub const AGG_TREE_HEIGHT_KEY: usize = 3;
-// Position of `FullTree::nodes` in `MessageRoot`'s storage layout.
+/// Position of `FullTree::nodes` in `MessageRoot`'s storage layout.
pub const AGG_TREE_NODES_KEY: usize = 5;
+
+/// Position of `chainTree` in `MessageRoot`'s storage layout.
+pub const CHAIN_TREE_KEY: usize = 7;
diff --git a/core/lib/contracts/src/lib.rs b/core/lib/contracts/src/lib.rs
index 74efa72793aa..e60fdb0e59f3 100644
--- a/core/lib/contracts/src/lib.rs
+++ b/core/lib/contracts/src/lib.rs
@@ -256,7 +256,9 @@ impl SystemContractsRepo {
"artifacts-zk/contracts-preprocessed/{0}{1}.sol/{1}.json",
directory, name
)))
- .expect("One of the outputs should exists")
+ .unwrap_or_else(|| {
+ panic!("One of the outputs should exists for {directory}{name}");
+ })
}
}
ContractLanguage::Yul => {
@@ -975,3 +977,461 @@ pub static DIAMOND_CUT: Lazy = Lazy::new(|| {
}"#;
serde_json::from_str(abi).unwrap()
});
+
+pub static POST_BOOJUM_COMMIT_FUNCTION: Lazy = Lazy::new(|| {
+ let abi = r#"
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint64",
+ "name": "batchNumber",
+ "type": "uint64"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "batchHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint64",
+ "name": "indexRepeatedStorageChanges",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint256",
+ "name": "numberOfLayer1Txs",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "priorityOperationsHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "l2LogsTreeRoot",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "timestamp",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "commitment",
+ "type": "bytes32"
+ }
+ ],
+ "internalType": "struct IExecutor.StoredBatchInfo",
+ "name": "_lastCommittedBatchData",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint64",
+ "name": "batchNumber",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "timestamp",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "indexRepeatedStorageChanges",
+ "type": "uint64"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "newStateRoot",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "numberOfLayer1Txs",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "priorityOperationsHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "bootloaderHeapInitialContentsHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "eventsQueueStateHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes",
+ "name": "systemLogs",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "pubdataCommitments",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IExecutor.CommitBatchInfo[]",
+ "name": "_newBatchesData",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "commitBatches",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }"#;
+ serde_json::from_str(abi).unwrap()
+});
+
+pub static POST_SHARED_BRIDGE_COMMIT_FUNCTION: Lazy = Lazy::new(|| {
+ let abi = r#"
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_chainId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint64",
+ "name": "batchNumber",
+ "type": "uint64"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "batchHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint64",
+ "name": "indexRepeatedStorageChanges",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint256",
+ "name": "numberOfLayer1Txs",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "priorityOperationsHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "l2LogsTreeRoot",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "timestamp",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "commitment",
+ "type": "bytes32"
+ }
+ ],
+ "internalType": "struct IExecutor.StoredBatchInfo",
+ "name": "_lastCommittedBatchData",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint64",
+ "name": "batchNumber",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "timestamp",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "indexRepeatedStorageChanges",
+ "type": "uint64"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "newStateRoot",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "numberOfLayer1Txs",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "priorityOperationsHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "bootloaderHeapInitialContentsHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "eventsQueueStateHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes",
+ "name": "systemLogs",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "pubdataCommitments",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IExecutor.CommitBatchInfo[]",
+ "name": "_newBatchesData",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "commitBatchesSharedBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }"#;
+ serde_json::from_str(abi).unwrap()
+});
+
+pub static POST_SHARED_BRIDGE_PROVE_FUNCTION: Lazy = Lazy::new(|| {
+ let abi = r#"
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_chainId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint64",
+ "name": "batchNumber",
+ "type": "uint64"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "batchHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint64",
+ "name": "indexRepeatedStorageChanges",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint256",
+ "name": "numberOfLayer1Txs",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "priorityOperationsHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "l2LogsTreeRoot",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "timestamp",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "commitment",
+ "type": "bytes32"
+ }
+ ],
+ "internalType": "struct IExecutor.StoredBatchInfo",
+ "name": "_prevBatch",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint64",
+ "name": "batchNumber",
+ "type": "uint64"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "batchHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint64",
+ "name": "indexRepeatedStorageChanges",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint256",
+ "name": "numberOfLayer1Txs",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "priorityOperationsHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "l2LogsTreeRoot",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "timestamp",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "commitment",
+ "type": "bytes32"
+ }
+ ],
+ "internalType": "struct IExecutor.StoredBatchInfo[]",
+ "name": "_committedBatches",
+ "type": "tuple[]"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256[]",
+ "name": "recursiveAggregationInput",
+ "type": "uint256[]"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "serializedProof",
+ "type": "uint256[]"
+ }
+ ],
+ "internalType": "struct IExecutor.ProofInput",
+ "name": "_proof",
+ "type": "tuple"
+ }
+ ],
+ "name": "proveBatchesSharedBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }"#;
+ serde_json::from_str(abi).unwrap()
+});
+
+pub static POST_SHARED_BRIDGE_EXECUTE_FUNCTION: Lazy = Lazy::new(|| {
+ let abi = r#"
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_chainId",
+ "type": "uint256"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint64",
+ "name": "batchNumber",
+ "type": "uint64"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "batchHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint64",
+ "name": "indexRepeatedStorageChanges",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint256",
+ "name": "numberOfLayer1Txs",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "priorityOperationsHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "l2LogsTreeRoot",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "timestamp",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "commitment",
+ "type": "bytes32"
+ }
+ ],
+ "internalType": "struct IExecutor.StoredBatchInfo[]",
+ "name": "_batchesData",
+ "type": "tuple[]"
+ }
+ ],
+ "name": "executeBatchesSharedBridge",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }"#;
+ serde_json::from_str(abi).unwrap()
+});
+
+// Temporary thing, should be removed when new contracts are merged.
+pub static MESSAGE_ROOT_CONTRACT: Lazy = Lazy::new(|| {
+ let abi = r#"
+ [{
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_chainId",
+ "type": "uint256"
+ }
+ ],
+ "name": "getChainRoot",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }]"#;
+ serde_json::from_str(abi).unwrap()
+});
diff --git a/core/lib/dal/.sqlx/query-228aa5ec4c4eb56143823b96a8190ded732839b9f5bf16042205a730fac07c3a.json b/core/lib/dal/.sqlx/query-228aa5ec4c4eb56143823b96a8190ded732839b9f5bf16042205a730fac07c3a.json
index b8d6482ea744..32a2212dfdf6 100644
--- a/core/lib/dal/.sqlx/query-228aa5ec4c4eb56143823b96a8190ded732839b9f5bf16042205a730fac07c3a.json
+++ b/core/lib/dal/.sqlx/query-228aa5ec4c4eb56143823b96a8190ded732839b9f5bf16042205a730fac07c3a.json
@@ -11,7 +11,8 @@
"kind": {
"Enum": [
"ProtocolUpgrades",
- "PriorityTransactions"
+ "PriorityTransactions",
+ "ChainBatchRoot"
]
}
}
diff --git a/core/lib/dal/.sqlx/query-2d0a4e9281e53b0e410b9be0ebd53b2126b52d568196f333973a345f984ea7c4.json b/core/lib/dal/.sqlx/query-2d0a4e9281e53b0e410b9be0ebd53b2126b52d568196f333973a345f984ea7c4.json
new file mode 100644
index 000000000000..adbd2c0931ec
--- /dev/null
+++ b/core/lib/dal/.sqlx/query-2d0a4e9281e53b0e410b9be0ebd53b2126b52d568196f333973a345f984ea7c4.json
@@ -0,0 +1,22 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "\n SELECT\n batch_chain_merkle_path\n FROM\n l1_batches\n WHERE\n number = $1\n ",
+ "describe": {
+ "columns": [
+ {
+ "ordinal": 0,
+ "name": "batch_chain_merkle_path",
+ "type_info": "Bytea"
+ }
+ ],
+ "parameters": {
+ "Left": [
+ "Int8"
+ ]
+ },
+ "nullable": [
+ true
+ ]
+ },
+ "hash": "2d0a4e9281e53b0e410b9be0ebd53b2126b52d568196f333973a345f984ea7c4"
+}
diff --git a/core/lib/dal/.sqlx/query-2e3107b0c5e8466598066ceca9844469e431e35c4419fd710050d51eeefd6b8b.json b/core/lib/dal/.sqlx/query-2e3107b0c5e8466598066ceca9844469e431e35c4419fd710050d51eeefd6b8b.json
new file mode 100644
index 000000000000..69dd87a6c355
--- /dev/null
+++ b/core/lib/dal/.sqlx/query-2e3107b0c5e8466598066ceca9844469e431e35c4419fd710050d51eeefd6b8b.json
@@ -0,0 +1,22 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "\n SELECT\n local_root\n FROM\n l1_batches\n WHERE\n number = $1\n ",
+ "describe": {
+ "columns": [
+ {
+ "ordinal": 0,
+ "name": "local_root",
+ "type_info": "Bytea"
+ }
+ ],
+ "parameters": {
+ "Left": [
+ "Int8"
+ ]
+ },
+ "nullable": [
+ true
+ ]
+ },
+ "hash": "2e3107b0c5e8466598066ceca9844469e431e35c4419fd710050d51eeefd6b8b"
+}
diff --git a/core/lib/dal/.sqlx/query-3ee6c2a87c65eaece7048da53c9f98ded0ad3e59e6de69c2b13d92d8ab1a07dd.json b/core/lib/dal/.sqlx/query-3ee6c2a87c65eaece7048da53c9f98ded0ad3e59e6de69c2b13d92d8ab1a07dd.json
index e2a808d41f89..8bab74d20f5c 100644
--- a/core/lib/dal/.sqlx/query-3ee6c2a87c65eaece7048da53c9f98ded0ad3e59e6de69c2b13d92d8ab1a07dd.json
+++ b/core/lib/dal/.sqlx/query-3ee6c2a87c65eaece7048da53c9f98ded0ad3e59e6de69c2b13d92d8ab1a07dd.json
@@ -17,7 +17,8 @@
"kind": {
"Enum": [
"ProtocolUpgrades",
- "PriorityTransactions"
+ "PriorityTransactions",
+ "ChainBatchRoot"
]
}
}
diff --git a/core/lib/dal/.sqlx/query-5503575d9377785894de6cf6139a8d4768c6a803a1a90889e5a1b8254c315231.json b/core/lib/dal/.sqlx/query-5cc172812d228c5b60be8dd8b8eaf99779da93fc8939dc724a49b286c5568129.json
similarity index 57%
rename from core/lib/dal/.sqlx/query-5503575d9377785894de6cf6139a8d4768c6a803a1a90889e5a1b8254c315231.json
rename to core/lib/dal/.sqlx/query-5cc172812d228c5b60be8dd8b8eaf99779da93fc8939dc724a49b286c5568129.json
index 5f27c7549b47..c2ccaf3b3d7c 100644
--- a/core/lib/dal/.sqlx/query-5503575d9377785894de6cf6139a8d4768c6a803a1a90889e5a1b8254c315231.json
+++ b/core/lib/dal/.sqlx/query-5cc172812d228c5b60be8dd8b8eaf99779da93fc8939dc724a49b286c5568129.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "INSERT INTO eth_txs (raw_tx, nonce, tx_type, contract_address, predicted_gas_cost, created_at, updated_at) VALUES ('\\x00', 0, $1, '', 0, now(), now()) RETURNING id",
+ "query": "INSERT INTO eth_txs (raw_tx, nonce, tx_type, contract_address, predicted_gas_cost, chain_id, created_at, updated_at) VALUES ('\\x00', 0, $1, '', 0, $2, now(), now()) RETURNING id",
"describe": {
"columns": [
{
@@ -11,12 +11,13 @@
],
"parameters": {
"Left": [
- "Text"
+ "Text",
+ "Int8"
]
},
"nullable": [
false
]
},
- "hash": "5503575d9377785894de6cf6139a8d4768c6a803a1a90889e5a1b8254c315231"
+ "hash": "5cc172812d228c5b60be8dd8b8eaf99779da93fc8939dc724a49b286c5568129"
}
diff --git a/core/lib/dal/.sqlx/query-d3760406b7bf5d14a3fe6cbc9fb3926df634ebf0d8286181fa04884fb747cee8.json b/core/lib/dal/.sqlx/query-9b011c7afa158edd17fe0dc56dad5204831b7ede1a8e3b3c2d441d505c4ca58f.json
similarity index 52%
rename from core/lib/dal/.sqlx/query-d3760406b7bf5d14a3fe6cbc9fb3926df634ebf0d8286181fa04884fb747cee8.json
rename to core/lib/dal/.sqlx/query-9b011c7afa158edd17fe0dc56dad5204831b7ede1a8e3b3c2d441d505c4ca58f.json
index ed3270de573e..8de8a19da5f8 100644
--- a/core/lib/dal/.sqlx/query-d3760406b7bf5d14a3fe6cbc9fb3926df634ebf0d8286181fa04884fb747cee8.json
+++ b/core/lib/dal/.sqlx/query-9b011c7afa158edd17fe0dc56dad5204831b7ede1a8e3b3c2d441d505c4ca58f.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "\n SELECT\n miniblocks.number,\n COALESCE(\n miniblocks.l1_batch_number,\n (\n SELECT\n (MAX(number) + 1)\n FROM\n l1_batches\n WHERE\n is_sealed\n )\n ) AS \"l1_batch_number!\",\n miniblocks.timestamp,\n miniblocks.l1_tx_count,\n miniblocks.l2_tx_count,\n miniblocks.hash AS \"root_hash?\",\n commit_tx.tx_hash AS \"commit_tx_hash?\",\n commit_tx.confirmed_at AS \"committed_at?\",\n prove_tx.tx_hash AS \"prove_tx_hash?\",\n prove_tx.confirmed_at AS \"proven_at?\",\n execute_tx.tx_hash AS \"execute_tx_hash?\",\n execute_tx.confirmed_at AS \"executed_at?\",\n miniblocks.l1_gas_price,\n miniblocks.l2_fair_gas_price,\n miniblocks.fair_pubdata_price,\n miniblocks.bootloader_code_hash,\n miniblocks.default_aa_code_hash,\n l1_batches.evm_emulator_code_hash,\n miniblocks.protocol_version,\n miniblocks.fee_account_address\n FROM\n miniblocks\n LEFT JOIN l1_batches ON miniblocks.l1_batch_number = l1_batches.number\n LEFT JOIN eth_txs_history AS commit_tx\n ON (\n l1_batches.eth_commit_tx_id = commit_tx.eth_tx_id\n AND commit_tx.confirmed_at IS NOT NULL\n )\n LEFT JOIN eth_txs_history AS prove_tx\n ON (\n l1_batches.eth_prove_tx_id = prove_tx.eth_tx_id\n AND prove_tx.confirmed_at IS NOT NULL\n )\n LEFT JOIN eth_txs_history AS execute_tx\n ON (\n l1_batches.eth_execute_tx_id = execute_tx.eth_tx_id\n AND execute_tx.confirmed_at IS NOT NULL\n )\n WHERE\n miniblocks.number = $1\n ",
+ "query": "\n SELECT\n miniblocks.number,\n COALESCE(\n miniblocks.l1_batch_number,\n (\n SELECT\n (MAX(number) + 1)\n FROM\n l1_batches\n WHERE\n is_sealed\n )\n ) AS \"l1_batch_number!\",\n miniblocks.timestamp,\n miniblocks.l1_tx_count,\n miniblocks.l2_tx_count,\n miniblocks.hash AS \"root_hash?\",\n commit_tx.tx_hash AS \"commit_tx_hash?\",\n commit_tx.confirmed_at AS \"committed_at?\",\n commit_tx_data.chain_id AS \"commit_chain_id?\",\n prove_tx.tx_hash AS \"prove_tx_hash?\",\n prove_tx.confirmed_at AS \"proven_at?\",\n prove_tx_data.chain_id AS \"prove_chain_id?\",\n execute_tx.tx_hash AS \"execute_tx_hash?\",\n execute_tx.confirmed_at AS \"executed_at?\",\n execute_tx_data.chain_id AS \"execute_chain_id?\",\n miniblocks.l1_gas_price,\n miniblocks.l2_fair_gas_price,\n miniblocks.fair_pubdata_price,\n miniblocks.bootloader_code_hash,\n miniblocks.default_aa_code_hash,\n l1_batches.evm_emulator_code_hash,\n miniblocks.protocol_version,\n miniblocks.fee_account_address\n FROM\n miniblocks\n LEFT JOIN l1_batches ON miniblocks.l1_batch_number = l1_batches.number\n LEFT JOIN eth_txs_history AS commit_tx\n ON (\n l1_batches.eth_commit_tx_id = commit_tx.eth_tx_id\n AND commit_tx.confirmed_at IS NOT NULL\n )\n LEFT JOIN eth_txs_history AS prove_tx\n ON (\n l1_batches.eth_prove_tx_id = prove_tx.eth_tx_id\n AND prove_tx.confirmed_at IS NOT NULL\n )\n LEFT JOIN eth_txs_history AS execute_tx\n ON (\n l1_batches.eth_execute_tx_id = execute_tx.eth_tx_id\n AND execute_tx.confirmed_at IS NOT NULL\n )\n LEFT JOIN eth_txs AS commit_tx_data\n ON (\n l1_batches.eth_commit_tx_id = commit_tx_data.id\n AND commit_tx_data.confirmed_eth_tx_history_id IS NOT NULL\n )\n LEFT JOIN eth_txs AS prove_tx_data\n ON (\n l1_batches.eth_prove_tx_id = prove_tx_data.id\n AND prove_tx_data.confirmed_eth_tx_history_id IS NOT NULL\n )\n LEFT JOIN eth_txs AS execute_tx_data\n ON (\n l1_batches.eth_execute_tx_id = execute_tx_data.id\n AND execute_tx_data.confirmed_eth_tx_history_id IS NOT NULL\n )\n WHERE\n miniblocks.number = $1\n ",
"describe": {
"columns": [
{
@@ -45,61 +45,76 @@
},
{
"ordinal": 8,
+ "name": "commit_chain_id?",
+ "type_info": "Int8"
+ },
+ {
+ "ordinal": 9,
"name": "prove_tx_hash?",
"type_info": "Text"
},
{
- "ordinal": 9,
+ "ordinal": 10,
"name": "proven_at?",
"type_info": "Timestamp"
},
{
- "ordinal": 10,
+ "ordinal": 11,
+ "name": "prove_chain_id?",
+ "type_info": "Int8"
+ },
+ {
+ "ordinal": 12,
"name": "execute_tx_hash?",
"type_info": "Text"
},
{
- "ordinal": 11,
+ "ordinal": 13,
"name": "executed_at?",
"type_info": "Timestamp"
},
{
- "ordinal": 12,
+ "ordinal": 14,
+ "name": "execute_chain_id?",
+ "type_info": "Int8"
+ },
+ {
+ "ordinal": 15,
"name": "l1_gas_price",
"type_info": "Int8"
},
{
- "ordinal": 13,
+ "ordinal": 16,
"name": "l2_fair_gas_price",
"type_info": "Int8"
},
{
- "ordinal": 14,
+ "ordinal": 17,
"name": "fair_pubdata_price",
"type_info": "Int8"
},
{
- "ordinal": 15,
+ "ordinal": 18,
"name": "bootloader_code_hash",
"type_info": "Bytea"
},
{
- "ordinal": 16,
+ "ordinal": 19,
"name": "default_aa_code_hash",
"type_info": "Bytea"
},
{
- "ordinal": 17,
+ "ordinal": 20,
"name": "evm_emulator_code_hash",
"type_info": "Bytea"
},
{
- "ordinal": 18,
+ "ordinal": 21,
"name": "protocol_version",
"type_info": "Int4"
},
{
- "ordinal": 19,
+ "ordinal": 22,
"name": "fee_account_address",
"type_info": "Bytea"
}
@@ -118,10 +133,13 @@
false,
false,
true,
+ true,
false,
true,
+ true,
false,
true,
+ true,
false,
false,
true,
@@ -132,5 +150,5 @@
false
]
},
- "hash": "d3760406b7bf5d14a3fe6cbc9fb3926df634ebf0d8286181fa04884fb747cee8"
+ "hash": "9b011c7afa158edd17fe0dc56dad5204831b7ede1a8e3b3c2d441d505c4ca58f"
}
diff --git a/core/lib/dal/.sqlx/query-c1f9ecf033d609457106189bc4d7928aa933616d2186c13a4e005297b0ad63a7.json b/core/lib/dal/.sqlx/query-c1f9ecf033d609457106189bc4d7928aa933616d2186c13a4e005297b0ad63a7.json
new file mode 100644
index 000000000000..90623e77e985
--- /dev/null
+++ b/core/lib/dal/.sqlx/query-c1f9ecf033d609457106189bc4d7928aa933616d2186c13a4e005297b0ad63a7.json
@@ -0,0 +1,15 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "\n UPDATE\n l1_batches\n SET\n batch_chain_merkle_path = $2\n WHERE\n number = $1\n ",
+ "describe": {
+ "columns": [],
+ "parameters": {
+ "Left": [
+ "Int8",
+ "Bytea"
+ ]
+ },
+ "nullable": []
+ },
+ "hash": "c1f9ecf033d609457106189bc4d7928aa933616d2186c13a4e005297b0ad63a7"
+}
diff --git a/core/lib/dal/.sqlx/query-c2c288d268d6b266acbfc1058bc55a360f8ae12b6378f8168c000d668d6489d0.json b/core/lib/dal/.sqlx/query-c2c288d268d6b266acbfc1058bc55a360f8ae12b6378f8168c000d668d6489d0.json
new file mode 100644
index 000000000000..751d272b0b0e
--- /dev/null
+++ b/core/lib/dal/.sqlx/query-c2c288d268d6b266acbfc1058bc55a360f8ae12b6378f8168c000d668d6489d0.json
@@ -0,0 +1,22 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "\n SELECT\n l2_l1_merkle_root\n FROM\n l1_batches\n WHERE\n number = $1\n ",
+ "describe": {
+ "columns": [
+ {
+ "ordinal": 0,
+ "name": "l2_l1_merkle_root",
+ "type_info": "Bytea"
+ }
+ ],
+ "parameters": {
+ "Left": [
+ "Int8"
+ ]
+ },
+ "nullable": [
+ true
+ ]
+ },
+ "hash": "c2c288d268d6b266acbfc1058bc55a360f8ae12b6378f8168c000d668d6489d0"
+}
diff --git a/core/lib/dal/.sqlx/query-c2c40d5aae2e0276de453c78a39ce5a6cca1524adfe99b0cb35662746479dcc1.json b/core/lib/dal/.sqlx/query-c2c40d5aae2e0276de453c78a39ce5a6cca1524adfe99b0cb35662746479dcc1.json
index 61832d25fd24..5e2ea45e0bc2 100644
--- a/core/lib/dal/.sqlx/query-c2c40d5aae2e0276de453c78a39ce5a6cca1524adfe99b0cb35662746479dcc1.json
+++ b/core/lib/dal/.sqlx/query-c2c40d5aae2e0276de453c78a39ce5a6cca1524adfe99b0cb35662746479dcc1.json
@@ -11,7 +11,8 @@
"kind": {
"Enum": [
"ProtocolUpgrades",
- "PriorityTransactions"
+ "PriorityTransactions",
+ "ChainBatchRoot"
]
}
}
diff --git a/core/lib/dal/.sqlx/query-a88b113b5dc06ac990a66202b3c05e2c2f10d5cbdb03d02c3c541f7eaa1f58a6.json b/core/lib/dal/.sqlx/query-cd6ab0aea6e1f72c58c189e098be5d1cd01521f82e2962c3feebac395caef36f.json
similarity index 51%
rename from core/lib/dal/.sqlx/query-a88b113b5dc06ac990a66202b3c05e2c2f10d5cbdb03d02c3c541f7eaa1f58a6.json
rename to core/lib/dal/.sqlx/query-cd6ab0aea6e1f72c58c189e098be5d1cd01521f82e2962c3feebac395caef36f.json
index 28ffcc5ae468..1af3384a2d9f 100644
--- a/core/lib/dal/.sqlx/query-a88b113b5dc06ac990a66202b3c05e2c2f10d5cbdb03d02c3c541f7eaa1f58a6.json
+++ b/core/lib/dal/.sqlx/query-cd6ab0aea6e1f72c58c189e098be5d1cd01521f82e2962c3feebac395caef36f.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "\n WITH\n mb AS (\n SELECT\n l1_gas_price,\n l2_fair_gas_price,\n fair_pubdata_price\n FROM\n miniblocks\n WHERE\n l1_batch_number = $1\n LIMIT\n 1\n )\n \n SELECT\n l1_batches.number,\n l1_batches.timestamp,\n l1_batches.l1_tx_count,\n l1_batches.l2_tx_count,\n l1_batches.hash AS \"root_hash?\",\n commit_tx.tx_hash AS \"commit_tx_hash?\",\n commit_tx.confirmed_at AS \"committed_at?\",\n prove_tx.tx_hash AS \"prove_tx_hash?\",\n prove_tx.confirmed_at AS \"proven_at?\",\n execute_tx.tx_hash AS \"execute_tx_hash?\",\n execute_tx.confirmed_at AS \"executed_at?\",\n mb.l1_gas_price,\n mb.l2_fair_gas_price,\n mb.fair_pubdata_price,\n l1_batches.bootloader_code_hash,\n l1_batches.default_aa_code_hash,\n l1_batches.evm_emulator_code_hash\n FROM\n l1_batches\n INNER JOIN mb ON TRUE\n LEFT JOIN eth_txs_history AS commit_tx\n ON (\n l1_batches.eth_commit_tx_id = commit_tx.eth_tx_id\n AND commit_tx.confirmed_at IS NOT NULL\n )\n LEFT JOIN eth_txs_history AS prove_tx\n ON (\n l1_batches.eth_prove_tx_id = prove_tx.eth_tx_id\n AND prove_tx.confirmed_at IS NOT NULL\n )\n LEFT JOIN eth_txs_history AS execute_tx\n ON (\n l1_batches.eth_execute_tx_id = execute_tx.eth_tx_id\n AND execute_tx.confirmed_at IS NOT NULL\n )\n WHERE\n l1_batches.number = $1\n ",
+ "query": "\n WITH\n mb AS (\n SELECT\n l1_gas_price,\n l2_fair_gas_price,\n fair_pubdata_price\n FROM\n miniblocks\n WHERE\n l1_batch_number = $1\n LIMIT\n 1\n )\n \n SELECT\n l1_batches.number,\n l1_batches.timestamp,\n l1_batches.l1_tx_count,\n l1_batches.l2_tx_count,\n l1_batches.hash AS \"root_hash?\",\n commit_tx.tx_hash AS \"commit_tx_hash?\",\n commit_tx.confirmed_at AS \"committed_at?\",\n commit_tx_data.chain_id AS \"commit_chain_id?\",\n prove_tx.tx_hash AS \"prove_tx_hash?\",\n prove_tx.confirmed_at AS \"proven_at?\",\n prove_tx_data.chain_id AS \"prove_chain_id?\",\n execute_tx.tx_hash AS \"execute_tx_hash?\",\n execute_tx.confirmed_at AS \"executed_at?\",\n execute_tx_data.chain_id AS \"execute_chain_id?\",\n mb.l1_gas_price,\n mb.l2_fair_gas_price,\n mb.fair_pubdata_price,\n l1_batches.bootloader_code_hash,\n l1_batches.default_aa_code_hash,\n l1_batches.evm_emulator_code_hash\n FROM\n l1_batches\n INNER JOIN mb ON TRUE\n LEFT JOIN eth_txs_history AS commit_tx\n ON (\n l1_batches.eth_commit_tx_id = commit_tx.eth_tx_id\n AND commit_tx.confirmed_at IS NOT NULL\n )\n LEFT JOIN eth_txs_history AS prove_tx\n ON (\n l1_batches.eth_prove_tx_id = prove_tx.eth_tx_id\n AND prove_tx.confirmed_at IS NOT NULL\n )\n LEFT JOIN eth_txs_history AS execute_tx\n ON (\n l1_batches.eth_execute_tx_id = execute_tx.eth_tx_id\n AND execute_tx.confirmed_at IS NOT NULL\n )\n LEFT JOIN eth_txs AS commit_tx_data\n ON (\n l1_batches.eth_commit_tx_id = commit_tx_data.id\n AND commit_tx_data.confirmed_eth_tx_history_id IS NOT NULL\n )\n LEFT JOIN eth_txs AS prove_tx_data\n ON (\n l1_batches.eth_prove_tx_id = prove_tx_data.id\n AND prove_tx_data.confirmed_eth_tx_history_id IS NOT NULL\n )\n LEFT JOIN eth_txs AS execute_tx_data\n ON (\n l1_batches.eth_execute_tx_id = execute_tx_data.id\n AND execute_tx_data.confirmed_eth_tx_history_id IS NOT NULL\n )\n WHERE\n l1_batches.number = $1\n ",
"describe": {
"columns": [
{
@@ -40,51 +40,66 @@
},
{
"ordinal": 7,
+ "name": "commit_chain_id?",
+ "type_info": "Int8"
+ },
+ {
+ "ordinal": 8,
"name": "prove_tx_hash?",
"type_info": "Text"
},
{
- "ordinal": 8,
+ "ordinal": 9,
"name": "proven_at?",
"type_info": "Timestamp"
},
{
- "ordinal": 9,
+ "ordinal": 10,
+ "name": "prove_chain_id?",
+ "type_info": "Int8"
+ },
+ {
+ "ordinal": 11,
"name": "execute_tx_hash?",
"type_info": "Text"
},
{
- "ordinal": 10,
+ "ordinal": 12,
"name": "executed_at?",
"type_info": "Timestamp"
},
{
- "ordinal": 11,
+ "ordinal": 13,
+ "name": "execute_chain_id?",
+ "type_info": "Int8"
+ },
+ {
+ "ordinal": 14,
"name": "l1_gas_price",
"type_info": "Int8"
},
{
- "ordinal": 12,
+ "ordinal": 15,
"name": "l2_fair_gas_price",
"type_info": "Int8"
},
{
- "ordinal": 13,
+ "ordinal": 16,
"name": "fair_pubdata_price",
"type_info": "Int8"
},
{
- "ordinal": 14,
+ "ordinal": 17,
"name": "bootloader_code_hash",
"type_info": "Bytea"
},
{
- "ordinal": 15,
+ "ordinal": 18,
"name": "default_aa_code_hash",
"type_info": "Bytea"
},
{
- "ordinal": 16,
+ "ordinal": 19,
"name": "evm_emulator_code_hash",
"type_info": "Bytea"
}
@@ -102,10 +117,13 @@
true,
false,
true,
+ true,
false,
true,
+ true,
false,
true,
+ true,
false,
false,
true,
@@ -114,5 +132,5 @@
true
]
},
- "hash": "a88b113b5dc06ac990a66202b3c05e2c2f10d5cbdb03d02c3c541f7eaa1f58a6"
+ "hash": "cd6ab0aea6e1f72c58c189e098be5d1cd01521f82e2962c3feebac395caef36f"
}
diff --git a/core/lib/dal/.sqlx/query-cf8aaa95e3e8c376b6083c7015753e30af54675ce58273cbb29312e6e88cbdf5.json b/core/lib/dal/.sqlx/query-cf8aaa95e3e8c376b6083c7015753e30af54675ce58273cbb29312e6e88cbdf5.json
new file mode 100644
index 000000000000..b79441ab4d63
--- /dev/null
+++ b/core/lib/dal/.sqlx/query-cf8aaa95e3e8c376b6083c7015753e30af54675ce58273cbb29312e6e88cbdf5.json
@@ -0,0 +1,22 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "\n SELECT eth_txs.chain_id\n FROM l1_batches\n JOIN eth_txs ON eth_txs.id = l1_batches.eth_commit_tx_id\n WHERE\n number = $1\n ",
+ "describe": {
+ "columns": [
+ {
+ "ordinal": 0,
+ "name": "chain_id",
+ "type_info": "Int8"
+ }
+ ],
+ "parameters": {
+ "Left": [
+ "Int8"
+ ]
+ },
+ "nullable": [
+ true
+ ]
+ },
+ "hash": "cf8aaa95e3e8c376b6083c7015753e30af54675ce58273cbb29312e6e88cbdf5"
+}
diff --git a/core/lib/dal/.sqlx/query-f516657dd48332522a5580e26c509fb7e3baa5ae84bd5e010008f8972e1a7f98.json b/core/lib/dal/.sqlx/query-f516657dd48332522a5580e26c509fb7e3baa5ae84bd5e010008f8972e1a7f98.json
new file mode 100644
index 000000000000..9f7de50539be
--- /dev/null
+++ b/core/lib/dal/.sqlx/query-f516657dd48332522a5580e26c509fb7e3baa5ae84bd5e010008f8972e1a7f98.json
@@ -0,0 +1,28 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "\n SELECT\n number, l2_l1_merkle_root\n FROM\n l1_batches\n JOIN eth_txs ON eth_txs.id = l1_batches.eth_execute_tx_id\n WHERE\n batch_chain_merkle_path IS NOT NULL\n AND chain_id = $1\n ORDER BY number\n ",
+ "describe": {
+ "columns": [
+ {
+ "ordinal": 0,
+ "name": "number",
+ "type_info": "Int8"
+ },
+ {
+ "ordinal": 1,
+ "name": "l2_l1_merkle_root",
+ "type_info": "Bytea"
+ }
+ ],
+ "parameters": {
+ "Left": [
+ "Int8"
+ ]
+ },
+ "nullable": [
+ false,
+ true
+ ]
+ },
+ "hash": "f516657dd48332522a5580e26c509fb7e3baa5ae84bd5e010008f8972e1a7f98"
+}
diff --git a/core/lib/dal/migrations/20241011081834_batch_chain_merkle_path.down.sql b/core/lib/dal/migrations/20241011081834_batch_chain_merkle_path.down.sql
new file mode 100644
index 000000000000..da7142b8f819
--- /dev/null
+++ b/core/lib/dal/migrations/20241011081834_batch_chain_merkle_path.down.sql
@@ -0,0 +1,2 @@
+ALTER TABLE l1_batches
+ DROP COLUMN batch_chain_merkle_path BYTEA;
diff --git a/core/lib/dal/migrations/20241011081834_batch_chain_merkle_path.up.sql b/core/lib/dal/migrations/20241011081834_batch_chain_merkle_path.up.sql
new file mode 100644
index 000000000000..8b133f70904b
--- /dev/null
+++ b/core/lib/dal/migrations/20241011081834_batch_chain_merkle_path.up.sql
@@ -0,0 +1,5 @@
+ALTER TABLE l1_batches
+ ADD COLUMN batch_chain_merkle_path BYTEA;
+
+-- postgres doesn't allow dropping enum variant, so nothing is done in down.sql
+ALTER TYPE event_type ADD VALUE 'ChainBatchRoot';
diff --git a/core/lib/dal/src/blocks_dal.rs b/core/lib/dal/src/blocks_dal.rs
index 0cb607a304e2..5d27b6067cd0 100644
--- a/core/lib/dal/src/blocks_dal.rs
+++ b/core/lib/dal/src/blocks_dal.rs
@@ -22,9 +22,9 @@ use zksync_types::{
},
commitment::{L1BatchCommitmentArtifacts, L1BatchWithMetadata},
fee_model::BatchFeeInput,
- l2_to_l1_log::UserL2ToL1Log,
+ l2_to_l1_log::{BatchAndChainMerklePath, UserL2ToL1Log},
writes::TreeWrite,
- Address, Bloom, L1BatchNumber, L2BlockNumber, ProtocolVersionId, H256, U256,
+ Address, Bloom, L1BatchNumber, L2BlockNumber, ProtocolVersionId, SLChainId, H256, U256,
};
use zksync_vm_interface::CircuitStatistic;
@@ -1982,6 +1982,150 @@ impl BlocksDal<'_, '_> {
Ok(Some((H256::from_slice(&hash), row.timestamp as u64)))
}
+ pub async fn get_l1_batch_local_root(
+ &mut self,
+ number: L1BatchNumber,
+ ) -> DalResult