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

     1  package keeper
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/hex"
     6  	"fmt"
     7  	"strconv"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/mpt"
    12  
    13  	types2 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec/types"
    14  
    15  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/exported"
    16  
    17  	"github.com/fibonacci-chain/fbc/x/staking/types"
    18  	"github.com/stretchr/testify/require"
    19  
    20  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    21  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto"
    22  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/ed25519"
    23  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/log"
    24  	tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types"
    25  	dbm "github.com/fibonacci-chain/fbc/libs/tm-db"
    26  
    27  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    28  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store"
    29  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    30  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth"
    31  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank"
    32  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/supply"
    33  	"github.com/fibonacci-chain/fbc/x/params"
    34  	//distr "github.com/fibonacci-chain/fbc/x/distribution"
    35  )
    36  
    37  // dummy addresses used for testing
    38  // nolint: unused deadcode
    39  var (
    40  	Addrs = createTestAddrs(500)
    41  	PKs   = createTestPubKeys(500)
    42  
    43  	addrDels = []sdk.AccAddress{
    44  		Addrs[0],
    45  		Addrs[1],
    46  		Addrs[2],
    47  	}
    48  
    49  	addrVals = []sdk.ValAddress{
    50  		sdk.ValAddress(Addrs[3]),
    51  		sdk.ValAddress(Addrs[4]),
    52  		sdk.ValAddress(Addrs[5]),
    53  		sdk.ValAddress(Addrs[6]),
    54  		sdk.ValAddress(Addrs[7]),
    55  	}
    56  
    57  	SufficientInitBalance = int64(10000)
    58  	InitMsd2000           = sdk.NewDec(2000)
    59  	TestChainID           = "stkchainid"
    60  )
    61  
    62  type MockStakingKeeper struct {
    63  	Keeper
    64  	StoreKey     sdk.StoreKey
    65  	TkeyStoreKey sdk.StoreKey
    66  	SupplyKeeper supply.Keeper
    67  	MountedStore store.MultiStore
    68  	AccKeeper    auth.AccountKeeper
    69  }
    70  
    71  func NewMockStakingKeeper(k Keeper, keyStoreKey, tkeyStoreKey sdk.StoreKey, sKeeper supply.Keeper,
    72  	ms store.MultiStore, accKeeper auth.AccountKeeper) MockStakingKeeper {
    73  	return MockStakingKeeper{
    74  		k,
    75  		keyStoreKey,
    76  		tkeyStoreKey,
    77  		sKeeper,
    78  		ms,
    79  		accKeeper,
    80  	}
    81  }
    82  
    83  //_______________________________________________________________________________________
    84  
    85  // MakeTestCodec creates a codec used only for testing
    86  func MakeTestCodec() *codec.Codec {
    87  	var cdc = codec.New()
    88  
    89  	// Register Msgs
    90  	cdc.RegisterInterface((*sdk.Msg)(nil), nil)
    91  	cdc.RegisterConcrete(bank.MsgSend{}, "test/staking/Send", nil)
    92  	cdc.RegisterConcrete(types.MsgCreateValidator{}, "test/staking/CreateValidator", nil)
    93  	cdc.RegisterConcrete(types.MsgDestroyValidator{}, "test/staking/DestroyValidator", nil)
    94  	cdc.RegisterConcrete(types.MsgEditValidator{}, "test/staking/EditValidator", nil)
    95  	cdc.RegisterConcrete(types.MsgWithdraw{}, "test/staking/MsgWithdraw", nil)
    96  	cdc.RegisterConcrete(types.MsgAddShares{}, "test/staking/MsgAddShares", nil)
    97  
    98  	// Register AppAccount
    99  	cdc.RegisterInterface((*exported.Account)(nil), nil)
   100  	cdc.RegisterConcrete(&auth.BaseAccount{}, "test/staking/BaseAccount", nil)
   101  	supply.RegisterCodec(cdc)
   102  	codec.RegisterCrypto(cdc)
   103  
   104  	return cdc
   105  }
   106  
   107  // CreateTestInput returns all sorts of input required for testing
   108  // initBalance is converted to an amount of tokens.
   109  func CreateTestInput(t *testing.T, isCheckTx bool, initBalance int64) (sdk.Context, auth.AccountKeeper, MockStakingKeeper) {
   110  
   111  	// init storage
   112  	keyStaking := sdk.NewKVStoreKey(types.StoreKey)
   113  	tkeyStaking := sdk.NewTransientStoreKey(types.TStoreKey)
   114  	keyAcc := sdk.NewKVStoreKey(auth.StoreKey)
   115  	keyMpt := sdk.NewKVStoreKey(mpt.StoreKey)
   116  	keyParams := sdk.NewKVStoreKey(params.StoreKey)
   117  	tkeyParams := sdk.NewTransientStoreKey(params.TStoreKey)
   118  	keySupply := sdk.NewKVStoreKey(supply.StoreKey)
   119  
   120  	db := dbm.NewMemDB()
   121  	ms := store.NewCommitMultiStore(db)
   122  	ms.MountStoreWithDB(tkeyStaking, sdk.StoreTypeTransient, nil)
   123  	ms.MountStoreWithDB(keyStaking, sdk.StoreTypeIAVL, db)
   124  	ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db)
   125  	ms.MountStoreWithDB(keyMpt, sdk.StoreTypeMPT, db)
   126  	ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db)
   127  	ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db)
   128  	ms.MountStoreWithDB(keySupply, sdk.StoreTypeIAVL, db)
   129  	err := ms.LoadLatestVersion()
   130  	require.Nil(t, err)
   131  
   132  	// init context
   133  	ctx := sdk.NewContext(ms, abci.Header{ChainID: TestChainID}, isCheckTx, log.NewNopLogger())
   134  	ctx.SetConsensusParams(
   135  		&abci.ConsensusParams{
   136  			Validator: &abci.ValidatorParams{
   137  				PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeEd25519},
   138  			},
   139  		},
   140  	)
   141  	ctx.SetBlockTime(time.Now())
   142  	cdc := MakeTestCodec()
   143  	reg := types2.NewInterfaceRegistry()
   144  	cc := codec.NewProtoCodec(reg)
   145  	pro := codec.NewCodecProxy(cc, cdc)
   146  
   147  	feeCollectorAcc := supply.NewEmptyModuleAccount(auth.FeeCollectorName)
   148  	notBondedPool := supply.NewEmptyModuleAccount(types.NotBondedPoolName, supply.Burner, supply.Staking)
   149  	bondPool := supply.NewEmptyModuleAccount(types.BondedPoolName, supply.Burner, supply.Staking)
   150  
   151  	blacklistedAddrs := make(map[string]bool)
   152  	blacklistedAddrs[feeCollectorAcc.String()] = true
   153  	blacklistedAddrs[notBondedPool.String()] = true
   154  	blacklistedAddrs[bondPool.String()] = true
   155  
   156  	// init module keepers
   157  	pk := params.NewKeeper(cdc, keyParams, tkeyParams, log.NewNopLogger())
   158  
   159  	accountKeeper := auth.NewAccountKeeper(
   160  		cdc,    // amino codec
   161  		keyAcc, // target store
   162  		keyMpt,
   163  		pk.Subspace(auth.DefaultParamspace),
   164  		auth.ProtoBaseAccount, // prototype
   165  	)
   166  
   167  	bk := bank.NewBaseKeeper(
   168  		accountKeeper,
   169  		pk.Subspace(bank.DefaultParamspace),
   170  		blacklistedAddrs,
   171  	)
   172  
   173  	maccPerms := map[string][]string{
   174  		auth.FeeCollectorName:   nil,
   175  		types.NotBondedPoolName: {supply.Burner, supply.Staking},
   176  		types.BondedPoolName:    {supply.Burner, supply.Staking},
   177  	}
   178  	supplyKeeper := supply.NewKeeper(cdc, keySupply, accountKeeper, bank.NewBankKeeperAdapter(bk), maccPerms)
   179  
   180  	initTokens := sdk.NewInt(initBalance)
   181  	initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens))
   182  	totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens.MulRaw(int64(len(Addrs)))))
   183  
   184  	supplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply))
   185  
   186  	keeper := NewKeeper(pro, keyStaking, supplyKeeper, pk.Subspace(DefaultParamspace))
   187  	keeper.SetParams(ctx, types.DefaultParams())
   188  
   189  	// set module accounts
   190  	supplyKeeper.SetModuleAccount(ctx, feeCollectorAcc)
   191  	supplyKeeper.SetModuleAccount(ctx, bondPool)
   192  
   193  	// fill all the addresses with some coins, set the loose pool tokens simultaneously
   194  	for _, addr := range Addrs {
   195  		_, err := bk.AddCoins(ctx, addr, initCoins)
   196  		if err != nil {
   197  			panic(err)
   198  		}
   199  	}
   200  
   201  	distrKeeper := mockDistributionKeeper{}
   202  	hooks := types.NewMultiStakingHooks(distrKeeper.Hooks())
   203  	keeper.SetHooks(hooks)
   204  
   205  	mockKeeper := NewMockStakingKeeper(keeper, keyStaking, tkeyStaking,
   206  		supplyKeeper, ms, accountKeeper)
   207  
   208  	return ctx, accountKeeper, mockKeeper
   209  }
   210  
   211  func NewPubKey(pk string) (res crypto.PubKey) {
   212  	pkBytes, err := hex.DecodeString(pk)
   213  	if err != nil {
   214  		panic(err)
   215  	}
   216  	//res, err = crypto.PubKeyFromBytes(pkBytes)
   217  	var pkEd ed25519.PubKeyEd25519
   218  	copy(pkEd[:], pkBytes[:])
   219  	return pkEd
   220  }
   221  
   222  // TestAddr is designed for incode address generation
   223  func TestAddr(addr string, bech string) sdk.AccAddress {
   224  
   225  	res, err := sdk.AccAddressFromHex(addr)
   226  	if err != nil {
   227  		panic(err)
   228  	}
   229  	bechexpected := res.String()
   230  	if bech != bechexpected {
   231  		panic("Bech encoding doesn't match reference")
   232  	}
   233  
   234  	bechres, err := sdk.AccAddressFromBech32(bech)
   235  	if err != nil {
   236  		panic(err)
   237  	}
   238  	if !bytes.Equal(bechres, res) {
   239  		panic("Bech decode and hex decode don't match")
   240  	}
   241  
   242  	return res
   243  }
   244  
   245  func createTestAddrs(numAddrs int) []sdk.AccAddress {
   246  	var addresses []sdk.AccAddress
   247  	var buffer bytes.Buffer
   248  
   249  	// start at 100 so we can make up to 999 test addresses with valid test addresses
   250  	for i := 100; i < (numAddrs + 100); i++ {
   251  		numString := strconv.Itoa(i)
   252  		buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") //base address string
   253  
   254  		buffer.WriteString(numString) //adding on final two digits to make addresses unique
   255  		res, err := sdk.AccAddressFromHex(buffer.String())
   256  		if err != nil {
   257  			fmt.Print("error")
   258  		}
   259  		bech := res.String()
   260  		addresses = append(addresses, TestAddr(buffer.String(), bech))
   261  		buffer.Reset()
   262  	}
   263  	return addresses
   264  }
   265  
   266  // nolint: unparam
   267  func createTestPubKeys(numPubKeys int) []crypto.PubKey {
   268  	var publicKeys []crypto.PubKey
   269  	var buffer bytes.Buffer
   270  
   271  	//start at 10 to avoid changing 1 to 01, 2 to 02, etc
   272  	for i := 100; i < (numPubKeys + 100); i++ {
   273  		numString := strconv.Itoa(i)
   274  		buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AF") //base pubkey string
   275  		buffer.WriteString(numString)                                                       //adding on final two digits to make pubkeys unique
   276  		publicKeys = append(publicKeys, NewPubKey(buffer.String()))
   277  		buffer.Reset()
   278  	}
   279  	return publicKeys
   280  }
   281  
   282  //_____________________________________________________________________________________
   283  
   284  // ValidatorByPowerIndexExists checks whether a certain by-power index record exist
   285  func ValidatorByPowerIndexExists(ctx sdk.Context, keeper MockStakingKeeper, power []byte) bool {
   286  	store := ctx.KVStore(keeper.StoreKey)
   287  	return store.Has(power)
   288  }
   289  
   290  func NewTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, msdAmt sdk.Dec) types.MsgCreateValidator {
   291  	msd := sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, msdAmt)
   292  
   293  	return types.NewMsgCreateValidator(address, pubKey,
   294  		types.NewDescription("my moniker", "my identity", "my website", "my details"), msd,
   295  	)
   296  }
   297  
   298  func NewTestMsgDeposit(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt sdk.Dec) types.MsgDeposit {
   299  	amount := sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, amt)
   300  	return types.NewMsgDeposit(delAddr, amount)
   301  }
   302  
   303  func SimpleCheckValidator(t *testing.T, ctx sdk.Context, stkKeeper Keeper, vaAddr sdk.ValAddress,
   304  	expMsd sdk.Dec, expStatus sdk.BondStatus, expDlgShares sdk.Dec, expJailed bool) *types.Validator {
   305  	val, ok := stkKeeper.GetValidator(ctx, vaAddr)
   306  	require.True(t, ok)
   307  	require.True(t, val.GetMinSelfDelegation().Equal(expMsd), val.MinSelfDelegation.String(), expMsd.String())
   308  	require.True(t, val.GetStatus().Equal(expStatus), val.GetStatus().String(), expStatus.String())
   309  	require.True(t, val.GetDelegatorShares().Equal(expDlgShares), val.GetDelegatorShares().String(), expDlgShares.String())
   310  	require.True(t, val.IsJailed() == expJailed)
   311  
   312  	return &val
   313  }
   314  
   315  // mockDistributionKeeper is supported to test Hooks
   316  type mockDistributionKeeper struct{}
   317  
   318  func (dk mockDistributionKeeper) Hooks() types.StakingHooks                                       { return dk }
   319  func (dk mockDistributionKeeper) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress)   {}
   320  func (dk mockDistributionKeeper) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {}
   321  func (dk mockDistributionKeeper) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
   322  }
   323  func (dk mockDistributionKeeper) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
   324  }
   325  func (dk mockDistributionKeeper) AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
   326  }
   327  func (dk mockDistributionKeeper) AfterValidatorDestroyed(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
   328  }