Rivellum

Rivellum Portal

Checking...
testnet

Proof-of-Useful-Work (PoUW) System

Overview

The PoUW system provides a job abstraction layer that decouples ZK proof generation from the main node execution loop. Execution traces are converted into proof jobs that can be solved by local or external workers (provers).

Architecture

ExecutionTrace → ProofJob → JobQueue → Prover
                               ↓
                         Completed Proof
                               ↓
                          Ledger Entry

Components

1. ProofJob

Located in rivellum-pouw/src/job.rs

A proof job represents work to be done by a prover:

  • job_id: Unique hex identifier (deterministic)
  • tier: Job complexity (Micro/Macro/Full)
  • intent_id: Associated intent
  • trace_hash: BLAKE3 hash of execution trace
  • fee_budget: Gas budget for proof generation
  • created_at_ms: Job creation timestamp
  • deadline_ms: Job expiration deadline
  • trace_data: Serialized execution trace

2. JobQueue

Located in rivellum-pouw/src/queue.rs

Thread-safe in-memory job queue:

  • enqueue(job) - Add new job
  • pop_next() - Get next pending job
  • get(job_id) - Retrieve job by ID
  • get_status(job_id) - Get job status
  • mark_completed(job_id, proof) - Mark job done
  • mark_failed(job_id, error) - Mark job failed
  • list_pending() - List all pending jobs

3. JobStatus

Located in rivellum-pouw/src/status.rs

Job lifecycle states:

  • Pending: Waiting to be picked up
  • InProgress: Being worked on by a prover
  • Completed: Successfully proven
  • Failed: Error during proving
  • Expired: Deadline passed

4. PoUW Modes

Located in rivellum-pouw/src/lib.rs

  • Disabled: No PoUW - proofs generated inline (traditional)
  • Local: Jobs created and processed locally by node
  • Remote: Jobs created for external workers to process

Configuration

Node Config

Add to NodeConfig (automatic):

pouw_mode = "disabled"  # or "local" or "remote"

Example Configs

PoUW Disabled (default):

zk_mode = "mock"
pouw_mode = "disabled"  # Traditional inline proving

PoUW Local (node processes own jobs):

zk_mode = "mock"
pouw_mode = "local"  # Jobs created and processed locally

PoUW Remote (external workers):

zk_mode = "mock"
pouw_mode = "remote"  # Jobs created for external workers

Integration Points

Node Context

struct NodeContext {
    // ... existing fields
    pouw_mode: rivellum_pouw::PoUwMode,
    job_queue: rivellum_pouw::JobQueue,
}

Execution Pipeline

In process_next_intent():

  1. Execute intent → Generate execution trace
  2. Check PoUW mode:
    • Disabled: Generate proof inline (old behavior)
    • Local: Create job, enqueue, process immediately
    • Remote: Create job, enqueue, return (worker picks up later)
  3. Store job_id in ledger entry for audit trail

Ledger Integration

pub struct LedgerEntryMeta {
    // ... existing fields
    pub job_ids: Vec<String>,  // Job IDs for audit trail
}

Job Creation Flow

// 1. Execute with trace
let (result, trace) = executor.execute_intent_with_trace(&intent, &state);

// 2. Create proof job
let job = ProofJob::new_for_trace(
    &trace,
    JobTier::Macro,
    result.gas_summary.fee_charged,
    60000, // 60 second TTL
)?;

// 3. Enqueue job
job_queue.enqueue(job)?;

// 4. Process based on mode
match pouw_mode {
    PoUwMode::Local => {
        // Process immediately
        let proof = generate_proof(&job)?;
        job_queue.mark_completed(&job.job_id, proof)?;
    }
    PoUwMode::Remote => {
        // External worker will pick up
    }
    _ => {}
}

Job Tiers

Micro

  • Individual instruction proofs
  • Fast, small circuits
  • Low gas budget

Macro

  • Complete intent proofs (current implementation)
  • Medium complexity
  • Standard gas budget

Full

  • Batched intent proofs
  • Large, complex circuits
  • High gas budget

External Worker (Future)

Workers can be implemented as separate binaries that:

  1. Connect to node's job queue (via RPC/API)
  2. pop_next() to claim a job
  3. Deserialize trace: job.get_trace()
  4. Generate proof: prove_trace(trace, zk_mode)
  5. Submit proof: mark_completed(job_id, proof)

Example worker pseudocode:

loop {
    // Poll for jobs
    if let Some(job) = job_queue.pop_next()? {
        job_queue.mark_in_progress(&job.job_id, "worker-1")?;
        
        // Recover trace
        let trace = job.get_trace()?;
        
        // Generate proof
        match prove_trace(&trace, zk_mode) {
            Ok(proof) => {
                job_queue.mark_completed(&job.job_id, proof)?;
            }
            Err(e) => {
                job_queue.mark_failed(&job.job_id, e.to_string())?;
            }
        }
    }
    
    sleep(Duration::from_millis(100));
}

Testing

Unit Tests

cargo test --release --lib -p rivellum-pouw

Integration Test (Local Mode)

# Build
cargo build --release

# Run with PoUW local mode
target/release/rivellum-node config/pouw-local.toml

# Submit intents - jobs will be created and processed locally

Integration Test (Remote Mode)

# Run node in remote mode
target/release/rivellum-node config/pouw-remote.toml

# Jobs are created but not processed (waiting for external worker)
# Check job queue stats via RPC (future)

Performance Characteristics

Disabled Mode

  • Proof generation: Inline with execution
  • Overhead: Minimal (blocks on proof)
  • Use case: Single-threaded, simple deployments

Local Mode

  • Proof generation: Via job queue, immediate processing
  • Overhead: Job creation + queue overhead
  • Use case: Testing PoUW system, benchmarking

Remote Mode

  • Proof generation: Deferred to external workers
  • Overhead: Job creation only
  • Use case: Production, distributed proving, GPU workers

API Extensions (Future)

RPC Endpoints

POST /pouw/jobs/list          # List pending jobs
GET  /pouw/jobs/{id}          # Get job details
POST /pouw/jobs/{id}/claim    # Claim job (mark in-progress)
POST /pouw/jobs/{id}/submit   # Submit proof
GET  /pouw/stats              # Queue statistics

Queue Statistics

pub struct QueueStats {
    pub pending_count: usize,
    pub in_progress_count: usize,
    pub completed_count: usize,
    pub failed_count: usize,
    pub expired_count: usize,
}

Acceptance Criteria ✓

  1. Job Types Defined: ProofJob, JobTier, JobStatus
  2. Job Queue Implemented: In-memory with enqueue/dequeue/complete
  3. PoUW Mode Config: disabled/local/remote in NodeConfig
  4. Pipeline Integration: Jobs created during execution
  5. Ledger Tracking: job_ids stored in LedgerEntryMeta
  6. Mode Disabled: No jobs created
  7. Mode Local: Jobs created and processed locally
  8. Mode Remote: Jobs created for external workers
  9. Build Success: Compiles without errors
  10. Tests Pass: All unit tests pass

Future Enhancements

Phase 1: RPC API

  • Job query endpoints
  • Job submission endpoints
  • Worker authentication

Phase 2: Persistence

  • DB-backed job queue
  • Job history and analytics
  • Recovery after restart

Phase 3: Advanced Features

  • Priority queues by fee
  • Job batching
  • Distributed worker pools
  • GPU prover support

Phase 4: Incentives

  • Proof marketplace
  • Fee distribution
  • Worker reputation
  • SLA tracking

Summary

The PoUW system provides a clean abstraction for decoupling proof generation from execution. It's production-ready for local mode and designed for easy extension to distributed proving with external workers.

Status: COMPLETE