Rivellum

Rivellum Portal

Checking...
testnet

PoUW Dynamic Pricing Market

Overview

Rivellum's Proof-of-Useful-Work (PoUW) system now features a dynamic pricing/auction market where provers compete for jobs by submitting bids. This replaces the fixed-fee model with a cost-efficient, market-driven approach.

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Node createsβ”‚
β”‚   ProofJob  β”‚
β”‚ base_fee=1000β”‚
β”‚  min_bid=100 β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Job Queue (Pending) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Provers submit bids:                β”‚
β”‚ - Prover A: 300 βœ“ (WINNER)          β”‚
β”‚ - Prover B: 500 βœ“ (valid, higher)   β”‚
β”‚ - Prover C:  50 βœ— (below min)       β”‚
β”‚ - Prover D: 1200 βœ— (above budget)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Winner (Prover A)    β”‚
β”‚ computes proof       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
       β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Node validates proof β”‚
β”‚ Pays winner 300      β”‚
β”‚ (saves 700!)         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Components

1. ProofJob with Pricing

pub struct ProofJob {
    pub job_id: String,
    pub tier: JobTier,
    pub intent_id: IntentId,
    pub trace_hash: [u8; 32],
    
    // Dynamic pricing fields
    pub base_fee_budget: u64,  // Maximum willing to pay
    pub min_bid_fee: u64,      // Minimum acceptable bid (quality floor)
    
    pub created_at_ms: u64,
    pub deadline_ms: u64,
    pub trace_data: Vec<u8>,
}

Pricing Strategy:

  • min_bid_fee = 10% of base_fee_budget (configurable)
  • Valid bids: min_bid_fee ≀ bid_fee ≀ base_fee_budget
  • Prevents race-to-zero while allowing up to 90% cost savings

2. ProofJobBid

pub struct ProofJobBid {
    pub job_id: String,
    pub prover_id: String,  // Identifier (future: cryptographic address)
    pub bid_fee: u64,       // Amount prover wants to earn
    pub timestamp_ms: u64,  // Tie-breaker
}

3. Bid Selection Strategy

Default: LowestBid

  • Choose bid with lowest bid_fee
  • Tie-breaker: earliest timestamp_ms
  • Deterministic and fair

Future strategies:

  • WeightedReputation: Factor in prover success rate
  • RandomWeighted: Lottery based on bid competitiveness

4. JobQueue Bidding API

// Submit bid (validates against job constraints)
pub fn submit_bid(&self, bid: ProofJobBid) -> Result<bool, String>

// Get all bids for a job
pub fn get_bids(&self, job_id: &str) -> Result<Vec<ProofJobBid>, String>

// Get current winning bid
pub fn get_winning_bid(&self, job_id: &str) -> Result<Option<ProofJobBid>, String>

// Get assigned prover (winner)
pub fn get_assigned_prover(&self, job_id: &str) -> Result<Option<String>, String>

RPC Endpoints

POST /pouw/jobs/:job_id/bid

Submit a bid for a proof job.

Request:

{
  "prover_id": "prover_alice",
  "bid_fee": 300
}

Response:

{
  "success": true,
  "message": "Bid accepted. You are currently the winning bidder",
  "is_winner": true
}

Validation:

  • bid_fee >= job.min_bid_fee
  • bid_fee <= job.base_fee_budget
  • Job must be in Pending status
  • No duplicate bids from same prover

GET /pouw/jobs/:job_id/bids

List all bids for a job.

Response:

{
  "job_id": "abc123...",
  "bids": [
    {
      "prover_id": "prover_alice",
      "bid_fee": 300,
      "timestamp_ms": 1700000001000,
      "is_winner": true
    },
    {
      "prover_id": "prover_bob",
      "bid_fee": 500,
      "timestamp_ms": 1700000002000,
      "is_winner": false
    }
  ],
  "winning_bid": {
    "prover_id": "prover_alice",
    "bid_fee": 300,
    "timestamp_ms": 1700000001000,
    "is_winner": true
  }
}

POST /pouw/jobs/:job_id/submit (Updated)

Proof submission now validates assigned prover and uses bid fee for rewards.

Behavior Changes:

  1. Prover Validation: If job has bids, only the winning bidder can submit proof
  2. Reward Calculation: Prover earns bid_fee (not base_fee_budget)
  3. Cost Savings: Node saves base_fee_budget - bid_fee

Metrics

New Prometheus Metrics

# Total bids submitted
rivellum_pouw_bids_total{} 150

# Jobs assigned to winners
rivellum_pouw_jobs_assigned{} 42

# Average clearing price ratio (bid_fee / base_fee_budget)
# Lower = better for node (more savings)
rivellum_pouw_avg_clearing_price_ratio{} 0.35

Clearing Price Ratio Interpretation:

  • 0.1 = 90% average discount (provers bidding 10% of budget)
  • 0.5 = 50% average discount
  • 1.0 = No discount (bids equal to budget)

Updated Metrics Dashboard

PoUW Market Statistics:
- Pending Jobs: 12
- Total Bids: 150
- Jobs Assigned: 42
- Avg Clearing Price: 0.35 (65% savings!)
- Completed Jobs: 42
- Failed Jobs: 5

Prover Workflow

1. Discover Available Jobs

GET /pouw/jobs/pending

Returns jobs with base_fee_budget and min_bid_fee.

2. Submit Competitive Bid

POST /pouw/jobs/:job_id/bid
{
  "prover_id": "my_prover",
  "bid_fee": 250  # Between min_bid_fee and base_fee_budget
}

3. Check Bid Status

GET /pouw/jobs/:job_id/bids

Check if you're the current winner (is_winner: true).

4. Compute Proof (if winning)

Only compute proof if you're the assigned prover to avoid wasted work.

5. Submit Proof

POST /pouw/jobs/:job_id/submit
{
  "proof": {...},
  "prover_id": "my_prover"
}

Validation: Node checks assigned_prover == prover_id.

6. Earn Reward

On success, earn your bid_fee amount (simulated credits pre-tokenomics).

Bidding Strategies

Fixed Bid

Bid a constant amount regardless of job:

bid_fee = 200  # Always bid 200

Fractional Bid

Bid a percentage of base budget:

bid_fee = base_fee_budget * 0.3  # Bid 30% of budget

Competitive Bid

Undercut existing bids slightly:

winning_bid = GET /pouw/jobs/:job_id/bids
if winning_bid:
    bid_fee = winning_bid.bid_fee - 10  # Undercut by 10
else:
    bid_fee = base_fee_budget * 0.5  # Start at 50%

Reputation-Weighted (Future)

Factor in your success rate:

base_bid = base_fee_budget * 0.4
if success_rate > 0.95:
    bid_fee = base_bid * 1.1  # Premium for reliability
else:
    bid_fee = base_bid * 0.9  # Discount to compete

Node Configuration

No configuration changes needed - market is automatically enabled.

Optional Tuning (future):

[pouw.market]
# Minimum bid as percentage of base budget (default: 0.1 = 10%)
min_bid_ratio = 0.1

# Bid selection strategy
selection_strategy = "lowest_bid"  # or "weighted_reputation", "random_weighted"

# Maximum bids per job before auto-assignment
max_bids_per_job = 10

Economics

Cost Savings Example

Old Fixed-Fee Model:

10 jobs Γ— 1000 fee_budget = 10,000 total cost

New Market Model (35% avg clearing price):

10 jobs Γ— 1000 budget Γ— 0.35 ratio = 3,500 total cost
Savings: 6,500 (65%)

Prover Revenue Example

Aggressive Bidder (20% of budget):

  • Win rate: 80%
  • Jobs won: 8/10
  • Revenue: 8 Γ— 200 = 1,600

Conservative Bidder (60% of budget):

  • Win rate: 30%
  • Jobs won: 3/10
  • Revenue: 3 Γ— 600 = 1,800

Optimal Strategy: Balance win rate and bid amount.

Security Considerations

Current (Pre-Tokenomics)

  • Simple string prover_id (no crypto identity)
  • Trust-based model
  • Simulated credits (not real tokens)

Future (Production)

  • Cryptographic Identity: Address + signature required
  • Staking: Provers stake tokens to prevent spam bids
  • Slashing: Invalid proofs result in stake loss
  • Reputation System: On-chain track record
  • Bid Collateral: Small deposit with bid (returned on completion)

Acceptance Criteria βœ…

  • Multiple provers can compete - Bidding API implemented
  • Node deterministically chooses winner - LowestBid strategy with timestamp tie-breaker
  • Rewards reflect chosen bid - submit_proof uses bid_fee for accounting
  • Assigned prover validation - mark_completed checks assigned_prover
  • Market metrics - bids_total, jobs_assigned, avg_clearing_price_ratio
  • RPC endpoints - POST /bid, GET /bids
  • Backward compatible - Jobs without bids use base_fee_budget (legacy behavior)

Testing

Unit Tests

cargo test --package rivellum-pouw
# All bidding tests pass βœ“

Integration Test

# Start node
cargo run --bin rivellum-node -- --config config/dev.toml

# Prover A bids low
curl -X POST http://localhost:3030/pouw/jobs/abc123/bid \
  -H "Content-Type: application/json" \
  -d '{"prover_id":"prover_a","bid_fee":300}'

# Prover B bids higher
curl -X POST http://localhost:3030/pouw/jobs/abc123/bid \
  -H "Content-Type: application/json" \
  -d '{"prover_id":"prover_b","bid_fee":500}'

# Check bids
curl http://localhost:3030/pouw/jobs/abc123/bids
# winner: prover_a (lowest bid)

# Prover A submits proof (succeeds)
# Prover B submits proof (rejected - not assigned)

Future Enhancements

  1. Advanced Strategies: Weighted reputation, random lottery
  2. Bid Expiry: Bids timeout after N seconds
  3. Rebidding: Allow provers to update bids
  4. Batch Auctions: Assign multiple jobs at once
  5. Dynamic Min Bid: Adjust based on market conditions
  6. Job Tiers Pricing: Different strategies per tier (Micro/Macro/Full)
  7. Gas Price Oracle: Adjust budgets based on network conditions

Migration Path

Phase 1 (Current): Simulated market with pre-tokenomics Phase 2: On-chain identity and staking Phase 3: RIVL token integration Phase 4: Reputation system and slashing Phase 5: Advanced market mechanisms (auctions, batching)


Status: βœ… Core market prototype complete and functional
Next: Update pouwd daemon with bidding logic