How Akash Network Handles IP Lease Assignments and Endpoint Management
Akash manages IP lease assignments by storing lease state on-chain in the market module while delegating actual endpoint allocation to the provider's runtime configuration, requiring clients to query both modules to resolve full service endpoints.
The akash-network/node repository implements a decentralized compute marketplace where leases represent the binding contract between client orders and provider resources. While the blockchain tracks lease ownership and state, the actual IP addresses and service endpoints are managed through a combination of on-chain identifiers and off-chain provider host configuration.
On-Chain Lease Creation in the Market Module
When a provider accepts a bid, the market keeper instantiates a lease record that serves as the canonical reference for the provider-client pairing. In x/market/keeper/keeper.go, the CreateLease function builds and persists this record:
func (k Keeper) CreateLease(ctx sdk.Context, bid types.Bid) error {
lease := mv1.Lease{
ID: bid.ID.LeaseID(),
Price: bid.Price,
State: mv1.LeaseActive,
}
pk := keys.LeaseIDToKey(lease.ID)
return k.leases.Set(ctx, pk, lease)
}
The LeaseID derives from the order owner, deployment sequence (dseq), group sequence (gseq), and provider address. This identifier uniquely links the on-chain lease to the provider's advertised resources, though the endpoint data itself is added later by the provider's runtime rather than stored in the on-chain proto.
Provider-Side Endpoint Allocation
The actual network endpoint—comprising IP address and port—lives in the provider's host configuration rather than the blockchain state. The system handles allocation differently depending on the environment.
Production Host Configuration
In production deployments, providers define their endpoints through the Host configuration stored via the provider module. The CreateProvider and UpdateProvider MsgServers in x/provider/handler/server.go persist these definitions:
// x/provider/handler/server.go
func (s msgServer) CreateProvider(goCtx context.Context, msg *v1beta4.MsgCreateProvider) (*v1beta4.MsgCreateProviderResponse, error) {
// Validation and storage of Host definition containing service endpoints
// Host.Services[].Endpoint provides the accessible host:port
}
Each Host contains a list of services with endpoint specifications (host:port) supplied via the provider CLI or infrastructure tools like Helm charts. When the provider runtime accepts a lease, it binds these pre-configured endpoints to the workload.
Testnet IP Generation
For local testnets, Akash automatically assigns sequential IPv4 addresses to validators. The calculateIP function in cmd/akash/cmd/testnet.go generates these addresses based on a starting-ip-address flag:
func calculateIP(ip string, i int) (string, error) {
ipv4 := net.ParseIP(ip).To4()
if ipv4 == nil {
return "", fmt.Errorf("invalid ipv4")
}
// Increment the last octet by index i
ipv4[3] = ipv4[3] + byte(i)
return ipv4.String(), nil
}
This utility creates sequential IPs (e.g., 192.168.0.1, 192.168.0.2) for each validator-node pair during testnet initialization, simulating network allocation without requiring manual configuration.
Endpoint Discovery via Market Queries
Clients discover service endpoints through a two-phase lookup process combining market and provider queries. First, x/market/query/path.go constructs the query path for lease lookups:
fmt.Sprintf("%s/%s/%s", leasePath, orderParts(id.OrderID()), id.Provider)
The GetLease handler in x/market/handler/server.go returns the lease record containing the provider address, but not the endpoint itself. Client utilities such as those in client/utils.go perform the resolution:
func ResolveLeaseEndpoint(leaseID types.LeaseID) (string, error) {
// 1. Query market module for lease → retrieve provider address
provider, err := queryMarketProvider(leaseID.Provider)
// 2. Query provider module for Host definition
host, err := queryProviderHost(provider)
// 3. Compose endpoint from first service (host:port)
return fmt.Sprintf("%s:%d", host.Services[0].Host, host.Services[0].Port), nil
}
This architecture separates the concerns of lease ownership (on-chain) from network topology (off-chain), allowing providers to manage their infrastructure independently while maintaining verifiable lease records.
Lease Lifecycle and Endpoint Teardown
When a lease terminates due to insufficient funds or quota exhaustion, the market keeper updates the on-chain state without directly managing network resources. The OnLeaseClosed function in x/market/keeper/keeper.go handles this transition:
func (k Keeper) OnLeaseClosed(ctx sdk.Context, lease mv1.Lease) error {
lease.State = mv1.LeaseClosed
lease.ClosedOn = ctx.BlockHeight()
return k.leases.Set(ctx, keys.LeaseIDToKey(lease.ID), lease)
}
The provider runtime monitors these state changes and must stop serving traffic on the allocated endpoint. Provider deletion remains partially implemented; the DeleteProvider MsgServer in x/provider/handler/server.go currently contains a TODO comment (// TODO: cancel leases) indicating that future implementations will iterate active leases, invoke OnLeaseClosed, and instruct the runtime to release allocated IPs.
Summary
- Lease creation occurs in
x/market/keeper/keeper.goviaCreateLease, generating a unique LeaseID from order and provider data. - Endpoints are defined in the provider's Host configuration (
x/provider/handler/server.go), not stored on-chain, allowing flexible infrastructure management. - Testnet IPs are auto-generated sequentially using
calculateIPincmd/akash/cmd/testnet.gofor local development environments. - Client discovery requires querying the market module for the provider address, then the provider module for the Host definition to assemble the full endpoint.
- Lease closure updates on-chain state via
OnLeaseClosedbut relies on the provider runtime to release the actual network endpoint.
Frequently Asked Questions
Where is the IP address stored for an Akash lease?
The IP address and port are not stored on-chain. According to the Akash source code, endpoints reside in the provider's Host configuration, which is persisted through the provider module's MsgServer while the market module only tracks the lease state and provider address.
How does a client find the endpoint for their deployed workload?
Clients must perform a two-step resolution: first query the market module (x/market/handler/server.go) to retrieve the lease and provider address, then query the provider module for that provider's Host definition containing the service endpoints. This pattern is implemented in client utilities like ResolveLeaseEndpoint.
What happens to the endpoint when a lease is closed?
When a lease closes, the OnLeaseClosed function in x/market/keeper/keeper.go updates the lease state to LeaseClosed and records the block height, but the blockchain does not directly release the IP or port. The provider's runtime must detect this state change and stop serving traffic on that endpoint.
Does Akash support dynamic IP allocation for testnets?
Yes. For local testnets, the calculateIP function in cmd/akash/cmd/testnet.go automatically assigns sequential IPv4 addresses (e.g., 192.168.0.1, 192.168.0.2) to validators based on a configurable starting IP address flag, eliminating the need for manual network configuration during development.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →