OPoI Protocol
OPoI — Optimistic Proof of Inference — is how Cloud Service pays miners for running AI inference. It runs alongside Proof of Work: the same miner can mine blocks and answer AI requests.
This page documents the consensus rules. For using the chat, see AI Chat; for mining setup, see OPoI Mining.
The cycle
REQUEST → assignment → inference → COMMIT → window → REVEAL → payment
on-chain off-chain off-chain on-chain closes on-chain coinbaseA requester posts a REQUEST on-chain carrying the model name, a hash of the prompt, and a declared payment. The prompt text itself never touches the chain — it reaches the miner off-chain.
The miner runs the model, then posts a COMMIT: a hash of its answer plus a secret nonce. Once the commit window closes, an eligible miner posts the REVEAL, and the answer becomes public and provable.
Transactions carry no value
OPoI transactions are required to have empty inputs and outputs. Consensus rejects any that don't. They move no funds.
Miners are paid from the block coinbase, and that payment must fit inside the normal block subsidy — it is not added on top of it. A block whose coinbase exceeds the subsidy is invalid, so an inflated payment field cannot mint coins; it simply makes the block unminable, and no miner would include it.
The practical consequence: a requester needs no balance. The declared payment sizes the miner's share of a reward that already exists.
The commit-reveal window
No REVEAL is accepted before the window closes, and no COMMIT after. Closing the commit phase for everyone at the same height is what prevents copying: while commits are still open, no answer is public to copy.
| Network | Window | At target block time |
|---|---|---|
| Mainnet | 144 blocks | ~4.8 hours |
| Testnet | 20 blocks | ~20 minutes |
| Regtest | 3 blocks | seconds |
Settlement is not delivery
The window governs when an answer becomes public and provable — not when the person who asked may see it. Clients are expected to deliver the answer to the requester as soon as the miner produces it, and let settlement finish in the background. The window protects miners from each other, not the requester from their own answer.
Who may answer: VRF sortition
Not every miner may reveal an answer. Eligibility is decided by an ECVRF sortition, seeded from the hash of the block the REQUEST itself was mined in.
That seed never changes once mined, which makes eligibility deterministic and permanent for each (request, address) pair. A miner that isn't selected for a request will never be selected for it — retrying is futile.
Adaptive threshold
The threshold is derived from the number of ACTIVE stakers recorded when the request was mined:
threshold = 2^256 × target / stakerswith target (nOPoIVrfTargetEligible) defaulting to 3 — roughly three miners eligible per request.
This holds coverage near 95% at any network size. A fixed threshold only works at one specific size: calibrated for a thousand miners, it leaves a ten-miner network answering a small fraction of requests, with the requester paying either way.
| Active stakers | Threshold | Chance a request gets answered |
|---|---|---|
| 10 | 30% | 97% |
| 25 | 12% | 96% |
| 100 | 3% | 95% |
| 1000 | 0.3% | 95% |
Adding your own addresses does not help
If you control every staker, coverage stays near 95% regardless of how many addresses you run — adding addresses raises the denominator too. More addresses only multiply the commit transactions you pay for.
The staker count is frozen at the request's own block, never read live. A live count would differ between mempool acceptance and mining, and between one node's view and another's — which is how a chain splits.
Activation: mainnet at block 100000 (OPoI's own activation), testnet at block 50. Below that height the fixed nOPoIVrfThreshold applies. Requests are judged by the rule in force when they were made, for their whole life.
Stake renewal
A staker must periodically prove liveness with a RENEW transaction. Miss the deadline and the stake goes SUSPENDED — it stays staked, but consensus rejects its responses until renewed. No collateral is slashed.
| Network | Deadline |
|---|---|
| Mainnet | 20160 blocks |
| Testnet | 200 blocks |
The deadline is in blocks, not time
A stake ages at the block rate, not at the rate a wall-clock timer fires. Any renewal scheduled on a fixed time interval will drift out of step whenever the block rate differs from what was assumed — and the failure is silent: responses just stop being accepted. Derive renewal from last_renewal_height and the current height instead.
The model must match
A miner may only answer requests for the model its stake declares. If stake.model_id is set and differs from the request's model, consensus rejects the commit.
An empty model_id matches any model.
Silent failure
A mismatch produces no error anywhere visible: the request is simply never answered, and expires. Operators configuring a chat should verify that at least one ACTIVE stake serves the configured model before enabling it.
Throughput
| Limit | Mainnet |
|---|---|
| Requests per block | 50 |
| Responses per block | 100 |
At two-minute blocks that is 36,000 requests per day for the entire network. This is a consensus parameter — adding miners raises capacity to serve, but not this ceiling.
Expiry
A PENDING request that nobody answers expires: 2016 blocks on mainnet, 200 on testnet. The declared payment is not paid out.