Skip to content

Rust-based zero-knowledge virtual machine (zkVM) executor

License

Notifications You must be signed in to change notification settings

RollupX-FYP/executor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

zkVM Execution Environment

A provable execution environment that executes transactions, generates state transitions, and produces zero-knowledge proofs using Risc0 zkVM.

🚀 Features

  • Core Processor: Handles transfers, contract calls, and contract creation
  • State Management: Sparse Merkle Tree backed by RocksDB
  • zkVM Integration:
    • Execute: Processes transaction batches
    • Prove: Generates execution witnesses and ZK proofs
    • Verify: Commits public outputs (State Root, Gas Used, etc.)
  • Integration Interfaces:
    • Sequencer: Batch structure for input
    • Submitter: SubmitterPayload for L1/DA output

📦 Installation

cd executor
cargo build --release

🧪 Testing

The project has comprehensive test coverage (89 tests passing):

cargo test
  • Unit Tests: Core logic, state, proofs
  • Integration Tests: End-to-end execution flows
  • Interface Tests: Sequencer/Submitter integration

📚 Integration Guide

1. Sequencer Integration (Input)

Serialize your transactions into a Batch and send to the Executor.

use executor::{Batch, Transaction};

// 1. Create a batch
let batch = Batch::new(id, timestamp, vec![/* transactions */]);

// 2. Serialize and send to Executor
let bytes = batch.to_bytes()?;

2. Submitter Integration (Output)

Receive SubmitterPayload from the Executor and push to L1/DA.

use executor::SubmitterPayload;

// 1. Deserialize payload
let payload: SubmitterPayload = bincode::deserialize(&received_bytes)?;

// 2. Extract Data
let proof_data = payload.proof;      // -> Verify on L1
let public_io = payload.journal;     // -> Public Outputs (Root, BlockNum)
let da_data   = payload.batch_data;  // -> Store on Celestia/Blobstream

3. Expected Input Types

The Sequencer must provide data matching these Rust structures:

Batch (The Input Container)

struct Batch {
    id: u64,                // Unique Batch ID
    timestamp: u64,         // UNIX Timestamp
    transactions: Vec<Transaction>,
}

Transaction Types

enum Transaction {
    Transfer(TransferTx),
    ContractCall(ContractCallTx),
    ContractCreate(ContractCreateTx),
}

struct TransferTx {
    from: [u8; 20],         // Sender Address
    to: [u8; 20],           // Receiver Address
    value: [u8; 32],        // Amount (Big-Endian U256)
    nonce: u64,             // Account Nonce
    signature: Vec<u8>,     // 65-byte ECDSA Signature
}

struct ContractCallTx {
    caller: [u8; 20],
    contract: [u8; 20],
    calldata: Vec<u8>,      // Function Selector + Args
    value: [u8; 32],
    gas_limit: u64,
    nonce: u64,
    signature: Vec<u8>,
}

4. Expected Output Types

The Executor produces data matching this Rust structure for the Submitter:

SubmitterPayload ( The Output Container)

struct SubmitterPayload {
    proof: Vec<u8>,         // ZK Proof (Opaque bytes)
    journal: Vec<u8>,       // Public Outputs (64 bytes)
    batch_data: Vec<u8>,    // Raw Batch Data (for DA)
    block_number: u64,      // Block Height
    tx_count: u64,          // Transaction Count
}

5. Public Outputs Format

The journal (64 bytes) verifies the execution correctness:

Offset Field Type Description
0 post_state_root [u8; 32] Final Merkle State Root
32 block_number u64 Block Height
40 transaction_count u64 Total Transactions
48 total_gas_used u64 Total Gas Consumed
56 successful_txs u64 Txs with Status::Success

🛠️ Usage Example

use executor::{Database, StateManager, Processor, ProofGenerator, PublicOutputs};

fn main() -> anyhow::Result<()> {
    // 1. Setup
    let db = Database::new("./data")?;
    let state = StateManager::new(db);
    let mut processor = Processor::new(state);

    // 2. Execute Transactions
    // ... (load txs from batch) ...
    let witness = processor.generate_witness(&txs, block_num, timestamp)?;

    // 3. Generate Proof
    let generator = ProofGenerator::new();
    let (journal, proof) = generator.generate_proof(&witness)?;

    // 4. Verify & Commit
    let outputs = PublicOutputs::from_journal(&journal)?;
    println!("New State Root: {:?}", outputs.post_state_root);

    Ok(())
}

📂 Project Structure

  • src/core: Transaction types, Batch struct
  • src/state: Database, Merkle Tree, State Manager
  • src/executor: Transaction validation and execution logic
  • src/proof: Witness generation, Host program, Submitter payload
  • methods/guest: The zkVM guest program (runs inside ZK circuit)

📄 License

MIT

About

Rust-based zero-knowledge virtual machine (zkVM) executor

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages