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" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" bankexported "github.com/cosmos/cosmos-sdk/x/bank/exported" "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) 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 account has a sufficient // balance in the set of genesis accounts. func ValidateAccountInGenesis( appGenesisState map[string]json.RawMessage, genBalIterator types.GenesisBalancesIterator, addr sdk.Address, coins sdk.Coins, cdc *codec.Codec, ) error { var stakingData stakingtypes.GenesisState cdc.MustUnmarshalJSON(appGenesisState[stakingtypes.ModuleName], &stakingData) bondDenom := stakingData.Params.BondDenom var err error accountIsInGenesis := false genBalIterator.IterateGenesisBalances(cdc, appGenesisState, func(bal bankexported.GenesisBalance) (stop bool) { accAddress := bal.GetAddress() accCoins := bal.GetCoins() // ensure that account is in genesis if accAddress.Equals(addr) { // ensure account contains enough funds of default bond denom if coins.AmountOf(bondDenom).GT(accCoins.AmountOf(bondDenom)) { err = fmt.Errorf( "account %s has a balance in genesis, but it only has %v%s available to stake, not %v%s", addr, 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 does not have a balance in the genesis state", addr) } return nil } type deliverTxfn func(abci.RequestDeliverTx) abci.ResponseDeliverTx // DeliverGenTxs iterates over all genesis txs, decodes each into a StdTx and // invokes the provided deliverTxfn with the decoded StdTx. It returns the result // of the staking module's ApplyAndReturnValidatorSetUpdates. 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) }