mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-02 17:31:39 +00:00
Regular → Executable
+118
-82
@@ -1,3 +1,4 @@
|
||||
// Package app provides export functionality for the Sonr blockchain application.
|
||||
package app
|
||||
|
||||
import (
|
||||
@@ -5,8 +6,10 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
|
||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
@@ -15,8 +18,19 @@ import (
|
||||
)
|
||||
|
||||
// ExportAppStateAndValidators exports the state of the application for a genesis
|
||||
// file.
|
||||
func (app *SonrApp) ExportAppStateAndValidators(forZeroHeight bool, jailAllowedAddrs, modulesToExport []string) (servertypes.ExportedApp, error) {
|
||||
// file. It can export at the current height or prepare the state for a zero-height
|
||||
// genesis, which is useful for chain upgrades or migrations.
|
||||
//
|
||||
// Parameters:
|
||||
// - forZeroHeight: If true, prepares the state for zero-height genesis
|
||||
// - jailAllowedAddrs: List of validator addresses allowed to remain unjailed
|
||||
// - modulesToExport: Specific modules to export (exports all if empty)
|
||||
//
|
||||
// Returns the exported application state and validator set.
|
||||
func (app *ChainApp) ExportAppStateAndValidators(
|
||||
forZeroHeight bool,
|
||||
jailAllowedAddrs, modulesToExport []string,
|
||||
) (servertypes.ExportedApp, error) {
|
||||
// as if they could withdraw from the start of the next block
|
||||
ctx := app.NewContextLegacy(true, cmtproto.Header{Height: app.LastBlockHeight()})
|
||||
|
||||
@@ -39,22 +53,39 @@ func (app *SonrApp) ExportAppStateAndValidators(forZeroHeight bool, jailAllowedA
|
||||
}
|
||||
|
||||
validators, err := staking.WriteValidators(ctx, app.StakingKeeper)
|
||||
if err != nil {
|
||||
return servertypes.ExportedApp{}, err
|
||||
}
|
||||
|
||||
return servertypes.ExportedApp{
|
||||
AppState: appState,
|
||||
Validators: validators,
|
||||
Height: height,
|
||||
ConsensusParams: app.GetConsensusParams(ctx),
|
||||
}, err
|
||||
}, nil
|
||||
}
|
||||
|
||||
// prepare for fresh start at zero height
|
||||
// NOTE zero height genesis is a temporary feature which will be deprecated
|
||||
// prepForZeroHeightGenesis prepares the application state for a fresh start at zero height.
|
||||
// This includes withdrawing all rewards, resetting validator states, and optionally
|
||||
// jailing validators not in the allowed list. This function modifies the state to ensure
|
||||
// a clean genesis export.
|
||||
//
|
||||
// in favor of export at a block height
|
||||
func (app *SonrApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) {
|
||||
// NOTE: Zero height genesis is a temporary feature which will be deprecated
|
||||
// in favor of export at a block height.
|
||||
func (app *ChainApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) {
|
||||
var err error
|
||||
|
||||
// Just to be safe, assert the invariants on current state.
|
||||
app.CrisisKeeper.AssertInvariants(ctx)
|
||||
|
||||
// set context height to zero
|
||||
height := ctx.BlockHeight()
|
||||
ctx = ctx.WithBlockHeight(0)
|
||||
|
||||
applyAllowedAddrs := len(jailAllowedAddrs) > 0
|
||||
|
||||
// check if there is a allowed address list
|
||||
|
||||
allowedAddrsMap := make(map[string]bool)
|
||||
|
||||
for _, addr := range jailAllowedAddrs {
|
||||
@@ -65,20 +96,20 @@ func (app *SonrApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
|
||||
allowedAddrsMap[addr] = true
|
||||
}
|
||||
|
||||
// Just to be safe, assert the invariants on current state.
|
||||
app.CrisisKeeper.AssertInvariants(ctx)
|
||||
|
||||
// Handle fee distribution state.
|
||||
|
||||
// withdraw all validator commission
|
||||
err := app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
|
||||
valBz, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, _ = app.DistrKeeper.WithdrawValidatorCommission(ctx, valBz)
|
||||
return false
|
||||
})
|
||||
err = app.StakingKeeper.IterateValidators(
|
||||
ctx,
|
||||
func(_ int64, val stakingtypes.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)
|
||||
}
|
||||
@@ -90,9 +121,9 @@ func (app *SonrApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
|
||||
}
|
||||
|
||||
for _, delegation := range dels {
|
||||
valAddr, errB := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
|
||||
if errB != nil {
|
||||
panic(errB)
|
||||
valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
delAddr := sdk.MustAccAddressFromBech32(delegation.DelegatorAddress)
|
||||
@@ -108,55 +139,54 @@ func (app *SonrApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
|
||||
// clear validator historical rewards
|
||||
app.DistrKeeper.DeleteAllValidatorHistoricalRewards(ctx)
|
||||
|
||||
// set context height to zero
|
||||
height := ctx.BlockHeight()
|
||||
ctx = ctx.WithBlockHeight(0)
|
||||
|
||||
// reinitialize all validators
|
||||
err = app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
|
||||
valBz, errB := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator())
|
||||
if errB != nil {
|
||||
panic(errB)
|
||||
}
|
||||
// donate any unwithdrawn outstanding reward fraction tokens to the community pool
|
||||
scraps, errC := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, valBz)
|
||||
if errC != nil {
|
||||
panic(errC)
|
||||
}
|
||||
feePool, errD := app.DistrKeeper.FeePool.Get(ctx)
|
||||
if errD != nil {
|
||||
panic(errD)
|
||||
}
|
||||
feePool.CommunityPool = feePool.CommunityPool.Add(scraps...)
|
||||
if errE := app.DistrKeeper.FeePool.Set(ctx, feePool); errE != nil {
|
||||
panic(errE)
|
||||
}
|
||||
err = app.StakingKeeper.IterateValidators(
|
||||
ctx,
|
||||
func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
|
||||
valBz, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// donate any unwithdrawn outstanding reward fraction tokens to the community pool
|
||||
scraps, err := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, valBz)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
feePool, err := app.DistrKeeper.FeePool.Get(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
feePool.CommunityPool = feePool.CommunityPool.Add(scraps...)
|
||||
if err := app.DistrKeeper.FeePool.Set(ctx, feePool); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if errF := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, valBz); errF != nil {
|
||||
panic(errF)
|
||||
}
|
||||
return false
|
||||
})
|
||||
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, errcc := sdk.ValAddressFromBech32(del.ValidatorAddress)
|
||||
if errcc != nil {
|
||||
panic(errcc)
|
||||
valAddr, err := sdk.ValAddressFromBech32(del.ValidatorAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
delAddr := sdk.MustAccAddressFromBech32(del.DelegatorAddress)
|
||||
|
||||
if errcb := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); errcb != nil {
|
||||
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", errcb))
|
||||
panic(fmt.Errorf("error while incrementing period: %w", err))
|
||||
}
|
||||
|
||||
if errcd := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); errcd != nil {
|
||||
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", errcd))
|
||||
panic(fmt.Errorf("error while creating a new delegation period record: %w", err))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,31 +196,37 @@ func (app *SonrApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
|
||||
// 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
|
||||
})
|
||||
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.IterateUnbondingDelegations(ctx, func(_ int64, ubd stakingtypes.UnbondingDelegation) (stop bool) {
|
||||
for i := range ubd.Entries {
|
||||
ubd.Entries[i].CreationHeight = 0
|
||||
}
|
||||
err = app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return false
|
||||
})
|
||||
err = app.StakingKeeper.IterateUnbondingDelegations(
|
||||
ctx,
|
||||
func(_ int64, ubd stakingtypes.UnbondingDelegation) (stop bool) {
|
||||
for i := range ubd.Entries {
|
||||
ubd.Entries[i].CreationHeight = 0
|
||||
}
|
||||
err = app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return false
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -202,8 +238,8 @@ func (app *SonrApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
|
||||
|
||||
for ; iter.Valid(); iter.Next() {
|
||||
addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key()))
|
||||
validator, errr := app.StakingKeeper.GetValidator(ctx, addr)
|
||||
if errr != nil {
|
||||
validator, err := app.StakingKeeper.GetValidator(ctx, addr)
|
||||
if err != nil {
|
||||
panic("expected validator, not found")
|
||||
}
|
||||
|
||||
@@ -218,8 +254,8 @@ func (app *SonrApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
|
||||
}
|
||||
}
|
||||
|
||||
if erra := iter.Close(); erra != nil {
|
||||
app.Logger().Error("error while closing the key-value store reverse prefix iterator: ", erra)
|
||||
if err := iter.Close(); err != nil {
|
||||
app.Logger().Error("error while closing the key-value store reverse prefix iterator: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -235,8 +271,8 @@ func (app *SonrApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
|
||||
ctx,
|
||||
func(addr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool) {
|
||||
info.StartHeight = 0
|
||||
if errb := app.SlashingKeeper.SetValidatorSigningInfo(ctx, addr, info); errb != nil {
|
||||
panic(errb)
|
||||
if err := app.SlashingKeeper.SetValidatorSigningInfo(ctx, addr, info); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return false
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user