Validium in ZK Stack

Dive deeper into the ZK Stack's Validiums, learn how to operate and configure them.

This section provides an in-depth exploration of Validiums in ZK Stack. For more general overview of Validiums, see here.

What kinds of Validium are there

We define 3 different kinds of Validiums based on the level of data availability they provide:

  • Stage 0 - the simplest type of Validium that only stores the pubdata in the database of the node(s) running the chain
  • Stage 1 - a Validium that only sends the data to the DA layer, but doesn’t verify its inclusion
  • Stage 2 - a Validium that sends the data to the DA layer, and also verifies its inclusion on L1 either by using the verification bridges or zk-proofs directly.

There are multiple DA layers that we are going to integrate with, the first on the list are: Avail, Celestia, EigenDA.

Getting a bit deeper into the technicalities, the process of persisting the pubdata in the different DA layers is handled by two components: DA dispatcher and DA client:

  • DA client’s role is to abstract the access to the DA layer and generalize it to 2 functions: dispatch_blob and get_inclusion_data. Clients are a part of the zksync-era repository, see the code here.
  • DA dispatcher is responsible for periodically fetching the pubdata from the database, and calling the DA client either to dispatch a blob or get an inclusion proofs. It also handles retries in case the client function call failed with a retryable error.

The DA related information is stored in the data_availability table in the database, Validium’s new batches can’t be committed if their inclusion data in that table is NULL.

Configuration

The Validium chain is required to have the following configuration:

  1. Set a pubdata sending mode general.yaml
    • pubdata_sending_mode: CUSTOM
  2. Configure DA dispatcher (reference values below) general.yaml
    da_dispatcher:
      polling_interval_ms: 5000
      max_rows_to_dispatch: 100
      max_retries: 5
    
  3. Add DA client’s config and secrets, see FAQ for details.

All the configs can also be set using environment variables instead of .yaml files, but it is less preferred.

Smart contracts

DA inclusion verification contracts are only going to be available in ZK Gateway release, which is planned to go live in Q1 2025.

The DA inclusion verification consist of 2 different steps, with a corresponding smart contract responsible for each of them:

  1. Committing to the pubdata - L2DAValidator
  2. Using a commitment and a data provided by the operator to verify that the pubdata was included in the DA layer - L1DAValidator

The commitment is passed from L2DAValidator to L1DAValidator via L2→L1 logs, this happens within the system contracts’ execution, so this process can be trusted as it is covered by ZK proof. The format of the commitment is arbitrary, it is up to the L2DAValidator to decide what is the one that suits the specific DA layer the most.

The L1DAValidator implementations may have different logic from DA layer to DA layer, our protocol only requires it to return whether the commitment and proof pair is valid. There are 2 approaches that can be used here: verification bridges and ZK poofs.

  • Verification bridges: these are the smart contracts that gets updated with the state roots of the specific DA layers. They utilize the ZK proofs to verify the validity of the provided state roots. Later on, the verification bridges are called from L1DAValidator contract and normally use Merkle-proofs to verify against the known state roots.
  • ZK proofs: similarly to the verification bridges, we can utilize ZK proofs here, but directly in the L1DAValidator. If we go a step further and do the ZK proof that has the following
    • complete the asserts that verification bridges do to ensure the validity of the state root
    • verify that the pubdata commitment relates to the data included in the data root of some specific block
    • verify that the data root is included in the state root

    we would be able to only verify that proof without the need for additional checks against the bridges. This solution is especially relevant with DA layers that use the commitments that are inefficient to produce on L2.

The chain operator would be able to change the implementations of the L1/L2DAValidators, which allows for applying updates/optimizations or completely changing the DA verification logic, e.g. due to migration to the different DA layer.

FAQ

How do I set up the new Validium chain locally?
  1. Install zkstack following this guide
  2. zkstack dev clean all - to make sure you have an empty setup
  3. zkstack containers - this creates the necessary docker containers
  4. zkstack ecosystem init - init a default ecosystem (go with default options everywhere)
  5. zkstack chain create - create a new chain, stick to the default options, but select Validium when prompted, use this chain as default (the last question there)
  6. zkstack chain init - init the new chain
  7. configure the client, see the sections below
  8. zkstack server --chain YOUR_CHAIN_NAME - run the server
How to configure Avail client?
  1. Add the following block to the general.yaml, values used are only an example:
    • Full client:
      da_client:
        avail:
          bridge_api_url: https://bridge.somedomain.com
          timeout_ms: 10000
          full_client:
            api_node_url: wss://turing-rpc.avail.so/ws
            app_id: 1
      
    • Gas relay:
      da_client:
        avail:
          bridge_api_url: https://bridge.somedomain.com
          timeout_ms: 10000
          gas_relay:
            gas_relay_api_url: https://gas-relay.domain.com
            max_retries: 5
      
  2. Add the following block to the secrets.yaml:
    • Full client
      da:
        avail:
          seed_phrase: YOUR_SEED_PHRASE
      
    • Gas relay
      da:
        avail:
          gas_relay_api_key: YOUR_API_KEY
      
How to configure Celestia client?
  1. Add the following block to the general.yaml, values used are only an example:
     da_client:
       celestia:
         api_node_url: https://api-node.somedomain.com
         namespace: 000000000000000000000000000000000000ca1de12a5e2d5beb9ba9
         chain_id: mocha-4
         timeout_ms: 30000
    
  2. Add the following block to the secrets.yaml:
    da:
      celestia:
        private_key: YOUR_PRIVATE_KEY
    
How to configure EigenDA client?
  1. Add the following block to the general.yaml, values used are only an example:
    da_client:
      eigen:
        rpc_node_url: https://disperser-holesky.eigenda.xyz:443
        inclusion_polling_interval_ms: 2000
    
  2. Add the following block to the secrets.yaml:
    da:
      eigen:
        private_key: YOUR_PRIVATE_KEY
    
Is it possible to switch DA layers?

Yes, it is possible.

  • For stage 0 and stage 1 Validiums it is enough to change the client configuration and secrets.
  • For stage 2 Validiums, the operator would need to deploy new L1/L2DAValidator contracts and change their addresses in the contracts that call them.

The exact details will be provided later, when the process is fully established.

Is it possible to transition from Validium to Rollup and vice versa?

Yes, it is possible, the process would be the same as switching DA layers.

Rollup L1/L2 DA validators are the same kind of contracts as the Validium ones, as they are also an implementations of the same interface, so the procedure wouldn't differ a lot.


Made with ❤️ by the ZKsync Community