github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/gov/test_common.go (about)

     1  // nolint
     2  // DONTCOVER
     3  package gov
     4  
     5  import (
     6  	"bytes"
     7  	"errors"
     8  	"log"
     9  	"sort"
    10  	"testing"
    11  
    12  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/ed25519"
    13  	"github.com/stretchr/testify/require"
    14  
    15  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    16  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto"
    17  
    18  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    19  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
    20  	authexported "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/exported"
    21  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank"
    22  	keep "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/gov/keeper"
    23  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/gov/types"
    24  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/mock"
    25  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking"
    26  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/supply"
    27  	supplyexported "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/supply/exported"
    28  )
    29  
    30  var (
    31  	valTokens  = sdk.TokensFromConsensusPower(42)
    32  	initTokens = sdk.TokensFromConsensusPower(100000)
    33  	valCoins   = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, valTokens))
    34  	initCoins  = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens))
    35  )
    36  
    37  type testInput struct {
    38  	mApp     *mock.App
    39  	keeper   keep.Keeper
    40  	router   types.Router
    41  	sk       staking.Keeper
    42  	addrs    []sdk.AccAddress
    43  	pubKeys  []crypto.PubKey
    44  	privKeys []crypto.PrivKey
    45  }
    46  
    47  func getMockApp(
    48  	t *testing.T, numGenAccs int, genState types.GenesisState, genAccs []authexported.Account,
    49  	handler func(ctx sdk.Context, c types.Content) error,
    50  ) testInput {
    51  
    52  	mApp := mock.NewApp()
    53  
    54  	staking.RegisterCodec(mApp.Cdc.GetCdc())
    55  	types.RegisterCodec(mApp.Cdc.GetCdc())
    56  	supply.RegisterCodec(mApp.Cdc.GetCdc())
    57  
    58  	keyStaking := sdk.NewKVStoreKey(staking.StoreKey)
    59  	keyGov := sdk.NewKVStoreKey(types.StoreKey)
    60  	keySupply := sdk.NewKVStoreKey(supply.StoreKey)
    61  
    62  	govAcc := supply.NewEmptyModuleAccount(types.ModuleName, supply.Burner)
    63  	notBondedPool := supply.NewEmptyModuleAccount(staking.NotBondedPoolName, supply.Burner, supply.Staking)
    64  	bondPool := supply.NewEmptyModuleAccount(staking.BondedPoolName, supply.Burner, supply.Staking)
    65  
    66  	blacklistedAddrs := make(map[string]bool)
    67  	blacklistedAddrs[govAcc.GetAddress().String()] = true
    68  	blacklistedAddrs[notBondedPool.GetAddress().String()] = true
    69  	blacklistedAddrs[bondPool.GetAddress().String()] = true
    70  
    71  	pk := mApp.ParamsKeeper
    72  
    73  	rtr := types.NewRouter().
    74  		AddRoute(types.RouterKey, handler)
    75  
    76  	bk := bank.NewBaseKeeper(mApp.AccountKeeper, mApp.ParamsKeeper.Subspace(bank.DefaultParamspace), blacklistedAddrs)
    77  
    78  	maccPerms := map[string][]string{
    79  		types.ModuleName:          {supply.Burner},
    80  		staking.NotBondedPoolName: {supply.Burner, supply.Staking},
    81  		staking.BondedPoolName:    {supply.Burner, supply.Staking},
    82  	}
    83  	supplyKeeper := supply.NewKeeper(mApp.Cdc.GetCdc(), keySupply, mApp.AccountKeeper, bank.NewBankKeeperAdapter(bk), maccPerms)
    84  	sk := staking.NewKeeper(
    85  		mApp.Cdc.GetCdc(), keyStaking, supplyKeeper, pk.Subspace(staking.DefaultParamspace),
    86  	)
    87  
    88  	keeper := keep.NewKeeper(
    89  		mApp.Cdc.GetCdc(), keyGov, pk.Subspace(DefaultParamspace).WithKeyTable(ParamKeyTable()), supplyKeeper, sk, rtr,
    90  	)
    91  
    92  	mApp.Router().AddRoute(types.RouterKey, NewHandler(keeper))
    93  	mApp.QueryRouter().AddRoute(types.QuerierRoute, keep.NewQuerier(keeper))
    94  
    95  	mApp.SetEndBlocker(getEndBlocker(keeper))
    96  	mApp.SetInitChainer(getInitChainer(mApp, keeper, sk, supplyKeeper, genAccs, genState,
    97  		[]supplyexported.ModuleAccountI{govAcc, notBondedPool, bondPool}))
    98  
    99  	require.NoError(t, mApp.CompleteSetup(keyStaking, keyGov, keySupply))
   100  
   101  	var (
   102  		addrs    []sdk.AccAddress
   103  		pubKeys  []crypto.PubKey
   104  		privKeys []crypto.PrivKey
   105  	)
   106  
   107  	if genAccs == nil || len(genAccs) == 0 {
   108  		genAccs, addrs, pubKeys, privKeys = mock.CreateGenAccounts(numGenAccs, valCoins)
   109  	}
   110  
   111  	mock.SetGenesis(mApp, genAccs)
   112  
   113  	return testInput{mApp, keeper, rtr, sk, addrs, pubKeys, privKeys}
   114  }
   115  
   116  // gov and staking endblocker
   117  func getEndBlocker(keeper Keeper) sdk.EndBlocker {
   118  	return func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
   119  		EndBlocker(ctx, keeper)
   120  		return abci.ResponseEndBlock{}
   121  	}
   122  }
   123  
   124  // gov and staking initchainer
   125  func getInitChainer(mapp *mock.App, keeper Keeper, stakingKeeper staking.Keeper, supplyKeeper supply.Keeper, accs []authexported.Account, genState GenesisState,
   126  	blacklistedAddrs []supplyexported.ModuleAccountI) sdk.InitChainer {
   127  	return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
   128  		mapp.InitChainer(ctx, req)
   129  
   130  		stakingGenesis := staking.DefaultGenesisState()
   131  
   132  		totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens.MulRaw(int64(len(mapp.GenesisAccounts)))))
   133  		supplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply))
   134  
   135  		// set module accounts
   136  		for _, macc := range blacklistedAddrs {
   137  			supplyKeeper.SetModuleAccount(ctx, macc)
   138  		}
   139  
   140  		validators := staking.InitGenesis(ctx, stakingKeeper, mapp.AccountKeeper, supplyKeeper, stakingGenesis)
   141  		if genState.IsEmpty() {
   142  			InitGenesis(ctx, keeper, supplyKeeper, types.DefaultGenesisState())
   143  		} else {
   144  			InitGenesis(ctx, keeper, supplyKeeper, genState)
   145  		}
   146  		return abci.ResponseInitChain{
   147  			Validators: validators,
   148  		}
   149  	}
   150  }
   151  
   152  // SortAddresses - Sorts Addresses
   153  func SortAddresses(addrs []sdk.AccAddress) {
   154  	var byteAddrs [][]byte
   155  	for _, addr := range addrs {
   156  		byteAddrs = append(byteAddrs, addr.Bytes())
   157  	}
   158  	SortByteArrays(byteAddrs)
   159  	for i, byteAddr := range byteAddrs {
   160  		addrs[i] = byteAddr
   161  	}
   162  }
   163  
   164  // implement `Interface` in sort package.
   165  type sortByteArrays [][]byte
   166  
   167  func (b sortByteArrays) Len() int {
   168  	return len(b)
   169  }
   170  
   171  func (b sortByteArrays) Less(i, j int) bool {
   172  	// bytes package already implements Comparable for []byte.
   173  	switch bytes.Compare(b[i], b[j]) {
   174  	case -1:
   175  		return true
   176  	case 0, 1:
   177  		return false
   178  	default:
   179  		log.Panic("not fail-able with `bytes.Comparable` bounded [-1, 1].")
   180  		return false
   181  	}
   182  }
   183  
   184  func (b sortByteArrays) Swap(i, j int) {
   185  	b[j], b[i] = b[i], b[j]
   186  }
   187  
   188  // SortByteArrays - sorts the provided byte array
   189  func SortByteArrays(src [][]byte) [][]byte {
   190  	sorted := sortByteArrays(src)
   191  	sort.Sort(sorted)
   192  	return sorted
   193  }
   194  
   195  const contextKeyBadProposal = "contextKeyBadProposal"
   196  
   197  // badProposalHandler implements a governance proposal handler that is identical
   198  // to the actual handler except this fails if the context doesn't contain a value
   199  // for the key contextKeyBadProposal or if the value is false.
   200  func badProposalHandler(ctx sdk.Context, c types.Content) error {
   201  	switch c.ProposalType() {
   202  	case types.ProposalTypeText:
   203  		v := ctx.Context().Value(contextKeyBadProposal)
   204  
   205  		if v == nil || !v.(bool) {
   206  			return errors.New("proposal failed")
   207  		}
   208  
   209  		return nil
   210  
   211  	default:
   212  		return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized gov proposal type: %s", c.ProposalType())
   213  	}
   214  }
   215  
   216  var (
   217  	pubkeys = []crypto.PubKey{
   218  		ed25519.GenPrivKey().PubKey(),
   219  		ed25519.GenPrivKey().PubKey(),
   220  		ed25519.GenPrivKey().PubKey(),
   221  	}
   222  )
   223  
   224  func createValidators(t *testing.T, stakingHandler sdk.Handler, ctx sdk.Context, addrs []sdk.ValAddress, powerAmt []int64) {
   225  	require.True(t, len(addrs) <= len(pubkeys), "Not enough pubkeys specified at top of file.")
   226  
   227  	for i := 0; i < len(addrs); i++ {
   228  
   229  		valTokens := sdk.TokensFromConsensusPower(powerAmt[i])
   230  		valCreateMsg := staking.NewMsgCreateValidator(
   231  			addrs[i], pubkeys[i], sdk.NewCoin(sdk.DefaultBondDenom, valTokens),
   232  			keep.TestDescription, keep.TestCommissionRates, sdk.OneInt(),
   233  		)
   234  
   235  		res, err := stakingHandler(ctx, valCreateMsg)
   236  		require.NoError(t, err)
   237  		require.NotNil(t, res)
   238  	}
   239  }