refactor: remove epoching module (#13503)
* remove epoching module * remvoe mention in readme
This commit is contained in:
parent
56709d4e1d
commit
dabcedce71
|
@ -13,7 +13,6 @@ Here are some production-grade modules that can be used in Cosmos SDK applicatio
|
||||||
* [Capability](./capability/README.md) - Object capability implementation.
|
* [Capability](./capability/README.md) - Object capability implementation.
|
||||||
* [Crisis](./crisis/README.md) - Halting the blockchain under certain circumstances (e.g. if an invariant is broken).
|
* [Crisis](./crisis/README.md) - Halting the blockchain under certain circumstances (e.g. if an invariant is broken).
|
||||||
* [Distribution](./distribution/README.md) - Fee distribution, and staking token provision distribution.
|
* [Distribution](./distribution/README.md) - Fee distribution, and staking token provision distribution.
|
||||||
* [Epoching](./epoching/README.md) - Allows modules to queue messages for execution at a certain block height.
|
|
||||||
* [Evidence](./evidence/README.md) - Evidence handling for double signing, misbehaviour, etc.
|
* [Evidence](./evidence/README.md) - Evidence handling for double signing, misbehaviour, etc.
|
||||||
* [Feegrant](./feegrant/README.md) - Grant fee allowances for executing transactions.
|
* [Feegrant](./feegrant/README.md) - Grant fee allowances for executing transactions.
|
||||||
* [Governance](./gov/README.md) - On-chain proposals and voting.
|
* [Governance](./gov/README.md) - On-chain proposals and voting.
|
||||||
|
|
|
@ -1,89 +0,0 @@
|
||||||
---
|
|
||||||
sidebar_position: 1
|
|
||||||
---
|
|
||||||
|
|
||||||
# `x/epoching`
|
|
||||||
|
|
||||||
## Abstract
|
|
||||||
|
|
||||||
The epoching module allows modules to queue messages for execution at a certain block height. Each module will have its own instance of the epoching module, this allows each module to have its own message queue and own duration for epochs.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
In this example, we are creating an epochkeeper for a module that will be used by the module to queue messages to be executed at a later point in time.
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Keeper struct {
|
|
||||||
storeKey sdk.StoreKey
|
|
||||||
cdc codec.BinaryMarshaler
|
|
||||||
epochKeeper epochkeeper.Keeper
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewKeeper creates a new staking Keeper instance
|
|
||||||
func NewKeeper(cdc codec.BinaryMarshaler, key sdk.StoreKey) Keeper {
|
|
||||||
return Keeper{
|
|
||||||
storeKey: key,
|
|
||||||
cdc: cdc,
|
|
||||||
epochKeeper: epochkeeper.NewKeeper(cdc, key),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Contents
|
|
||||||
|
|
||||||
* [State](#state)
|
|
||||||
|
|
||||||
# State
|
|
||||||
|
|
||||||
## Messages queue
|
|
||||||
|
|
||||||
Messages are queued to run at the end of each epoch. Queued messages have an epoch number and for each epoch number, the queues are iterated over and each message is executed.
|
|
||||||
|
|
||||||
### Message queues
|
|
||||||
|
|
||||||
Each module has one unique message queue that is specific to that module.
|
|
||||||
|
|
||||||
## Actions
|
|
||||||
|
|
||||||
A module will add a message that implements the `sdk.Msg` interface. These message will be executed at a later time (end of the next epoch).
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Msg interface {
|
|
||||||
proto.Message
|
|
||||||
|
|
||||||
// Return the message type.
|
|
||||||
// Must be alphanumeric or empty.
|
|
||||||
Route() string
|
|
||||||
|
|
||||||
// Returns a human-readable string for the message, intended for utilization
|
|
||||||
// within tags
|
|
||||||
Type() string
|
|
||||||
|
|
||||||
// ValidateBasic does a simple validation check that
|
|
||||||
// doesn't require access to any other information.
|
|
||||||
ValidateBasic() error
|
|
||||||
|
|
||||||
// Get the canonical byte representation of the Msg.
|
|
||||||
GetSignBytes() []byte
|
|
||||||
|
|
||||||
// Signers returns the addrs of signers that must sign.
|
|
||||||
// CONTRACT: All signatures must be present to be valid.
|
|
||||||
// CONTRACT: Returns addrs in some deterministic order.
|
|
||||||
GetSigners() []AccAddress
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Buffered Messages Export / Import
|
|
||||||
|
|
||||||
For now, the `x/epoching` module is implemented to export all buffered messages without epoch numbers. When state is imported, buffered messages are stored on current epoch to run at the end of current epoch.
|
|
||||||
|
|
||||||
## Genesis Transactions
|
|
||||||
|
|
||||||
We execute epoch after execution of genesis transactions to see the changes instantly before node start.
|
|
||||||
|
|
||||||
## Execution on epochs
|
|
||||||
|
|
||||||
* Try executing the message for the epoch
|
|
||||||
* If success, make changes as it is
|
|
||||||
* If failure, try making revert extra actions done on handlers (e.g. EpochDelegationPool deposit)
|
|
||||||
* If revert fail, panic
|
|
|
@ -1,192 +0,0 @@
|
||||||
package keeper
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
|
||||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
|
||||||
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
||||||
db "github.com/tendermint/tm-db"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
DefaultEpochActionID = 1
|
|
||||||
DefaultEpochNumber = 0
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
NextEpochActionID = []byte{0x11}
|
|
||||||
EpochNumberID = []byte{0x12}
|
|
||||||
EpochActionQueuePrefix = []byte{0x13} // prefix for the epoch
|
|
||||||
)
|
|
||||||
|
|
||||||
// Keeper of the store
|
|
||||||
type Keeper struct {
|
|
||||||
storeKey storetypes.StoreKey
|
|
||||||
cdc codec.BinaryCodec
|
|
||||||
// Used to calculate the estimated next epoch time.
|
|
||||||
// This is local to every node
|
|
||||||
// TODO: remove in favor of consensus param when its added
|
|
||||||
commitTimeout time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewKeeper creates a epoch queue manager
|
|
||||||
func NewKeeper(cdc codec.BinaryCodec, key storetypes.StoreKey, commitTimeout time.Duration) Keeper {
|
|
||||||
return Keeper{
|
|
||||||
storeKey: key,
|
|
||||||
cdc: cdc,
|
|
||||||
commitTimeout: commitTimeout,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNewActionID returns ID to be used for next epoch
|
|
||||||
func (k Keeper) GetNewActionID(ctx sdk.Context) uint64 {
|
|
||||||
store := ctx.KVStore(k.storeKey)
|
|
||||||
|
|
||||||
bz := store.Get(NextEpochActionID)
|
|
||||||
if bz == nil {
|
|
||||||
// return default action ID to 1
|
|
||||||
return DefaultEpochActionID
|
|
||||||
}
|
|
||||||
id := sdk.BigEndianToUint64(bz)
|
|
||||||
|
|
||||||
// increment next action ID
|
|
||||||
store.Set(NextEpochActionID, sdk.Uint64ToBigEndian(id+1))
|
|
||||||
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionStoreKey returns action store key from ID
|
|
||||||
func ActionStoreKey(epochNumber int64, actionID uint64) []byte {
|
|
||||||
return append(EpochActionQueuePrefix, byte(epochNumber), byte(actionID))
|
|
||||||
}
|
|
||||||
|
|
||||||
// QueueMsgForEpoch save the actions that need to be executed on next epoch
|
|
||||||
func (k Keeper) QueueMsgForEpoch(ctx sdk.Context, epochNumber int64, msg sdk.Msg) {
|
|
||||||
store := ctx.KVStore(k.storeKey)
|
|
||||||
|
|
||||||
bz, err := k.cdc.MarshalInterface(msg)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
actionID := k.GetNewActionID(ctx)
|
|
||||||
store.Set(ActionStoreKey(epochNumber, actionID), bz)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RestoreEpochAction restore the actions that need to be executed on next epoch
|
|
||||||
func (k Keeper) RestoreEpochAction(ctx sdk.Context, epochNumber int64, action *codectypes.Any) {
|
|
||||||
store := ctx.KVStore(k.storeKey)
|
|
||||||
|
|
||||||
// reference from TestMarshalAny(t *testing.T)
|
|
||||||
bz, err := k.cdc.MarshalInterface(action)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
actionID := k.GetNewActionID(ctx)
|
|
||||||
store.Set(ActionStoreKey(epochNumber, actionID), bz)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetEpochMsg gets a msg by ID
|
|
||||||
func (k Keeper) GetEpochMsg(ctx sdk.Context, epochNumber int64, actionID uint64) sdk.Msg {
|
|
||||||
store := ctx.KVStore(k.storeKey)
|
|
||||||
|
|
||||||
bz := store.Get(ActionStoreKey(epochNumber, actionID))
|
|
||||||
if bz == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var action sdk.Msg
|
|
||||||
k.cdc.UnmarshalInterface(bz, &action)
|
|
||||||
|
|
||||||
return action
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetEpochActions get all actions
|
|
||||||
func (k Keeper) GetEpochActions(ctx sdk.Context) []sdk.Msg {
|
|
||||||
actions := []sdk.Msg{}
|
|
||||||
iterator := k.GetEpochActionsIterator(ctx)
|
|
||||||
defer iterator.Close()
|
|
||||||
|
|
||||||
for ; iterator.Valid(); iterator.Next() {
|
|
||||||
var action sdk.Msg
|
|
||||||
bz := iterator.Value()
|
|
||||||
k.cdc.UnmarshalInterface(bz, &action)
|
|
||||||
actions = append(actions, action)
|
|
||||||
}
|
|
||||||
|
|
||||||
return actions
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetEpochActionsIterator returns iterator for EpochActions
|
|
||||||
func (k Keeper) GetEpochActionsIterator(ctx sdk.Context) db.Iterator {
|
|
||||||
return sdk.KVStorePrefixIterator(ctx.KVStore(k.storeKey), EpochActionQueuePrefix)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DequeueEpochActions dequeue all the actions store on epoch
|
|
||||||
func (k Keeper) DequeueEpochActions(ctx sdk.Context) {
|
|
||||||
store := ctx.KVStore(k.storeKey)
|
|
||||||
iterator := sdk.KVStorePrefixIterator(store, EpochActionQueuePrefix)
|
|
||||||
defer iterator.Close()
|
|
||||||
|
|
||||||
for ; iterator.Valid(); iterator.Next() {
|
|
||||||
key := iterator.Key()
|
|
||||||
store.Delete(key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteByKey delete item by key
|
|
||||||
func (k Keeper) DeleteByKey(ctx sdk.Context, key []byte) {
|
|
||||||
store := ctx.KVStore(k.storeKey)
|
|
||||||
store.Delete(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetEpochActionByIterator get action by iterator
|
|
||||||
func (k Keeper) GetEpochActionByIterator(iterator db.Iterator) sdk.Msg {
|
|
||||||
bz := iterator.Value()
|
|
||||||
|
|
||||||
var action sdk.Msg
|
|
||||||
k.cdc.UnmarshalInterface(bz, &action)
|
|
||||||
|
|
||||||
return action
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetEpochNumber set epoch number
|
|
||||||
func (k Keeper) SetEpochNumber(ctx sdk.Context, epochNumber int64) {
|
|
||||||
store := ctx.KVStore(k.storeKey)
|
|
||||||
store.Set(EpochNumberID, sdk.Uint64ToBigEndian(uint64(epochNumber)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetEpochNumber fetches epoch number
|
|
||||||
func (k Keeper) GetEpochNumber(ctx sdk.Context) int64 {
|
|
||||||
store := ctx.KVStore(k.storeKey)
|
|
||||||
|
|
||||||
bz := store.Get(EpochNumberID)
|
|
||||||
if bz == nil {
|
|
||||||
return DefaultEpochNumber
|
|
||||||
}
|
|
||||||
|
|
||||||
return int64(sdk.BigEndianToUint64(bz))
|
|
||||||
}
|
|
||||||
|
|
||||||
// IncreaseEpochNumber increases epoch number
|
|
||||||
func (k Keeper) IncreaseEpochNumber(ctx sdk.Context) {
|
|
||||||
epochNumber := k.GetEpochNumber(ctx)
|
|
||||||
k.SetEpochNumber(ctx, epochNumber+1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNextEpochHeight returns next epoch block height
|
|
||||||
func (k Keeper) GetNextEpochHeight(ctx sdk.Context, epochInterval int64) int64 {
|
|
||||||
currentHeight := ctx.BlockHeight()
|
|
||||||
return currentHeight + (epochInterval - currentHeight%epochInterval)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNextEpochTime returns estimated next epoch time
|
|
||||||
func (k Keeper) GetNextEpochTime(ctx sdk.Context, epochInterval int64) time.Time {
|
|
||||||
currentTime := ctx.BlockTime()
|
|
||||||
currentHeight := ctx.BlockHeight()
|
|
||||||
|
|
||||||
return currentTime.Add(k.commitTimeout * time.Duration(k.GetNextEpochHeight(ctx, epochInterval)-currentHeight))
|
|
||||||
}
|
|
Loading…
Reference in New Issue