diff --git a/core/lib/snapshots_applier/README.md b/core/lib/snapshots_applier/README.md index 60f17344f5b1..9ec934cbce35 100644 --- a/core/lib/snapshots_applier/README.md +++ b/core/lib/snapshots_applier/README.md @@ -4,7 +4,7 @@ Library responsible for recovering Postgres from a protocol-level snapshot. ## Recovery workflow -_(See [node docs](../../../docs/guides/external-node/07_snapshots_recovery.md) for a high-level snapshot recovery +_(See [node docs](../../../docs/src/guides/external-node/07_snapshots_recovery.md) for a high-level snapshot recovery overview and [snapshot creator docs](../../bin/snapshots_creator/README.md) for the snapshot format details)_ 1. Recovery is started by querying the main node and determining the snapshot parameters. By default, recovery is diff --git a/core/node/consensus/src/en.rs b/core/node/consensus/src/en.rs index e417b68cf2cb..2bddc3280362 100644 --- a/core/node/consensus/src/en.rs +++ b/core/node/consensus/src/en.rs @@ -178,7 +178,7 @@ impl EN { tracing::warn!("\ WARNING: this node is using ZKsync API synchronization, which will be deprecated soon. \ Please follow this instruction to switch to p2p synchronization: \ - https://github.com/matter-labs/zksync-era/blob/main/docs/guides/external-node/10_decentralization.md"); + https://github.com/matter-labs/zksync-era/blob/main/docs/src/guides/external-node/10_decentralization.md"); let res: ctx::Result<()> = scope::run!(ctx, |ctx, s| async { // Update sync state in the background. s.spawn_bg(self.fetch_state_loop(ctx)); diff --git a/core/node/db_pruner/README.md b/core/node/db_pruner/README.md index ee1317d01e46..b1528bd0ade0 100644 --- a/core/node/db_pruner/README.md +++ b/core/node/db_pruner/README.md @@ -10,7 +10,7 @@ There are two types of objects that are not fully cleaned: ## Pruning workflow -_(See [node docs](../../../docs/guides/external-node/08_pruning.md) for a high-level pruning overview)_ +_(See [node docs](../../../docs/src/guides/external-node/08_pruning.md) for a high-level pruning overview)_ There are two phases of pruning an L1 batch, soft pruning and hard pruning. Every batch that would have its records removed if first _soft-pruned_. Soft-pruned batches cannot safely be used. One minute (this is configurable) after soft diff --git a/core/node/node_storage_init/README.md b/core/node/node_storage_init/README.md index e1b6768878ec..39f7d6fc1205 100644 --- a/core/node/node_storage_init/README.md +++ b/core/node/node_storage_init/README.md @@ -1,5 +1,5 @@ # `zksync_node_storage_init` -A set of actions to ensure that any ZKsync node has initialized storage and can start running. +A set of actions to ensure that any Node has initialized storage and can start running. This includes genesis, but not limited to it, and may involve other steps. diff --git a/docs/src/announcements/attester_commitee.md b/docs/src/announcements/attester_commitee.md index 148e51a4f976..d4205ee52aa9 100644 --- a/docs/src/announcements/attester_commitee.md +++ b/docs/src/announcements/attester_commitee.md @@ -2,8 +2,8 @@ ## Overview -The Attester committee is a subset of ZKSync nodes. After each l1 batch execution, participating nodes sign its -execution result and send back to the network. +The Attester committee is a subset of Nodes. After each l1 batch execution, participating nodes sign its execution +result and send back to the network. The ultimate goal is to make L1 commit operation contingent on such signatures. This will improve the security and finality guarantees: having these signatures on L1 shows that additional actors executed the corresponding blocks - and @@ -36,7 +36,7 @@ Participants can leave the committee at any time. The only action that is required to participate is to share your attester public key with the Main Node operator (by opening an issue in this repo or using any other communication channel). You can find it in the comment in the `consensus_secrets.yaml` file (that was - in most cases - generated by the tool described -[here](https://github.com/matter-labs/zksync-era/blob/main/docs/guides/external-node/10_decentralization.md#generating-secrets)) +[here](https://github.com/matter-labs/zksync-era/blob/main/docs/src/guides/external-node/10_decentralization.md#generating-secrets)) > [!WARNING] > diff --git a/docs/src/guides/external-node/00_quick_start.md b/docs/src/guides/external-node/00_quick_start.md index 07e52085cf4f..547d65fcbc0c 100644 --- a/docs/src/guides/external-node/00_quick_start.md +++ b/docs/src/guides/external-node/00_quick_start.md @@ -6,7 +6,15 @@ Install `docker compose` and `Docker` ## Running ZKsync node locally -These commands start ZKsync node locally inside docker. +These commands start ZKsync Node locally inside docker. + +For adjusting the Dockerfiles to use them with other chains setup using ZK Stack, see +[setup_for_other_chains](11_setup_for_other_chains.md) + +> [!NOTE] +> +> If you want to run Node for a chain different than ZKsync ERA, you can ask the company hosting the chains for the +> ready docker-compose files. To start a mainnet instance, run: @@ -58,11 +66,16 @@ The HTTP JSON-RPC API can be accessed on port `3060` and WebSocket API can be ac > setup). > > For requirements for nodes running from DB dump see the [running](03_running.md) section. DB dumps are a way to start -> ZKsync node with full historical transactions history. +> Node with full historical transactions history. > > For nodes with pruning disabled, expect the storage requirements on mainnet to grow at 1TB per month. If you want to > stop historical DB pruning you can read more about this in the [pruning](08_pruning.md) section. +> [!NOTE] +> +> For chains other than ZKSync Era, the system requirements can be slightly lower (CPU and RAM) or even much lower +> (storage), depending on the chain. + - 32 GB of RAM and a relatively modern CPU - 50 GB of storage for testnet nodes - 500 GB of storage for mainnet nodes diff --git a/docs/src/guides/external-node/01_intro.md b/docs/src/guides/external-node/01_intro.md index 10fc55acac21..b5842e160b6c 100644 --- a/docs/src/guides/external-node/01_intro.md +++ b/docs/src/guides/external-node/01_intro.md @@ -1,39 +1,36 @@ -# ZkSync Node Documentation +# Node Documentation -This documentation explains the basics of the ZKsync Node. +The Node (sometimes referred to as External Node or EN) is a read-only replica of the main node. -## Disclaimers +## What is the Node -- The ZKsync node is in the alpha phase, and should be used with caution. -- The ZKsync node is a read-only replica of the main node. +The Node is a read-replica of the main (centralized) node that can be run by external parties. It functions by receiving +blocks from the given ZK Stack chain and re-applying transactions locally, starting from the genesis block. The Node +shares most of its codebase with the main node. Consequently, when it re-applies transactions, it does so exactly as the +main node did in the past. -## What is the ZKsync node +**It has three modes of initialization:** -The ZKsync node is a read-replica of the main (centralized) node that can be run by external parties. It functions by -receiving blocks from the ZKsync network and re-applying transactions locally, starting from the genesis block. The -ZKsync node shares most of its codebase with the main node. Consequently, when it re-applies transactions, it does so -exactly as the main node did in the past. - -**It has two modes of initialization:** - -- recovery from a DB dump, in Ethereum terms this corresponds to archival node +- recovery from genesis (Not supported on ZKsync Era), in Ethereum terms this corresponds to archival node, this option + is slower than recovery from DB dump, but is the easiest way to spin up new Node. +- recovery from a DB dump, in Ethereum terms this corresponds to archival node. - recovery from a snapshot, in Ethereum terms this corresponds to light node, such nodes will only have access to transactions data from after the node was initialized. The database can be pruned on such nodes. ## High-level overview -At a high level, the ZKsync node can be seen as an application that has the following modules: +At a high level, the Node can be seen as an application that has the following modules: - API server that provides the publicly available Web3 interface. -- Consensus layer that interacts with the peer network and retrieves transactions and blocks to re-execute. +- Consensus layer (ZKsync Era only for now) that interacts with the peer network and retrieves transactions and blocks + to re-execute. - Sequencer component that actually executes and persists transactions received from the synchronization layer. -- Several checker modules that ensure the consistency of the ZKsync node state. +- Several checker modules that ensure the consistency of the Node state. With the EN, you are able to: -- Locally recreate and verify the ZKsync Era mainnet/testnet state. -- Interact with the recreated state in a trustless way (in a sense that the validity is locally verified, and you should - not rely on a third-party API ZKsync Era provides). +- Locally recreate and verify a ZK Stack chain's, for example ZKsync Era's mainnet/testnet state. +- Interact with the recreated state in a trustless way. The validity is locally verified. - Use the Web3 API without having to query the main node. - Send L2 transactions (that will be proxied to the main node). @@ -43,12 +40,12 @@ With the EN, you _can not_: - Generate proofs. - Submit data to L1. -A more detailed overview of the EN's components is provided in the [components](06_components.md) section. +A more detailed overview of the Node's components is provided in the [components](06_components.md) section. ## API overview -API exposed by the ZKsync node strives to be Web3-compliant. If some method is exposed but behaves differently compared -to Ethereum, it should be considered a bug. Please [report][contact_us] such cases. +API exposed by the Node strives to be Web3-compliant. If some method is exposed but behaves differently compared to +Ethereum, it should be considered a bug. Please [report][contact_us] such cases. [contact_us]: https://zksync.io/contact @@ -58,42 +55,42 @@ Data getters in this namespace operate in the L2 space: require/return L2 block Available methods: -| Method | Notes | -| ----------------------------------------- | ---------------------------------------------------------------------------------- | -| `eth_blockNumber` | | -| `eth_chainId` | | -| `eth_call` | | -| `eth_estimateGas` | | -| `eth_gasPrice` | | -| `eth_newFilter` | Maximum amount of installed filters is configurable | -| `eth_newBlockFilter` | Same as above | -| `eth_newPendingTransactionsFilter` | Same as above | -| `eth_uninstallFilter` | | -| `eth_getLogs` | Maximum amount of returned entities can be configured | -| `eth_getFilterLogs` | Same as above | -| `eth_getFilterChanges` | Same as above | -| `eth_getBalance` | | -| `eth_getBlockByNumber` | | -| `eth_getBlockByHash` | | -| `eth_getBlockTransactionCountByNumber` | | -| `eth_getBlockTransactionCountByHash` | | -| `eth_getCode` | | -| `eth_getStorageAt` | | -| `eth_getTransactionCount` | | -| `eth_getTransactionByHash` | | -| `eth_getTransactionByBlockHashAndIndex` | | -| `eth_getTransactionByBlockNumberAndIndex` | | -| `eth_getTransactionReceipt` | | -| `eth_protocolVersion` | | -| `eth_sendRawTransaction` | | -| `eth_syncing` | ZKsync node is considered synced if it's less than 11 blocks behind the main node. | -| `eth_coinbase` | Always returns a zero address | -| `eth_accounts` | Always returns an empty list | -| `eth_getCompilers` | Always returns an empty list | -| `eth_hashrate` | Always returns zero | -| `eth_getUncleCountByBlockHash` | Always returns zero | -| `eth_getUncleCountByBlockNumber` | Always returns zero | -| `eth_mining` | Always returns false | +| Method | Notes | +| ----------------------------------------- | --------------------------------------------------------------------------- | +| `eth_blockNumber` | | +| `eth_chainId` | | +| `eth_call` | | +| `eth_estimateGas` | | +| `eth_gasPrice` | | +| `eth_newFilter` | Maximum amount of installed filters is configurable | +| `eth_newBlockFilter` | Same as above | +| `eth_newPendingTransactionsFilter` | Same as above | +| `eth_uninstallFilter` | | +| `eth_getLogs` | Maximum amount of returned entities can be configured | +| `eth_getFilterLogs` | Same as above | +| `eth_getFilterChanges` | Same as above | +| `eth_getBalance` | | +| `eth_getBlockByNumber` | | +| `eth_getBlockByHash` | | +| `eth_getBlockTransactionCountByNumber` | | +| `eth_getBlockTransactionCountByHash` | | +| `eth_getCode` | | +| `eth_getStorageAt` | | +| `eth_getTransactionCount` | | +| `eth_getTransactionByHash` | | +| `eth_getTransactionByBlockHashAndIndex` | | +| `eth_getTransactionByBlockNumberAndIndex` | | +| `eth_getTransactionReceipt` | | +| `eth_protocolVersion` | | +| `eth_sendRawTransaction` | | +| `eth_syncing` | Node is considered synced if it's less than 11 blocks behind the main node. | +| `eth_coinbase` | Always returns a zero address | +| `eth_accounts` | Always returns an empty list | +| `eth_getCompilers` | Always returns an empty list | +| `eth_hashrate` | Always returns zero | +| `eth_getUncleCountByBlockHash` | Always returns zero | +| `eth_getUncleCountByBlockNumber` | Always returns zero | +| `eth_mining` | Always returns false | ### PubSub @@ -153,5 +150,5 @@ Always refer to the documentation linked above to see the list of stabilized met ### `en` namespace -This namespace contains methods that ZKsync nodes call on the main node while syncing. If this namespace is enabled, -other ENs can sync from this node. +This namespace contains methods that Nodes call on the main node while syncing. If this namespace is enabled, other ENs +can sync from this node. diff --git a/docs/src/guides/external-node/02_configuration.md b/docs/src/guides/external-node/02_configuration.md index 5b8b7512eb3e..90da7c1eea79 100644 --- a/docs/src/guides/external-node/02_configuration.md +++ b/docs/src/guides/external-node/02_configuration.md @@ -1,7 +1,7 @@ -# ZkSync Node Configuration +# Node Configuration -This document outlines various configuration options for the EN. Currently, the ZKsync node requires the definition of -numerous environment variables. To streamline this process, we provide prepared configs for the ZKsync Era - for both +This document outlines various configuration options for the EN. Currently, the Node requires the definition of numerous +environment variables. To streamline this process, we provide prepared configs for the ZKsync Era - for both [mainnet](prepared_configs/mainnet-config.env) and [testnet](prepared_configs/testnet-sepolia-config.env). You can use these files as a starting point and modify only the necessary sections. @@ -10,7 +10,7 @@ default settings.** ## Database -The ZKsync node uses two databases: PostgreSQL and RocksDB. +The Node uses two databases: PostgreSQL and RocksDB. PostgreSQL serves as the main source of truth in the EN, so all the API requests fetch the state from there. The PostgreSQL connection is configured by the `DATABASE_URL`. Additionally, the `DATABASE_POOL_SIZE` variable defines the @@ -22,12 +22,12 @@ recommended to use an NVME SSD for RocksDB. RocksDB requires two variables to be ## L1 Web3 client -ZKsync node requires a connection to an Ethereum node. The corresponding env variable is `EN_ETH_CLIENT_URL`. Make sure -to set the URL corresponding to the correct L1 network (L1 mainnet for L2 mainnet and L1 sepolia for L2 testnet). +Node requires a connection to an Ethereum node. The corresponding env variable is `EN_ETH_CLIENT_URL`. Make sure to set +the URL corresponding to the correct L1 network (L1 mainnet for L2 mainnet and L1 sepolia for L2 testnet). -Note: Currently, the ZKsync node makes 2 requests to the L1 per L1 batch, so the Web3 client usage for a synced node -should not be high. However, during the synchronization phase the new batches would be persisted on the ZKsync node -quickly, so make sure that the L1 client won't exceed any limits (e.g. in case you use Infura). +Note: Currently, the Node makes 2 requests to the L1 per L1 batch, so the Web3 client usage for a synced node should not +be high. However, during the synchronization phase the new batches would be persisted on the Node quickly, so make sure +that the L1 client won't exceed any limits (e.g. in case you use Infura). ## Exposed ports @@ -50,13 +50,13 @@ the metrics, leave this port not configured, and the metrics won't be collected. There are variables that allow you to fine-tune the limits of the RPC servers, such as limits on the number of returned entries or the limit for the accepted transaction size. Provided files contain sane defaults that are recommended for -use, but these can be edited, e.g. to make the ZKsync node more/less restrictive. +use, but these can be edited, e.g. to make the Node more/less restrictive. ## JSON-RPC API namespaces There are 7 total supported API namespaces: `eth`, `net`, `web3`, `debug` - standard ones; `zks` - rollup-specific one; -`pubsub` - a.k.a. `eth_subscribe`; `en` - used by ZKsync nodes while syncing. You can configure what namespaces you want -to enable using `EN_API_NAMESPACES` and specifying namespace names in a comma-separated list. By default, all but the +`pubsub` - a.k.a. `eth_subscribe`; `en` - used by Nodes while syncing. You can configure what namespaces you want to +enable using `EN_API_NAMESPACES` and specifying namespace names in a comma-separated list. By default, all but the `debug` namespace are enabled. ## Logging and observability @@ -64,8 +64,8 @@ to enable using `EN_API_NAMESPACES` and specifying namespace names in a comma-se `MISC_LOG_FORMAT` defines the format in which logs are shown: `plain` corresponds to the human-readable format, while the other option is `json` (recommended for deployments). -`RUST_LOG` variable allows you to set up the logs granularity (e.g. make the ZKsync node emit fewer logs). You can read -about the format [here](https://docs.rs/env_logger/0.10.0/env_logger/#enabling-logging). +`RUST_LOG` variable allows you to set up the logs granularity (e.g. make the Node emit fewer logs). You can read about +the format [here](https://docs.rs/env_logger/0.10.0/env_logger/#enabling-logging). `MISC_SENTRY_URL` and `MISC_OTLP_URL` variables can be configured to set up Sentry and OpenTelemetry exporters. diff --git a/docs/src/guides/external-node/03_running.md b/docs/src/guides/external-node/03_running.md index caa528238aea..c59733825c4d 100644 --- a/docs/src/guides/external-node/03_running.md +++ b/docs/src/guides/external-node/03_running.md @@ -1,8 +1,9 @@ -# Running the ZkSync Node +# Running the Node > [!NOTE] > -> If you want to just run node with recommended default setting, please see the [quick start](00_quick_start.md) page. +> If you want to just run ZKSync node with recommended default setting, please see the [quick start](00_quick_start.md) +> page. This section assumes that you have prepared a configuration file as described on the [previous page](02_configuration.md). @@ -14,12 +15,14 @@ This configuration is approximate and should be considered as **minimal** requir - 32-core CPU - 64GB RAM - SSD storage (NVME recommended): - - Sepolia Testnet - 10GB ZKsync node + 50GB PostgreSQL (at the time of writing, will grow over time, so should be + - ZKsync Sepolia Testnet - 10GB Node + 50GB PostgreSQL (at the time of writing, will grow over time, so should be constantly monitored) - - Mainnet - 3TB ZKsync node + 8TB PostgreSQL (at the time of writing, will grow over time, so should be constantly + - ZKsync Mainnet - 3TB Node + 8TB PostgreSQL (at the time of writing, will grow over time, so should be constantly monitored) - 100 Mbps connection (1 Gbps+ recommended) +For smaller chains, less powerful hardware may be sufficient, especially in terms of disk space. + ## A note about PostgreSQL storage By far, the heaviest table to maintain is the `call_traces` table. This table is only required for the `debug` @@ -36,23 +39,23 @@ it in Docker. There are many of guides on that, [here's one example](https://www.docker.com/blog/how-to-use-the-postgres-docker-official-image/). Note however that if you run PostgresSQL as a stand-alone Docker image (e.g. not in Docker-compose with a network shared -between ZKsync node and Postgres), ZKsync node won't be able to access Postgres via `localhost` or `127.0.0.1` URLs. To -make it work, you'll have to either run it with a `--network host` (on Linux) or use `host.docker.internal` instead of -`localhost` in the ZKsync node configuration ([official docs][host_docker_internal]). +between Node and Postgres), Node won't be able to access Postgres via `localhost` or `127.0.0.1` URLs. To make it work, +you'll have to either run it with a `--network host` (on Linux) or use `host.docker.internal` instead of `localhost` in +the Node configuration ([official docs][host_docker_internal]). Besides running Postgres, you are expected to have a DB dump from a corresponding env. You can restore it using `pg_restore -O -C --dbname=`. You can also refer to -[ZKsync Node configuration management blueprint](https://github.com/matter-labs/zksync-era/blob/main/docs/guides/external-node/00_quick_start.md#advanced-setup) +[Node configuration management blueprint](https://github.com/matter-labs/zksync-era/blob/main/docs/src/guides/external-node/00_quick_start.md#advanced-setup) for advanced DB instance configurations. [host_docker_internal](https://docs.docker.com/desktop/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host) ## Running -Assuming you have the ZKsync node Docker image, an env file with the prepared configuration, and you have restored your -DB with the pg dump, that is all you need. +Assuming you have the Node Docker image, an env file with the prepared configuration, and you have restored your DB with +the pg dump, that is all you need. Sample running command: @@ -69,9 +72,9 @@ in RocksDB (mainly the Merkle tree) is absent. Before the node can make any prog RocksDB and verify consistency. The exact time required for that depends on the hardware configuration, but it is reasonable to expect the state rebuild on the mainnet to take more than 20 hours. -## Redeploying the ZKsync node with a new PG dump +## Redeploying the Node with a new PG dump -If you've been running the ZKsync node for some time and are going to redeploy it using a new PG dump, you should +If you've been running the Node for some time and are going to redeploy it using a new PG dump, you should - Stop the EN - Remove SK cache (corresponding to `EN_STATE_CACHE_PATH`) diff --git a/docs/src/guides/external-node/04_observability.md b/docs/src/guides/external-node/04_observability.md index 05b39b74c5d2..cdf0f9dd25f8 100644 --- a/docs/src/guides/external-node/04_observability.md +++ b/docs/src/guides/external-node/04_observability.md @@ -1,6 +1,6 @@ -# ZKsync node Observability +# Node Observability -The ZKsync node provides several options for setting up observability. Configuring logs and sentry is described in the +The Node provides several options for setting up observability. Configuring logs and sentry is described in the [configuration](02_configuration.md) section, so this section focuses on the exposed metrics. This section is written with the assumption that you're familiar with @@ -16,8 +16,8 @@ By default, latency histograms are distributed in the following buckets (in seco ## Metrics -ZKsync node exposes a lot of metrics, a significant amount of which aren't interesting outside the development flow. -This section's purpose is to highlight metrics that may be worth observing in the external setup. +Node exposes a lot of metrics, a significant amount of which aren't interesting outside the development flow. This +section's purpose is to highlight metrics that may be worth observing in the external setup. If you are not planning to scrape Prometheus metrics, please unset `EN_PROMETHEUS_PORT` environment variable to prevent memory leaking. @@ -25,7 +25,7 @@ memory leaking. | Metric name | Type | Labels | Description | | ---------------------------------------------- | --------- | ------------------------------------- | ------------------------------------------------------------------ | | `external_node_synced` | Gauge | - | 1 if synced, 0 otherwise. Matches `eth_call` behavior | -| `external_node_sync_lag` | Gauge | - | How many blocks behind the main node the ZKsync node is | +| `external_node_sync_lag` | Gauge | - | How many blocks behind the main node the Node is | | `external_node_fetcher_requests` | Histogram | `stage`, `actor` | Duration of requests performed by the different fetcher components | | `external_node_fetcher_cache_requests` | Histogram | - | Duration of requests performed by the fetcher cache layer | | `external_node_fetcher_miniblock` | Gauge | `status` | The number of the last L2 block update fetched from the main node | diff --git a/docs/src/guides/external-node/05_troubleshooting.md b/docs/src/guides/external-node/05_troubleshooting.md index 43d6ae26b135..49369897143f 100644 --- a/docs/src/guides/external-node/05_troubleshooting.md +++ b/docs/src/guides/external-node/05_troubleshooting.md @@ -1,8 +1,8 @@ -# ZKsync node Troubleshooting +# Node Troubleshooting -The ZKsync node tries to follow the fail-fast principle: if an anomaly is discovered, instead of attempting state -recovery, in most cases it will restart. Most of the time it will manifest as crashes, and if it happens once, it -shouldn't be treated as a problem. +The Node tries to follow the fail-fast principle: if an anomaly is discovered, instead of attempting state recovery, in +most cases it will restart. Most of the time it will manifest as crashes, and if it happens once, it shouldn't be +treated as a problem. However, if the node enters the crash loop or otherwise behaves unexpectedly, it may indicate either a bug in the implementation or a problem with configuration. This section tries to cover common problems. @@ -24,8 +24,8 @@ Other kinds of panic aren't normally expected. While in most cases, the state wi ## Genesis Issues -The ZKsync node is supposed to start with an applied DB dump. If you see any genesis-related errors, it probably means -the ZKsync node was started without an applied dump. +The Node is supposed to start with an applied DB dump. If you see any genesis-related errors, it probably means the Node +was started without an applied dump. [contact_us]: https://zksync.io/contact @@ -43,7 +43,7 @@ you don't consider actionable, you may disable logs for a component by tweaking | WARN | "Following transport error occurred" | There was a problem with fetching data from the main node. | | WARN | "Unable to get the gas price" | There was a problem with fetching data from the main node. | | WARN | "Consistency checker error" | There are problems querying L1, check the Web3 URL you specified in the config. | -| WARN | "Reorg detected" | Reorg was detected on the main node, the ZKsync node will rollback and restart | +| WARN | "Reorg detected" | Reorg was detected on the main node, the Node will rollback and restart | Same as with panics, normally it's only a problem if a WARN+ level log appears many times in a row. diff --git a/docs/src/guides/external-node/06_components.md b/docs/src/guides/external-node/06_components.md index 733400058a82..ec6ff4f9936a 100644 --- a/docs/src/guides/external-node/06_components.md +++ b/docs/src/guides/external-node/06_components.md @@ -1,58 +1,56 @@ -# ZKsync node components +# Node components This section contains an overview of the EN's main components. ## API -The ZKsync node can serve both the HTTP and the WS Web3 API, as well as PubSub. Whenever possible, it provides data -based on the local state, with a few exceptions: +The Node can serve both the HTTP and the WS Web3 API, as well as PubSub. Whenever possible, it provides data based on +the local state, with a few exceptions: - Submitting transactions: Since it is a read replica, submitted transactions are proxied to the main node, and the - response is returned from the main node. -- Querying transactions: The ZKsync node is not aware of the main node's mempool, and it does not sync rejected - transactions. Therefore, if a local lookup for a transaction or its receipt fails, the ZKsync node will attempt the - same query on the main node. + response is returned from the main node. -[06_components.md](06_components.md) Querying transactions: The Node is not + aware of the main node's mempool, and it does not sync rejected transactions. Therefore, if a local lookup for a + transaction or its receipt fails, the Node will attempt the same query on the main node. Apart from these cases, the API does not depend on the main node. Even if the main node is temporarily unavailable, the -ZKsync node can continue to serve the state it has locally. +Node can continue to serve the state it has locally. ## Fetcher -The Fetcher component is responsible for maintaining synchronization between the ZKsync node and the main node. Its -primary task is to fetch new blocks in order to update the local chain state. However, its responsibilities extend -beyond that. For instance, the Fetcher is also responsible for keeping track of L1 batch statuses. This involves -monitoring whether locally applied batches have been committed, proven, or executed on L1. +The Fetcher component is responsible for maintaining synchronization between the Node and the main node. Its primary +task is to fetch new blocks in order to update the local chain state. However, its responsibilities extend beyond that. +For instance, the Fetcher is also responsible for keeping track of L1 batch statuses. This involves monitoring whether +locally applied batches have been committed, proven, or executed on L1. -It is worth noting that in addition to fetching the _state_, the ZKsync node also retrieves the L1 gas price from the -main node for the purpose of estimating fees for L2 transactions (since this also happens based on the local state). -This information is necessary to ensure that gas estimations are performed in the exact same manner as the main node, -thereby reducing the chances of a transaction not being included in a block. +It is worth noting that in addition to fetching the _state_, the Node also retrieves the L1 gas price from the main node +for the purpose of estimating fees for L2 transactions (since this also happens based on the local state). This +information is necessary to ensure that gas estimations are performed in the exact same manner as the main node, thereby +reducing the chances of a transaction not being included in a block. ## State Keeper / VM The State Keeper component serves as the "sequencer" part of the node. It shares most of its functionality with the main node, with one key distinction. The main node retrieves transactions from the mempool and has the authority to decide -when a specific L2 block or L1 batch should be sealed. On the other hand, the ZKsync node retrieves transactions from -the queue populated by the Fetcher and seals the corresponding blocks/batches based on the data obtained from the -Fetcher queue. +when a specific L2 block or L1 batch should be sealed. On the other hand, the Node retrieves transactions from the queue +populated by the Fetcher and seals the corresponding blocks/batches based on the data obtained from the Fetcher queue. -The actual execution of batches takes place within the VM, which is identical in both the Main and ZKsync nodes. +The actual execution of batches takes place within the VM, which is identical in both the Main and Nodes. ## Reorg Detector -In ZKsync Era, it is theoretically possible for L1 batches to be reverted before the corresponding "execute" operation -is applied on L1, that is before the block is [final][finality]. Such situations are highly uncommon and typically occur -due to significant issues: e.g. a bug in the sequencer implementation preventing L1 batch commitment. Prior to batch -finality, the ZKsync operator can perform a rollback, reverting one or more batches and restoring the blockchain state -to a previous point. Finalized batches cannot be reverted at all. +In a ZK Stack chain, it is theoretically possible for L1 batches to be reverted before the corresponding "execute" +operation is applied on L1, that is before the block is [final][finality]. Such situations are highly uncommon and +typically occur due to significant issues: e.g. a bug in the sequencer implementation preventing L1 batch commitment. +Prior to batch finality, the chain operator can perform a rollback, reverting one or more batches and restoring the +blockchain state to a previous point. Finalized batches cannot be reverted at all. -However, even though such situations are rare, the ZKsync node must handle them correctly. +However, even though such situations are rare, the Node must handle them correctly. -To address this, the ZKsync node incorporates a Reorg Detector component. This module keeps track of all L1 batches that -have not yet been finalized. It compares the locally obtained state root hashes with those provided by the main node's -API. If the root hashes for the latest available L1 batch do not match, the Reorg Detector searches for the specific L1 -batch responsible for the divergence. Subsequently, it rolls back the local state and restarts the node. Upon restart, -the EN resumes normal operation. +To address this, the Node incorporates a Reorg Detector component. This module keeps track of all L1 batches that have +not yet been finalized. It compares the locally obtained state root hashes with those provided by the main node's API. +If the root hashes for the latest available L1 batch do not match, the Reorg Detector searches for the specific L1 batch +responsible for the divergence. Subsequently, it rolls back the local state and restarts the node. Upon restart, the EN +resumes normal operation. [finality]: https://docs.zksync.io/zk-stack/concepts/finality @@ -67,13 +65,12 @@ When the Consistency Checker detects that a particular batch has been sent to L1 known as the "block commitment" for the L1 transaction. The block commitment contains crucial data such as the state root and batch number, and is the same commitment that is used for generating a proof for the batch. The Consistency Checker then compares the locally obtained commitment with the actual commitment sent to L1. If the data does not match, -it indicates a potential bug in either the main node or ZKsync node implementation or that the main node API has -provided incorrect data. In either case, the state of the ZKsync node cannot be trusted, and the ZKsync node enters a -crash loop until the issue is resolved. +it indicates a potential bug in either the main node or Node implementation or that the main node API has provided +incorrect data. In either case, the state of the Node cannot be trusted, and the Node enters a crash loop until the +issue is resolved. ## Health check server -The ZKsync node also exposes an additional server that returns HTTP 200 response when the ZKsync node is operating -normally, and HTTP 503 response when some of the health checks don't pass (e.g. when the ZKsync node is not fully -initialized yet). This server can be used, for example, to implement the readiness probe in an orchestration solution -you use. +The Node also exposes an additional server that returns HTTP 200 response when the Node is operating normally, and HTTP +503 response when some of the health checks don't pass (e.g. when the Node is not fully initialized yet). This server +can be used, for example, to implement the readiness probe in an orchestration solution you use. diff --git a/docs/src/guides/external-node/07_snapshots_recovery.md b/docs/src/guides/external-node/07_snapshots_recovery.md index 0053717af063..ecab9c3702df 100644 --- a/docs/src/guides/external-node/07_snapshots_recovery.md +++ b/docs/src/guides/external-node/07_snapshots_recovery.md @@ -39,10 +39,10 @@ error mentioning the first locally retained block or L1 batch if queried this mi used for [pruning](08_pruning.md) because logically, recovering from a snapshot is equivalent to pruning node storage to the snapshot L1 batch. -## Configuration +## Configuration (for ZKsync Era) -To enable snapshot recovery on mainnet, you need to set environment variables for a node before starting it for the -first time: +To enable snapshot recovery on ZKsync mainnet, you need to set environment variables for a node before starting it for +the first time: ```yaml EN_SNAPSHOTS_RECOVERY_ENABLED: 'true' @@ -50,7 +50,7 @@ EN_SNAPSHOTS_OBJECT_STORE_BUCKET_BASE_URL: 'zksync-era-mainnet-external-node-sna EN_SNAPSHOTS_OBJECT_STORE_MODE: 'GCSAnonymousReadOnly' ``` -For the Sepolia testnet, use: +For the ZKsync Sepolia testnet, use: ```yaml EN_SNAPSHOTS_RECOVERY_ENABLED: 'true' @@ -58,7 +58,7 @@ EN_SNAPSHOTS_OBJECT_STORE_BUCKET_BASE_URL: 'zksync-era-boojnet-external-node-sna EN_SNAPSHOTS_OBJECT_STORE_MODE: 'GCSAnonymousReadOnly' ``` -For a working examples of a fully configured Nodes recovering from snapshots, see +For a working examples of a fully configured ZKsync Nodes recovering from snapshots, see [Docker Compose examples](docker-compose-examples) and [_Quick Start_](00_quick_start.md). If a node is already recovered (does not matter whether from a snapshot or from a Postgres dump), setting these env diff --git a/docs/src/guides/external-node/08_pruning.md b/docs/src/guides/external-node/08_pruning.md index 06bd9f8d8a9d..7bb1a64dbed8 100644 --- a/docs/src/guides/external-node/08_pruning.md +++ b/docs/src/guides/external-node/08_pruning.md @@ -1,9 +1,8 @@ # Pruning -It is possible to configure a ZKsync node to periodically prune all data from L1 batches older than a configurable -threshold. Data is pruned both from Postgres and from tree (RocksDB). Pruning happens continuously (i.e., does not -require stopping the node) in the background during normal node operation. It is designed to not significantly impact -node performance. +It is possible to configure a Node to periodically prune all data from L1 batches older than a configurable threshold. +Data is pruned both from Postgres and from tree (RocksDB). Pruning happens continuously (i.e., does not require stopping +the node) in the background during normal node operation. It is designed to not significantly impact node performance. Types of pruned data in Postgres include: diff --git a/docs/src/guides/external-node/09_treeless_mode.md b/docs/src/guides/external-node/09_treeless_mode.md index ceeea6f86c67..05062c30abef 100644 --- a/docs/src/guides/external-node/09_treeless_mode.md +++ b/docs/src/guides/external-node/09_treeless_mode.md @@ -1,10 +1,10 @@ # Treeless Operation Mode -Normally, a ZKsync node needs to run the Merkle tree component (aka _metadata calculator_) in order to compute L1 batch -state root hashes. A state root hash from the previous batch can be accessed by L2 contracts, so processing transactions -in an L1 batch cannot start until the state root hash of the previous L1 batch is computed. Merkle tree requires -non-trivial storage space and RAM (roughly 3 TB and 32 GB respectively for an archival mainnet node as of July 2024). -While storage and RAM requirements can be significantly lowered with [snapshot recovery](07_snapshots_recovery.md) and +Normally, a Node needs to run the Merkle tree component (aka _metadata calculator_) in order to compute L1 batch state +root hashes. A state root hash from the previous batch can be accessed by L2 contracts, so processing transactions in an +L1 batch cannot start until the state root hash of the previous L1 batch is computed. Merkle tree requires non-trivial +storage space and RAM (roughly 3 TB and 32 GB respectively for an archival mainnet node as of July 2024). While storage +and RAM requirements can be significantly lowered with [snapshot recovery](07_snapshots_recovery.md) and [pruning](08_pruning.md), **treeless operation mode** allows to run a node without a local Merkle tree instance at all. ## How it works diff --git a/docs/src/guides/external-node/10_decentralization.md b/docs/src/guides/external-node/10_decentralization.md index 951538e6ab86..7f301cfbf045 100644 --- a/docs/src/guides/external-node/10_decentralization.md +++ b/docs/src/guides/external-node/10_decentralization.md @@ -1,8 +1,8 @@ # Decentralization -In the default setup, the ZKsync node will fetch data from the ZKsync API endpoint maintained by Matter Labs. To reduce -the reliance on this centralized endpoint we have developed a decentralized p2p networking stack (aka gossipnet) which -will eventually be used instead of ZKsync API for synchronizing data. +In the default setup, the Node will fetch data from the ZKsync API endpoint maintained by Matter Labs. To reduce the +reliance on this centralized endpoint we have developed a decentralized p2p networking stack (aka gossipnet) which will +eventually be used instead of ZKsync API for synchronizing data. On the gossipnet, the data integrity will be protected by the BFT (byzantine fault-tolerant) consensus algorithm (currently data is signed just by the main node though). @@ -35,9 +35,9 @@ chmod 600 consensus_secrets.yaml ### Preparing configuration file Copy the template of the consensus configuration file (for -[mainnet](https://github.com/matter-labs/zksync-era/blob/main/docs/guides/external-node/prepared_configs/mainnet_consensus_config.yaml) +[mainnet](https://github.com/matter-labs/zksync-era/blob/main/docs/src/guides/external-node/prepared_configs/mainnet_consensus_config.yaml) or -[testnet](https://github.com/matter-labs/zksync-era/blob/main/docs/guides/external-node/prepared_configs/testnet_consensus_config.yaml) +[testnet](https://github.com/matter-labs/zksync-era/blob/main/docs/src/guides/external-node/prepared_configs/testnet_consensus_config.yaml) ). > [!NOTE] diff --git a/docs/src/guides/external-node/11_setup_for_other_chains.md b/docs/src/guides/external-node/11_setup_for_other_chains.md new file mode 100644 index 000000000000..9d1c88ea91be --- /dev/null +++ b/docs/src/guides/external-node/11_setup_for_other_chains.md @@ -0,0 +1,50 @@ +# Steps to modify the docker-compose files to support Other Chains + +Below are the steps for adjusting ZKsync Era docker-compose files from [here](00_quick_start.md) to support chains other +than ZKsync Era. + +> [!NOTE] +> +> If you want to run Node for a given chain, you can first ask the company hosting the chains for the Dockerfiles. + +## 1. Update `EN_L2_CHAIN_ID` + +The `EN_L2_CHAIN_ID` environment variable specifies the Layer 2 chain ID of the blockchain. + +You can get it using main node rpc call `eth_chainId` or by asking the company hosting the chain. For example: + +``` +curl -X POST https://mainnet.era.zksync.io \ +-H "Content-Type: application/json" \ +-d '{"jsonrpc": "2.0", "method": "eth_chainId", "params": [], "id": 1}' +``` + +returns + +``` +{ "jsonrpc": "2.0", "result": "0x144", "id": 1} +``` + +where `0x144` is the chain ID (324 in decimal) + +## 2. Update `EN_MAIN_NODE_URL` + +The `EN_MAIN_NODE_URL` The EN_MAIN_NODE_URL environment variable should point to the main node URL of the target chain + +## 3. Update snapshots recovery settings + +Snapshots recovery is a feature that allows faster Node startup at the cost of no transaction history. By default the +ZKsync Era docker-compose file has this feature enabled, but it's only recommended to use if the Node first startup time +is too slow. It can be disabled by changing `EN_SNAPSHOTS_RECOVERY_ENABLED` to `false` + +If you want to keep this feature enabled for a Node, ask the company hosting the chain for the bucket name where the +snapshots are stored and update the value of `EN_SNAPSHOTS_OBJECT_STORE_BUCKET_BASE_URL` + +## 4. Disable consensus + +Chains other than ZKsync Era aren't currently running consensus(as of December 2024). You need to disable it by removing +`--enable-consensus` flag from `entrypoint.sh` invocation in docker-compose + +## 5. (Validium chains only) Set `EN_L1_BATCH_COMMIT_DATA_GENERATOR_MODE` + +For validium chains, you need to set `EN_L1_BATCH_COMMIT_DATA_GENERATOR_MODE: "Validium"`