IRONQ

Architecture

System overview and data flow

System Overview

IronQ is composed of five subsystems that work together on-chain.

SubsystemInstructionsRole
Queue Managementinit · update · pauseCreate, configure, and pause job queues. One queue per authority with an associated SPL token vault.
Worker Operationsregister · stake · deregisterWorkers register against a queue, lock stake tokens, and deregister when idle.
Job LifecyclecreateclaimsubmitapproveFull lifecycle from creation to completion.
Dispute PathdisputeresolveContested results are flagged and resolved by the queue authority.
Permissionless Cranksreclaim_expired · close_jobAnyone can call — slash timed-out workers, reclaim rent from terminal jobs.

SPL Token Vault (PDA) — Holds worker stakes and job rewards. Authority is the vault PDA itself — fully self-custodial, no admin key can drain funds.

Data Flow

  1. Creator creates job — calls create_job(reward). The reward amount is transferred via SPL Token into the queue's vault PDA.

  2. Worker claims job — calls claim_job(). The job status is set to Claimed and a deadline is assigned based on the queue's timeout configuration.

  3. Worker submits result — calls submit_result(hash). A new JobResult PDA is created storing the result data hash. Job status moves to Submitted.

  4. Creator approves result — calls approve_result(). The vault transfers the reward to the worker's token account. Job status becomes Completed.

  5. Creator closes job — calls close_job() to reclaim the rent from the terminal-state Job and Result accounts.

PDA Derivation

All accounts are Program Derived Addresses (PDAs), ensuring deterministic addresses without account registries:

AccountSeedsDescription
Queue["queue", authority]One queue per authority
Vault["vault", queue]One vault per queue
Job["job", queue, job_id_le_bytes]Unique per queue + monotonic ID
Worker["worker", queue, wallet]One registration per worker per queue
Result["result", job]One result per job

job_id_le_bytes is the 8-byte little-endian representation of the u64 job ID.

Design Decisions

DecisionRationale
One queue per authoritySimplifies PDA derivation; create multiple with different wallets
Max 3 concurrent jobs per workerPrevents overcommitment, bounds compute
Vault PDA as its own authoritySelf-custodial — no admin key can drain funds
data_hash instead of dataSolana accounts are expensive; store payloads on Arweave/IPFS
Separate Result accountKeeps Job account fixed-size; result can be closed independently
Basis points for ratesInteger math, no floating point, max precision of 0.01%
Immutable reward_mintChanging it would orphan vault funds. Create a new queue for a different token
max_concurrent_jobs snapshotCopied at registration time; prevents retroactive restriction of active workers

Performance

Compute Units

All instructions fit within Solana's default 200,000 CU limit — no setComputeUnitLimit needed.

  • initialize_queue: ~24,000 CU (most expensive — PDA creation + vault init)
  • claim_job: ~6,500 CU (lightest — single status update)
  • Most others: 10,000–25,000 CU range
  • Token transfers via CPI add ~4,500 CU per SPL Token call

Throughput

Solana enforces single-writer semantics per account. A single queue processes ~400 state transitions per second. For higher throughput, deploy multiple queues across different authorities — each queue's PDAs are independent and execute in parallel.

Latency

OperationWeb2 (Celery + Redis)IronQ (Solana)
Job dispatch< 1ms~400ms (1 slot)
Result confirmationInstant~400ms + finality (~6–13s)
End-to-end cycle< 10ms~2–15 seconds

IronQ trades latency for trustlessness. Suitable for tasks taking minutes/hours where assignment latency is negligible.