github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/simapp/export.go (about) 1 package simapp 2 3 import ( 4 "encoding/json" 5 "log" 6 7 abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types" 8 tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types" 9 10 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec" 11 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 12 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/slashing" 13 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking" 14 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking/exported" 15 ) 16 17 // ExportAppStateAndValidators exports the state of the application for a genesis 18 // file. 19 func (app *SimApp) ExportAppStateAndValidators( 20 forZeroHeight bool, jailWhiteList []string, 21 ) (appState json.RawMessage, validators []tmtypes.GenesisValidator, err error) { 22 23 // as if they could withdraw from the start of the next block 24 ctx := app.NewContext(true, abci.Header{Height: app.LastBlockHeight()}) 25 26 if forZeroHeight { 27 app.prepForZeroHeightGenesis(ctx, jailWhiteList) 28 } 29 30 genState := app.mm.ExportGenesis(ctx) 31 appState, err = codec.MarshalJSONIndent(app.cdc, genState) 32 if err != nil { 33 return nil, nil, err 34 } 35 36 validators = staking.WriteValidators(ctx, app.StakingKeeper) 37 return appState, validators, nil 38 } 39 40 // prepare for fresh start at zero height 41 // NOTE zero height genesis is a temporary feature which will be deprecated 42 // 43 // in favour of export at a block height 44 func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailWhiteList []string) { 45 applyWhiteList := false 46 47 //Check if there is a whitelist 48 if len(jailWhiteList) > 0 { 49 applyWhiteList = true 50 } 51 52 whiteListMap := make(map[string]bool) 53 54 for _, addr := range jailWhiteList { 55 _, err := sdk.ValAddressFromBech32(addr) 56 if err != nil { 57 log.Fatal(err) 58 } 59 whiteListMap[addr] = true 60 } 61 62 /* Just to be safe, assert the invariants on current state. */ 63 app.CrisisKeeper.AssertInvariants(ctx) 64 65 /* Handle fee distribution state. */ 66 67 // withdraw all validator commission 68 app.StakingKeeper.IterateValidators(ctx, func(_ int64, val exported.ValidatorI) (stop bool) { 69 _, _ = app.DistrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator()) 70 return false 71 }) 72 73 // withdraw all delegator rewards 74 dels := app.StakingKeeper.GetAllDelegations(ctx) 75 for _, delegation := range dels { 76 _, _ = app.DistrKeeper.WithdrawDelegationRewards(ctx, delegation.DelegatorAddress, delegation.ValidatorAddress) 77 } 78 79 // clear validator slash events 80 app.DistrKeeper.DeleteAllValidatorSlashEvents(ctx) 81 82 // clear validator historical rewards 83 app.DistrKeeper.DeleteAllValidatorHistoricalRewards(ctx) 84 85 // set context height to zero 86 height := ctx.BlockHeight() 87 ctx.SetBlockHeight(0) 88 89 // reinitialize all validators 90 app.StakingKeeper.IterateValidators(ctx, func(_ int64, val exported.ValidatorI) (stop bool) { 91 92 // donate any unwithdrawn outstanding reward fraction tokens to the community pool 93 scraps := app.DistrKeeper.GetValidatorOutstandingRewards(ctx, val.GetOperator()) 94 feePool := app.DistrKeeper.GetFeePool(ctx) 95 feePool.CommunityPool = feePool.CommunityPool.Add(scraps...) 96 app.DistrKeeper.SetFeePool(ctx, feePool) 97 98 app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()) 99 return false 100 }) 101 102 // reinitialize all delegations 103 for _, del := range dels { 104 app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, del.DelegatorAddress, del.ValidatorAddress) 105 app.DistrKeeper.Hooks().AfterDelegationModified(ctx, del.DelegatorAddress, del.ValidatorAddress) 106 } 107 108 // reset context height 109 ctx.SetBlockHeight(height) 110 111 /* Handle staking state. */ 112 113 // iterate through redelegations, reset creation height 114 app.StakingKeeper.IterateRedelegations(ctx, func(_ int64, red staking.Redelegation) (stop bool) { 115 for i := range red.Entries { 116 red.Entries[i].CreationHeight = 0 117 } 118 app.StakingKeeper.SetRedelegation(ctx, red) 119 return false 120 }) 121 122 // iterate through unbonding delegations, reset creation height 123 app.StakingKeeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd staking.UnbondingDelegation) (stop bool) { 124 for i := range ubd.Entries { 125 ubd.Entries[i].CreationHeight = 0 126 } 127 app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) 128 return false 129 }) 130 131 // Iterate through validators by power descending, reset bond heights, and 132 // update bond intra-tx counters. 133 store := ctx.KVStore(app.keys[staking.StoreKey]) 134 iter := sdk.KVStoreReversePrefixIterator(store, staking.ValidatorsKey) 135 counter := int16(0) 136 137 for ; iter.Valid(); iter.Next() { 138 addr := sdk.ValAddress(iter.Key()[1:]) 139 validator, found := app.StakingKeeper.GetValidator(ctx, addr) 140 if !found { 141 panic("expected validator, not found") 142 } 143 144 validator.UnbondingHeight = 0 145 if applyWhiteList && !whiteListMap[addr.String()] { 146 validator.Jailed = true 147 } 148 149 app.StakingKeeper.SetValidator(ctx, validator) 150 counter++ 151 } 152 153 iter.Close() 154 155 _ = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) 156 157 /* Handle slashing state. */ 158 159 // reset start height on signing infos 160 app.SlashingKeeper.IterateValidatorSigningInfos( 161 ctx, 162 func(addr sdk.ConsAddress, info slashing.ValidatorSigningInfo) (stop bool) { 163 info.StartHeight = 0 164 app.SlashingKeeper.SetValidatorSigningInfo(ctx, addr, info) 165 return false 166 }, 167 ) 168 }