aligned_layer

module
v0.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 10, 2024 License: MIT

README

Aligned

[!CAUTION] To be used in testnet only.

Table of Contents

The Project

Aligned works with EigenLayer to leverage ethereum consensus mechanism for ZK proof verification. Working outside the EVM, this allows for cheap verification of any proving system. This enables the usage of cutting edge algorithms, that may use new techniques to prove even faster. Even more, proving systems that reduce the proving overhead and add verifier overhead, now become economically feasable to verify thanks to Aligned.

How to use the testnet

Requirements

To install the batcher client to send proofs in the testnet, run:

make install_aligned
Run
SP1 proof

The SP1 proof needs the proof file and the vm program file.

aligned \
--proving_system <SP1|GnarkPlonkBn254|GnarkPlonkBls12_381|Groth16Bn254> \
--proof <proof_file> \
--vm_program <vm_program_file> \
--conn wss://batcher.alignedlayer.com \
--proof_generator_addr [proof_generator_addr]

Example

aligned \
--proving_system SP1 \
--proof ./batcher/client/test_files/sp1/sp1_fibonacci.proof \
--vm_program ./batcher/client/test_files/sp1/sp1_fibonacci-elf \
--conn wss://batcher.alignedlayer.com
GnarkPlonkBn254, GnarkPlonkBls12_381 and Groth16Bn254

The GnarkPlonkBn254, GnarkPlonkBls12_381 and Groth16Bn254 proofs need the proof file, the public input file and the verification key file.

aligned \
--proving_system <SP1|GnarkPlonkBn254|GnarkPlonkBls12_381|Groth16Bn254> \
--proof <proof_file> \
--public_input <public_input_file> \
--vk <verification_key_file> \
--conn wss://batcher.alignedlayer.com \
--proof_generator_addr [proof_generator_addr]

Examples

aligned \
--proving_system GnarkPlonkBn254 \
--proof ./batcher/client/test_files/plonk_bn254/plonk.proof \
--public_input ./batcher/client/test_files/plonk_bn254/plonk_pub_input.pub \
--vk ./batcher/client/test_files/plonk_bn254/plonk.vk \
--conn wss://batcher.alignedlayer.com
aligned \
--proving_system GnarkPlonkBls12_381 \
--proof ./batcher/client/test_files/plonk_bls12_381/plonk.proof \
--public_input ./batcher/client/test_files/plonk_bls12_381/plonk_pub_input.pub \
--vk ./batcher/client/test_files/plonk_bls12_381/plonk.vk \
--conn wss://batcher.alignedlayer.com
aligned \
--proving_system Groth16Bn254 \
--proof ./batcher/client/test_files/groth16/ineq_1_groth16.proof \
--public_input ./batcher/client/test_files/groth16/ineq_1_groth16.pub \
--vk ./batcher/client/test_files/groth16/ineq_1_groth16.vk \
--conn wss://batcher.alignedlayer.com

Local Devnet Setup

Dependencies

Ensure you have the following installed:

To install Go, Rust, jq and yq go to the provided links and follow the instructions.

Install Go dependencies (zap-pretty, abigen, eigenlayer-cli):

make go_deps

Install Foundry:

make install_foundry
foundryup

Install necessary submodules and build all the FFIs for your OS:

make deps

If you want to rebuild the FFIs you can use:

make build_all_ffi
Booting Devnet with Default configs

Before starting you need to setup an S3 bucket. More data storage will be tested in the future.

You need to fill the data in:

batcher/.env

And you can use this file as an example on how to fill it:

batcher/.env.example

After having the env setup, run in different terminals the following commands to boot Aligned locally:

make anvil_start_with_block_time
make aggregator_start
make operator_register_and_start
make batcher_start

If you need to start again the operator, and it's already registered, use:

make operator_start

If you want to start the explorer for the devnet, see how to run it using it's documentation below.

Send test proofs to batcher for testing

All these proofs are for testing purposes

Send 8 proofs each second:

make batcher_send_burst_groth16

Send Groth 16 proofs each 2 seconds:

make batcher_send_infinite_groth16

Send an individual Groth 16 proof:

make batcher_send_groth16_task

To send an individual test SP1 proof:

make batcher_send_sp1_task
Detailed Testnet Deployment
Changing operator keys

Operator keys can be changed if needed.

To create a keystore, run:

cast wallet new-mnemonic
cast wallet import <keystore-name> --private-key <private-key>

To create an ECDSA keystore, run:

eigenlayer operator keys import --key-type ecdsa <keystore-name> <private-key>

To create a BLS keystore, run:

eigenlayer operator keys import --key-type bls <keystore-name> <private-key>
Aggregator

If you want to run the aggregator with the default configuration, run:

make aggregator_start

To start the aggregator with a custom configuration, run:

make aggregator_start CONFIG_FILE=<path_to_config_file>
Operator

Operator needs to register in both EigenLayer and Aligned. Then it can start verifying proofs.

Register into EigenLayer

To register an operator in EigenLayer Devnet with the default configuration, run:

make operator_register_with_eigen_layer

To register an operator in EigenLayer with a custom configuration, run:

make operator_register_with_eigen_layer CONFIG_FILE=<path_to_config_file>
Register into Aligned

To register an operator in Aligned with the default configuration, run:

make operator_register_with_aligned_layer

To register an operator in Aligned with a custom configuration, run:

make operator_register_with_aligned_layer CONFIG_FILE=<path_to_config_file>
Full Registration in Anvil with one command

To register an operator in EigenLayer and Aligned and deposit strategy tokens in EigenLayer with the default configuration, run:

make operator_full_registration

To register an operator in EigenLayer and Aligned and deposit strategy tokens in EigenLayer with a custom configuration, run:

make operator_full_registration CONFIG_FILE=<path_to_config_file>
Deposit Strategy Tokens in Anvil local devnet

There is an ERC20 token deployed in the Anvil chain to use as strategy token with EigenLayer.

To deposit strategy tokens in the Anvil chain with the default configuration, run:

make operator_mint_mock_tokens
make operator_deposit_into_mock_strategy

To deposit strategy tokens in the Anvil chain with a custom configuration, run:

make operator_mint_mock_tokens CONFIG_FILE=<path_to_config_file>
make operator_deposit_into_mock_strategy CONFIG_FILE=<path_to_config_file>
Deposit Strategy tokens in Holesky/Mainnet

EigenLayer strategies are available in eigenlayer-strategies.

For Holesky, we are using WETH as the strategy token.

To obtain HolETH and swap it for different strategies, you can use the following guide.

Config

There is a default configuration for devnet purposes in config-files/config.yaml. Also, there are 3 different configurations for the operator in config-files/devnet/operator-1.yaml, config-files/devnet/operator-2.yaml and config-files/devnet/operator-3.yaml.

The configuration file has the following structure:

# Common variables for all the services
# 'production' only prints info and above. 'development' also prints debug
environment: <production/development>
aligned_layer_deployment_config_file_path: <path_to_aligned_layer_deployment_config_file>
eigen_layer_deployment_config_file_path: <path_to_eigen_layer_deployment_config_file>
eth_rpc_url: <http_rpc_url>
eth_ws_url: <ws_rpc_url>
eigen_metrics_ip_port_address: <ip:port>

## ECDSA Configurations
ecdsa:
  private_key_store_path: <path_to_ecdsa_private_key_store>
  private_key_store_password: <ecdsa_private_key_store_password>

## BLS Configurations
bls:
  private_key_store_path: <path_to_bls_private_key_store>
  private_key_store_password: <bls_private_key_store_password>

## Operator Configurations
operator:
  aggregator_rpc_server_ip_port_address: <ip:port> # This is the aggregator url
  address: <operator_address>
  earnings_receiver_address: <earnings_receiver_address> # This is the address where the operator will receive the earnings, it can be the same as the operator address
  delegation_approver_address: "0x0000000000000000000000000000000000000000"
  staker_opt_out_window_blocks: 0
  metadata_url: "https://yetanotherco.github.io/operator_metadata/metadata.json"
# Operators variables needed for register it in EigenLayer
el_delegation_manager_address: <el_delegation_manager_address> # This is the address of the EigenLayer delegationManager
private_key_store_path: <path_to_bls_private_key_store>
bls_private_key_store_path: <bls_private_key_store_password>
signer_type: local_keystore
chain_id: <chain_id>
Run

If you want to run the operator with the default configuration, run:

make operator_start

To start the operator with a custom configuration, run:

make operator_start CONFIG_FILE=<path_to_config_file>
Batcher
Config

To run the batcher, you will need to set environment variables in a .env file in the same directory as the batcher (batcher/).

The necessary environment variables are:

Variable Name Description
AWS_SECRET_ACCESS_KEY Secret key to authenticate and authorize API requests to the AWS S3 Bucket.
AWS_REGION Geographical region where the AWS S3 Bucket will be accessed.
AWS_ACCESS_KEY_ID Access key used in combination with the AWS_SECRET_ACCESS_KEY to authenticate and authorize API requests to the AWS S3 Bucket.
AWS_BUCKET_NAME Name of the AWS S3 Bucket.
RUST_LOG Rust log level (info, debug, error, warn, etc.).

You can find an example .env file in .env.example

You can configure the batcher in config-files/config.yaml:

# Common variables for all the services
eth_rpc_url: <http_rpc_url>
eth_ws_url: <ws_rpc_url>
aligned_layer_deployment_config_file_path: <path_to_aligned_layer_deployment_config_file>

## Batcher Configurations
batcher:
  block_interval: <block_interval>
  batch_size_interval: <batch_size_interval>

## ECDSA Configurations
ecdsa:
  private_key_store_path: <path_to_ecdsa_private_key_store>
  private_key_store_password: <ecdsa_private_key_store_password>
Run
make batcher_start
Send tasks
Sending a Task to the Batcher using our Rust TaskSender CLI
Send one SP1 proof
make batcher_send_sp1_task
Send one Groth 16 proof
make batcher_send_groth16_task
Send infinite Groth 16 proofs
make batcher_send_infinite_groth16
Send burst of Groth 16 proofs
make batcher_send_burst_groth16
Send specific proof

To install the batcher client to send a specific proof, run:

make install_batcher_client

The SP1 proof needs the proof file and the vm program file. The GnarkPlonkBn254, GnarkPlonkBls12_381 and Groth16Bn254 proofs need the proof file, the public input file and the verification key file.

aligned \
--proving_system <SP1|GnarkPlonkBn254|GnarkPlonkBls12_381|Groth16Bn254> \
--proof <proof_file> \
--public-input <public_input_file> \
--vm_program <vm_program_file> \
--proof_generator_addr [proof_generator_addr]
Task Sender
Config

There is a default configuration for devnet purposes in config-files/config.yaml.

The configuration file have the following structure:

# Common variables for all the services
# 'production' only prints info and above. 'development' also prints debug
environment: <production/development>
aligned_layer_deployment_config_file_path: <path_to_aligned_layer_deployment_config_file>
eigen_layer_deployment_config_file_path: <path_to_eigen_layer_deployment_config_file>
eth_rpc_url: <http_rpc_url>
eth_ws_url: <ws_rpc_url>
eigen_metrics_ip_port_address: <ip:port>

## ECDSA Configurations
ecdsa:
  private_key_store_path: <path_to_ecdsa_private_key_store>
  private_key_store_password: <ecdsa_private_key_store_password>
Send PLONK BLS12_381 proof

To send a single PLONK BLS12_381 proof, run:

make send_plonk_bls12_381_proof

To send PLONK BLS12_381 proofs in loop, run:

make send_plonk_bls12_381_proof_loop
Send PLONK BN254 proof

To send a single PLONK BN254 proof, run:

make send_plonk_bn254_proof

To send PLONK BN254 proofs in loop, run:

make send_plonk_bn254_proof_loop
Send Groth 16 BN254 proof

To send a single Groth 16 BN254 proof, run:

make send_groth16_bn254_proof

To send Groth 16 BN254 proofs in loop, run:

make send_groth16_bn254_proof_loop

To send different Groth 16 BN254 proofs in loop, run:

make send_infinite_groth16_bn254_proof
Send SP1 proof

To send a single SP1 proof, run:

make send_sp1_proof
Send a specific proof
go run task_sender/cmd/main.go send-task \
--proving-system <plonk_bls12_381|plonk_bn254|groth16_bn254|sp1> \
--proof <proof_file> \
--public-input <public_input_file> \
--verification-key <verification_key_file> \
--config <config_file> \
--quorum-threshold <quorum_threshold> \
2>&1 | zap-pretty
Send a specific proof in loop
go run task_sender/cmd/main.go loop-tasks
    --proving-system <plonk_bls12_381|plonk_bn254|groth16_bn254|sp1> \
    --proof <proof_file> \
    --public-input <public_input_file> \
    --verification-key <verification_key_file> \
    --config <config_file> \
    --quorum-threshold <quorum_threshold> \
    --interval <interval-in-seconds>

Deploying Aligned Contracts to Holesky or Testnet

Eigenlayer Contracts: Anvil

If EigenLayer contracts change, the anvil state needs to be updated with:

make anvil_deploy_eigen_contracts

You will also need to redeploy the MockStrategy & MockERC20 contracts:

make anvil_deploy_mock_strategy
Eigenlayer Contracts: Holesky/Mainnet

These contracts are not deployed by Aligned. Current EigenLayer contracts:

Aligned Contracts: Anvil

When changing Aligned contracts, the anvil state needs to be updated with:

make anvil_deploy_aligned_contracts
Aligned Contracts: Holesky/Mainnet

To deploy the contracts to Testnet/Mainnet, you will need to set environment variables in a .env file in the same directory as the deployment script (contracts/scripts/).

The necessary environment variables are:

Variable Name Description
RPC_URL The RPC URL of the network you want to deploy to.
PRIVATE_KEY The private key of the account you want to deploy the contracts with.
EXISTING_DEPLOYMENT_INFO_PATH The path to the file containing the deployment info about EigenLayer.
DEPLOY_CONFIG_PATH The path to the deployment config file.
OUTPUT_PATH The path to the file where the deployment info will be saved.

You can find an example .env file in .env.example.holesky

Then run the following command:

make deploy_aligned_contracts

You need to complete the DEPLOY_CONFIG_PATH file with the following information:

{
    "chainInfo": {
      "chainId": "<chain_id>"
    },
    "permissions" : {
      "owner": "<owner_address>",
      "aggregator": "<aggregator_address>",
      "upgrader": "<upgrader_address>",
      "churner": "<churner_address>",
      "ejector": "<ejector_address>",
      "deployer": "<deployer_address>",
      "initalPausedStatus": 0
    },
    "minimumStakes": [],  
    "strategyWeights": [],
    "operatorSetParams": [],
    "uri": ""
  }

You can find an example config file in contracts/script/deploy/config/holesky/aligned.holesky.config.json.

Bindings

Also make sure to re-generate the Go smart contract bindings:

make bindings
Deployment

To build go binaries run:

make build_binaries

Metrics

Aggregator Metrics

Aggregator metrics are exposed on the /metrics endpoint.

If you are using the default config, you can access the metrics on http://localhost:9091/metrics.

To run Prometheus and Grafana just run:

make run_metrics

Then you can access Grafana on http://localhost:3000 with the default credentials admin:admin.

If you want to install Prometheus and Grafana manually, you can follow the instructions below.

To install Prometheus, you can follow the instructions on the official website.

To install Grafana, you can follow the instructions on the official website.

Explorer

Minimum Requirements
Running for local devnet

make run_devnet_explorer

Now you can visit localhost:4000 from your browser. You can access to a tasks information by visiting localhost:4000/batches/:merkle_root.

Run with custom env / other devnets

Create a .env file in the /explorer directory of the project. The .env file needs to contain the following variables:

Variable Description
RPC_URL The RPC URL of the network you want to connect to.
ENVIRONMENT The environment you want to run the application in. It can be devnet, holesky or mainnet.
PHX_HOST The host URL where the Phoenix server will be running.

make run_explorer

Send example data

If you want to have some data to see on it, you can start our infinite task sender, which will constantly send new proofs to the batcher.

make batcher_send_burst_groth16

Notes on project creation / devnet deployment

Eigenlayer middleware was installed as a submodule with:

mkdir contracts
cd contacts
forge init . --no-commit
forge install Layr-Labs/eigenlayer-middleware@mainnet

Then to solve the issue https://github.com/Layr-Labs/eigenlayer-middleware/issues/229, we changed it to:

forge install yetanotherco/eigenlayer-middleware@yac-mainnet --no-commit

As soon as it gets fixed in mainnet we can revert it.

Base version of middleware used is 7229f2b.

The script to initialize the devnet can be found on contracts/scripts/anvil.

The addresses of the relevant contracts after running the anvil script is dumped on contracts/script/output/devnet.

The state is backuped on contracts/scripts/anvil/state.

Eigenlayer contract deployment is almost the same as the EigenLayer contract deployment on mainnet. Changes are described on the file.

Tests

To run the go tests

make test

Verify Proofs

SP1
Dependencies

This guide assumes that:

  • sp1 prover installed (instructions here)
  • sp1 project to generate the proofs (instructions here)
  • aligned layer repository cloned:
    git clone https://github.com/yetanotherco/aligned_layer.git
    
How to generate a proof

AlignedLayer only verifies SP1 in compressed version. You can check you are using compressed by opening script/src/main.rs and check that the proof is generated with client.prove_compressed instead of client.prove.

First, open a terminal and navigate to the script folder in the sp1 project directory

Then, run the following command to generate a proof:

cargo run --release
How to get the proof verified by AlignedLayer

After generating the proof, you will have to find two different files:

  • proof file: usually found under script directory, with the name proof.json or similar
  • elf file: usually found under program/elf/ directory

Then, you can send the proof to the AlignedLayer network by running the following command from batcher/client folder inside the AlignedLayer repository directory:

cargo run --release -- \
--proving_system SP1 \
--proof <proof_path> \
--vm_program <vm_program_path> \
--conn wss://batcher.alignedlayer.com \
--proof_generator_addr [proof_generator_addr]

FAQ

What is the objective of Aligned?

Aligned’s mission is to extend Ethereum’s zero-knowledge capabilities. We are certain the zero-knowledge proofs will have a key role in the future of blockchains and computation. We don’t know what that future will look like, but we are certain it will be in Ethereum. The question we want to share is: If we are certain zero-knowledge proofs are the future of Ethereum but we are not certain which of the many possible zero-knowledge futures will win. How can we build an infrastructure for Ethereum to be compatible with any future zero-knowledge proving system?

Why do we need a ZK verification layer?

Verifiable computation allows developers to build applications that help Ethereum scale or even create applications that were not possible before, with enhanced privacy properties. We believe the future of Ethereum will be shaped by zero-knowledge proofs and help it increase its capabilities.

What are the use cases of Aligned?

Among the possible use cases of Aligned we have:

Soft finality for Rollups and Appchains, fast bridging, new settlement layers (use Aligned + EigenDA) for Rollups and Intent based systems, P2P protocols based on SNARKs such as payment systems and social networks, alternative L1s interoperable with Ethereum, Verifiable Machine Learning, cheap verification and interoperability for Identity Protocols, ZK Oracles, new credential protocols such as zkTLS based systems, ZK Coprocessor, encrypted Mempools using SNARKs to show the correctness of the encryption, protocols against misinformation and fake news, and on-chain gaming.

Why build on top of Ethereum?

Ethereum is the most decentralized and biggest source of liquidity in the crypto ecosystem. We believe it is the most ambitious and long-term project on the internet. Aligned is being built to help Ethereum achieve its highest potential, and we believe this is only possible through validity/zero-knowledge proofs.

Why not do this directly on top of Ethereum?

In order to do this we would have to aggregate all the proofs into a single proof. This is not a good solution considering that we would need some way to wrap proofs (for example, by means of recursion), which involves complex operations such as field emulation, bitwise, and/or elliptic curve operations.

Why not make Aligned a ZK L1?

An L1 would not have the security properties of Ethereum consensus, and bootstrapping a new decentralized network is not only expensive but might be an impossible task. Zero-knowledge proofs are a nascent technology, and change is a constant. The best solution for today may not be the best for tomorrow; modifying L1s is extremely costly, especially as time progresses.

Why not a ZK L2?

An L2 needs to use the EVM to settle in Ethereum. This means that the proofs need to be efficiently verified in the EVM, and their data made available there.

The EVM is not designed for ZK Verification, so most verifications are expensive.

To solve this, for pairing-based cryptography, Ethereum has added a precompile for verifications using the curve BN254.

But technology changes fast. BN254 security was demonstrated to be around 100 bits instead of the expected 128. Fast Starks need efficient hashing for fields. Which is the best field? Mersenne’s? Goldilocks? Binary fields? What about the sumcheck protocol? Is Jolt the endgame? Or is GKR going to be faster?

The amount of progress in the field is big, and nobody can predict the endgame.

Even more, it would be naive to think that only one optimized prover will exist in the future. In the world of ZK, as in many others, there are trade-offs and systems that solve different problems.

Maybe we want faster proving and don't care about proof size. Maybe we want the fastest proof verification and smallest size and can do more work on the prover. The system may be optimized to prove Keccak really fast. Or we can skip the traditional hashes altogether and just optimize for Poseidon, Rescue, or one hash not created yet.

Aligned solves all of this. No matter how or what you want to prove, it can be verified efficiently here while still inheriting the security of Ethereum as other L2s.

Why EigenLayer?

We believe Ethereum is the best settlement layer, and zero-knowledge will play a key role in helping it be THE settlement layer of the internet. We want to build a verification layer that helps Ethereum achieve this goal. This layer needs to have a decentralized group of validators that will just re-execute the verification of different proofs, but how can we build such a decentralized network that will help Ethereum? Creating a new L1 doesn’t benefit Ethereum because using it will add new trust assumptions to the Ethereum protocols relying on it. So, if we must have:

  1. A decentralized network of verifiers
  2. A similar economic security level that can be easily measured in Ethereum
  3. Part of the Ethereum ecosystem
  4. Flexible enough to support many current and future proving systems
Will you aggregate proofs?

Proof aggregation can also be supported by proving the verification of many of these different verifications. This will likely not be an urgent feature, but it will be needed in the future with more demand.

How does it compare to the Polygon aggregation layer?

Aligned is just a network of decentralized verifiers renting security from Ethereum. On the other hand, the Polygon aggregation layer, in essence, is a rollup verifying multiple proofs. That is not the case for Aligned, which just executes a rust binary from different verifiers directly in multiple Ethereum validators.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL