Epochs Module (x/epochs)
Thex/epochs module provides on-chain timers that execute at fixed time intervals. Other SDK modules can register hooks to execute logic when epoch timers tick, enabling time-based automation without relying on external triggers.
Overview
The epochs module defines on-chain timers that tick at regular intervals (e.g., daily, weekly). When a timer ticks, all registered hooks are called in sequence, allowing modules to perform periodic tasks like:- Distributing staking rewards
- Updating oracle prices
- Executing scheduled governance actions
- Resetting rate limits
- Triggering algorithmic market operations
Key Concepts
EpochInfo
Each timer is represented by anEpochInfo struct:
Timer Ticking Logic
Timers tick at the first block whose timestamp exceeds the epoch end time:Catching Up After Downtime
If the chain is down for multiple epochs, the keeper will tick once per block until caught up:Epoch Hooks
Modules receive epoch notifications by implementing theEpochHooks interface:
Registering Hooks
Manual Wiring:Implementing Hooks
Modules filter by epoch identifier and execute their logic:Panic Isolation
If a hook panics, its state changes are reverted, but other hooks continue executing:Keeper Functions
GetEpochInfo
Retrieve epoch information by identifier:AddEpochInfo
Add a new epoch timer (typically done in genesis or upgrades):AllEpochInfos
Iterate over all epoch timers:NumBlocksSinceEpochStart
Get the number of blocks since the current epoch started:Query Endpoints
EpochInfos
Query all running epoch timers:CurrentEpoch
Query the current epoch number for a specific identifier:Events
The epochs module emits events when epochs start and end:epoch_start
epoch_end
Genesis Configuration
Define epoch timers in your genesis file:Use Cases
Staking Rewards Distribution
Oracle Price Updates
Rate Limit Reset
Incentive Programs
Module Integration
Module Manager Setup
Add epochs to your module manager:Store Keys
Register the epochs store key:Best Practices
- Filter by identifier in your hooks to avoid executing logic for irrelevant epochs
- Handle errors gracefully to prevent halting hook execution
- Keep hook logic efficient since it runs on every block during catch-up
- Use appropriate epoch intervals (daily, weekly) based on your use case
- Test hook behavior during chain downtime scenarios
- Monitor epoch events to ensure timers are ticking as expected
- Store epoch-specific state in your module’s store, not in memory
Security Considerations
- Hook panics are isolated but can waste gas if they consistently fail
- Long-running hooks can delay block production
- Ensure hooks have bounded execution time
- Validate epoch identifiers before processing in hooks
- Be cautious with hooks that modify validator sets or critical state
Performance Notes
- The epochs keeper iterates all epoch infos in
BeginBlock - Keep the number of epoch identifiers small (< 10)
- Hook execution is sequential, not parallel
- During catch-up, hooks execute once per block per missed epoch
- Use events to track hook execution for debugging