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  }