epochs

package
v22.2.0-testnet Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 2, 2024 License: Apache-2.0, Apache-2.0 Imports: 21 Imported by: 0

README


title: "Epochs" excerpt: "" category: 6392913957c533007128548e

Epochs

Abstract

While using the SDK, we often want to run certain code periodically. The epochs module allows other modules to be configured such that they are signaled once every period. So another module can specify it wants to execute code once a week, starting at UTC-time = x. epochs creates a generalized epoch interface to other modules so that they can easily be signalled upon such events.

Contents

  1. Concepts
  2. State
  3. Events
  4. Keeper
  5. Hooks
  6. Queries
  7. Future Improvements

Concepts

Epochs are on-chain timers that have timer ticks at specific time intervals, triggering the execution of certain logic that is constrained by a specific epoch. The purpose of the epochs module is to provide a generalized epoch interface to other modules so that they can easily implement epochs without keeping their own code for epochs.

Every epoch has a unique identifier. Every epoch will have a start time, and an end time, where end_time = start_time + duration. When an epoch triggers the execution of code, that code is executed at the first block whose blocktime is greater than end_time. It follows that the start_time of the following epoch will be the end_time of the previous epoch.

Stride uses three epoch identifiers as found in x/epochs/genesis.go

  1. DAY_EPOCH: this identifies an epoch that lasts 24 hours.
  2. STRIDE_EPOCH: this identifies an epoch that lasts 5 minutes on local mode testnet (although this may be changed) and longer on public testnet and mainnet, and is used in the x/stakeibc/ module as a time interval in accordance with which the Stride app chain performs certain functions, such as autocompound staking rewards.

State

The epochs module keeps EpochInfo objects and modifies the information as epoch info changes. Epochs are initialized as part of genesis initialization, and modified on begin blockers or end blockers.

Epoch information type

message EpochInfo {
    string identifier = 1;
    google.protobuf.Timestamp start_time = 2 [
        (gogoproto.stdtime) = true,
        (gogoproto.nullable) = false,
        (gogoproto.moretags) = "yaml:\"start_time\""
    ];
    google.protobuf.Duration duration = 3 [
        (gogoproto.nullable) = false,
        (gogoproto.stdduration) = true,
        (gogoproto.jsontag) = "duration,omitempty",
        (gogoproto.moretags) = "yaml:\"duration\""
    ];
    int64 current_epoch = 4;
    google.protobuf.Timestamp current_epoch_start_time = 5 [
        (gogoproto.stdtime) = true,
        (gogoproto.nullable) = false,
        (gogoproto.moretags) = "yaml:\"current_epoch_start_time\""
    ];
    bool epoch_counting_started = 6;
    reserved 7;
    int64 current_epoch_start_height = 8;
}

EpochInfo keeps identifier, start_time,duration, current_epoch, current_epoch_start_time, epoch_counting_started, current_epoch_start_height.

  1. identifier keeps epoch identification string.
  2. start_time keeps epoch counting start time, if block time passes start_time, epoch_counting_started is set.
  3. duration keeps target epoch duration.
  4. current_epoch keeps current active epoch number.
  5. current_epoch_start_time keeps the start time of current epoch.
  6. epoch_number is counted only when epoch_counting_started flag is set.
  7. current_epoch_start_height keeps the start block height of current epoch.

Events

The epochs module emits the following events:

BeginBlocker

Type Attribute Key Attribute Value
epoch_start epoch_number {epoch_number}
epoch_start start_time {start_time}

EndBlocker

Type Attribute Key Attribute Value
epoch_end epoch_number {epoch_number}

Keeper

Keeper Functions

epochs/keeper/ module provides utility functions to manage epochs.

// Keeper is the interface for lockup module keeper
type Keeper interface {
  // GetEpochInfo returns epoch info by identifier
  GetEpochInfo(ctx sdk.Context, identifier string) types.EpochInfo
  // SetEpochInfo set epoch info
  SetEpochInfo(ctx sdk.Context, epoch types.EpochInfo)
  // DeleteEpochInfo delete epoch info
  DeleteEpochInfo(ctx sdk.Context, identifier string)
  // IterateEpochInfo iterate through epochs
  IterateEpochInfo(ctx sdk.Context, fn func(index int64, epochInfo types.EpochInfo) (stop bool))
  // Get all epoch infos
  AllEpochInfos(ctx sdk.Context) []types.EpochInfo
}

Hooks

  // the first block whose timestamp is after the duration is counted as the end of the epoch
  AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumber int64)
  // new epoch is next block of epoch end block
  BeforeEpochStart(ctx sdk.Context, epochIdentifier string, epochNumber int64)

The BeforeEpochStart hook does different things depending on the identifier.

If in a day identifier it:

  1. begins unbondings
  2. sweeps unbonded tokens to the redemption account
  3. cleans up old records
  4. creates empty epoch unbonding records for the next day

If in a stride_epoch identifier it: 5. creates and deposits records on each host zone 6. sets withdrawal addresses 7. updates redemption rates (if the epoch coincides with the correct interval) 8. processes TRANSFER_QUEUE deposit records to the delegation Interchain Account (if the epoch coincides with the correct interval) 9. processes DELEGATION_QUEUE deposit records to the delegation Interchain Account (if the epoch coincides with the correct interval) 10. Query the rewards account using interchain queries, with the transfer callback to a delegation account as a staked record (if at proper interval)

How modules receive hooks

On the hook receiver functions of other modules, they need to filter epochIdentifier and execute for only a specific epochIdentifier. Filtering epochIdentifier could be in Params of other modules so that they can be modified by governance. Governance can change an epoch from week to day as needed.

Queries

epochs module provides the below queries to check the module's state

service Query {
  // EpochInfos provide running epochInfos
  rpc EpochInfos(QueryEpochsInfoRequest) returns (QueryEpochsInfoResponse) {}
  // CurrentEpoch provide current epoch of specified identifier
  rpc CurrentEpoch(QueryCurrentEpochRequest) returns (QueryCurrentEpochResponse) {}
}

Future Improvements

Lack point using this module

In current design each epoch should be at least 2 blocks as start block should be different from endblock. Because of this, each epoch time will be max(blocks_time x 2, epoch_duration). If epoch_duration is set to 1s, and block_time is 5s, actual epoch time should be 10s. We definitely recommend configure epoch_duration as more than 2x block_time, to use this module correctly. If you enforce to set it to 1s, it's same as 10s - could make module logic invalid.

TODO for postlaunch: We should see if we can architect things such that the receiver doesn't have to do this filtering, and the epochs module would pre-filter for them.

Block-time drifts problem

This implementation has block time drift based on block time. For instance, we have an epoch of 100 units that ends at t=100, if we have a block at t=97 and a block at t=104 and t=110, this epoch ends at t=104. And new epoch start at t=110. There are time drifts here, for around 1-2 blocks time. It will slow down epochs.

It's going to slow down epoch by 10-20s per week when epoch duration is 1 week. This should be resolved after launch.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExportGenesis

func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState

ExportGenesis returns the capability module's exported genesis.

func InitGenesis

func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState)

InitGenesis initializes the capability module's state from a provided genesis state.

func NewHandler

func NewHandler(k keeper.Keeper) sdk.Handler

NewHandler returns a handler for epochs module messages

Types

type AppModule

type AppModule struct {
	AppModuleBasic
	// contains filtered or unexported fields
}

AppModule implements the AppModule interface for the capability module.

func NewAppModule

func NewAppModule(cdc codec.Codec, keeper keeper.Keeper) AppModule

NewAppModule return a new AppModule

func (AppModule) BeginBlock

func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock)

BeginBlock executes all ABCI BeginBlock logic respective to the capability module.

func (AppModule) ConsensusVersion

func (AppModule) ConsensusVersion() uint64

ConsensusVersion implements AppModule/ConsensusVersion.

func (AppModule) EndBlock

EndBlock executes all ABCI EndBlock logic respective to the capability module. It returns no validator updates.

func (AppModule) ExportGenesis

func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage

ExportGenesis returns the capability module's exported genesis state as raw JSON bytes.

func (AppModule) GenerateGenesisState

func (AppModule) GenerateGenesisState(simState *module.SimulationState)

GenerateGenesisState creates a randomized GenState of the pool-incentives module.

func (AppModule) InitGenesis

func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate

InitGenesis performs the capability module's genesis initialization It returns no validator updates.

func (AppModule) Name

func (am AppModule) Name() string

Name returns the capability module's name.

func (AppModule) ProposalContents

func (AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalMsg

ProposalContents doesn't return any content functions for governance proposals.

func (AppModule) QuerierRoute

func (AppModule) QuerierRoute() string

QuerierRoute returns the capability module's query routing key.

func (AppModule) RandomizedParams

func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.LegacyParamChange

RandomizedParams creates randomized pool-incentives param changes for the simulator.

func (AppModule) RegisterInvariants

func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry)

RegisterInvariants registers the capability module's invariants.

func (AppModule) RegisterServices

func (am AppModule) RegisterServices(cfg module.Configurator)

RegisterServices registers a GRPC query service to respond to the module-specific GRPC queries.

func (AppModule) RegisterStoreDecoder

func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry)

RegisterStoreDecoder registers a decoder for supply module's types

func (AppModule) WeightedOperations

func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation

WeightedOperations returns the all the gov module operations with their respective weights.

type AppModuleBasic

type AppModuleBasic struct {
	// contains filtered or unexported fields
}

AppModuleBasic implements the AppModuleBasic interface for the capability module.

func NewAppModuleBasic

func NewAppModuleBasic(cdc codec.Codec) AppModuleBasic

NewAppModuleBasic return a new AppModuleBasic

func (AppModuleBasic) DefaultGenesis

func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage

DefaultGenesis returns the capability module's default genesis state.

func (AppModuleBasic) GetQueryCmd

func (AppModuleBasic) GetQueryCmd() *cobra.Command

GetQueryCmd returns the capability module's root query command.

func (AppModuleBasic) GetTxCmd

func (a AppModuleBasic) GetTxCmd() *cobra.Command

GetTxCmd returns the capability module's root tx command.

func (AppModuleBasic) Name

func (AppModuleBasic) Name() string

Name returns the capability module's name.

func (AppModuleBasic) RegisterGRPCGatewayRoutes

func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux)

RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module.

func (AppModuleBasic) RegisterInterfaces

func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry)

RegisterInterfaces registers the module's interface types

func (AppModuleBasic) RegisterLegacyAminoCodec

func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino)

RegisterLegacyAminoCodec registers a legacy amino codec

func (AppModuleBasic) RegisterRESTRoutes

func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router)

RegisterRESTRoutes registers the capability module's REST service handlers.

func (AppModuleBasic) ValidateGenesis

func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error

ValidateGenesis performs genesis state validation for the capability module.

Directories

Path Synopsis
client
cli
Package types is a reverse proxy.
Package types is a reverse proxy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL