<!-- Source: https://docs.paxeer.app/modules/epoch/ -->

# Epoch Module

Time-based hooks and epoch lifecycle management for coordinating periodic chain operations.

**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

- [Understand how the mint module uses epochs](https://docs.paxeer.app/modules/mint)

- [Review all Paxeer modules](https://docs.paxeer.app/modules)
