leonardoalt / fusion

An experimental progressive and fast zkRollup written in Rust, focused on performance, modularity, and applying cutting-edge Verifiable Computation proof systems.
GNU General Public License v3.0
119 stars 5 forks source link
ethereum l2 smart-contracts zkrollup zksnarks

Fusion zkRollup

Fusion is an experimental progressive Ethereum zkRollup written in Rust and focuses on performance, modularity, and applying cutting-edge Verifiable Computation proof systems.

Fusion is conceptually based on the original zkRollup. We use Zokrates for all circuits which provides high level abstractions for all algorithms and multiple backends. Currently the prover builds a Groth16 SNARK for each transaction in parallel, and there is no batching. Together with ZoKrates we are experimenting with Nova recursive proofs to enable incredibly fast transaction batching and compression.

See the end of this document for the full list of roadmap items, ideas, and concrete tasks.

Tool Suite

This repository contains the entire Fusion tool suite:

Cloning the repository

git clone --recurse-submodules https://github.com/leonardoalt/fusion.git

If you already cloned the repository without submodules, you can run the command below to initialize it:

git submodule update --init --recursive

Dependencies

Fusion requires the following installed:

Building the circuits

ZoKrates' latest release 0.8.7 is specifically required for this step.

cd circuits && make && make verifier

Note: the current circuits require at least 16GB of RAM to compile.

Building the L1 SNARK verifier

This step requires the circuit step above.

cd l1-verifier && make

Building the sequencer (has prover as dependency)

This step requires the L1 verifier step above.

cargo build --release --bin fusion-sequencer

Running

The easiest way to see everything running is via Rust tests with

cargo test --release -- --nocapture

For more details see the tests in fusion-sequencer. If you want to run it in production style, you may want to follow this list:

  1. Set eth_private_key in fusion.toml to the private key that will deploy the contract and submit L2 blocks.
  2. Set eth_rpc_url in fusion.toml to an Ethereum RPC endpoint. Since we are using anvil here, this is usually http://localhost:8545.
  3. Run source ./scripts/run_anvil_and_deploy_contract which starts anvil and deploys the contract.
  4. Set fusion_l1_contract in fusion.toml with the address of the deployed contract.
  5. Run ./scripts/run_node to start the node.
  6. You can run ./scripts/listen_to_node to check the ongoing output from the node.
  7. Now you can also run ./scripts/send_random_tx to send transactions.
  8. To stop everything, run ./scripts/kill_node and ./scripts/kill_anvil.

State

The state is a balanced Sparse Merkle Tree similar to this one. The tree has 256 levels besides the root. This implies that it has 2^256 leaves. Each leaf has an index, from 0 (left most) to 2^256 - 1 (right most). The path from the root to a leaf can be represented by the binary representation of the leaf's index: when walking down the tree, 0 means the path goes left, 1 means it goes right.

The tree also contains some optimizations, such as:

The used hash is Poseidon in order to be SNARK friendly.

Signature and Addresses

Since we need to verify signatures inside zkSNARKs, we use EdDSA with the Baby Jubjub Elliptic Curve. A public key (PK) consists of a curve point where x and y are elements of the field used by Baby Jubjub. The PK can be compressed into 256 bits, which does not necessarily fit in the field. Given a public key (x, y), its Fusion address consists of poseidon(x, y). This means that Fusion accounts are not compatible with Ethereum accounts.

Execution

There are no VM and smart contracts at the moment.

Modularity

Fusion is designed to be highly modular and extensible. For example, here are a few things that can be modified quite easily:

This enables fast experimental iterations on all fronts which can quickly turn into progress.

Roadmap (and TODO items)

v1. Batch proofs - production after this!

Done

TODO

v2. Execution

TODO