Skip to content

Commit

Permalink
temp commit, include logic for zeroheight
Browse files Browse the repository at this point in the history
  • Loading branch information
randygrok committed Aug 13, 2024
1 parent 7006da5 commit 91570fb
Show file tree
Hide file tree
Showing 5 changed files with 245 additions and 7 deletions.
2 changes: 1 addition & 1 deletion runtime/v2/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (a *AppBuilder[T]) RegisterModules(modules map[string]appmodulev2.AppModule

// RegisterStores registers the provided store keys.
// This method should only be used for registering extra stores
// wiich is necessary for modules that not registered using the app config.
// which is necessary for modules that not registered using the app config.
// To be used in combination of RegisterModules.
func (a *AppBuilder[T]) RegisterStores(keys ...string) {
a.app.storeKeys = append(a.app.storeKeys, keys...)
Expand Down
26 changes: 26 additions & 0 deletions server/v2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package serverv2

import (
"encoding/json"
dbm "github.com/cosmos/cosmos-db"
gogoproto "github.com/cosmos/gogoproto/proto"
"github.com/spf13/viper"
"io"

coreapp "cosmossdk.io/core/app"
"cosmossdk.io/core/transaction"
Expand All @@ -30,3 +32,27 @@ type ExportedApp struct {
// Height is the app's latest block height.
Height int64
}

// AppExporter is a function that dumps all app state to
// JSON-serializable structure and returns the current validator set.
type AppExporter func(
logger log.Logger,
db dbm.DB,
traceWriter io.Writer,
height int64,
forZeroHeight bool,
jailAllowedAddrs []string,
opts AppOptions,
modulesToExport []string,
) (ExportedApp, error)

// AppOptions defines an interface that is passed into an application
// constructor, typically used to set BaseApp options that are either supplied
// via config file or through CLI arguments/flags. The underlying implementation
// is defined by the server package and is typically implemented via a Viper
// literal defined on the server Context. Note, casting Get calls may not yield
// the expected types and could result in type assertion errors. It is recommend
// to either use the cast package or perform manual conversion for safety.
type AppOptions interface {
Get(string) interface{}
}
1 change: 0 additions & 1 deletion simapp/v2/app_di.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package simapp

import (
_ "embed"

"github.com/spf13/viper"

clienthelpers "cosmossdk.io/client/v2/helpers"
Expand Down
213 changes: 213 additions & 0 deletions simapp/v2/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ package simapp

import (
"context"
"cosmossdk.io/collections"
slashingtypes "cosmossdk.io/x/slashing/types"
stakingtypes "cosmossdk.io/x/staking/types"
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"log"

serverv2 "cosmossdk.io/server/v2"
)
Expand All @@ -27,3 +33,210 @@ func (app *SimApp[T]) ExportAppStateAndValidators(forZeroHeight bool, jailAllowe
Height: int64(latestHeight),
}, nil
}

// prepare for fresh start at zero height
// NOTE zero height genesis is a temporary feature which will be deprecated
//
// in favor of export at a block height
func (app *SimApp[T]) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) {
//applyAllowedAddrs := false
//
//// check if there is a allowed address list
//if len(jailAllowedAddrs) > 0 {
// applyAllowedAddrs = true
//}

allowedAddrsMap := make(map[string]bool)

for _, addr := range jailAllowedAddrs {
_, err := sdk.ValAddressFromBech32(addr)
if err != nil {
log.Fatal(err)
}
allowedAddrsMap[addr] = true
}

/* Handle fee distribution state. */

// withdraw all validator commission
err := app.StakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.ValidatorI) (stop bool) {
valBz, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator())
if err != nil {
panic(err)
}
_, _ = app.DistrKeeper.WithdrawValidatorCommission(ctx, valBz)
return false
})
if err != nil {
panic(err)
}

// withdraw all delegator rewards
dels, err := app.StakingKeeper.GetAllDelegations(ctx)
if err != nil {
panic(err)
}

for _, delegation := range dels {
valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
if err != nil {
panic(err)
}

delAddr := sdk.MustAccAddressFromBech32(delegation.DelegatorAddress)

_, _ = app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr)
}

// clear validator slash events
err = app.DistrKeeper.ValidatorSlashEvents.Clear(ctx, nil)
if err != nil {
panic(err)
}

// clear validator historical rewards
err = app.DistrKeeper.ValidatorHistoricalRewards.Clear(ctx, nil)
if err != nil {
panic(err)
}

// set context height to zero
height := ctx.BlockHeight()
ctx = ctx.WithBlockHeight(0)

// reinitialize all validators
err = app.StakingKeeper.IterateValidators(ctx, func(_ int64, val sdk.ValidatorI) (stop bool) {
valBz, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator())
if err != nil {
panic(err)
}
// donate any unwithdrawn outstanding reward tokens to the community pool
rewards, err := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, valBz)
if err != nil {
panic(err)
}
feePool, err := app.DistrKeeper.FeePool.Get(ctx)
if err != nil {
panic(err)
}
feePool.DecimalPool = feePool.DecimalPool.Add(rewards...) // distribution will allocate this to the protocolpool eventually
if err := app.DistrKeeper.FeePool.Set(ctx, feePool); err != nil {
panic(err)
}

if err := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, valBz); err != nil {
panic(err)
}
return false
})
if err != nil {
panic(err)
}

// reinitialize all delegations
for _, del := range dels {
valAddr, err := sdk.ValAddressFromBech32(del.ValidatorAddress)
if err != nil {
panic(err)
}
delAddr := sdk.MustAccAddressFromBech32(del.DelegatorAddress)

if err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil {
// never called as BeforeDelegationCreated always returns nil
panic(fmt.Errorf("error while incrementing period: %w", err))
}

if err := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); err != nil {
// never called as AfterDelegationModified always returns nil
panic(fmt.Errorf("error while creating a new delegation period record: %w", err))
}
}

// reset context height
ctx = ctx.WithBlockHeight(height)

/* Handle staking state. */

// iterate through redelegations, reset creation height
err = app.StakingKeeper.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) {
for i := range red.Entries {
red.Entries[i].CreationHeight = 0
}
err = app.StakingKeeper.SetRedelegation(ctx, red)
if err != nil {
panic(err)
}
return false
})
if err != nil {
panic(err)
}

// iterate through unbonding delegations, reset creation height
err = app.StakingKeeper.UnbondingDelegations.Walk(
ctx,
nil,
func(key collections.Pair[[]byte, []byte], ubd stakingtypes.UnbondingDelegation) (stop bool, err error) {
for i := range ubd.Entries {
ubd.Entries[i].CreationHeight = 0
}
err = app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
if err != nil {
return true, err
}
return false, err
},
)
if err != nil {
panic(err)
}

//// Iterate through validators by power descending, reset bond heights, and
//// update bond intra-tx counters.
//store := ctx.KVStore(app.GetKey(stakingtypes.StoreKey))
//iter := storetypes.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey)
//counter := int16(0)

//for ; iter.Valid(); iter.Next() {
// addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key()))
// validator, err := app.StakingKeeper.GetValidator(ctx, addr)
// if err != nil {
// panic("expected validator, not found")
// }
//
// validator.UnbondingHeight = 0
// if applyAllowedAddrs && !allowedAddrsMap[addr.String()] {
// validator.Jailed = true
// }
//
// if err = app.StakingKeeper.SetValidator(ctx, validator); err != nil {
// panic(err)
// }
// counter++
//}
//
//if err := iter.Close(); err != nil {
// app.Logger().Error("error while closing the key-value store reverse prefix iterator: ", err)
// return
//}

_, err = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
if err != nil {
log.Fatal(err)
}

/* Handle slashing state. */

// reset start height on signing infos
err = app.SlashingKeeper.ValidatorSigningInfo.Walk(ctx, nil, func(addr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool, err error) {
info.StartHeight = 0
err = app.SlashingKeeper.ValidatorSigningInfo.Set(ctx, addr, info)
if err != nil {
return true, err
}
return false, nil
})
if err != nil {
panic(err)
}
}
10 changes: 5 additions & 5 deletions simapp/v2/simdv2/cmd/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,13 @@ func genesisCommand[T transaction.Tx](
jailAllowedAddrs []string,
viper *viper.Viper,
modulesToExport []string,
) (servertypes.ExportedApp, error),
) (serverv2.ExportedApp, error),
cmds ...*cobra.Command,
) *cobra.Command {
compatAppExporter := func(logger log.Logger, db dbm.DB, traceWriter io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string, appOpts servertypes.AppOptions, modulesToExport []string) (servertypes.ExportedApp, error) {
compatAppExporter := func(logger log.Logger, db dbm.DB, traceWriter io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string, appOpts servertypes.AppOptions, modulesToExport []string) (serverv2.ExportedApp, error) {
viperAppOpts, ok := appOpts.(*viper.Viper)
if !ok {
return servertypes.ExportedApp{}, errors.New("appOpts is not viper.Viper")
return serverv2.ExportedApp{}, errors.New("appOpts is not viper.Viper")
}

return appExport(logger, height, forZeroHeight, jailAllowedAddrs, viperAppOpts, modulesToExport)
Expand Down Expand Up @@ -165,7 +165,7 @@ func appExport[T transaction.Tx](
jailAllowedAddrs []string,
viper *viper.Viper,
modulesToExport []string,
) (servertypes.ExportedApp, error) {
) (serverv2.ExportedApp, error) {
// overwrite the FlagInvCheckPeriod
viper.Set(server.FlagInvCheckPeriod, 1)

Expand All @@ -174,7 +174,7 @@ func appExport[T transaction.Tx](
simApp = simapp.NewSimApp[T](logger, viper)

if err := simApp.LoadHeight(uint64(height)); err != nil {
return servertypes.ExportedApp{}, err
return serverv2.ExportedApp{}, err
}
} else {
simApp = simapp.NewSimApp[T](logger, viper)
Expand Down

0 comments on commit 91570fb

Please sign in to comment.