On this page
Source: paxeer-network/modules/epoch/

Overview

The epoch module manages fixed time periods (epochs) and triggers registered hooks when each epoch begins or ends. An epoch defaults to 60 seconds relative to genesis time. This enables time-coordinated actions like validator set updates, reward distributions, and parameter adjustments.

Other modules register hooks via a simple interface, and the epoch module calls those hooks at the start and end of each epoch during BeginBlock.

State

The epoch module maintains a single state object:

> paxd q epoch epoch --output json
{
  "epoch": {
    "genesis_time": "2023-04-27T19:08:11.958027Z",
    "epoch_duration": "60s",
    "current_epoch": "0",
    "current_epoch_start_time": "2023-04-27T19:08:11.958027Z",
    "current_epoch_height": "0"
  }
}
  • genesis_time: Chain genesis time (fixed)
  • epoch_duration: Duration of each epoch in seconds (default 60s)
  • current_epoch: Current epoch number (increments at each epoch boundary)
  • current_epoch_start_time: Timestamp when the current epoch started
  • current_epoch_height: Block height at which the current epoch started

Epoch Boundaries

Epochs are defined by wall-clock time, not block height. The module checks the block timestamp in BeginBlock. If blockTime - current_epoch_start_time ≥ epoch_duration, a new epoch begins.

This time-based approach ensures epochs occur at predictable intervals even if block times vary.

Hooks

Other modules implement the epoch hooks interface to execute logic at epoch boundaries:

BeforeEpochStart

func (k Keeper) BeforeEpochStart(ctx sdk.Context, epoch epochTypes.Epoch) {
  // Execute logic at the start of each epoch
}

Called when a new epoch begins, before any other epoch processing.

AfterEpochEnd

func (k Keeper) AfterEpochEnd(ctx sdk.Context, epoch epochTypes.Epoch) {
  // Execute logic at the end of each epoch
}

Called when an epoch ends, after all epoch processing is complete.

Example: Mint Module

The mint module (modules/mint/keeper) implements epoch hooks to distribute inflation rewards daily. It registers its hooks in node/app.go:

app.EpochKeeper = *epochmodulekeeper.NewKeeper(
  appCodec,
  keys[epochmoduletypes.StoreKey],
  keys[epochmoduletypes.MemStoreKey],
  app.GetSubspace(epochmoduletypes.ModuleName),
).SetHooks(epochmoduletypes.NewMultiEpochHooks(
  app.MintKeeper.Hooks()))

Events

The epoch module emits a new_epoch event at each epoch boundary:

  • epoch_number: The new epoch's epoch number
  • epoch_time: The new epoch's start time
  • epoch_height: The block height at which the new epoch started

Messages

The epoch module does not expose any transactions. All interactions happen via hooks and events. Only the module itself updates epoch state during BeginBlock.

Parameters

The epoch module has no runtime parameters. The epoch duration is fixed at genesis and cannot be changed without a chain upgrade.

Use Cases

  • Mint module: Distribute inflation rewards once per epoch (daily)
  • Validator updates: Apply validator set changes at epoch boundaries
  • Parameter changes: Activate governance-approved parameter updates
  • Periodic cleanup: Prune expired state or cache entries

Next Steps

Paxeer Network · Developer documentationBack to top ↑

Ask Paxeer Docs

Answers from the documentation.

What would you like to know?

Ask a question, find a guide, or get help with your next step.

Enter to send · Shift+Enter for a new line