The Application Layer is where Akash’s blockchain logic lives. Built on the Cosmos SDK, this layer implements all blockchain functionality including accounts, tokens, staking, governance, and Akash’s unique marketplace features.
Application Architecture
+---------------------------------------------------------------+| Application Layer (ABCI) || || +----------------------------------------------------------+ || | AkashApp | || | | || | +-----------------------+ +-----------------------+ | || | | Module Manager | | Keepers | | || | | - Register Modules | | - Cosmos Keepers | | || | | - Order Execution | | - Akash Keepers | | || | | - Genesis | | - State Access | | || | +-----------------------+ +-----------------------+ | || | | || | +-----------------------+ +-----------------------+ | || | | Codec | | Transaction Router | | || | | - Proto/Amino | | - Message Routing | | || | | - Serialization | | - Handler Dispatch | | || | +-----------------------+ +-----------------------+ | || +----------------------------------------------------------+ || | || | ABCI Interface || v |+---------------------------------------------------------------+ | CometBFT ConsensusABCI Interface
The Application Blockchain Interface (ABCI) connects CometBFT consensus to the application logic.
ABCI Methods
Block Lifecycle:
PreBlock → BeginBlock → [DeliverTx...] → EndBlock → Commit1. PreBlock
PreBlock(RequestPreBlock) → ResponsePreBlock- Called before BeginBlock
- Used for upgrades and module initialization
- Introduced in Cosmos SDK v0.50
2. BeginBlock
BeginBlock(RequestBeginBlock) → ResponseBeginBlock- Called at block start
- Updates validator set
- Distributes block rewards
- Processes evidence
3. DeliverTx
DeliverTx(RequestDeliverTx) → ResponseDeliverTx- Called for each transaction in block
- Executes transaction logic
- Updates state
- Emits events
- Returns gas used
4. EndBlock
EndBlock(RequestEndBlock) → ResponseEndBlock- Called at block end
- Module end-block logic
- Validator set updates
- Returns validator changes
5. Commit
Commit() → ResponseCommit- Persists state to disk
- Computes app hash (state root)
- Returns app hash to CometBFT
Additional ABCI Methods
CheckTx - Validate transaction before mempool
CheckTx(RequestCheckTx) → ResponseCheckTxQuery - Query application state
Query(RequestQuery) → ResponseQueryInitChain - Initialize chain from genesis
InitChain(RequestInitChain) → ResponseInitChainModule System
Akash uses a modular architecture where each module handles specific functionality.
Module Structure
Each module contains:
- Keeper - State access and business logic
- Messages - User-initiated state changes
- Queries - Read-only state access
- Genesis - Initial state
- Events - Notifications of state changes
Module├── keeper/│ ├── keeper.go # State access│ ├── msg_server.go # Message handlers│ └── query.go # Query handlers├── types/│ ├── msgs.go # Message definitions│ ├── genesis.go # Genesis state│ └── events.go # Event types└── module.go # Module interfaceCosmos SDK Modules
Standard modules from Cosmos SDK that provide core blockchain functionality.
Auth Module
Purpose: Account authentication and signature verification
Key Features:
- Account management (BaseAccount, ModuleAccount)
- Signature verification
- Account sequences (nonce)
- Public key storage
Account Types:
BaseAccount // Standard user accountModuleAccount // Module-owned accountVestingAccount // Time-locked tokensKey Functions:
GetAccount(addr) → AccountSetAccount(account)NewAccountWithAddress(addr) → Account
Bank Module
Purpose: Token transfers and balance management
Key Features:
- Send tokens between accounts
- Track balances per denom
- Supply tracking
- Module-to-module transfers
Message Types:
MsgSend // Send tokens to addressMsgMultiSend // Send to multiple addressesQueries:
QueryBalance // Get account balanceQueryAllBalances // Get all denomsQuerySupply // Get total supplyExample:
# Query balanceakash query bank balances akash1abc...
# Send tokensakash tx bank send <from> <to> 1000000uaktStaking Module
Purpose: Proof-of-Stake consensus and delegation
Key Features:
- Validator registration
- Delegation/undelegation
- Rewards distribution
- Slashing for misbehavior
Validator States:
Unbonded → Unbonding → BondedMessage Types:
MsgCreateValidator // Register as validatorMsgEditValidator // Update validator infoMsgDelegate // Delegate to validatorMsgUndelegate // Undelegate from validatorMsgBeginRedelegate // Move delegationParameters:
UnbondingTime: 336h // 2 weeksMaxValidators: 100 // Top 100 by stakeMaxEntries: 7 // Max unbonding opsHistoricalEntries: 10000 // Historical info keptMinCommissionRate: 0.05 // 5% minimumDistribution Module
Purpose: Fee distribution to validators and delegators
Key Features:
- Block reward distribution
- Transaction fee distribution
- Commission for validators
- Community pool management
Distribution Flow:
Block Rewards + Fees → Validator Commission (5-20%) → Delegator Rewards (proportional) → Community Pool (if tax > 0%)Message Types:
MsgWithdrawDelegatorReward // Claim rewardsMsgWithdrawValidatorCommission // Claim commissionMsgFundCommunityPool // Donate to poolParameters:
CommunityTax: 0 // 0% to community poolWithdrawAddrEnabled: true // Allow changing withdraw addressGovernance Module
Purpose: On-chain governance and proposals
Key Features:
- Submit proposals
- Vote on proposals
- Tally votes
- Execute approved proposals
Proposal Types:
- Text Proposal - Signal/coordination
- Parameter Change - Update chain parameters
- Software Upgrade - Coordinate upgrades
- Community Pool Spend - Spend from pool
Voting Options:
Yes, No, Abstain, NoWithVetoParameters:
MinDeposit: 2500000000uakt // 2,500 AKTMaxDepositPeriod: 336h // 2 weeksVotingPeriod: 72h // 3 daysQuorum: 0.2 // 20% must voteThreshold: 0.5 // 50% yes to passVetoThreshold: 0.334 // 33.4% veto failsLifecycle:
Proposal Submitted → Deposit Period (2 weeks) → Voting Period (3 days) → Tally → Pass/Reject/VetoSlashing Module
Purpose: Penalize validator misbehavior
Slashing Conditions:
1. Downtime:
- Miss 50%+ blocks in window
- Penalty: 0.01% slash
- Jailed (can unjail)
2. Double-Signing:
- Sign two blocks at same height
- Penalty: 5% slash
- Permanently tombstoned
Parameters:
SignedBlocksWindow: 30000 // ~41 hoursMinSignedPerWindow: 0.5 // Must sign 50%+DowntimeJailDuration: 600s // 10 min jailSlashFractionDoubleSign: 0.05 // 5%SlashFractionDowntime: 0.0001 // 0.01%Mint Module
Purpose: Token inflation
Inflation Model:
Target: 7-20% APR (adjusts based on bonding ratio)Target Bonding Ratio: 67%Inflation adjusts:
- High bonding → Lower inflation
- Low bonding → Higher inflation
Block Rewards:
Reward = (Inflation × TotalSupply) / BlocksPerYearIBC Module
Purpose: Inter-Blockchain Communication
Key Features:
- Cross-chain token transfers
- Cross-chain contract calls
- Light client verification
- Channel/connection management
Transfer Flow:
Source Chain → Lock Tokens → Relay Packet → Target Chain → Mint IBC TokensAkash Marketplace Modules
Akash-specific modules that implement decentralized cloud marketplace.
Deployment Module
Purpose: Workload deployments on Akash
Location: x/deployment
Key Entities:
Deployment:
message Deployment { DeploymentID id = 1; DeploymentState state = 2; bytes version = 3; int64 created_at = 4;}States:
Active → ClosedMessage Types:
MsgCreateDeployment // Create new deploymentMsgUpdateDeployment // Update (new manifest version)MsgCloseDeployment // Close deploymentLifecycle:
Create Deployment (with SDL) → Order Created (in Market module) → Bids Received → Lease Created → Deployment Active → Close Deployment → Lease ClosedMarket Module
Purpose: Order book and lease management
Location: x/market
Key Entities:
Order:
- Created automatically from deployment
- Contains resource requirements
- Triggers bid matching
Bid:
- Provider’s offer to fulfill order
- Includes pricing
- Must match all requirements
Lease:
- Accepted bid
- Active workload placement
- Escrow payment handling
Message Types:
MsgCreateBid // Provider bids on orderMsgCloseBid // Close bidMsgWithdrawLease // End lease earlyMsgCloseLease // Close leaseState Flow:
Order (Open) ↓Bids Received ↓Lease Created (Order → Matched) ↓Lease Active ↓Lease ClosedProvider Module
Purpose: Provider registration and attributes
Location: x/provider
Provider Entity:
message Provider { string owner = 1; string host_uri = 2; repeated Attribute attributes = 3; ProviderInfo info = 4;}Attributes: Providers advertise capabilities:
- key: region value: us-west
- key: tier value: community
- key: hardware-cpu value: amd
- key: hardware-gpu value: nvidia-a100Message Types:
MsgCreateProvider // Register providerMsgUpdateProvider // Update attributesMsgDeleteProvider // Deregister providerEscrow Module
Purpose: Payment escrow for leases (ACT funding and provider payouts)
Location: x/escrow
How it works:
- Deposit at creation: Tenants fund escrow with ACT (USD-pegged compute credit). Deployment minimum deposit is in
uact. - Settlement: Providers are paid in ACT; escrow sends earnings in the payment denom (uact) to the provider on withdraw.
- Circuit breaker: When mint is halted (low collateral ratio), tenants can deposit AKT and the module settles overdrawn payments from AKT funds (
settleFromAktFallback), sending uakt to the provider. Otherwise use ACT.
Deployment Created ↓Escrow Account Created ↓Tenant Deposits ACT (or AKT when circuit breaker active) ↓Lease Created ↓Funds Locked in Escrow (uact) ↓Block-by-Block Payment (ACT) ↓Provider Withdraws Earnings (ACT) ↓Lease Closed → Refund BalanceAccount Types:
DeploymentAccount // Per deploymentLeaseAccount // Per lease (payment per lease)Settlement:
- Payments calculated per block in ACT (uact)
- Provider can withdraw anytime; receives ACT
- Tenant can top up escrow (ACT preferred; AKT when circuit breaker in effect)
- Refund on lease close
BME Module
Purpose: Burn-Mint-Equilibrium (ACT/AKT vault, ledger, circuit breakers)
Location: x/bme
Responsibilities:
- Vault and ledger: Tracks burned AKT (remint credits), processes ACT↔AKT burn/mint via pending ledger records.
- EndBlocker: Settles ACT→AKT (e.g. for provider payouts from escrow-driven burn) and AKT→ACT (mint ACT when circuit breaker allows) each block.
- Circuit breakers: Mint status (e.g. warning/halt) based on collateral ratio; when halted, new ACT mints pause and escrow can use AKT fallback.
Integrations: Escrow keeper uses BME for GetMintStatus only; settlement payouts in ACT are handled by escrow (payment denom uact).
Oracle Module
Purpose: Price feeds (e.g. AKT/USD) for escrow and remint
Location: x/oracle
Responsibilities:
- Aggregated price for denoms (e.g.
uakt,uact) used by escrow and the vault for conversions and circuit-breaker fallback (AKT price for uact→uakt).
Prices are supplied by an off-chain relayer (Hermes) that submits signed price data to CosmWasm contracts (Pyth, Wormhole); the Pyth contract then pushes updates into x/oracle. See Oracle price pipeline below.
Oracle Price Pipeline: Hermes and CosmWasm Contracts
The oracle uses a Hermes relayer and two CosmWasm contracts (Wormhole and Pyth) to bring attested price feeds on-chain. These contracts are deployed at chain upgrade; uploading or updating contract code is only allowed via governance proposal (see Wasm module below).
Flow: Hermes (off-chain) → Pyth contract (verifies VAA via Wormhole, parses price) → x/oracle
Hermes (Price Relayer)
Purpose: Off-chain service that fetches Pyth price attestations and submits them to the chain.
How it works:
- Hermes runs as a separate process (e.g. container
ghcr.io/akash-network/hermes). It is not part of the node binary. - It pulls price data and Verified Action Approvals (VAAs) from the Pyth Hermes API (
https://hermes.pyth.network). - It sends transactions to the Pyth CosmWasm contract on Akash (VAA payload, base64-encoded).
- Configuration typically includes:
RPC_ENDPOINT(node RPC),HERMES_ENDPOINT(Pyth API),CONTRACT_ADDRESS(Pyth contract),UPDATE_INTERVAL_MS, and gas/denom for fees.
Operational note: Validators or third parties run Hermes so that the chain receives continuous price updates. Without Hermes (or an equivalent relayer), oracle prices do not update. See Hermes Relayer Setup for installation and configuration.
Wormhole Contract (CosmWasm)
Purpose: Verify Wormhole VAAs (multi-guardian signatures) on-chain so that Pyth price payloads are trusted.
Location: Stored and instantiated via the Wasm module (CosmWasm/wasmd). Instantiated at Mainnet v2.0.0 upgrade; admin is the governance module.
Responsibilities:
- VAA verification: Any account can submit a VAA with
SubmitVAA. The contract checks signatures against the current guardian set (e.g. Wormhole mainnet guardian set). Parsed payloads are then available for other contracts. - Guardian set updates: Updates come from Wormhole governance VAAs (signed by 2/3+1 guardians). The contract stores the guardian set and expiration; no Akash governance proposal is required to apply a valid Wormhole governance VAA.
Key messages:
submit_vaa– Submit a base64-encoded VAA for verification and processing.- Queries:
guardian_set_info,get_state,verify_vaa, etc.
Pyth Contract (CosmWasm)
Purpose: Consume VAAs (delivered by Hermes), verify them via the Wormhole contract, parse Pyth price payloads, and relay prices to x/oracle.
Location: CosmWasm contract; instantiated after Wormhole at v2.0.0 upgrade. Admin is the governance module. Instantiation requires the Wormhole contract address.
Responsibilities:
- Receive execute messages containing VAA data (from Hermes).
- Use the Wormhole contract to verify the VAA.
- Parse the Pyth price feed payload (e.g. AKT/USD feed ID).
- Call into x/oracle to store/update the aggregated price.
Configuration: Stored in contract state (e.g. price feed ID, Wormhole contract address, data sources). Governance can update config via UpdateConfig (e.g. price feed ID, wormhole_contract, data_sources).
Wasm Module (CosmWasm Host)
Purpose: Host for CosmWasm smart contracts, including Wormhole and Pyth.
Location: Provided by wasmd (CosmWasm integration in the node). State lives under the wasm store (code and contract instances).
Code upload: Contract code (StoreCode) can only be uploaded via governance proposal. The node sets CodeUploadAccess to Nobody (Mainnet v2.0.0 upgrade); only the governance module is authorized to submit MsgStoreCode, so new or updated contract binaries must be proposed and voted on. Instantiation and migration of contracts can still be performed by the contract admin (e.g. governance).
Relevance to oracle: Wormhole and Pyth are stored and instantiated here; they execute in the Wasm VM and interact with x/oracle via the node’s module wiring. Governance (admin) can upgrade or migrate these contracts via standard CosmWasm messages.
Audit Module
Purpose: Provider auditing and attestations
Location: x/audit
Auditor Attributes: Auditors sign provider attributes:
auditor: akash1auditor...provider: akash1provider...attributes: - key: tier value: community - key: uptime value: 99.9Message Types:
MsgSignProviderAttributes // Auditor signsMsgDeleteProviderAttributes // Remove attestationCertificate Module
Purpose: TLS certificate management for mTLS
Location: x/cert
Purpose:
- Secure deployment communication
- Mutual TLS between tenant and provider
- On-chain certificate storage
Message Types:
MsgCreateCertificate // Publish certificateMsgRevokeCertificate // Revoke certificateTake Module
Purpose: Legacy network income distribution; no take-rate on lease settlements.
Location: x/take
Lease settlements are in ACT and providers are paid in ACT. The take module may remain in the codebase for legacy or future use but does not apply to escrow payouts.
State Management
IAVL Tree
State stored in Immutable AVL (IAVL) tree:
Features:
- Balanced binary search tree
- Immutable (versioned)
- Merkle proofs
- O(log n) operations
Store Structure:
Root (AppHash)├── auth/│ ├── accounts/│ └── params/├── bank/│ ├── balances/│ └── supply/├── staking/│ ├── validators/│ └── delegations/├── deployment/│ ├── deployments/│ └── groups/├── market/│ ├── orders/│ ├── bids/│ └── leases/├── escrow/ # Escrow accounts (ACT)├── bme/ # Vault, ledger, remint credits├── oracle/ # Price feed state├── wasm/ # CosmWasm code and instances (Wormhole, Pyth)└── ...KVStore Operations
Basic operations:
// Get valuevalue := store.Get(key)
// Set valuestore.Set(key, value)
// Delete valuestore.Delete(key)
// Iterate rangeiterator := store.Iterator(start, end)State Queries
Query examples:
# Query deploymentakash query deployment get \ --owner akash1abc... \ --dseq 123
# Query market leaseakash query market lease get \ --owner akash1abc... \ --dseq 123 \ --provider akash1provider...
# Query providerakash query provider get akash1provider...Transaction Processing
Transaction Structure
message Tx { TxBody body = 1; AuthInfo auth_info = 2; repeated bytes signatures = 3;}
message TxBody { repeated google.protobuf.Any messages = 1; string memo = 2; int64 timeout_height = 3;}Processing Flow
Transaction Received ↓Decode Transaction ↓Verify Signatures (AnteHandler) ↓Check Account Sequence ↓Deduct Fees ↓Route Messages to Modules ↓Execute Message Handlers ↓Update State ↓Emit Events ↓Return ResponseAnteHandler
Runs before message execution:
Checks:
- Signature verification
- Account exists
- Sequence number valid
- Sufficient balance for fees
- Gas limit valid
- Memo size limit
Gas deduction:
TotalGas = sum(message.Gas) + SignatureGas + TxSizeGasModule Execution Order
BeginBlock Order
BeginBlock and EndBlock ordering include (among others) Cosmos SDK modules plus Akash modules such as epochs, escrow, deployment, market, provider, audit, cert, oracle, bme, and wasm. Order is defined via partial ordering in the node app (e.g. orderBeginBlockers / orderEndBlockers). The take module is not in the execution path for lease settlements.
EndBlock Order
EndBlock runs module end-block logic (e.g. bme processes ACT↔AKT ledger pending records each block). Similar partial ordering as BeginBlock.
Genesis State
Genesis File Structure
{ "genesis_time": "2021-06-18T17:00:00Z", "chain_id": "akashnet-2", "initial_height": "1", "consensus_params": {...}, "app_state": { "auth": {...}, "bank": {...}, "staking": {...}, "deployment": {...}, "market": {...}, "provider": {...} }}Module Genesis
Each module defines initial state:
func (module) InitGenesis(ctx, genesis) { // Initialize module state}
func (module) ExportGenesis(ctx) { // Export current state}