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

     1  package keeper // noalias
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/hex"
     6  	"math/rand"
     7  	"strconv"
     8  	"testing"
     9  
    10  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/mpt"
    11  
    12  	"github.com/stretchr/testify/require"
    13  
    14  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    15  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto"
    16  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/ed25519"
    17  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/log"
    18  	tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types"
    19  	dbm "github.com/fibonacci-chain/fbc/libs/tm-db"
    20  
    21  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    22  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store"
    23  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    24  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth"
    25  	authexported "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/exported"
    26  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank"
    27  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/params"
    28  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking/types"
    29  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/supply"
    30  )
    31  
    32  // dummy addresses used for testing
    33  // nolint:unused, deadcode
    34  var (
    35  	Addrs = createTestAddrs(500)
    36  	PKs   = createTestPubKeys(500)
    37  
    38  	addrDels = []sdk.AccAddress{
    39  		Addrs[0],
    40  		Addrs[1],
    41  	}
    42  	addrVals = []sdk.ValAddress{
    43  		sdk.ValAddress(Addrs[2]),
    44  		sdk.ValAddress(Addrs[3]),
    45  		sdk.ValAddress(Addrs[4]),
    46  		sdk.ValAddress(Addrs[5]),
    47  		sdk.ValAddress(Addrs[6]),
    48  	}
    49  )
    50  
    51  //_______________________________________________________________________________________
    52  
    53  // intended to be used with require/assert:  require.True(ValEq(...))
    54  func ValEq(t *testing.T, exp, got types.Validator) (*testing.T, bool, string, types.Validator, types.Validator) {
    55  	return t, exp.TestEquivalent(got), "expected:\t%v\ngot:\t\t%v", exp, got
    56  }
    57  
    58  //_______________________________________________________________________________________
    59  
    60  // create a codec used only for testing
    61  func MakeTestCodec() *codec.Codec {
    62  	var cdc = codec.New()
    63  
    64  	// Register Msgs
    65  	cdc.RegisterInterface((*sdk.Msg)(nil), nil)
    66  	cdc.RegisterConcrete(bank.MsgSend{}, "test/staking/Send", nil)
    67  	cdc.RegisterConcrete(types.MsgCreateValidator{}, "test/staking/CreateValidator", nil)
    68  	cdc.RegisterConcrete(types.MsgEditValidator{}, "test/staking/EditValidator", nil)
    69  	cdc.RegisterConcrete(types.MsgUndelegate{}, "test/staking/Undelegate", nil)
    70  	cdc.RegisterConcrete(types.MsgBeginRedelegate{}, "test/staking/BeginRedelegate", nil)
    71  
    72  	// Register AppAccount
    73  	cdc.RegisterInterface((*authexported.Account)(nil), nil)
    74  	cdc.RegisterConcrete(&auth.BaseAccount{}, "test/staking/BaseAccount", nil)
    75  	supply.RegisterCodec(cdc)
    76  	codec.RegisterCrypto(cdc)
    77  
    78  	return cdc
    79  }
    80  
    81  // Hogpodge of all sorts of input required for testing.
    82  // `initPower` is converted to an amount of tokens.
    83  // If `initPower` is 0, no addrs get created.
    84  func CreateTestInput(t *testing.T, isCheckTx bool, initPower int64) (sdk.Context, auth.AccountKeeper, Keeper, types.SupplyKeeper) {
    85  	keyStaking := sdk.NewKVStoreKey(types.StoreKey)
    86  	keyAcc := sdk.NewKVStoreKey(auth.StoreKey)
    87  	keyMpt := sdk.NewKVStoreKey(mpt.StoreKey)
    88  	keyParams := sdk.NewKVStoreKey(params.StoreKey)
    89  	tkeyParams := sdk.NewTransientStoreKey(params.TStoreKey)
    90  	keySupply := sdk.NewKVStoreKey(supply.StoreKey)
    91  
    92  	db := dbm.NewMemDB()
    93  	ms := store.NewCommitMultiStore(db)
    94  	ms.MountStoreWithDB(keyStaking, sdk.StoreTypeIAVL, db)
    95  	ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db)
    96  	ms.MountStoreWithDB(keyMpt, sdk.StoreTypeMPT, db)
    97  	ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
    98  	ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db)
    99  	ms.MountStoreWithDB(keySupply, sdk.StoreTypeIAVL, db)
   100  	err := ms.LoadLatestVersion()
   101  	require.Nil(t, err)
   102  
   103  	ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, log.NewNopLogger())
   104  	ctx.SetConsensusParams(
   105  		&abci.ConsensusParams{
   106  			Validator: &abci.ValidatorParams{
   107  				PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeEd25519},
   108  			},
   109  		},
   110  	)
   111  	cdc := MakeTestCodec()
   112  
   113  	feeCollectorAcc := supply.NewEmptyModuleAccount(auth.FeeCollectorName)
   114  	notBondedPool := supply.NewEmptyModuleAccount(types.NotBondedPoolName, supply.Burner, supply.Staking)
   115  	bondPool := supply.NewEmptyModuleAccount(types.BondedPoolName, supply.Burner, supply.Staking)
   116  
   117  	blacklistedAddrs := make(map[string]bool)
   118  	blacklistedAddrs[feeCollectorAcc.GetAddress().String()] = true
   119  	blacklistedAddrs[notBondedPool.GetAddress().String()] = true
   120  	blacklistedAddrs[bondPool.GetAddress().String()] = true
   121  
   122  	pk := params.NewKeeper(cdc, keyParams, tkeyParams)
   123  
   124  	accountKeeper := auth.NewAccountKeeper(
   125  		cdc,    // amino codec
   126  		keyAcc, // target store
   127  		keyMpt,
   128  		pk.Subspace(auth.DefaultParamspace),
   129  		auth.ProtoBaseAccount, // prototype
   130  	)
   131  
   132  	bk := bank.NewBaseKeeper(
   133  		accountKeeper,
   134  		pk.Subspace(bank.DefaultParamspace),
   135  		blacklistedAddrs,
   136  	)
   137  
   138  	maccPerms := map[string][]string{
   139  		auth.FeeCollectorName:   nil,
   140  		types.NotBondedPoolName: {supply.Burner, supply.Staking},
   141  		types.BondedPoolName:    {supply.Burner, supply.Staking},
   142  	}
   143  	supplyKeeper := supply.NewKeeper(cdc, keySupply, accountKeeper, bank.NewBankKeeperAdapter(bk), maccPerms)
   144  
   145  	initTokens := sdk.TokensFromConsensusPower(initPower)
   146  	initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens))
   147  	totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens.MulRaw(int64(len(Addrs)))))
   148  
   149  	supplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply))
   150  
   151  	keeper := NewKeeper(cdc, keyStaking, supplyKeeper, pk.Subspace(DefaultParamspace))
   152  	keeper.SetParams(ctx, types.DefaultParams())
   153  
   154  	// set module accounts
   155  	err = notBondedPool.SetCoins(totalSupply)
   156  	require.NoError(t, err)
   157  
   158  	supplyKeeper.SetModuleAccount(ctx, feeCollectorAcc)
   159  	supplyKeeper.SetModuleAccount(ctx, bondPool)
   160  	supplyKeeper.SetModuleAccount(ctx, notBondedPool)
   161  
   162  	// fill all the addresses with some coins, set the loose pool tokens simultaneously
   163  	for _, addr := range Addrs {
   164  		_, err := bk.AddCoins(ctx, addr, initCoins)
   165  		if err != nil {
   166  			panic(err)
   167  		}
   168  	}
   169  
   170  	return ctx, accountKeeper, keeper, supplyKeeper
   171  }
   172  
   173  func NewPubKey(pk string) (res crypto.PubKey) {
   174  	pkBytes, err := hex.DecodeString(pk)
   175  	if err != nil {
   176  		panic(err)
   177  	}
   178  	//res, err = crypto.PubKeyFromBytes(pkBytes)
   179  	var pkEd ed25519.PubKeyEd25519
   180  	copy(pkEd[:], pkBytes)
   181  	return pkEd
   182  }
   183  
   184  // for incode address generation
   185  func TestAddr(addr string, bech string) sdk.AccAddress {
   186  
   187  	res, err := sdk.AccAddressFromHex(addr)
   188  	if err != nil {
   189  		panic(err)
   190  	}
   191  	bechexpected := res.String()
   192  	if bech != bechexpected {
   193  		panic("Bech encoding doesn't match reference")
   194  	}
   195  
   196  	bechres, err := sdk.AccAddressFromBech32(bech)
   197  	if err != nil {
   198  		panic(err)
   199  	}
   200  	if !bytes.Equal(bechres, res) {
   201  		panic("Bech decode and hex decode don't match")
   202  	}
   203  
   204  	return res
   205  }
   206  
   207  // nolint: unparam
   208  func createTestAddrs(numAddrs int) []sdk.AccAddress {
   209  	var addresses []sdk.AccAddress
   210  	var buffer bytes.Buffer
   211  
   212  	// start at 100 so we can make up to 999 test addresses with valid test addresses
   213  	for i := 100; i < (numAddrs + 100); i++ {
   214  		numString := strconv.Itoa(i)
   215  		buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") //base address string
   216  
   217  		buffer.WriteString(numString) //adding on final two digits to make addresses unique
   218  		res, _ := sdk.AccAddressFromHex(buffer.String())
   219  		bech := res.String()
   220  		addresses = append(addresses, TestAddr(buffer.String(), bech))
   221  		buffer.Reset()
   222  	}
   223  	return addresses
   224  }
   225  
   226  // nolint: unparam
   227  func createTestPubKeys(numPubKeys int) []crypto.PubKey {
   228  	var publicKeys []crypto.PubKey
   229  	var buffer bytes.Buffer
   230  
   231  	//start at 10 to avoid changing 1 to 01, 2 to 02, etc
   232  	for i := 100; i < (numPubKeys + 100); i++ {
   233  		numString := strconv.Itoa(i)
   234  		buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AF") //base pubkey string
   235  		buffer.WriteString(numString)                                                       //adding on final two digits to make pubkeys unique
   236  		publicKeys = append(publicKeys, NewPubKey(buffer.String()))
   237  		buffer.Reset()
   238  	}
   239  	return publicKeys
   240  }
   241  
   242  //_____________________________________________________________________________________
   243  
   244  // does a certain by-power index record exist
   245  func ValidatorByPowerIndexExists(ctx sdk.Context, keeper Keeper, power []byte) bool {
   246  	store := ctx.KVStore(keeper.storeKey)
   247  	return store.Has(power)
   248  }
   249  
   250  // update validator for testing
   251  func TestingUpdateValidator(keeper Keeper, ctx sdk.Context, validator types.Validator, apply bool) types.Validator {
   252  	keeper.SetValidator(ctx, validator)
   253  
   254  	// Remove any existing power key for validator.
   255  	store := ctx.KVStore(keeper.storeKey)
   256  	iterator := sdk.KVStorePrefixIterator(store, types.ValidatorsByPowerIndexKey)
   257  	defer iterator.Close()
   258  	deleted := false
   259  	for ; iterator.Valid(); iterator.Next() {
   260  		valAddr := types.ParseValidatorPowerRankKey(iterator.Key())
   261  		if bytes.Equal(valAddr, validator.OperatorAddress) {
   262  			if deleted {
   263  				panic("found duplicate power index key")
   264  			} else {
   265  				deleted = true
   266  			}
   267  			store.Delete(iterator.Key())
   268  		}
   269  	}
   270  
   271  	keeper.SetValidatorByPowerIndex(ctx, validator)
   272  	if apply {
   273  		keeper.ApplyAndReturnValidatorSetUpdates(ctx)
   274  		validator, found := keeper.GetValidator(ctx, validator.OperatorAddress)
   275  		if !found {
   276  			panic("validator expected but not found")
   277  		}
   278  		return validator
   279  	}
   280  	cachectx, _ := ctx.CacheContext()
   281  	keeper.ApplyAndReturnValidatorSetUpdates(cachectx)
   282  	validator, found := keeper.GetValidator(cachectx, validator.OperatorAddress)
   283  	if !found {
   284  		panic("validator expected but not found")
   285  	}
   286  	return validator
   287  }
   288  
   289  // nolint:deadcode, unused
   290  func validatorByPowerIndexExists(k Keeper, ctx sdk.Context, power []byte) bool {
   291  	store := ctx.KVStore(k.storeKey)
   292  	return store.Has(power)
   293  }
   294  
   295  // RandomValidator returns a random validator given access to the keeper and ctx
   296  func RandomValidator(r *rand.Rand, keeper Keeper, ctx sdk.Context) (val types.Validator, ok bool) {
   297  	vals := keeper.GetAllValidators(ctx)
   298  	if len(vals) == 0 {
   299  		return types.Validator{}, false
   300  	}
   301  
   302  	i := r.Intn(len(vals))
   303  	return vals[i], true
   304  }