package genutil // DONTCOVER import ( "encoding/json" "fmt" abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/genutil/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) // SetGenTxsInAppGenesisState - sets the genesis transactions in the app genesis state func SetGenTxsInAppGenesisState(cdc *codec.Codec, appGenesisState map[string]json.RawMessage, genTxs []authtypes.StdTx) (map[string]json.RawMessage, error) { genesisState := GetGenesisStateFromAppState(cdc, appGenesisState) // convert all the GenTxs to JSON genTxsBz := make([]json.RawMessage, 0, len(genTxs)) for _, genTx := range genTxs { txBz, err := cdc.MarshalJSON(genTx) if err != nil { return appGenesisState, err } genTxsBz = append(genTxsBz, txBz) } genesisState.GenTxs = genTxsBz return SetGenesisStateInAppState(cdc, appGenesisState, genesisState), nil } // ValidateAccountInGenesis checks that the provided key has sufficient // coins in the genesis accounts func ValidateAccountInGenesis(appGenesisState map[string]json.RawMessage, genAccIterator types.GenesisAccountsIterator, key sdk.Address, coins sdk.Coins, cdc *codec.Codec) error { accountIsInGenesis := false // TODO: refactor out bond denom to common state area stakingDataBz := appGenesisState[stakingtypes.ModuleName] var stakingData stakingtypes.GenesisState cdc.MustUnmarshalJSON(stakingDataBz, &stakingData) bondDenom := stakingData.Params.BondDenom genUtilDataBz := appGenesisState[stakingtypes.ModuleName] var genesisState GenesisState cdc.MustUnmarshalJSON(genUtilDataBz, &genesisState) var err error genAccIterator.IterateGenesisAccounts(cdc, appGenesisState, func(acc authexported.Account) (stop bool) { accAddress := acc.GetAddress() accCoins := acc.GetCoins() // Ensure that account is in genesis if accAddress.Equals(key) { // Ensure account contains enough funds of default bond denom if coins.AmountOf(bondDenom).GT(accCoins.AmountOf(bondDenom)) { err = fmt.Errorf( "account %v is in genesis, but it only has %v%v available to stake, not %v%v", key.String(), accCoins.AmountOf(bondDenom), bondDenom, coins.AmountOf(bondDenom), bondDenom, ) return true } accountIsInGenesis = true return true } return false }, ) if err != nil { return err } if !accountIsInGenesis { return fmt.Errorf("account %s in not in the app_state.accounts array of genesis.json", key) } return nil } type deliverTxfn func(abci.RequestDeliverTx) abci.ResponseDeliverTx // DeliverGenTxs - deliver a genesis transaction func DeliverGenTxs(ctx sdk.Context, cdc *codec.Codec, genTxs []json.RawMessage, stakingKeeper types.StakingKeeper, deliverTx deliverTxfn) []abci.ValidatorUpdate { for _, genTx := range genTxs { var tx authtypes.StdTx cdc.MustUnmarshalJSON(genTx, &tx) bz := cdc.MustMarshalBinaryLengthPrefixed(tx) res := deliverTx(abci.RequestDeliverTx{Tx: bz}) if !res.IsOK() { panic(res.Log) } } return stakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) }