All posts

Provider & Model Registry

9 min read · ComputeFlux Team
Runtime Infrastructure

In one sentence. Anyone can register as a provider and list models at prices they choose; the network doesn't police honesty, it tries to make dishonesty unprofitable.

Picture it like this. A farmers' market with no inspector at the gate. You can claim your stall handles a thousand customers an hour — nobody checks. But if you can't, orders back up, buyers leave, and the market's own signage starts pointing the next crowd at the stall beside you. And you only get one stall: your reputation is welded to a single identity you can't shed and re-register under.

Why it matters. Every marketplace has to answer "what stops bad actors?" Centralized ones answer with a review team. This one answers with economics. Worth reading closely, because this article is unusually candid about where that answer is currently thinner than the design intends.

Just want the routing consequences? Skip to the providerType split.


ComputeFlux's Provider Registry is not a directory of available models. It's an economic system. Every registration decision carries financial consequences, every model listing sets its own prices, and every API key is a binding commitment between a provider and the network. Making sense of it means looking at how staking, scheduling, and security pull on each other — and everything in ComputeFlux's routing layer sits on top of it, from personal GPU edge routes (Article 7) to sticky balancer scheduling (Article 8).

The Economics of Provider Registration

Provider registration includes a deposit value supplied by the registrant. It's worth being precise about what that value does today, because the name suggests more than the code delivers.

The deposit is not locked and later refunded, and registration isn't gated on it clearing any minimum. What it does is feed the provider's initial scheduling Priority, on a tiered scale: a higher declared deposit buys a higher priority tier. That's a genuine economic lever — better routing priority requires committing to a larger number — but as implemented, deposit is a self-reported input to a priority calculation, not a token-locking, Sybil-resistant registration gate. Delivering that anti-Sybil guarantee, which is the natural reason to have a deposit field at all, would take a minimum-deposit requirement or an enforced on-chain lock layered on top.

Because the provider picks the amount, provider types don't face different minimums either. An OpenAI reseller and a personal GPU operator are treated identically, since no minimum is enforced for anyone. Gating registration on a type-specific minimum, with real token locking and refund on graceful exit, is a natural extension of the priority-tier mechanism — not something already in place.

The one-provider-per-address constraint (the providerByOwner mapping) stops a single entity from fragmenting its deposit across multiple identities. The restriction is deliberate. A provider serving several model types — OpenAI-proxied and local GPU models, say — uses one provider record with multiple model registrations under it. The address becomes a reputation anchor: every model, every API key, and all settlement history trace back to it, which is what makes reputational damage cost something.

The IsActive boolean is the kill switch. Deactivate a model or provider and it drops out of Gateway scheduling immediately, either through an explicit call or automatically when a model's on-chain balance runs dry. Deactivation doesn't destroy data. A deactivated model can be reactivated later and reappears in the routing table without re-registration, so maintenance windows don't cost a provider its established routing weights.

The providerType Enum and Scheduling Divergence

The providerType field is a uint16 with four defined values — ProviderOpenAI(1), ProviderClaude(2), ProviderGemini(3), and ProviderPersonal(9999) — and its impact extends far beyond protocol selection. Each type triggers a fundamentally different scheduling path.

Types 1–3 (Remote API Providers): The Gateway forwards requests to the provider's official API endpoint (or a custom uri). Authentication uses the provider's native API key format: Bearer token for OpenAI, x-api-key for Anthropic, x-goog-api-key for Gemini. The Gateway's Adaptor system (Article 12) handles protocol conversion transparently. Scheduling is straightforward: an endpoint's Concurrency field limits parallel requests, and standard HTTP health checking determines availability.

Type 9999 (Personal): This is the Edge Route, covered in full in Article 7. There's no remote API to call. The Gateway has to find an active yamux tunnel connection from the provider's own machine, which turns the scheduling decision into two questions. Is the provider registered and active on-chain? And is there a live tunnel session in the Local Tunnel pool? A provider that passes the first check and fails the second is silently skipped — the router filters out any providerType == Personal model without an active session.

The Personal type also changes the failure model. For remote API providers, transient errors like 5xx responses and timeouts trigger retry with exponential backoff (Article 9). For Personal providers, a connection failure usually means the tunnel dropped, and retrying immediately is pointless because a separate heartbeat loop owns reconnection. So the failure blacklists that endpoint for the current request and falls through to the next one available.

MaxConcurrency vs Balance: Two Dimensions of Resource Limits

These two fields represent fundamentally different constraints, and confusing them leads to subtle bugs.

MaxConcurrency is a scheduling constraint enforced by the Gateway in-memory. Before dispatching a request, the Scheduler checks ep.InFlight() >= ep.Concurrency; an endpoint at capacity is skipped for this selection round. This is a soft limit — it only affects routing, not billing, and resets instantly when in-flight requests complete. It's appropriate for rate-limiting scenarios where the concern is overwhelming the upstream service.

Balance is an economic constraint enforced on-chain, representing the provider's prepaid credit for paying relay gas fees. When a request completes, the Gateway deducts from this balance based on token usage and the model's pricing tiers (Article 10 covers settlement in full). If balance reaches zero, the provider's models remain listed but requests fail with an "insufficient balance" error rather than being silently dropped — a hard limit with financial consequences, unlike Concurrency.

The interaction between these two limits creates a natural congestion control mechanism. A popular provider with high Concurrency but low Balance accepts many requests simultaneously but quickly exhausts credit, causing subsequent requests to fail with payment errors. A provider with high Balance but low Concurrency gets throttled by the Gateway before ever approaching its balance limit. The system encourages providers to set both limits appropriately for their economic model.

Providers set MaxConcurrency at registration and can update it later. Nothing validates it against physical reality — a single-GPU machine can claim Concurrency=1000. The Gateway doesn't enforce truthfulness here; the market does. Overstate your capacity and requests queue, then time out, which raises your failure rate, which lowers your routing score, which cuts the traffic you receive. The incentive points squarely at declaring something close to actual capacity.

API Key Binding and the Security Model of Key Ownership Verification

When a provider registers a model with apiKeys: ["sk-abc123..."], nothing cryptographically proves they own that key. Register someone else's leaked key and you get caught the way any invalid credential gets caught: it fails with a 401 or 403 the first time the Gateway actually uses it against the upstream provider.

That is meaningfully weaker than a registration-time challenge-response check, and adding one is exactly the kind of hardening this design would benefit from. What holds today is narrower: once a key is bound to a model, every subsequent request uses it without re-verification, so a key revoked upstream keeps failing requests until the provider updates it.

The apiKeys field is a slice, not a single value — a provider can register multiple keys (from different billing accounts, say), and the Scheduler selects among them with the same weighted-selection algorithm used for endpoints. This enables key-level load balancing and a fallback path: if one key is rate-limited, the Scheduler marks it "used" and selects the next available key for the retry.

Settlement and Price Configuration

Each model registration specifies three price points: inPrice (per million input tokens), outPrice (per million output tokens), and cachedPrice (per million cached input tokens, used when Anthropic's prompt caching is active). Prices are denominated in the chain's smallest unit, integers suitable for deterministic computation.

The Gateway does not set or validate prices. A provider can list GPT-4 far below OpenAI's actual price or far above market rate — the market, specifically user wallet balances and payment authorization, enforces reasonable pricing. Prices too high get no traffic; prices too low exhaust the provider's balance as the Gateway's margin goes negative.

That laissez-faire stance fits the system's decentralized character, and it leaves a real consumer protection gap. Nothing stops a bait-and-switch: list low prices, build a user base, then raise them. Closing it would take on-chain price-change notifications or governance-enforced ceilings. Neither exists yet.


Key Takeaways

  • One identity per address, on purpose. You cannot spread a damaged reputation across throwaway accounts. Every model, every key, every settlement traces back to one anchor, which is what makes reputational damage actually cost something.
  • The "deposit" is labeled honestly here. Today it buys a scheduling priority tier based on a self-reported number. It is not yet a locked, Sybil-resistant stake. This article says that plainly instead of letting the word "deposit" imply a guarantee the code doesn't make.
  • Two limits that get confused constantly. Concurrency is a soft routing cap that clears the instant a request finishes. Balance is a hard economic floor with a real failure at the bottom. Together they produce congestion control nobody had to design separately.
  • Nobody verifies your claims — the market does. Overstate your capacity and requests queue, time out, and drive your failure rate up until the scheduler routes around you. Price above the market and you get no traffic; price below your cost and you drain your own balance.
  • A known, unpatched gap. Nothing currently prevents listing cheap to attract users and raising prices afterward. Closing it needs on-chain price-change notice or governance-set ceilings, and neither exists yet.

The Provider Registry is a reputation engine disguised as a directory. Every parameter — deposit-derived priority, balance, concurrency, pricing, API key binding — exists to align provider incentives with network health. Set honest capacity limits, keep your balance funded, and price competitively, and the Gateway's weighted selection sends you more traffic (Article 8). Misrepresent any of it and you pay in failed requests, drained balances, and a falling routing score.

The system doesn't stop bad actors from registering. It tries to make bad behavior unprofitable — though as noted above, a genuinely Sybil-resistant gate would need more than today's declared-deposit mechanism. And the ProviderPersonal type is the doorway into a completely different problem, one with nothing to do with economics.

Next — Article 7: Edge Route: Personal GPU: the registry says a personal GPU is allowed to serve requests. But how does the network even reach a machine sitting behind a residential router with no public address?