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 }