Skip to content

Commit

Permalink
impl: zk rollup logic
Browse files Browse the repository at this point in the history
  • Loading branch information
berzanorg committed Apr 30, 2024
1 parent f6a2ba6 commit a5adcf0
Show file tree
Hide file tree
Showing 25 changed files with 510 additions and 240 deletions.
36 changes: 18 additions & 18 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ members = [
"processes",
"proofpool",
"rpc-server",
"rollup",
"zk-rollup",
"transactions-db",
"withdrawals-db",
"schnorr-signature",
Expand Down
65 changes: 24 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,26 @@
# Nacho

A decentralized and scalable layer-2 solution that allows decentralized trading on top of Mina Protocol.

Nacho is being built by [**Berzan**](https://berzan.org/) with his love, sweet and tears.

## System Architecture

In high level overview, Nacho consists of a sequencer, a prover and a smart contract.

Nacho has a client, a state database, a witness database, a prover and a smart contract.

### Client

The client provides an interface to interact with Nacho.
It uses a custom RPC protocol and data format for low deserialization cost and high performance.
It is the program that runs Nacho.

### State Database

The state database stores Nacho's state in a way that allows quick access.
It also stores the leaf index of each data along with the data to provide a constant time to get the witness of a data from the witness database.

### Witness Database

The witness database stores the hashes of each data stored in the state database inside an on disk Merkle tree.
It also makes it possible to represent the entire state as a fixed size Merkle root.
It is optimized for high performance and low disk usage.

### Prover

The prover generates proofs using user transactions in batches as private inputs and the Merkle root of the entire state as the public input, returning the Merkle root of the updated state as the public output.

### Smart Contract

The smart contract stores the Merkle root of the latest state backed up in the smart contract and updates it by verifying proofs generated by the prover.

### Bridge

The bridge allows users to send MINA and other tokens to the smart contract on Mina Protocol
and mint them back on Nacho by sending proofs of transfers to the client.

It also allows users to withdraw MINA and other tokens from the smart contract by burning them on Nacho and sending proofs of burns to the smart contract.
## Running Nacho

### Required Environment Variables

- `NACHO_RPC_SERVER_PORT`
- `NACHO_SUBMITTER_PRIVATE_KEY`
- `NACHO_MINA_NODE_URL`
- `NACHO_ROLLUP_CONTRACT_PUBLIC_KEY`
- `NACHO_BRIDGE_CONTRACT_PUBLIC_KEY`
- `NACHO_PROOFS_PATH`
- `NACHO_BALANCES_DB_PATH`
- `NACHO_LIQUIDITIES_DB_PATH`
- `NACHO_POOLS_DB_PATH`
- `NACHO_BURNS_DB_PATH`
- `NACHO_WITHRAWALS_DB_PATH`
- `NACHO_TRANSACTIONS_DB_PATH`
- `NACHO_EVENTS_DB_PATH`
- `NACHO_EVENT_FETCHER_PROCESS_SCRIPT_PATH`
- `NACHO_PROOF_GENERATOR_PROCESS_SCRIPT_PATH`
- `NACHO_PROOF_MERGER_PROCESS_SCRIPT_PATH`
- `NACHO_PROOF_SUBMITTER_PROCESS_SCRIPT_PATH`
- `NACHO_SIGNATURE_VERIFIER_PROCESS_SCRIPT_PATH`
- `NACHO_MEMPOOL_PATH`
- `NACHO_PROOFPOOL_PATH`
10 changes: 5 additions & 5 deletions js-process/src/js_process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ use crate::error::JsProcessError;
/// Spawn a process:
///
/// ```rs
/// let (stdin, stdout) = nacho_js_process::spawn(&["echo.js"])?;
/// let (stdin, stdout) = nacho_js_process::spawn("echo.js")?;
/// ```
///
pub fn spawn(
args: &[&str],
path: &str,
) -> Result<(&'static mut ChildStdin, &'static mut ChildStdout), JsProcessError> {
let mut process = Command::new("node")
.args(args)
.arg(path)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::inherit())
Expand All @@ -43,7 +43,7 @@ pub fn spawn(
/// Spawn a process:
///
/// ```rs
/// let (stdin, stdout) = nacho_js_process::spawn(&["greeting.js"])?;
/// let (stdin, stdout) = nacho_js_process::spawn("greeting.js")?;
/// ```
///
/// Interact with the process:
Expand Down Expand Up @@ -75,7 +75,7 @@ mod tests {
pub async fn test_echo_js_process() {
let js_file_path = concat!(env!("CARGO_MANIFEST_DIR"), "/resources/echo.mjs");

let (stdin, stdout) = spawn(&[js_file_path]).unwrap();
let (stdin, stdout) = spawn(js_file_path).unwrap();

// First try:
let input = [111u8; 5];
Expand Down
6 changes: 3 additions & 3 deletions processes/src/balances/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ use tokio::sync::mpsc;

use super::{Processor, Request};

pub fn process(path: &str) -> Processor {
let path = path.to_owned();
pub fn process() -> Processor {
let balances_db_path = std::env::var("NACHO_BALANCES_DB_PATH").unwrap();

let (sender, mut receiver) = mpsc::channel::<Request>(1000);

tokio::spawn(async move {
let mut balances_db = BalancesDb::new(path).await.unwrap();
let mut balances_db = BalancesDb::new(balances_db_path).await.unwrap();

while let Some(request) = receiver.recv().await {
match request {
Expand Down
6 changes: 3 additions & 3 deletions processes/src/burns/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ use tokio::sync::mpsc;

use super::{Processor, Request};

pub fn process(path: &str) -> Processor {
let path = path.to_owned();
pub fn process() -> Processor {
let burns_db_path = std::env::var("NACHO_BURNS_DB_PATH").unwrap();

let (sender, mut receiver) = mpsc::channel::<Request>(1000);

tokio::spawn(async move {
let mut burns_db = BurnsDb::new(path).await.unwrap();
let mut burns_db = BurnsDb::new(burns_db_path).await.unwrap();

while let Some(request) = receiver.recv().await {
match request {
Expand Down
12 changes: 6 additions & 6 deletions processes/src/executor/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ use nacho_data_structures::{
use tokio::sync::Notify;

pub fn process(
verifier: verifier::Processor,
transactions: transactions::Processor,
mempool: mempool::Processor,
proofpool: proofpool::Processor,
balances: balances::Processor,
pools: pools::Processor,
liquidities: liquidities::Processor,
burns: burns::Processor,
liquidities: liquidities::Processor,
mempool: mempool::Processor,
pools: pools::Processor,
proofpool: proofpool::Processor,
transactions: transactions::Processor,
verifier: verifier::Processor,
) -> Processor {
let notify: &Notify = Box::leak(Box::new(Notify::new()));

Expand Down
14 changes: 8 additions & 6 deletions processes/src/fetcher/process.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::time::Duration;

use super::Processor;
use crate::{burns, executor, mempool, transactions, withdrawals};
use crate::{burns, executor, generator, mempool, transactions, withdrawals};
use nacho_data_structures::{
ByteConversion, Deposit, DepositTokensTransaction, Transaction, Withdrawal,
};
Expand All @@ -12,17 +12,18 @@ use tokio::{
};

pub fn process(
events_db_path: &str,
event_fetcher_process_path: &str,
burns: burns::Processor,
executor: executor::Processor,
generator: generator::Processor,
mempool: mempool::Processor,
transactions: transactions::Processor,
burns: burns::Processor,
withdrawals: withdrawals::Processor,
) -> Processor {
let (stdin, stdout) = nacho_js_process::spawn(&[event_fetcher_process_path]).unwrap();
let event_fetcher_process_script_path =
std::env::var("NACHO_EVENT_FETCHER_PROCESS_SCRIPT_PATH").unwrap();
let events_db_path = std::env::var("NACHO_EVENTS_DB_PATH").unwrap();

let events_db_path = events_db_path.to_string();
let (stdin, stdout) = nacho_js_process::spawn(&event_fetcher_process_script_path).unwrap();

tokio::spawn(async move {
let mut events_db = EventsDb::new(events_db_path).await.unwrap();
Expand Down Expand Up @@ -55,6 +56,7 @@ pub fn process(
}

executor.keep_executing();
generator.keep_generating();
}
None => (),
};
Expand Down
14 changes: 8 additions & 6 deletions processes/src/generator/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,19 @@ use tokio::{
};

pub fn process(
path: &str,
transactions: transactions::Processor,
proofpool: proofpool::Processor,
balances: balances::Processor,
pools: pools::Processor,
liquidities: liquidities::Processor,
burns: burns::Processor,
liquidities: liquidities::Processor,
pools: pools::Processor,
proofpool: proofpool::Processor,
transactions: transactions::Processor,
) -> Processor {
let proof_generator_process_script_path =
std::env::var("NACHO_PROOF_GENERATOR_PROCESS_SCRIPT_PATH").unwrap();

let notify: &Notify = Box::leak(Box::new(Notify::new()));

let (stdin, stdout) = nacho_js_process::spawn(&[path]).unwrap();
let (stdin, stdout) = nacho_js_process::spawn(&proof_generator_process_script_path).unwrap();

tokio::spawn(async move {
let mut hasher = create_poseidon_hasher();
Expand Down
6 changes: 3 additions & 3 deletions processes/src/liquidities/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ use tokio::sync::mpsc;

use super::{Processor, Request};

pub fn process(path: &str) -> Processor {
let path = path.to_owned();
pub fn process() -> Processor {
let liquidities_db_path = std::env::var("NACHO_LIQUIDITIES_DB_PATH").unwrap();

let (sender, mut receiver) = mpsc::channel::<Request>(1000);

tokio::spawn(async move {
let mut liquidities_db = LiquiditiesDb::new(path).await.unwrap();
let mut liquidities_db = LiquiditiesDb::new(liquidities_db_path).await.unwrap();

while let Some(request) = receiver.recv().await {
match request {
Expand Down
6 changes: 3 additions & 3 deletions processes/src/mempool/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ use tokio::sync::mpsc;

use super::{Processor, Request};

pub fn process(path: &str) -> Processor {
let path = path.to_owned();
pub fn process() -> Processor {
let mempool_path = std::env::var("NACHO_MEMPOOL_PATH").unwrap();

let (sender, mut receiver) = mpsc::channel::<Request>(1000);

tokio::spawn(async move {
let mut mempool = Mempool::new(path).await.unwrap();
let mut mempool = Mempool::new(mempool_path).await.unwrap();

while let Some(request) = receiver.recv().await {
match request {
Expand Down
8 changes: 6 additions & 2 deletions processes/src/merger/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ use tokio::{
time::sleep,
};

pub fn process(path: &str, transactions: transactions::Processor) -> Processor {
pub fn process(transactions: transactions::Processor) -> Processor {
let proof_merger_process_script_path =
std::env::var("NACHO_PROOF_MERGER_PROCESS_SCRIPT_PATH").unwrap();

let (sender, mut receiver) = mpsc::channel::<u32>(1000);

let (mut stdin, mut stdout) = nacho_js_process::spawn(&[path]).unwrap();
let (mut stdin, mut stdout) =
nacho_js_process::spawn(&proof_merger_process_script_path).unwrap();

tokio::spawn(async move {
let sleep = sleep(Duration::from_millis(100));
Expand Down
6 changes: 3 additions & 3 deletions processes/src/pools/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ use tokio::sync::mpsc;

use super::{Processor, Request};

pub fn process(path: &str) -> Processor {
let path = path.to_owned();
pub fn process() -> Processor {
let pools_db_path = std::env::var("NACHO_POOLS_DB_PATH").unwrap();

let (sender, mut receiver) = mpsc::channel::<Request>(1000);

tokio::spawn(async move {
let mut pools_db = PoolsDb::new(path).await.unwrap();
let mut pools_db = PoolsDb::new(pools_db_path).await.unwrap();

while let Some(request) = receiver.recv().await {
match request {
Expand Down
6 changes: 3 additions & 3 deletions processes/src/proofpool/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ use tokio::sync::mpsc;

use super::{Processor, Request};

pub fn process(path: &str) -> Processor {
let path = path.to_owned();
pub fn process() -> Processor {
let proofpool_path = std::env::var("NACHO_PROOFPOOL_PATH").unwrap();

let (sender, mut receiver) = mpsc::channel::<Request>(1000);

tokio::spawn(async move {
let mut proofpool = Proofpool::new(path).await.unwrap();
let mut proofpool = Proofpool::new(proofpool_path).await.unwrap();

while let Some(request) = receiver.recv().await {
match request {
Expand Down
7 changes: 5 additions & 2 deletions processes/src/submitter/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ use std::time::Duration;

use super::Processor;

pub fn process(path: &str) -> Processor {
let (stdin, stdout) = nacho_js_process::spawn(&[path]).unwrap();
pub fn process() -> Processor {
let proof_submitter_process_script_path =
std::env::var("NACHO_PROOF_SUBMITTER_PROCESS_SCRIPT_PATH").unwrap();

let (stdin, stdout) = nacho_js_process::spawn(&proof_submitter_process_script_path).unwrap();

tokio::spawn(async move {
loop {
Expand Down
Loading

0 comments on commit a5adcf0

Please sign in to comment.