# Akash Provider Module: Role and Market Interaction Explained

> Understand the Akash provider module's role as a compute provider registry and its market interaction for bid validation lease creation and rule enforcement.

- Repository: [Akash Network/node](https://github.com/akash-network/node)
- Tags: deep-dive
- Published: 2026-02-24

---

**The provider module in the Akash Network acts as the authoritative registry for compute providers, storing their addresses, host URIs, and attributes, while the market module consumes this data via the ProviderKeeper interface to validate bids, create leases, and enforce provider-centric rules.**

The `akash-network/node` repository implements the provider module as a Cosmos SDK module responsible for on-chain provider identity management. This module maintains the canonical state of all compute providers in the network and exposes a read-only interface that the market module relies on to ensure every bid and lease references a valid, registered entity.

## Provider Module Core Responsibilities

The provider module serves as the single source of truth for provider metadata within the Akash ecosystem. It handles four critical functions that enable the decentralized cloud marketplace to operate securely.

### Provider Registry and State Management

At the heart of the module lies the **provider keeper**, implemented in [`x/provider/keeper/keeper.go`](https://github.com/akash-network/node/blob/main/x/provider/keeper/keeper.go), which persists provider objects to the blockchain state. Each provider is stored under a unique key `ProviderKey(owner)` and contains the owner address, host URI, and capability attributes. The keeper emits `EventProviderCreated` and `EventProviderUpdated` events during state transitions, allowing external observers to track provider lifecycle changes.

### Message Handling for Provider Lifecycle

The module processes three primary transaction types through its message handler defined in [`x/provider/handler/handler.go`](https://github.com/akash-network/node/blob/main/x/provider/handler/handler.go):

- **MsgCreateProvider**: Registers a new provider with initial attributes
- **MsgUpdateProvider**: Modifies existing provider metadata such as the host URI or capability attributes  
- **MsgDeleteProvider**: Removes a provider from the active registry

The `NewHandler` function routes these messages to `MsgServerImpl`, which validates and executes state changes through the keeper.

### Query Services and Module Wiring

In [`x/provider/module.go`](https://github.com/akash-network/node/blob/main/x/provider/module.go), the `RegisterServices` function exposes both the message server and a gRPC querier, enabling other modules and external clients to fetch provider data. The module also implements `DefaultGenesis`, `InitGenesis`, and `WeightedOperations` to support chain initialization and simulation testing.

## Market Module Integration and Provider Validation

The market module does not maintain its own provider state; instead, it depends on the provider module through a well-defined interface. This dependency injection pattern ensures loose coupling while maintaining data consistency.

### ProviderKeeper Interface Contract

Defined in [`x/market/handler/keepers.go`](https://github.com/akash-network/node/blob/main/x/market/handler/keepers.go), the **ProviderKeeper** interface specifies the minimal methods required by the market module:

```go
type ProviderKeeper interface {
    Get(sdk.Context, sdk.AccAddress) (ptypes.Provider, bool)
    WithProviders(sdk.Context, func(ptypes.Provider) bool)
}

```

The market module receives a concrete implementation of this interface during initialization. In [`x/market/module.go`](https://github.com/akash-network/node/blob/main/x/market/module.go), the `NewAppModule` constructor accepts a `handler.ProviderKeeper` parameter and stores it within the market keepers struct, establishing the wiring between the two modules.

### Bid and Lease Validation

When creating a bid, the market handler in [`x/market/handler/server.go`](https://github.com/akash-network/node/blob/main/x/market/handler/server.go) performs strict provider validation. The handler extracts `msg.ID.Provider` from the incoming `MsgCreateBid` transaction and invokes `ms.keepers.Provider.Get` to verify the address exists. If the lookup fails, the transaction aborts with `v1.ErrUnknownProvider`, preventing bids from referencing non-existent providers.

During lease creation and withdrawal operations, the market handler additionally queries audited provider attributes via `ms.keepers.Audit.GetProviderAttributes`. This ensures that only providers meeting specific audit criteria can participate in active leases.

### Market-Wide Provider Iteration

For housekeeping operations such as cleaning stale bids or calculating global statistics, the market module uses `WithProviders` to iterate over the entire provider set without loading them all into memory simultaneously. This efficient iteration pattern is defined in the keeper interface and implemented in the provider module's state layer.

## Practical Implementation: Creating Providers and Bids

The following example demonstrates the end-to-end interaction between the provider and market modules, showing how a provider registration enables subsequent market operations.

```go
// Step 1: Register a provider via the provider module
prov := ptypes.Provider{
    Owner:   "akash1xyz...",              // Bech32 provider address
    HostUri: "https://provider.example.com",
    Attributes: []atypes.Attribute{
        {Key: "region", Value: "us-east"},
        {Key: "tier", Value: "compute"},
    },
}

// Create through the provider keeper (IKeeper from x/provider/keeper)
err := providerKeeper.Create(ctx, prov)
if err != nil {
    panic(err)
}

// Step 2: Create a market bid referencing the registered provider
bid := v1.MsgCreateBid{
    ID: v1.BidID{
        Provider: prov.Owner,              // References the provider above
        // Additional bid identifiers...
    },
    Price: sdk.NewCoin("uakt", sdk.NewInt(1000)),
    // Additional bid parameters...
}

// Initialize market message server with injected keepers
msgSrv := marketHandler.NewServer(keepers) // keepers.Provider implements ProviderKeeper
res, err := msgSrv.CreateBid(ctx, &bid)
if err != nil {
    // Returns v1.ErrUnknownProvider if prov.Owner is not found in provider state
    // (see x/market/handler/server.go validation logic)
}

```

In this flow, the **provider keeper** manages the creation and persistence of provider data, while the **market handler** consumes this data through the `ProviderKeeper` interface to validate bid integrity.

## Summary

- The **provider module** maintains the canonical registry of all compute providers, storing addresses, host URIs, and attributes in [`x/provider/keeper/keeper.go`](https://github.com/akash-network/node/blob/main/x/provider/keeper/keeper.go).
- It exposes **CRUD operations** through `MsgCreateProvider`, `MsgUpdateProvider`, and `MsgDeleteProvider` handlers in [`x/provider/handler/handler.go`](https://github.com/akash-network/node/blob/main/x/provider/handler/handler.go).
- The **market module** consumes provider data via the **ProviderKeeper** interface defined in [`x/market/handler/keepers.go`](https://github.com/akash-network/node/blob/main/x/market/handler/keepers.go), enabling loose coupling between the two systems.
- **Bid validation** occurs in [`x/market/handler/server.go`](https://github.com/akash-network/node/blob/main/x/market/handler/server.go), where the market handler verifies provider existence before accepting bids, returning `ErrUnknownProvider` for invalid references.
- **Lease operations** leverage provider attributes fetched through the keeper interface to enforce audit requirements and provider-specific policies.

## Frequently Asked Questions

### How does the market module access provider data without direct state access?

The market module uses **dependency injection** to receive a `ProviderKeeper` interface implementation during app initialization. This interface, defined in [`x/market/handler/keepers.go`](https://github.com/akash-network/node/blob/main/x/market/handler/keepers.go), exposes only `Get` and `WithProviders` methods, allowing the market module to query provider state while the provider module retains full control over the underlying storage implementation.

### What happens if a bid references a provider that does not exist?

The market handler in [`x/market/handler/server.go`](https://github.com/akash-network/node/blob/main/x/market/handler/server.go) validates every `MsgCreateBid` by calling `ms.keepers.Provider.Get` with the provider address from the bid ID. If the provider is not found in the state, the transaction fails immediately with `v1.ErrUnknownProvider`, ensuring the market only processes bids from registered entities.

### Can provider attributes be updated after registration?

Yes. The provider module supports attribute modification through `MsgUpdateProvider`, handled in [`x/provider/handler/handler.go`](https://github.com/akash-network/node/blob/main/x/provider/handler/handler.go). When executed, the keeper updates the existing provider object under `ProviderKey(owner)` and emits an `EventProviderUpdated` event, making the new attributes immediately available to the market module for subsequent bid and lease evaluations.

### Where is the boundary between provider and market module responsibilities?

The **provider module** owns all state mutations and persistence logic for provider entities, including the `Create`, `Update`, and `Delete` keeper methods. The **market module** acts as a consumer, using the read-only `ProviderKeeper` interface to validate references and fetch attributes during bid creation and lease management, but never directly modifying provider state.