Skip to content

Commit

Permalink
sovereign: migrate export.go
Browse files Browse the repository at this point in the history
  • Loading branch information
MSalopek committed Oct 13, 2023
1 parent eed7c10 commit 69f7341
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 19 deletions.
3 changes: 3 additions & 0 deletions app/sovereign/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Sovereign/Standalone chain

Standalone simapp is modeled after the `app/consumer/app.go`. It must support all features that `app/consumer/app.go` supports so we can use it in standalone to consumer changeover procedures in our test suites.
84 changes: 84 additions & 0 deletions app/sovereign/abci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package app

import (
"bytes"
"crypto/rand"
"encoding/json"
"fmt"

abci "github.com/cometbft/cometbft/abci/types"

"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
)

type (
// VoteExtensionHandler defines a dummy vote extension handler for SimApp.
//
// NOTE: This implementation is solely used for testing purposes. DO NOT use
// in a production application!
VoteExtensionHandler struct{}

// VoteExtension defines the structure used to create a dummy vote extension.
VoteExtension struct {
Hash []byte
Height int64
Data []byte
}
)

func NewVoteExtensionHandler() *VoteExtensionHandler {
return &VoteExtensionHandler{}
}

func (h *VoteExtensionHandler) SetHandlers(bApp *baseapp.BaseApp) {
bApp.SetExtendVoteHandler(h.ExtendVote())
bApp.SetVerifyVoteExtensionHandler(h.VerifyVoteExtension())
}

func (h *VoteExtensionHandler) ExtendVote() sdk.ExtendVoteHandler {
return func(_ sdk.Context, req *abci.RequestExtendVote) (*abci.ResponseExtendVote, error) {
buf := make([]byte, 1024)

_, err := rand.Read(buf)
if err != nil {
return nil, fmt.Errorf("failed to generate random vote extension data: %w", err)
}

ve := VoteExtension{
Hash: req.Hash,
Height: req.Height,
Data: buf,
}

bz, err := json.Marshal(ve)
if err != nil {
return nil, fmt.Errorf("failed to encode vote extension: %w", err)
}

return &abci.ResponseExtendVote{VoteExtension: bz}, nil
}
}

func (h *VoteExtensionHandler) VerifyVoteExtension() sdk.VerifyVoteExtensionHandler {
return func(ctx sdk.Context, req *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) {
var ve VoteExtension

if err := json.Unmarshal(req.VoteExtension, &ve); err != nil {
return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil
}

switch {
case req.Height != ve.Height:
return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil

case !bytes.Equal(req.Hash, ve.Hash):
return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil

case len(ve.Data) != 1024:
return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil
}

return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_ACCEPT}, nil
}
}
75 changes: 56 additions & 19 deletions app/sovereign/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ package app

import (
"encoding/json"
"errors"
"log"

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"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"

tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
)

// ExportAppStateAndValidators exports the state of the application for a genesis
Expand All @@ -19,7 +20,7 @@ func (app *App) ExportAppStateAndValidators(
forZeroHeight bool, jailAllowedAddrs, modulesToExport []string,
) (servertypes.ExportedApp, error) {
// as if they could withdraw from the start of the next block
ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()})
ctx := app.NewContext(true)

// We export at last height + 1, because that's the height at which
// Tendermint will start InitChain.
Expand All @@ -29,7 +30,10 @@ func (app *App) ExportAppStateAndValidators(
app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs)
}

genState := app.MM.ExportGenesis(ctx, app.appCodec)
genState, err := app.MM.ExportGenesis(ctx, app.appCodec)
if err != nil {
return servertypes.ExportedApp{}, err
}
appState, err := json.MarshalIndent(genState, "", " ")
if err != nil {
return servertypes.ExportedApp{}, err
Expand Down Expand Up @@ -76,20 +80,31 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str

// withdraw all validator commission
app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
_, err := app.DistrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator())
valBz, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator())

if err != nil {
panic(err)
}
_, _ = app.DistrKeeper.WithdrawValidatorCommission(ctx, valBz)
return false
})

// withdraw all delegator rewards
dels := app.StakingKeeper.GetAllDelegations(ctx)
dels, err := app.StakingKeeper.GetAllDelegations(ctx)
if err != nil {
panic(err)
}
for _, delegation := range dels {
_, err := app.DistrKeeper.WithdrawDelegationRewards(ctx, delegation.GetDelegatorAddr(), delegation.GetValidatorAddr())
valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
if err != nil {
panic(err)
}

delAddr, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress)
if err != nil {
panic(err)
}
_, _ = app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr)
}

// clear validator slash events
Expand All @@ -103,27 +118,49 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str
ctx = ctx.WithBlockHeight(0)

// reinitialize all validators
app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
err = app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
valBz, err := sdk.ValAddressFromBech32(val.GetOperator())
if err != nil {
panic(err)
}
// donate any unwithdrawn outstanding reward fraction tokens to the community pool
scraps := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator())
feePool := app.DistrKeeper.GetFeePool(ctx)
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...)
app.DistrKeeper.SetFeePool(ctx, feePool)
if err := app.DistrKeeper.FeePool.Set(ctx, feePool); err != nil {
panic(err)
}

err := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator())
if err != nil {
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 {
err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr())
valAddr, err := sdk.ValAddressFromBech32(del.ValidatorAddress)
if err != nil {
panic(err)
}
delAddr, err := sdk.AccAddressFromBech32(del.DelegatorAddress)
if err != nil {
panic(err)
}
err = app.DistrKeeper.Hooks().AfterDelegationModified(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr())
err = app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr)
if err != nil {
panic(err)
}
err = app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -155,14 +192,14 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str
// Iterate through validators by power descending, reset bond heights, and
// update bond intra-tx counters.
store := ctx.KVStore(app.keys[stakingtypes.StoreKey])
iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey)
iter := storetypes.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey)
counter := int16(0)

for ; iter.Valid(); iter.Next() {
addr := sdk.ValAddress(iter.Key()[1:])
validator, found := app.StakingKeeper.GetValidator(ctx, addr)
if !found {
panic("expected validator, not found")
validator, err := app.StakingKeeper.GetValidator(ctx, addr)
if err != nil {
panic(errors.New("expected validator, not found"))
}

validator.UnbondingHeight = 0
Expand Down

0 comments on commit 69f7341

Please sign in to comment.